/* ---------- Project page ----------
   Layout: headline on top (cols 1–5); below it a row of labelled columns —
   Client (1–4), one empty column, Sector (6–7; class still `--industry`), Scope (8–9), then the project media
   (row 1: logo video on 5–12; row 2: Numbers image 1–4 with the Bagel 7–9 and Numbers 01 10–12 squares;
   row 3: Yes on 1–7 and World on 9–12; row 4: Graphic 01 on 1–3 with the project
   picture on 5–12; row 5: Images 01 on 1–6 with the phone mockup on 8–12;
   row 6: Cards on 1–3 with Web 04 on 5–12).
   Inspired by mouthwash.studio's project pages (labelled 16px columns) but with no rule.
   Everything sits on the shared 12-column grid (css/grid.css), with no
   padding/gap tweaks of its own: the grid decides.
   See docs/project-page.md. */

.project {
  padding-top: var(--content-top-space);
  padding-bottom: 200px;
}

/* ---- Headline + info row ---- */
.project-header {
  align-items: start;
  /* Rows are separated by the margin on the items below, not by the grid gap. */
  row-gap: 0;
}

.project-title {
  grid-column: 1 / span 5;
  font-family: var(--font-body);
  /* Identical to the home's "Selected Work" heading (.work-title in
     css/work.css) in every property — client request, change both together.
     Size is ~60% of the first version (4vw, mouthwash's own ratio): 36px at 1440. */
  font-size: clamp(28px, 2.5vw, 56px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.project-header-item {
  /* Same distance from the headline as when a thin rule sat here (that gap,
     plus the 12px the labels used to sit below the rule). */
  margin-top: calc(clamp(80px, 12vw, 200px) + 12px);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
}

.project-header-item--client {
  grid-column: 1 / span 4;
}

.project-header-item--industry {
  grid-column: 6 / span 2;
}

.project-header-item--scope {
  grid-column: 8 / span 2;
}

.project-header-label {
  font-size: 16px;
  font-weight: 500;
  color: var(--nav-link-inactive);
  transition: color 0.3s ease;
}

/* Values inherit body's animated color, so they follow the theme fade with
   no transition of their own. */
.project-header-value {
  color: inherit;
}

.project-scope-list {
  list-style: none;
}

/* ---- Media ---- */
.project-media {
  margin-top: 64px;
  row-gap: 10px;
  /* The Numbers image is much taller than the squares beside it; without this
     their frames would stretch to the same height and leave empty boxes. */
  align-items: start;
}

.project-video-frame {
  overflow: hidden;
  border-radius: var(--nav-radius);
  background: var(--color-surface);
  transition: background-color 0.3s ease;
}

.project-video {
  display: block;
  width: 100%;
  height: auto;
}

/* All direct children of .project-media (page columns, no nested grid).
   .project-media aligns items to the top, so a shorter square doesn't stretch
   to the height of its neighbour.
   Row 1: the logo video on columns 5–12 (flush right).
   Row 2: the Numbers image on 1–4, then the Bagel (7–9) and Numbers 01 (10–12)
   squares, 3 columns each, flush right.
   Row 3: the Yes video on 1–7 (left) and the World square on 9–12 (flush right).
   The Images 01 video (1–6) is not here: it's in .project-media-end, under the full-bleed picture.
   (The Graphic 01 square and 3.mp4 are out for now.) */
/* Top-aligned with the phone mockup beside it (.project-image-frame--phone),
   overriding .project-media-end's own align-items: end. */
.project-video-frame--images {
  grid-column: 1 / span 6;
  align-self: start;
}

.project-video-frame--logo {
  grid-column: 5 / span 8;
}

.project-video-frame--bagel {
  grid-column: 7 / span 3;
}

.project-video-frame--numbers {
  grid-column: 10 / span 3;
}

.project-video-frame--world {
  grid-column: 9 / span 4;
}

.project-video-frame--yes {
  grid-column: 1 / span 7;
}

/* The tall Numbers image, on the left of row 2 (columns 1–4). */
.project-image-frame {
  grid-column: 1 / span 4;
  overflow: hidden;
  border-radius: var(--nav-radius);
  background: var(--color-surface);
  transition: background-color 0.3s ease;
}

/* Cards image, left of the Web 04 video in the same row (1–3), top-aligned
   against it — overrides .project-media-end's own align-items: end. */
/* Unarranged dump layout (BNE Merch, BNE Sonora, Cúmulos, Giro, AECID):
   frames use the shared .w-N grid.css widths (mostly .w-6, two per row,
   in file order) as the client starts picking a bespoke composition per
   project like MSP/Dayhoff above — some rows already sized to specific
   widths on request (e.g. BNE Merch row 1). Compound selectors so they
   beat .project-image-frame's own default grid-column above despite
   .w-N coming from grid.css, loaded earlier (equal specificity would
   otherwise let the later rule here lose to source order). */
.project-image-frame.w-1, .project-video-frame.w-1 { grid-column: span 1; }
.project-image-frame.w-2, .project-video-frame.w-2 { grid-column: span 2; }
.project-image-frame.w-3, .project-video-frame.w-3 { grid-column: span 3; }
.project-image-frame.w-4, .project-video-frame.w-4 { grid-column: span 4; }
.project-image-frame.w-5, .project-video-frame.w-5 { grid-column: span 5; }
.project-image-frame.w-6, .project-video-frame.w-6 { grid-column: span 6; }
.project-image-frame.w-7, .project-video-frame.w-7 { grid-column: span 7; }
.project-image-frame.w-8, .project-video-frame.w-8 { grid-column: span 8; }
.project-image-frame.w-9, .project-video-frame.w-9 { grid-column: span 9; }
.project-image-frame.w-10, .project-video-frame.w-10 { grid-column: span 10; }
.project-image-frame.w-11, .project-video-frame.w-11 { grid-column: span 11; }
.project-image-frame.w-12, .project-video-frame.w-12 { grid-column: span 12; }

/* BNE Merch: T-shirt flush against the left margin (column 1) —
   explicit start column since this isn't a plain .w-N span; Tarjetas
   (.w-4, auto-placed after it in source order) fills the remaining
   columns 9-12 on its own, top-aligned (the row's default). */
.project-image-frame--merch-tshirt-14 {
  grid-column: 1 / span 8;
}

/* Empty filler after a lone image: takes the rest of the row (cols 5-12)
   so the next frame wraps to a new row instead of auto-packing beside it.
   Same trick as .work-grid-spacer on the home. */
.project-media-spacer {
  grid-column: span 8;
}

/* AECID: 08.png flush against column 12 (cols 5-12), row 4. */
.project-image-frame--aecid-flush-right-8 {
  grid-column: 5 / span 8;
}

/* AECID: 05.png sits beside the horizontal 01.mp4 in row 3, bottom-aligned
   instead of the row's default top alignment, client request. */
.project-image-frame--aecid-05-bottom {
  align-self: end;
}

/* AECID: 02.png sits beside the taller 01.png in the last row,
   bottom-aligned instead of the row's default top alignment, client
   request. Explicit start column 1: 08.png (9 cols) + 02.png (3) would
   otherwise share a row, this forces 02.png onto a new one with 01.png. */
.project-image-frame--aecid-02-bottom {
  grid-column: 1 / span 3;
  align-self: end;
}

/* Giro: 7-col videos flush against column 12 (cols 6-12): 02.mp4 beside
   03.jpg in row 2, 04.mp4 alone in row 9. */
.project-video-frame--giro-flush-right-7 {
  grid-column: 6 / span 7;
}

/* Giro: 03.jpg sits beside the taller 02.mp4 in row 2, bottom-aligned
   instead of the row's default top alignment, client request. */
.project-image-frame--giro-03-bottom {
  align-self: end;
}

/* Giro: 01.mp4 alone in row 6, flush left (cols 1-9). */
.project-video-frame--giro-left-9 {
  grid-column: 1 / span 9;
}

/* Giro: 05.mp4 sits beside the taller 12.jpg in row 5, flush against
   column 12 (cols 6-12, right against the image), bottom-aligned
   instead of the row's default top alignment, client request. */
.project-video-frame--giro-05-bottom {
  grid-column: 6 / span 7;
  align-self: end;
}

/* Giro: 5-col images flush against column 12 (cols 8-12): 07.jpg beside
   03.mp4 in row 5, 10.jpg beside 17.jpg in row 9. */
.project-image-frame--giro-flush-right-5 {
  grid-column: 8 / span 5;
}

/* Giro: 06.mp4 flush against column 12 (cols 10-12), beside 07.mp4. */
.project-video-frame--giro-flush-right-3 {
  grid-column: 10 / span 3;
}

/* BNE Merch: Detalle-Cuaderno is shorter than Cuadernos beside it —
   bottom-aligned instead of the row's default top alignment, client
   request. */
.project-image-frame--merch-detalle-cuaderno-18 {
  align-self: end;
}

/* BNE Merch: Tarjetas/Pegatinas (4 cols each), right-aligned as a pair
   against column 12 — explicit start columns since the pair otherwise
   defaults to flush left. */
.project-image-frame--merch-tarjetas-19-row {
  grid-column: 5 / span 4;
}

.project-image-frame--merch-pegatinas-16-row {
  grid-column: 9 / span 4;
}

/* Cumulos, row by row.
   1: image 02 alone, 8 cols right-aligned (cols 5-12).
   2: image 06 (4 cols, auto-placed at col 1) + image 05 anchored to col 7
      (6 cols, the slot it had before) — leaves cols 5-6 empty.
   3: image 00 (8 cols, cols 1-8) + video 01 (3 cols, flush right, 10-12,
      top-aligned like every item in the grid).
   4: image 03 alone, 8 cols flush right (5-12).
   5: video 02 alone, 8 cols flush left (1-8); video 03 doesn't fit in the
      4 cols left, so it wraps.
   6: video 03 (6 cols, auto-placed at 1-6) + video 04 (4 cols, flush right,
      9-12), then image 04 alone on the last row, full width (12 cols).
   Anchors are explicit where an item would otherwise auto-place beside the
   previous one instead of opening a new row. */
.project-image-frame--cumulos-02 {
  grid-column: 5 / span 8;
}
.project-image-frame--cumulos-05 {
  grid-column: 7 / span 6;
}
.project-image-frame--cumulos-00 {
  grid-column: 1 / span 8;
}
.project-video-frame--cumulos-01 {
  grid-column: 10 / span 3;
}
.project-video-frame--cumulos-02 {
  grid-column: 1 / span 8;
}
.project-image-frame--cumulos-03 {
  grid-column: 5 / span 8;
}
.project-video-frame--cumulos-04 {
  grid-column: 9 / span 4;
}

/* Design Campaigns, Pusher row: Pusher 2 (8 cols) right-aligned against
   column 12, beside the vertical Pusher 3 (.w-3, auto-placed before it,
   flush left) — leaves column 4 empty rather than sitting flush against it. */
.project-image-frame--pusher-2 {
  grid-column: 5 / span 8;
}

/* Design Campaigns, Plural row 1: video 3 (6 cols) shifted one column right
   of where it'd auto-place after AGM 1 (.w-5) — leaves column 6 empty
   instead of sitting flush against it. */
/* Design Campaigns: Spin video, third row (right after Plural's video 0), flush
   left across 7 columns (client request). Explicit start so it always opens a new row
   after video 0 (which starts at column 4). On phones it goes full width, below. */
.project-video-frame--spin {
  grid-column: 1 / span 7;
}

/* Design Campaigns, Pusher row: Pusher 3 (3 cols) explicitly in column 1 so it
   always opens a new row — after the Spin video (cols 1-7) the cursor would
   otherwise leave room for it in cols 8-12, beside Spin. */
.project-image-frame.project-image-frame--pusher-3 { /* two classes: has to beat .w-3's own column rule */
  grid-column: 1 / span 3;
}

.project-video-frame--plural-3 {
  grid-column: 7 / span 6;
}

/* Design Campaigns, Mussolini row 2: Animated Poster (6 cols) flush left in
   cols 1-6, Trailer (4 cols) flush right against column 12 (cols 9-12).
   Explicit starts: after the 8-col Cover the cursor sits at col 9, so neither
   would otherwise open a new row at the left. */
.project-video-frame--mussolini-animated-poster {
  grid-column: 1 / span 6;
}
.project-video-frame--mussolini-trailer {
  grid-column: 9 / span 4;
}

/* Design Campaigns, FT Goddard row 1: Goddard 3 (4 cols), explicitly in
   column 1 so it always opens a new row (flush left) after the Mussolini
   row above it. */
.project-image-frame--ft-goddard-3 {
  grid-column: 1 / span 4;
}

/* Design Campaigns, FT Goddard row 1: Goddard 1 (6 cols) right-aligned
   against column 12, beside Goddard 3 (.w-4, auto-placed before it, flush
   left) — leaves column 5 empty rather than sitting flush against it. */
.project-image-frame--ft-goddard-1 {
  grid-column: 7 / span 6;
}

/* Design Campaigns, FT Goddard row 3: Goddard 4, bottom-aligned against the
   Mussolini Cover beside it — overrides .project-media's own top alignment. */
.project-image-frame--ft-goddard-4 {
  align-self: end;
}

/* Design Campaigns, Plural row 2: video 0, alone after AGM 2 was removed,
   right-aligned at 10 cols against column 12 — explicit start since a lone
   item otherwise defaults to the left. */
.project-video-frame--plural-0 {
  grid-column: 4 / span 9;
}

/* BNE Merch: right slot beside T-shirt (cols 1-8) — now holds Cap
   (swapped with Tarjetas), right-aligned at 4 cols against column 12,
   bottom-aligned since it's shorter than T-shirt at this width. Class
   name kept from when this slot held Tarjetas. */
.project-image-frame--merch-tarjetas-19 {
  grid-column: 9 / span 4;
  align-self: end;
}

/* BNE Sonora: Home, alone in row 1, right-aligned at 8 cols (one
   narrower than before, from the left) — explicit start since a lone
   item otherwise defaults to the left. */
.project-video-frame--sonora-home-01 {
  grid-column: 5 / span 8;
}

/* BNE Sonora: Vinilo (4 cols) directly left of Generador (4 cols,
   flush against column 12) — leaves columns 1-4 empty, reading as
   right-aligned within the row rather than flush left. */
.project-video-frame--sonora-vinilo-09 {
  grid-column: 5 / span 4;
}

.project-video-frame--sonora-generador-06 {
  grid-column: 9 / span 4;
}

/* BNE Sonora: Favoritos, beside Iconos (3 cols), right-aligned at
   8 cols against column 12 — explicit start since a plain .w-8 would
   auto-place it right after Iconos instead of flush right. */
.project-video-frame--sonora-favoritos-05 {
  grid-column: 5 / span 8;
}

/* BNE Sonora: Tarjetas, alone in its row, right-aligned at 9 cols (one
   wider than before) — explicit start since a lone item otherwise
   defaults to the left. */
.project-video-frame--sonora-tarjetas-08 {
  grid-column: 5 / span 8;
}

/* BNE Sonora: Generador and Vinilo, row 3, cropped to a square (native
   ratio isn't 1:1) via aspect-ratio + object-fit on the video itself,
   since .project-video only sets width:100%/height:auto. */
.project-video-frame--sonora-square-crop .project-video {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.project-image-frame--cards {
  grid-column: 1 / span 3;
  align-self: start;
}

/* Phone mockup, right of the Images 01 video in the same row (8–12, flush
   right), top-aligned against it — overrides .project-media-end's own
   align-items: end, which the Cards/Web 04 row below still uses. */
.project-image-frame--phone {
  grid-column: 8 / span 5;
  align-self: start;
}

.project-image {
  display: block;
  width: 100%;
  height: auto;
}

/* Picture row: its own 12-column grid, same as .project-media-end below
   (the picture used to be full-bleed, outside every grid — now it's a
   regular row like the rest). Graphic 01 flush left on 1–3, the picture on
   5–12 (8 cols, flush right); align-items: start top-aligns the shorter
   square frame with the taller picture instead of stretching it. The 10px
   top margin is the grid gutter, like the gap between the rows above. */
.project-media-picture {
  margin-top: var(--grid-gutter);
  align-items: start;
}

.project-video-frame--graphic {
  grid-column: 1 / span 3;
}

.project-image-frame--picture {
  grid-column: 5 / span 8;
}

/* Last rows, under the picture row: its own 12-column grid. Images 01 +
   the phone mockup share the first row; Cards + Web 04 get their own row
   below (see the markup-order comment in projects/msp/index.html). */
.project-media-end {
  margin-top: var(--grid-gutter);
  align-items: end;
}

.project-video-frame--web-right {
  grid-column: 5 / span 8;
}

/* ---- Dayhoff ----
   Row 1: the orange nature image on 1–5, top-aligned, next to the logo
   mark with its construction guides on 6–12 (flush right).
   Row 2: the vertical marks on 1–5, the logo/nature video on 6–12 (flush
   right), bottom-aligned against the marks; then the interactive Gray-
   Scott block, full-bleed (100% of the page width, outside the padded
   grid, see projects/dayhoff/index.html and css/dayhoff-reaction.css).
   Row 3: the mark animation video, its own grid row, full width (1–12),
   no longer full-bleed.
   Row 4: the event screen, flush left (1–6). The purple circular images
   row that used to sit between rows 3 and 4 was removed entirely. */
.project-image-frame--dayhoff-nature {
  grid-column: 1 / span 5;
}

.project-image-frame--dayhoff-guides {
  grid-column: 6 / span 7;
}

.project-image-frame--dayhoff-marks {
  grid-column: 1 / span 5;
}

.project-video-frame--dayhoff-logo-horizontal {
  grid-column: 6 / span 7;
  align-self: end;
}

/* Full-bleed: since .project has no side padding, width: 100% is exactly
   edge to edge. */
.project-bleed {
  width: 100%;
  margin-top: var(--grid-gutter);
  margin-bottom: var(--grid-gutter);
  overflow: hidden;
}

/* Sibling margins collapse by default (the bleed's margin-bottom and the
   next section's margin-top would otherwise collapse to the larger of the
   two, 64px, instead of adding up) — zeroed here so the bleed's own
   margin-bottom is the only thing controlling the gap below it. */
.project-bleed + .project-media {
  margin-top: 0;
}

.project-bleed .project-video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* Row right after the interactive block: the colour-variations square
   video on the left (4 columns), and to its right the event image
   (second version), flush right (7 columns, 6–12). */
.project-video-frame--dayhoff-logo-variations {
  grid-column: 1 / span 4;
}

.project-image-frame--dayhoff-event-2 {
  grid-column: 6 / span 7;
}

/* Socials video: alone in its own row right below the row above, full
   width (1–12). */
.project-video-frame--dayhoff-socials {
  grid-column: 1 / span 12;
}

/* Presentations video, left (8 columns, 1–8), paired with the merch
   video to its right (4 columns, 9–12). */
.project-video-frame--dayhoff-presentations {
  grid-column: 1 / span 8;
}

.project-video-frame--dayhoff-merch {
  grid-column: 9 / span 4;
}

.project-image-frame--dayhoff-archive {
  grid-column: 1 / span 12;
}

/* .dayhoff-reaction (css/dayhoff-reaction.css) owns its own exact 100px
   margin-top/bottom (desktop) — cancel the two ambient rules it would
   otherwise inherit unevenly from its .project-media neighbours: the
   generic 90px padding-bottom above (client-found bug: this and the
   .dayhoff-reaction below never fully cancelled out, reading as visibly
   more space above the block than below it) and the generic 64px
   margin-top below. */
.project-media:has(+ .dayhoff-reaction) {
  padding-bottom: 0;
}

.dayhoff-reaction + .project-media {
  margin-top: 0;
}

/* Client request: the mark-animation video's own grid and the event-
   screen's grid right after it should read as two rows of one continuous
   flow (10px gap, the site's normal row spacing), not two separate
   sections (the generic 64px .project-media margin-top) — the enormous
   gap that read as a bug once the circular-images row between them was
   removed. Client-found bug in the first attempt at this: only the
   64px margin-top was addressed — the *first* grid of the pair (the
   mark-animation video's) still carried the generic 90px padding-bottom
   too (empty space inside its own box, invisible but very much part of
   the visual gap), so the two never actually added up to 10px. Both
   ambient rules need cancelling on consecutive grids, not just one.
   Dayhoff is the only page with two .project-media grids back to back,
   but this is written generically since the intent (consecutive media
   grids read as continuous, not as separate sections) isn't
   Dayhoff-specific. */
.project-media:has(+ .project-media) {
  padding-bottom: 0;
}

.project-media + .project-media {
  margin-top: 10px;
}

/* 100px between the Yes + World row and the picture row (90px here + the
   picture row's own 10px margin-top). Desktop only — stacked keeps the
   normal 10px.
   Also 100px above and below the full-bleed mark animation video: above,
   this 90px + the bleed's own 10px margin-top (no collapsing — padding
   isn't a margin); below, the bleed's own margin-bottom carries the full
   100px by itself, since the next section's margin-top is zeroed above
   (it would otherwise collapse with the bleed's margin-bottom instead of
   adding to it, leaving less than 100px). */
@media (min-width: 768px) {
  .project-media {
    padding-bottom: 90px;
  }

  .project-bleed {
    margin-bottom: 100px;
  }

  /* Site-wide standard: whatever media row ends a project page carries
     only .project's own 200px padding-bottom before the footer, not this
     90px on top of it. MSP already reads right because its last row is
     .project-media-end, which never had this padding-bottom; this makes
     every project match that instead of only the ones that happen to end
     on a non-.project-media row (Dayhoff's last row used to run 90px too
     big for exactly that reason). */
  .project > .project-media:last-child {
    padding-bottom: 0;
  }
}

/* Below this width the row no longer fits beside itself: everything stacks,
   one item per row, same breakpoint as the home's cards. */
@media (max-width: 1180px) {
  .project-header {
    row-gap: 32px;
  }

  .project-header-item {
    margin-top: 0;
  }

  .project-title,
  .project-header-item--client,
  .project-header-item--industry,
  .project-header-item--scope {
    grid-column: span 12;
  }
}

/* Phones: the media of every project goes one item per row. Tablets
   (768–1180px) keep the laptop composition — the column widths, rows and
   spacers set above for desktop — client request. */
@media (max-width: 767px) {
  .project-image-frame.w-1, .project-video-frame.w-1,
  .project-image-frame.w-2, .project-video-frame.w-2,
  .project-image-frame.w-3, .project-video-frame.w-3,
  .project-image-frame.w-4, .project-video-frame.w-4,
  .project-image-frame.w-5, .project-video-frame.w-5,
  .project-image-frame.w-6, .project-video-frame.w-6,
  .project-image-frame.w-7, .project-video-frame.w-7,
  .project-image-frame.w-8, .project-video-frame.w-8,
  .project-image-frame.w-9, .project-video-frame.w-9,
  .project-image-frame.w-10, .project-video-frame.w-10,
  .project-image-frame.w-11, .project-video-frame.w-11,
  .project-image-frame--merch-tshirt-14,
  .project-image-frame--aecid-flush-right-8,
  .project-image-frame--aecid-02-bottom,
  .project-video-frame--giro-05-bottom,
  .project-video-frame--giro-flush-right-3,
  .project-image-frame--giro-flush-right-5,
  .project-image-frame--giro-03-bottom,
  .project-video-frame--giro-flush-right-7,
  .project-video-frame--giro-left-9,
  .project-image-frame--merch-tarjetas-19-row,
  .project-image-frame--merch-pegatinas-16-row,
  .project-image-frame--merch-tarjetas-19,
  .project-video-frame--sonora-home-01,
  .project-video-frame--sonora-generador-06,
  .project-video-frame--sonora-favoritos-05,
  .project-video-frame--sonora-tarjetas-08,
  .project-video-frame--sonora-vinilo-09,
  .project-image-frame,
  .project-image-frame--dayhoff-guides,
  .project-image-frame--dayhoff-nature,
  .project-video-frame--dayhoff-logo-horizontal,
  .project-video-frame--images,
  .project-video-frame--graphic,
  .project-video-frame--web-right,
  .project-video-frame--logo,
  .project-video-frame--bagel,
  .project-video-frame--numbers,
  .project-video-frame--world,
  .project-video-frame--yes,
  .project-video-frame--dayhoff-logo-variations,
  .project-video-frame--dayhoff-merch,
  .project-video-frame--mussolini-animated-poster,
  .project-video-frame--mussolini-trailer,
  .project-video-frame--plural-3,
  .project-video-frame--plural-0,
  .project-video-frame--spin,
  .project-video-frame--cumulos-01,
  .project-video-frame--cumulos-02,
  .project-video-frame--cumulos-04,
  .project-video-frame--dayhoff-socials,
  .project-video-frame--dayhoff-presentations,
  .project-image-frame--dayhoff-event-2,
  .project-image-frame--dayhoff-archive {
    grid-column: span 12;
  }

  .project-media-spacer {
    display: none;
  }
}


/* Phones and tablets: half the space under the last block before the footer shows. */
@media (max-width: 1180px) {
  .project {
    padding-bottom: 100px;
  }
}

/* Phones and tablets: headline → Client at half the distance between the
   home's opening paragraph and "Selected Work" (.work-intro padding-bottom
   120px + .work padding-top var(--content-top-space), css/work-intro.css and
   css/work.css; both halved there) (88px on phones and tablets) —
   minus the 32px row-gap already between header items. */
@media (max-width: 1180px) {
  .project-header-item--client {
    margin-top: calc((120px + var(--content-top-space)) / 2 - 32px);
  }
}

/* Phones and tablets: Sector and Scope no longer stack under Client.
   Tablet: Client, Sector and Scope share one row (6 + 3 + 3 columns of the
   12). Phones: Client on its own row, Sector (left) and Scope (right) side by
   side under it, 6 + 6 columns. The longest single word in any Sector/Scope
   (e.g. "Merchandising", "Architecture") fits a 6-column half down to 320px
   wide — checked on every project page; if a longer word ever appears,
   Scope goes back under Sector (grid-column: 1 / -1). */
@media (max-width: 1180px) {
  .project-header-item--client {
    grid-column: 1 / span 6;
  }

  .project-header-item--industry {
    grid-column: 7 / span 3;
  }

  .project-header-item--scope {
    grid-column: 10 / span 3;
  }

  /* One row: all three carry the headline gap, so they stay aligned. */
  .project-header-item--industry,
  .project-header-item--scope {
    margin-top: calc((120px + var(--content-top-space)) / 2 - 32px);
  }
}

@media (max-width: 767px) {
  .project-header-item--client {
    grid-column: 1 / -1;
  }

  .project-header-item--industry {
    grid-column: 1 / span 6;
  }

  .project-header-item--scope {
    grid-column: 7 / span 6;
  }

  /* Under Client: the row-gap is the only space. */
  .project-header-item--industry,
  .project-header-item--scope {
    margin-top: 0;
  }
}

/* Tablets (768–1180px): the headline is no wider than 5 columns; longer ones
   break onto the next line. Phones keep it full width, desktop its 5 columns. */
@media (min-width: 768px) and (max-width: 1180px) {
  .project-title {
    grid-column: 1 / span 5;
  }
}

/* Tablets (768–1180px): Sector one column to the right (columns 8–9), so it
   isn't right up against Client; Scope stays on columns 10–12. */
@media (min-width: 768px) and (max-width: 1180px) {
  .project-header-item--industry {
    grid-column: 8 / span 2;
  }
}

/* Mobile and tablet: the full-width blocks (.project-bleed here; the interactive
   blocks do the same in their own CSS) get extra space above and below, 2 times
   the page's side margin: 40px on a phone, 50px on a tablet (client request).
   The block owns both gaps, so the ambient spacing of its neighbours is cancelled
   — otherwise it would add up unevenly (the 90px padding-bottom of the media grid
   above, the 10px margin-top of the picture row below). Desktop keeps its 100px. */
@media (max-width: 1180px) {
  .project-bleed {
    margin-top: calc(2 * var(--grid-margin));
    margin-bottom: calc(2 * var(--grid-margin));
  }

  .project-media:has(+ .project-bleed),
  .project-media:has(+ .landscape-playground) {
    padding-bottom: 0;
  }

  .landscape-playground + .project-media-picture {
    margin-top: 0;
  }
}

/* ---------- Previous / Next project (053, js/project-nav.js) ----------
   Two plain links at the end of the page, before the footer: "Previous" on the left,
   "Next" on the right, each with the project's name under it. Same small type as the
   labelled columns of the page header (16px, grey label). */
.project-pager {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--grid-gutter);
  padding-left: var(--grid-margin);
  padding-right: var(--grid-margin);
  max-width: var(--content-max);
  margin-left: auto;
  margin-right: auto;
  /* 064 round 4: the margins are measured from the project NAME (the small "Next" / "Previous" does not
     count: it hangs up into the top margin). Above: .project's own padding-bottom (the space the last
     block of the page leaves before whatever follows; 200px, 100px on tablets and phones); below: HALF of
     that up to the footer (100px; 50px on tablets and phones; round 8). */
  margin-top: 0;
  padding-bottom: 100px;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  /* The hover arrow hangs 24px off the label even at rest (opacity 0): clip it so it never widens the page. */
  overflow-x: clip;
}

.project-pager-link {
  display: block;
  position: relative;
  /* 058: only the text (label + name) reacts to hover and clicks, not the empty part of its half. */
  width: fit-content;
  max-width: 100%;
  /* Ronda 2: the link's own box is not a target; each line of text is (a short label next to
     a longer name left a clickable blank). Clicks on the lines still bubble to the link. */
  pointer-events: none;
  color: inherit;
  text-decoration: none;
  /* 042: no browser tap flash on phones. */
  -webkit-tap-highlight-color: transparent;
}

.project-pager-link--prev {
  grid-column: 1 / span 6;
  justify-self: start;
}

.project-pager-link--next {
  grid-column: 7 / span 6;
  justify-self: end;
  text-align: right;
}

/* 064 round 4: the small word sits ABOVE the name, out of the flow: the link is only the name's box, so
   the margins are measured from the name and the word hangs up into the top margin. */
.project-pager-label {
  display: block;
  position: absolute;
  bottom: 100%;
  left: 0;
  pointer-events: auto;
  width: fit-content;
  max-width: 100%;
  color: var(--nav-link-inactive);
}

/* 054: the project name is a headline (same size as "Work" on the home); the label stays 16px. */
.project-pager-name {
  display: block;
  pointer-events: auto;
  width: fit-content;
  max-width: 100%;
  font-size: clamp(28px, 2.5vw, 56px);
  line-height: 1.1;
  overflow-wrap: anywhere;
  transition: color 0.3s ease;
}

.project-pager-link--next .project-pager-label {
  left: auto;
  right: 0;
}

.project-pager-link--next .project-pager-name {
  margin-left: auto;
}

/* 064 round 4: the arrow of the Contact form's buttons (no button), at most as tall as the small word's type (16px), made by
   js/project-nav.js inside the small label. To the left of "Previous" (points left) and to the right of
   "Next" (points right); it slides in on hover and the small word makes room for it. The NAME never
   moves. Mouse only: on touch screens the arrow does not exist. */
.pager-arrow {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .project-pager-link:hover .project-pager-name {
    color: var(--nav-link-inactive);
  }

  .pager-arrow {
    --pager-arrow-size: 16px; /* Contact's arrow is 18px; capped at the label's type height (16px) */
    display: block;
    position: absolute;
    top: 50%;
    width: var(--pager-arrow-size);
    height: var(--pager-arrow-size);
    overflow: visible;
    color: var(--nav-link-inactive);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease-in-out;
  }

  /* Constant gap: the arrow hangs off the label at a FIXED distance (16px arrow + 8px gap) and the whole
     label (word + arrow) slides together on hover, so the gap never changes. The name never moves. */
  .pager-arrow--prev {
    left: calc((var(--pager-arrow-size) + 8px) * -1);
    transform: translateY(-50%);
  }

  .pager-arrow--next {
    right: calc((var(--pager-arrow-size) + 8px) * -1);
    transform: translateY(-50%);
  }

  .project-pager-label {
    transition: transform 0.3s ease-in-out;
  }

  .project-pager-link:hover .project-pager-label .pager-arrow {
    opacity: 1;
  }

  .project-pager-link--prev:hover .project-pager-label {
    transform: translateX(calc(16px + 8px));
  }

  .project-pager-link--next:hover .project-pager-label {
    transform: translateX(calc((16px + 8px) * -1));
  }
}

/* Tablets and phones: 50px below the name (half of the 100px above, .project's padding-bottom). */
@media (max-width: 1180px) {
  .project-pager {
    padding-bottom: 50px;
  }
}

/* ---------- Page transition between projects (061, round 2: zoom out, cards, zoom in) ----------
   Cross-document View Transition, the same for Previous and Next, told as ONE camera: (1) the page
   you are on shrinks to a card with the proportions of the window; (2) the other 7 projects come
   in one by one along a staggered diagonal that sits inside the outer margins of the site
   (--grid-margin), the ones that follow in front and the ones that precede behind; (3) they leave
   again along the same diagonal, the farthest first, and the chosen one is left centred;
   (4) it grows until it fills the screen and is the new page. The cards are the REAL first
   screen of each project, a small picture (Assets/Pager, made by tools/pager-tarjetas.js).
   Only the pager links start it (js/project-nav.js types it "pager", lays the cards and
   runs the keyframes, which depend on the size of the window); any other navigation, and
   "reduce motion", change page directly (css/nav.css fades between pages).
   Layers (from the bottom): the page you leave blurred (pager-bg, 064),
   the cards that precede the page (pager-d5..d7), the page itself (root: old = the leaving page
   that becomes a card, new = the arriving page that grows), the cards that follow it
   (pager-d1..d4) and the menu on top. */
:root {
  --pager-zoom-shadow-color: rgba(0, 0, 0, 0.55);
  --pager-zoom-shadow-y: 8px;
  --pager-zoom-shadow-blur: 22px;
  --pager-zoom-ring: transparent;
}

[data-theme="dark"] {
  --pager-zoom-shadow-color: rgba(0, 0, 0, 0.6);
  --pager-zoom-ring: rgba(255, 255, 255, 0.1); /* dark cards on dark cards still read apart */
}

/* The cards of the other projects: built by the script in the leaving page, kept out of sight. */
.pager-zoom {
  position: fixed;
  inset: 0;
  /* 064 round 4: in the LIVE page (the frames between the click and the snapshot) the blur and the cards sit
     BEHIND the page (.page-content is z-index 2 and opaque): never above the current project. In the
     transition their stacking is decided by the groups below, not by this. */
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  display: none;
}

.pager-zoom.is-armed {
  display: block;
}

/* 064 R5: behind the cards, the page you leave (its first screen) blurred like the background of the
   Contact form: the same blur and saturation, the same veil (--overlay-bg) in light and dark. It is
   its own layer of the transition, fixed during the whole animation, blurred ONCE with a plain
   `filter` on the picture (no backdrop-filter in a fixed layer: bugs 027/028/030). It is bigger than the
   window so the soft edge of the blur falls outside it. Only on the screens that have the camera
   (landscape), so phones never pay for the blur. */
.pager-zoom-bg {
  position: fixed;
  inset: -180px;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  display: none;
}

.pager-zoom-bg.is-armed {
  display: block;
}

/* 064 round 4: the background is ALWAYS what the light theme gives (the page you leave blurred under the
   dark veil), also in the dark theme, where --overlay-bg would be a light veil. */
.pager-zoom-bg {
  --overlay-bg: rgba(17, 17, 17, 0.55);
}

.pager-zoom-bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(56px) saturate(140%);
}

.pager-zoom-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--overlay-bg);
}

/* 064 round 4 (point 7): on touch screens the blurred background is not a FIXED layer with a background (Safari
   tints its bars with those: bugs 028 / 030): it is absolute, laid over the window by js/project-nav.js (top =
   the scroll, height = the window), and the picture is scaled so the soft edge of the blur falls outside it. */
@media (pointer: coarse), (hover: none) {
  .pager-zoom-bg {
    position: absolute;
    inset: auto;
    left: 0;
    width: 100%;
    top: 0;
    height: 100vh;
  }

  .pager-zoom-bg img {
    transform: scale(1.35);
  }
}

.pager-zoom-tile {
  position: absolute;
  overflow: hidden;
  border-radius: var(--nav-radius);
  background: #1a1a1a;
  box-shadow:
    0 var(--pager-zoom-shadow-y) var(--pager-zoom-shadow-blur) var(--pager-zoom-shadow-color),
    0 0 0 1px var(--pager-zoom-ring);
}

.pager-zoom-tile img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }

  /* Untyped (back button, menu...): no animation at all, the new page just replaces the old. */
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
  }

  ::view-transition-group(root),
  ::view-transition-image-pair(root) {
    animation: none;
    isolation: auto;
  }

  /* The menu stays put, in its own layers on top, instead of riding along inside the page.
     The PARTS of the menu are named, never .floating-nav: an ancestor with a
     view-transition-name becomes the backdrop root of the glass and the blur stops seeing the
     page (R11, measured: with the name on .floating-nav stripes show through the bar; with it
     on .nav-header itself the bar is blurred). */
  .nav-header {
    view-transition-name: site-nav-bar;
  }

  .nav-theme-toggle {
    view-transition-name: site-nav-theme;
  }

  .pager-zoom-bg.is-armed {
    view-transition-name: pager-bg;
  }

  /* Each card is its own layer, named by how far after the page you leave it comes in the ring. */
  .pager-zoom.is-armed .pager-zoom-tile[data-d="1"] {
    view-transition-name: pager-d1;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="2"] {
    view-transition-name: pager-d2;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="3"] {
    view-transition-name: pager-d3;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="4"] {
    view-transition-name: pager-d4;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="5"] {
    view-transition-name: pager-d5;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="6"] {
    view-transition-name: pager-d6;
  }

  .pager-zoom.is-armed .pager-zoom-tile[data-d="7"] {
    view-transition-name: pager-d7;
  }

  ::view-transition-group(site-nav-bar),
  ::view-transition-image-pair(site-nav-bar),
  ::view-transition-old(site-nav-bar),
  ::view-transition-new(site-nav-bar),
  ::view-transition-group(site-nav-theme),
  ::view-transition-image-pair(site-nav-theme),
  ::view-transition-old(site-nav-theme),
  ::view-transition-new(site-nav-theme),
  ::view-transition-group(pager-bg),
  ::view-transition-image-pair(pager-bg),
  ::view-transition-old(pager-bg),
  ::view-transition-group(pager-d1),
  ::view-transition-image-pair(pager-d1),
  ::view-transition-old(pager-d1),
  ::view-transition-group(pager-d2),
  ::view-transition-image-pair(pager-d2),
  ::view-transition-old(pager-d2),
  ::view-transition-group(pager-d3),
  ::view-transition-image-pair(pager-d3),
  ::view-transition-old(pager-d3),
  ::view-transition-group(pager-d4),
  ::view-transition-image-pair(pager-d4),
  ::view-transition-old(pager-d4),
  ::view-transition-group(pager-d5),
  ::view-transition-image-pair(pager-d5),
  ::view-transition-old(pager-d5),
  ::view-transition-group(pager-d6),
  ::view-transition-image-pair(pager-d6),
  ::view-transition-old(pager-d6),
  ::view-transition-group(pager-d7),
  ::view-transition-image-pair(pager-d7),
  ::view-transition-old(pager-d7) {
    animation: none;
    mix-blend-mode: normal;
  }

  ::view-transition-old(site-nav-bar),
  ::view-transition-old(site-nav-theme) {
    display: none;
  }

  /* The group of the bar copies the bar's own backdrop-filter, as a plain rectangle, and that
     is what keeps the page blurred under the bar during the transition (the snapshot's own
     filter cannot see the page: it is isolated inside its image pair). Measured: at the edge of
     that rectangle the blur drags in transparent black, so a dark 1px rim and square dark corners
     showed behind the rounded bar (056 R4). Fix: grow the group by 3px of transparent border (the
     blur edge now falls outside), shift it back by the same, and clip it to the bar's own rounded
     shape. */
  ::view-transition-group(site-nav-bar) {
    box-sizing: content-box;
    border: 3px solid transparent;
    translate: -3px -3px;
    clip-path: inset(3px round var(--nav-radius));
  }

  /* The snapshot of the bar is a picture: the glass is given back to it here, over the layers
     that are under it in the transition. */
  ::view-transition-new(site-nav-bar) {
    backdrop-filter: blur(var(--nav-blur)) saturate(140%);
    border-radius: var(--nav-radius);
  }

  /* Behind the cards: the page background (the blurred page covers all of it). */
  html:active-view-transition-type(pager)::view-transition {
    background: var(--color-bg);
  }

  /* 064 round 4 (point 7): touch screens (iPad in landscape has this camera): no full-screen layer with a
     background for Safari to tint its bars with: <html> paints the page colour behind the cards. */
  @media (pointer: coarse), (hover: none) {
    html:active-view-transition-type(pager)::view-transition {
      background: transparent;
    }
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-bg) {
    z-index: 0;
  }

  /* 064 round 2: nothing blurred is on screen at full size before the page starts to shrink. The
     blurred background is invisible in the first frame and fades in while the leaving page shrinks
     (keyframes `bg` of js/project-nav.js, over `shrink`). The background, the arriving page and the
     cards that leave are hidden until the keyframes of the script take them (each keyframe sets
     opacity; the page and the cards start out of the window): the browser's own first frame, before those keyframes run, shows only
     the leaving page, sharp, and cannot show them stacked at full size. */
  html:active-view-transition-type(pager)::view-transition-old(pager-bg),
  html:active-view-transition-type(pager)::view-transition-new(root),
  html:active-view-transition-type(pager)::view-transition-old(pager-d1),
  html:active-view-transition-type(pager)::view-transition-old(pager-d2),
  html:active-view-transition-type(pager)::view-transition-old(pager-d3),
  html:active-view-transition-type(pager)::view-transition-old(pager-d4),
  html:active-view-transition-type(pager)::view-transition-old(pager-d5),
  html:active-view-transition-type(pager)::view-transition-old(pager-d6),
  html:active-view-transition-type(pager)::view-transition-old(pager-d7) {
    opacity: 0;
  }

  /* The page that leaves and the page that arrives are moved by the keyframes of the script from
     their top-left corner. */
  html:active-view-transition-type(pager)::view-transition-old(root),
  html:active-view-transition-type(pager)::view-transition-new(root) {
    transform-origin: 0 0;
  }

  /* Stacking: cards that precede < the page (leaving card, arriving page) < cards that follow < menu. */
  html:active-view-transition-type(pager)::view-transition-group(pager-d5) {
    z-index: 1;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d6) {
    z-index: 2;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d7) {
    z-index: 3;
  }

  html:active-view-transition-type(pager)::view-transition-group(root) {
    z-index: 4;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d1) {
    z-index: 5;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d2) {
    z-index: 6;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d3) {
    z-index: 7;
  }

  html:active-view-transition-type(pager)::view-transition-group(pager-d4) {
    z-index: 8;
  }

  html:active-view-transition-type(pager)::view-transition-group(site-nav-bar),
  html:active-view-transition-type(pager)::view-transition-group(site-nav-theme) {
    z-index: 30;
  }
}

/* 068: touch screens get no cross-document View Transition. Last in the file, so it wins over the
   `navigation: auto` rules above. */
@media (pointer: coarse), (hover: none) {
  @view-transition { navigation: none; }
}
