/* ============================================================
   All Work (/work) — the gallery page and its facet filters. Links after core.css.
   Split out of the former style.css on 2026-10-18; rules unchanged, in their
   original order. ============================================================ */

/* ============================================================
   All-work page (/work/) — the theme's ground (light until 2026-09-24), sticky
   filter, recolored grid
   ============================================================ */
body.work-all { background: var(--bg); color: var(--fg); }

/* Header: static (scrolls away, so it never clashes with the footer). */
.work-all .site-header { position: static; pointer-events: auto; }

.work-all-main {
  position: relative;
  z-index: 1;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  gap: 10px;                         /* between the bar and the grid rows */
  padding-inline: var(--pad-inline);
}
/* Sticky masthead on a 12-col grid (10px gap): filter (cols 1–6) + studio blurb
   (cols 7–9); the last 3 cols stay empty. */
.work-all-bar {
  position: sticky;
  top: 10px;
  z-index: 10;
  margin-top: 4.17vw;                 /* separation from the header/site above */
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  align-items: start;
  column-gap: 10px;
  margin-bottom: 40px;
}
.work-filter {
  grid-column: 1 / span 6;
  display: flex;
  align-items: baseline;
  gap: 20px;
  font-family: var(--ff-serif);
  font-weight: 400;
  letter-spacing: -0.03em;
  font-size: 3.75vw;                /* 72px @ 1920 — scales with viewport width */
  line-height: 1;
}
/* All filters read full black at rest; hover underlines (via the shared
   underline rule above). No dimming, no persistent active-state style — the
   .is-active class is still toggled by work-all.js but carries no visual. */
.work-filter-btn {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;                     /* serif label, inherited from .work-filter */
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
  opacity: 0.5;
}
.work-filter-btn.is-active { opacity: 1; }
.work-filter-btn:hover { opacity: 1; }
/* Counts as a parenthesised serif superscript, e.g. All ( 42 ). The number is set
   by work-all.js; the spaced parens are added here so the DOM value stays numeric.
   display:inline-block makes the sup an atomic inline, so the button's hover
   underline runs under the WORD only — never under the "( n )" total. */
/* The count after a trigger's word is the .count recipe (core.css). */
.work-filter .sep { opacity: 0.25; }
/* Layout only — type comes from the shared .t-body serif recipe on the <p>.
   Sits in cols 7–9, left-aligned (fills the track; text reads from the left). */
.work-all-desc {
  grid-column: 7 / span 3;
  margin: 0;
}

/* Grid recolor — the rows come from work.js (the [data-work-grid] host is
   display:contents, so .work-row lands directly in .work-all-main). Captions
   read in the page's ink; on desktop they stay hidden (image-only, like the homepage). */
.work-all .work-caption { color: var(--fg); }


/* ---- Mobile layout (≤48em) — MUST stay last in this sheet: media queries
   add no specificity, so source order decides. ---- */
@media (max-width: 48em) {
  /* All-work filter bar — stack filters above about text on mobile. */
  .work-all-bar {
    display: flex;
    flex-direction: column;
    gap: var(--label-gap);
    margin-top: 15.38vw;
    margin-bottom: 40px;
  }
  .work-filter {
    font-size: 7.18vw;
    gap: 10px;
  }
  .work-filter .sep { display: none; }
  .work-all-desc {
    grid-column: auto;
  }
}

/* ============================================================
   All-work v2 (/work-2/)
   Figma: "All Work @1920px" 1798:3276 / 1798:3719 / 1802:3999.

   The page turns white here and #F3F3F3 demotes from page ground to
   panel fill (facet dropdown + tag chips).

   Split in three on purpose: STRUCTURE first (unscoped — work-all-2.js
   tweens against these, so they have to hold at every width), then the
   desktop and mobile dimension sets. Only numbers differ between the
   two breakpoints.

   Desktop sits on the boards' 10px margin / 10px gutter grid, which is
   already what --pad-inline is, so the maths lands exactly at 1920:
     gallery  4 cols → 467.5    facets  12 cols → 149.17 (span 2 = 308.33)
   Mobile has no board yet; sizes below are derived (÷390).
   ============================================================ */

/* ---- Structure (all widths) --------------------------------------------- */
/* The header is `position: static` here (it scrolls away rather than staying
   fixed), so it takes real flow height. Putting the full-viewport constraint on
   the BODY rather than on main lets the two share the viewport exactly —
   main:100svh would start below the header and overflow by its height, which is
   header-height-dependent and would need a magic number to correct. */
body.work-v2 {
  background: var(--bg);
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}
.work-v2 .work-all-main { flex: 1 0 auto; }
.work-v2 .work-all-main {
  background: var(--bg);
  gap: 0;                              /* .page-masthead owns its own rhythm */
}


.work-v2 .page-masthead {
  display: flex;
  flex-direction: column;
}
.work-v2 .work-badge { margin: 0; }

.work-v2 .work-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 0;                          /* the chips row carries its own gap so
                                          the two can collapse together */
}
.work-v2 .work-filter {
  /* One line that runs off the screen and scrolls sideways (user,
     2026-10-11) rather than wrapping. Bleeds to the page edges so the
     overflow is cut by the viewport, not 10px in; the scrollbar is hidden. */
  flex-wrap: nowrap;
  width: auto;
  flex: 1 0 100%;
  margin-inline: calc(-1 * var(--pad-inline));
  padding-inline: var(--pad-inline);
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* The clip box takes in the descenders (line-height is 1), the negative
     margin gives the room back so the row's rhythm is unchanged. */
  padding-block: 0.2em;
  margin-block: -0.2em;
  /* A soft fade on an edge that has more to show (work-3.js toggles the
     classes from scrollLeft), so the row reads as scrollable. */
  --fade-l: 0px;
  --fade-r: 0px;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent);
          mask-image: linear-gradient(to right, transparent, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent);
  transition: --fade-l 0.3s ease, --fade-r 0.3s ease;
}
.work-v2 .work-filter.can-scroll-left  { --fade-l: 15vw; }
.work-v2 .work-filter.can-scroll-right { --fade-r: 15vw; }
.work-v2 .work-filter::-webkit-scrollbar { display: none; }
.work-v2 .work-filter-btn { flex: 0 0 auto; white-space: nowrap; }
/* Every trigger reads full black at rest; the open one keeps the shared
   underline. Hovering dims it to 30% (and underlines, from the
   .t-link--underline group) — the open trigger too, which is why the :hover
   selector is restated: v1's `.work-filter-btn:hover { opacity: 1 }` would
   otherwise outrank the 30%. */
.work-v2 .work-filter-btn { opacity: 1; }
.work-v2 .work-filter-btn:hover { opacity: 0.3; }


/* Chips: always in flow at height 0 rather than display:none, so work-all-2.js
   can tween the row open and slide the dropdown down with it. --chips-gap is
   read back by the JS so the value stays defined once. */
.work-v2 .work-chips {
  flex: 1 0 100%;                      /* always breaks to its own line */
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  height: 0;
  margin-top: 0;
}
.work-chip {
  appearance: none;
  border: 0;
  margin: 0;
  border-radius: 0;
  background: none;                    /* plain text — no ground, no padding (QA 2026-10-08) */
  color: inherit;
  line-height: 1;
  cursor: pointer;
  /* Label only — no close glyph. The whole chip is the remove target, which
     the button's aria-label spells out. */
  display: inline-flex;
  align-items: baseline;
}
.work-chip:hover { opacity: 0.3; }

/* Facet dropdown. Full-bleed: negative margin escapes .work-all-main's padding,
   then the panel re-applies it so its content stays on the page margin. */
/* The dropdown's reveal is a CSS transition on a grid track, not a height
   tween: .work-facets-clip is a one-row grid whose row goes 0fr → 1fr
   (.is-open, toggled by work-3.js), and the browser interpolates the track.
   The row item clips; the panel inside is laid out exactly as it rests —
   padding, its gap above, the blurb, the list — so nothing in it moves while
   the clip's edge rolls down over it and back up (user, 2026-10-18). The clip
   cancels the masthead's gap above it with a negative margin and the panel
   puts that gap back as its own, so the closed state takes no room and
   nothing jumps when it opens or shuts. Closed, it is also invisible and
   inert (the script sets `inert`), so its links take no focus. */
.work-v2 .work-facets-clip {
  display: grid;
  grid-template-rows: 0fr;
  margin-top: calc(-1 * var(--head-gap));
  visibility: hidden;
  transition: grid-template-rows 0.6s var(--ease-out-expo), visibility 0s 0.6s;
}
.work-v2 .work-facets-clip.is-open {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows 0.6s var(--ease-out-expo), visibility 0s;
}
.work-v2 .work-facets-row {
  min-height: 0;                       /* lets the 0fr row collapse the item */
  overflow-y: clip;                    /* clips vertically only: the panel bleeds to the page edges sideways */
}
@media (prefers-reduced-motion: reduce) {
  .work-v2 .work-facets-clip { transition: none; }
}
.work-v2 .work-facets {
  display: grid;
  margin-top: var(--head-gap);         /* the masthead gap the clip cancelled, inside the clip */
  margin-inline: calc(-1 * var(--pad-inline));
  background: var(--bg);
}

.work-v2 .work-facets-intro {
  display: flex;
  flex-direction: column;
  gap: 0.5em;                            /* the blank line between paragraphs */
  line-height: 1;
  text-wrap: balance;                /* no orphaned last word */
}
.work-v2 .work-facets-intro p { margin: 0; }

.work-v2 .work-facet { display: flex; flex-direction: column; }
.work-v2 .work-facet-label { margin: 0; }
.work-v2 .work-facet-list {
  display: flex;
  flex-direction: column;
  gap: var(--list-gap);                /* 10px between the values, rows and columns, at every width (user, 2026-10-18) */
  margin: 0;
  padding: 0;
  list-style: none;
  line-height: 1;
}
.work-v2 .work-facet-list button {
  appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
/* The chips row clips at its measured height (line-height 1): room for the
   descenders, below the text only, so a "g" or "y" is never cut. */
.work-v2 .work-chip { padding-bottom: 0.2em; }
/* Already picked — it shows as a chip instead (or, in the Type list, it is the
   pick the trigger wears). */
.work-v2 .work-facet-list .is-selected button { opacity: 0.3; }

/* ---- Uniform work grid (component) --------------------------------------
   The gallery from the Sept 2026 boards, as a class rather than a page scope
   so /work-2/ and /post/ share one definition. Cards are direct grid children
   carrying no inline placement, which also overrides v1's display:contents. */
.work-grid-uniform {
  display: grid;
  column-gap: var(--pad-inline);
}
/* Captions stay hidden on desktop — the floating hover label (work-cursor.js)
   carries project + director there. The shared mobile block prints them
   instead, since touch has no hover. */

/* ---- Desktop dimensions -------------------------------------------------- */
@media (min-width: 48.0625em) {
  /* The masthead is a .page-head (core.css): --page-top under the header,
     --head-gap between the badge and the triggers — Post's rhythm exactly —
     and --head-foot to the grid. */
  .work-v2 .work-all-main { padding-top: 0; }
  .work-v2 .page-masthead { padding-bottom: var(--head-foot); }
  .work-v2 .work-filters { column-gap: 20px; }
  /* Six triggers at 72px do not fit one line at 1920 (they wrap to two, which
     is fine — the row wraps like the old All / Commercial / Branded + More did
     on narrow screens). The size scales with the viewport but is bounded at
     both ends: 72px is the board's size at 1920 and it should not keep growing
     past that; the floor keeps the words legible. */
  .work-v2 .work-filter { gap: 60px; }   /* 60px between the triggers (user, 2026-10-11); the size is .t-display (core.css) */

  .work-v2 .work-chips {
    --chips-gap: var(--head-gap);      /* trigger row → chips: the head's beat (40px; user, 2026-10-18) */
    gap: 20px;                         /* between chips (user, 2026-10-18) */
  }
  .work-chip { padding: 0; }           /* size: .t-display-sm (core.css) */

  .work-v2 .work-facets {
    grid-template-columns: repeat(12, 1fr);
    gap: 10px;
    padding: var(--head-gap) var(--pad-inline);   /* chips → values and values → grid: the head's beat (40px; user, 2026-10-18) */
  }
  .work-v2 .work-facets-intro {
    grid-column: 1 / span 4;           /* = 626.67px @ 1920 */
    font-size: 48px;
  }
  .work-v2 .work-facet { gap: 20px; }   /* label → tags, halved (QA 2026-10-08) */
  /* One list shows at a time (the open dropdown's), across the right half —
     three columns of values so fifteen directors sit in five rows. */
  .work-v2 .work-facet { grid-column: 7 / span 6; }
  .work-v2 .work-facet-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }                                    /* gap: --list-gap; size: .t-display-sm (core.css) */

  /* Columns fit themselves: a card is never narrower than 320px, and never
     more than four across. The ceiling is the quarter share (a quarter of the
     row less its three 10px gutters), which wins above ~1330px; below that the
     320px floor wins and the grid drops to three, then two at 769px, with no
     further breakpoint (the user's rule, 2026-09-25). */
  .work-grid-uniform {
    grid-template-columns: repeat(auto-fill, minmax(max(320px, calc(25% - 7.5px)), 1fr));
    row-gap: 8.33vw;                   /* 160px @ 1920 */
  }
  /* 80px of the 467.5 slot is right-hand air, leaving a 387.5 x 242 image. */
  .work-grid-uniform .work-item { padding-right: 4.17vw; }
  .work-grid-uniform .work-media {
    flex: 0 0 auto;
    aspect-ratio: 16 / 9;
  }
  /* The shared rule oversizes the image (top:-9%, height:118%) purely to give
     card-parallax.js room to drift. This grid has no parallax, so the headroom
     is just a crop — sit the image flush in its frame instead. Desktop only:
     the mobile block below already drops the parallax and sizes its own card. */
  .work-grid-uniform .work-item img,
  .work-grid-uniform .work-card-video {
    top: 0;
    height: 100%;
  }
}

/* ---- Up to 1440 -----------------------------------------------------------
   The grid's columns now fit themselves (the auto-fill rule above), so this
   range only carries the facet panel's narrower layout. Must sit AFTER the
   desktop block: the min-width query above also matches here, so it needs
   source order to win the overlap. */
@media (min-width: 48.0625em) and (max-width: 90em) {
  /* Facet panel: no studio blurb below desktop (user, 2026-10-11); the open
     list runs full width in three columns (the desktop list grid carries
     over) — three equal columns are ~460px at 1440 and ~290px at 900, both of
     which hold a name on one line. */
  .work-v2 .work-facets-intro { display: none; }
  .work-v2 .work-facets {
    grid-template-columns: repeat(3, 1fr);
    gap: 40px 10px;
  }
  .work-v2 .work-facets-intro {
    grid-column: 1 / -1;
    font-size: 28px;
  }
  .work-v2 .work-facet { grid-column: 1 / -1; gap: 10px; }   /* gap halved (QA 2026-10-08) */
}

/* ---- Mobile dimensions (÷390) -------------------------------------------
   No mobile board yet — these are derived from the desktop hierarchy and the
   v1 mobile conventions (filter at 7.18vw, --pad-inline unchanged at 10px).
   The facet columns stack, since three of them will not fit at 390. */
@media (max-width: 48em) {
  /* The masthead is a .page-head (core.css) here too: 60px under the header,
     20px badge → triggers, 60px to the grid — Post's phone rhythm. */
  .work-v2 .work-all-main { padding-top: 0; }
  .work-v2 .page-masthead { padding-bottom: var(--head-foot); }
  .work-v2 .work-filters { column-gap: 10px; }
  .work-v2 .work-filter {
    gap: 20px;                         /* between the triggers (user, 2026-10-14: 20, down from 40); size .t-display = 28px (user, 2026-10-18) */
    align-items: baseline;
  }

  .work-v2 .work-chips {
    --chips-gap: var(--head-gap);      /* 20px */
    gap: 10px 20px;
  }
  .work-chip { padding: 0; }           /* size: .t-display-sm = 20px, as the values */

  /* No studio blurb on phones (user, 2026-10-11); the open list runs full width. */
  .work-v2 .work-facets-intro { display: none; }
  .work-v2 .work-facets {
    grid-template-columns: repeat(2, 1fr);
    gap: 10.26vw 10px;                 /* 40px @ 390 between rows, gutter across */
    padding: var(--head-gap) var(--pad-inline);   /* 20px above and below the list (user, 2026-10-18) */
  }
  .work-v2 .work-facets-intro {
    grid-column: 1 / -1;
    font-size: 5.13vw;                 /* 20px @ 390 */
  }
  .work-v2 .work-facet { grid-column: 1 / -1; gap: 10px; }   /* gap halved (QA 2026-10-08) */
  .work-v2 .work-facet-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }                                    /* gap: --list-gap (10px); size: .t-display-sm */

  /* Cards match the homepage's mobile card — full-width image at 82.05vw with
     the caption under it. Those rules are unscoped inside this same breakpoint,
     so v2 only has to stop overriding them: one column, the homepage's 32px
     rhythm, and no aspect-ratio or height of its own. */
  .work-grid-uniform,
  .work-v3 .work-grid-uniform {      /* v3's 4.17vw row gap is desktop-only; phones use --card-gap */
    grid-template-columns: 1fr;
    row-gap: var(--card-gap);
  }
  .work-grid-uniform .work-item { padding-right: 0; }
  /* Captions print here (the shared mobile rule shows them); 10px matches the
     gap in the Figma Work Card component. */
  .work-grid-uniform .work-caption { margin-top: 10px; }
  /* v1 caps the mobile grid at 6 cards; a catalogue shows everything. Block, not
     flex — the homepage rule makes .work-item a block on mobile. */
  .work-grid-uniform .work-item[data-mobile-hide] { display: block; }
}


/* ============================================================
   /work-3/ — variation of /work-2/
   The body carries .work-v2 too, so the masthead, filters, facet
   panel and grid all come from those rules untouched. Only the
   differences live here.
   ============================================================ */

/* 1. Cards fill their column — no right-hand air. */
.work-v3 .work-grid-uniform .work-item { padding-right: 0; }

/* Half the row gap of /work-2/ — with captions printing under every card the
   rows already read as separated, so 160px of air between them is more than the
   grid needs. */
@media (min-width: 48.0625em) {                           /* phones keep the 60px rhythm (the shared mobile rule) */
  .work-v3 .work-grid-uniform { row-gap: 3.125vw; }     /* 60px @ 1920 (QA 2026-10-08) */
}

/* 2. No client · director pointer label — the caption already prints under
      the card. The pointer reads "View" instead (cursor-label.js); this plain
      pointer is what touch and no-JS get. */
.work-v3 .work-item { cursor: pointer; }

/* Half the masthead→cards gap of /work-2/ and /post-2/, which sit at 160px
   (8.33vw). Scoped here so those two keep the original spacing and the pair
   stays comparable. Two rules because the page shapes differ: work and team
   put the gap on .page-masthead's padding, post on .post-content's gap. */
@media (min-width: 48.0625em) {
  .work-v3 .page-masthead { padding-bottom: 4.17vw; }   /* 80px @ 1920 */
  /* Only the hero→gallery gap halves. .post-content's `gap` applies between
     EVERY section — cards, services, team, the bar — so shrinking it there
     pulled the whole page together. Pulling the gallery up by half the gap
     leaves every other separation at its original 160px. */
  .work-v3 .post-gallery { margin-top: -4.17vw; }
}
@media (max-width: 48em) {
  .work-v3 .page-masthead { padding-bottom: 7.69vw; }   /* 30px @ 390 */
  .work-v3 .post-gallery  { margin-top: -7.69vw; }
}

/* 3. Captions print at every width, not just mobile. The floating label is
      gone, so this is the only way to read a card.

      No date — client over director, as the card component already emits. */
.work-v3 .work-caption {
  display: block;
  margin-top: 10px;
}
