/* ═══════════════════════════════════════════════════════════════════════
   humans ⚫ collective — design system
   Type scale and lockup shared with wonderwayofj.com so the two sites
   read as one family. Change a token here, it changes everywhere.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* colour */
  --bg:        #dcdcdc;   /* page ground, from the Figma concept */
  --ink:       #0c1313;   /* all text */
  --accent:    #ff4448;   /* shared with wonderwayofj.com */
  --hairline:  rgba(12, 19, 19, 0.16);
  --ink-soft:  rgba(12, 19, 19, 0.55);
  --light:     #f4f2ee;   /* text on dark tiles */
  --light-soft: rgba(244, 242, 238, 0.62);

  /* type — same fluid scale as wonderwayofj.com */
  --t-hero:  clamp(44px, 5vw, 88px);
  --t-h1:    clamp(34px, 2.48vw + 24px, 60px);
  --t-h2:    clamp(28px, 1.33vw + 23px, 42px);
  --t-h3:    clamp(22px, 0.76vw + 19px, 30px);
  --t-body:  clamp(17px, 0.38vw + 15.5px, 21px);
  --t-nav:   clamp(15px, 0.4vw + 13.4px, 21px);
  --t-meta:  clamp(12px, 0.19vw + 11.3px, 14px);

  /* layout */
  --pad-x:   clamp(20px, 2.3vw, 40px);
  --stack:   clamp(56px, 7vw, 120px);
  --max:      1120px;
  --case-max: 1200px;    /* case-study column, centred on the page */
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "realist", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  font-weight: 600;
  font-size: var(--t-body);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, .wide {
  font-family: "realistwide", "realist", system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.015em;
}

a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

.u {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: opacity 0.2s;
}
.u:hover { opacity: 0.6; }

/* skip link ─────────────────────────────────────────────────────────── */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--ink); color: var(--bg); padding: 12px 20px;
}
.skip:focus { left: 0; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ─── header ─────────────────────────────────────────────────────────── */
.hdr {
  position: sticky; top: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 18px var(--pad-x);
  background: var(--bg);
}
.lockup {
  display: flex; align-items: center; gap: 8.4px;   /* 12 × 0.7 — words 30% closer to the symbol */
  font-family: "realistwide", "realist", sans-serif;
  font-size: var(--t-nav); line-height: 1; white-space: nowrap;
}
.lockup svg, .lockup img { height: 1.05em; width: auto; }

.hdr nav { display: flex; align-items: center; gap: clamp(16px, 2vw, 34px); }
.hdr nav a { font-size: var(--t-nav); line-height: 1; transition: opacity 0.2s; }
.hdr nav a:hover { opacity: 0.55; }
.hdr nav a[aria-current="page"] { text-decoration: underline; text-underline-offset: 5px; }

.menu-btn {
  display: none; align-items: center; gap: 10px;
  background: none; border: 0; cursor: pointer; color: inherit;
  font-family: "realistwide", "realist", sans-serif;
  font-weight: 600;                    /* buttons don't inherit weight */
  font-size: var(--t-nav); line-height: 1;
}
.burger { display: flex; flex-direction: column; justify-content: space-between; width: 22px; height: 11px; }
.burger i { display: block; height: 1.5px; background: var(--ink); transition: transform 0.28s, opacity 0.28s; }
body.nav-open .burger i:nth-child(1) { transform: translateY(4.75px) rotate(45deg); }
body.nav-open .burger i:nth-child(2) { opacity: 0; }
body.nav-open .burger i:nth-child(3) { transform: translateY(-4.75px) rotate(-45deg); }

@media (max-width: 720px) {
  .menu-btn { display: flex; }
  .hdr nav {
    /* anchored to the header itself, so it can't drift when the fluid
       type scale changes the header's height */
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start; gap: 18px;
    padding: 24px var(--pad-x) 34px;
    background: var(--bg); border-bottom: 1px solid var(--hairline);
    /* slid up AND hidden when closed — a slide alone left its bottom
       hairline peeking out above the header on phones */
    transform: translateY(-110%); visibility: hidden;
    transition: transform 0.34s cubic-bezier(0.16,1,0.3,1), visibility 0s 0.34s;
  }
  .hdr nav a { font-size: var(--t-h3); font-family: "realistwide", sans-serif; }
  body.nav-open .hdr nav {
    transform: translateY(0); visibility: visible;
    transition: transform 0.34s cubic-bezier(0.16,1,0.3,1), visibility 0s;
  }
}

/* ─── hero ───────────────────────────────────────────────────────────── */
.hero { padding: clamp(40px, 6vw, 96px) var(--pad-x) clamp(40px, 5vw, 72px); }
.hero h1 {
  font-size: var(--t-hero);
  line-height: 1.08;
  max-width: 15ch;
}
.hero p {
  margin-top: clamp(20px, 2vw, 32px);
  max-width: 52ch;
  line-height: 1.7;
}

/* ─── project grid ───────────────────────────────────────────────────── */
.grid-label {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px;
  padding: 0 var(--pad-x) 14px;
  font-size: var(--t-meta);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-soft);
}
/* label · dot · a plain-case signpost to the grid. The count on the right
   never wraps; the note gives way first. */
.grid-label > [data-count] { white-space: nowrap; flex-shrink: 0; }
.grid-label-l { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; min-width: 0; }
.grid-label .divider { width: 3px; height: 3px; border-radius: 50%; background: var(--ink-soft); opacity: 0.55; align-self: center; }
.grid-label .note { text-transform: none; letter-spacing: 0; font-weight: 400; }

/* Three columns is the ceiling — auto-fit would keep adding narrower columns
   on a wide monitor, which makes the tiles smaller the bigger the screen gets.
   Breakpoints are columns x a 480px floor, so no tile renders below it:
   3-up above 1440, 2-up above 960, one column under that. Media queries can't
   read a custom property, so that floor lives here rather than in a token. */
.grid {
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 960px)  { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1440px) { .grid { grid-template-columns: repeat(3, 1fr); } }

/* ─── tile ───────────────────────────────────────────────────────────── */
.tile {
  --tile-pad: clamp(18px, 2vw, 30px);
  --mark-lift: 5%;       /* how far above centre the logo sits */
  position: relative;
  display: block;
  aspect-ratio: 36 / 25;                 /* 864 × 600 from the concept */
  background: var(--tile-bg, var(--bg));
  overflow: hidden;
  isolation: isolate;
}
@media (max-width: 959px) { .tile { aspect-ratio: 5 / 4; } }

/* The photo is the tile's own background, not a stacked child — one less
   paint layer to fight, and nothing can slide behind the tile's fill. */
.tile[data-kind="photo"] {
  background-color: #14100f;
  background-image: var(--tile-photo);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.tile[data-kind="photo"]::after {           /* legibility scrim */
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(0,0,0,0.66) 0%, rgba(0,0,0,0.10) 48%, rgba(0,0,0,0.20) 100%);
}

/* the whole tile is the primary link */
.tile-hit { position: absolute; inset: 0; z-index: 3; }

/* Centred on both axes, then lifted so it sits optically centred in the
   space the caption leaves. Reserving 2x the lift at the bottom moves the
   centre of the remaining area up by exactly --mark-lift of the tile. */
.tile-mark {
  position: absolute; z-index: 2;
  top: 0; left: 0; right: 0; bottom: calc(var(--mark-lift) * 2);
  display: flex; align-items: center; justify-content: center;
  padding: var(--tile-pad);   /* symmetric, or it biases the centre back down */
}
.tile-mark .wordmark {
  display: flex; align-items: center; gap: 0.42em;
  font-family: "realistwide", "realist", sans-serif;
  font-size: clamp(19px, 2.1vw, 34px);
  line-height: 1; letter-spacing: -0.02em; white-space: nowrap;
}
.tile-mark .wordmark img { height: 0.82em; width: auto; }

/* The symbol SVGs ship with their ink fill baked in, so on a dark tile they
   disappear. Inverting a solid #0c1313 lands on #f3ecec — near enough to
   --light. Only valid because these marks are monochrome. */
.tile[data-fg="light"] .wordmark img,
.case-hero[data-fg="light"] .wordmark img { filter: invert(1); }
.tile-mark > img { width: var(--logo-w, 42%); height: auto; }

/* Caption pinned to the bottom edge. The left column (what + optional
   collaborator) and the links both bottom-align and grow upward, so a tile
   with no collaborator still lines its one line up with its links. */
.tile-meta {
  position: absolute; z-index: 4;
  left: var(--tile-pad); right: var(--tile-pad); bottom: var(--tile-pad);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 6px clamp(14px, 1.6vw, 26px);
  font-size: var(--t-meta);
  line-height: 1.45;
  pointer-events: none;                   /* only the links inside are clickable */
}
.tile-meta > * { pointer-events: auto; }
.tile-info { display: flex; flex-direction: column; min-width: 0; }
.tile-what { text-wrap: pretty; }
.tile-coop { color: var(--meta-soft); }
.tile-links { display: flex; gap: clamp(10px, 1.2vw, 18px); white-space: nowrap; }

.tile-links a {
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
  transition: opacity 0.2s;
}
.tile-links a:hover { opacity: 0.6; }

/* a link whose url isn't filled in yet — impossible to miss, not clickable */
.tile-links [data-todo] {
  text-decoration-style: dashed;
  opacity: 0.45;
  cursor: not-allowed;
}
.tile-links [data-todo]::after { content: ' ⟵ url?'; letter-spacing: 0.04em; }

.tile[data-fg="dark"]  { color: var(--ink);  --meta-soft: var(--ink-soft); }
.tile[data-fg="light"] { color: var(--light); --meta-soft: var(--light-soft); }

.tile-hit:hover ~ .tile-mark > img,
.tile-hit:hover ~ .tile-mark .wordmark,
.tile:focus-within .tile-mark > img { transform: scale(1.02); }
.tile-mark > img, .tile-mark .wordmark { transition: transform 0.4s cubic-bezier(0.16,1,0.3,1); }

/* Closing CTA — an ordinary tile again, the way the Figma concept had it.
   With eleven projects it completes the grid exactly: 12 cells, 4 rows at
   3-up, 6 at 2-up. It sits on the page ground so the space reads as unclaimed. */
.tile-cta {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(16px, 1.8vw, 26px);
  text-align: center;
  background: var(--bg);
}
.tile-cta h2 { font-size: var(--t-h2); line-height: 1.1; }
/* Two buttons only: ink on light grounds, light on dark ones. The ink is
   #0c1313, never pure black. Type is 1.5× the caption step. */
.btn {
  display: inline-block;
  padding: 0.62em 1.25em;
  background: var(--ink); color: var(--light);
  font-family: "realistwide", "realist", sans-serif;
  font-size: calc(var(--t-meta) * 1.5); letter-spacing: 0.01em; line-height: 1.25;
  transition: opacity 0.2s;
}
.btn:hover { opacity: 0.8; }
.btn-light { background: var(--light); color: var(--ink); }

/* ─── full-bleed photo between two page sections (collective page) ───── */
.band-white { padding-bottom: clamp(56px, 7vw, 120px); }   /* name kept; it's grey now */
.photo-band { margin: 0; }
.photo-band img {
  display: block; width: 100%; height: auto;
  max-height: 82vh; object-fit: cover;
}
.photo-band + .page { padding-top: clamp(56px, 7vw, 120px); }

/* ─── client quotes (home) ───────────────────────────────────────────── */
.quotes-sect { padding-top: var(--stack); }
/* all four in one row; the type steps down so they fit side by side */
.quotes {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(36px, 4vw, 64px) clamp(24px, 3vw, 44px);
  align-items: start;
}
.quotes figure { margin: 0; }
.quotes blockquote {
  margin: 0;
  font-family: "realistwide", "realist", sans-serif;
  font-size: clamp(16px, 0.5vw + 13px, 20px); line-height: 1.42; letter-spacing: -0.005em;
  text-wrap: pretty;
}
.quotes blockquote::before { content: '\201C'; }
.quotes blockquote::after  { content: '\201D'; }
.quotes figcaption { margin-top: 18px; display: flex; flex-direction: column; gap: 2px; }
.quotes figcaption b { font-weight: 600; }
.quotes figcaption span { font-size: var(--t-meta); color: var(--ink-soft); }
.quotes-more { margin-top: clamp(36px, 4vw, 56px); }
@media (max-width: 1100px) { .quotes { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px)  { .quotes { grid-template-columns: 1fr; } }

/* ─── generic content page ───────────────────────────────────────────── */
.page { padding: clamp(30px, 4vw, 60px) var(--pad-x) var(--stack); }
.page-w { max-width: var(--max); }
.lede { font-size: var(--t-h1); line-height: 1.14; max-width: 26ch; font-family: "realistwide","realist",sans-serif; }

.sect { margin-top: var(--stack); }
/* Section labels carry no rule — a line under a label divides nothing.
   The lists below draw their own. */
.sect > h2 {
  font-size: var(--t-meta);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 22px;
  font-family: "realist", sans-serif;
}
.sect p + p { margin-top: 1.1em; }
.sect .big { font-size: var(--t-h2); line-height: 1.18; max-width: 26ch; font-family: "realistwide","realist",sans-serif; }
.prose { max-width: 62ch; }

/* People list. The role sits on the name's baseline — with align-self:center
   it drifted downward whenever a neighbour in the same grid row wrapped and
   stretched the row, which read as rows being misaligned. Baseline keeps every
   role on the same line as its name no matter how tall the row gets. */
.people { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px 34px; }
.person {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0 10px; padding: 9px 0;
  border-bottom: 1px solid var(--hairline);
}
.person b { font-weight: 600; white-space: nowrap; }
.person span { color: var(--ink-soft); font-size: var(--t-meta); }

/* ─── founder ────────────────────────────────────────────────────────────
   One tension holds the composition: the portrait breaks out to the left page
   edge while the type stays on the page's own left margin. The name sits above
   the role line, and the pair bottom-aligns to the photo's base. Beneath the
   photo the picture is mirrored and faded into the ground — it was taken in a
   room of mirrors, so the reflection is the subject, not decoration. */
.founder {
  margin: var(--stack) 0 0 calc(var(--pad-x) * -1);
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  /* 1fr on top: the photo spans rows 1-2, and a flexible first row absorbs
     its height so row 2 hugs the prose and the name + words sit as one block
     on the photo's base. With two auto rows grid would split the height
     equally and strand the prose halfway up. */
  grid-template-rows: 1fr auto auto;
  column-gap: clamp(26px, 4vw, 72px);
}

.founder-media { grid-column: 1; grid-row: 1 / 3; }
.founder-media img { width: 100%; height: auto; display: block; }

.founder-name {
  grid-column: 2; grid-row: 1;
  align-self: end;                       /* sits straight on top of the role */
  margin-bottom: clamp(18px, 2.2vw, 38px);
  font-size: clamp(44px, 6.4vw, 100px);
  line-height: 0.88;
  letter-spacing: -0.035em;
}

.founder-text {
  grid-column: 2; grid-row: 2;
  padding-bottom: clamp(4px, 1vw, 16px);
  max-width: 46ch;
}
.founder-role {
  font-size: var(--t-meta);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft);
  margin-bottom: 18px;
}

.founder-echo {
  grid-column: 1; grid-row: 3;
  display: block;                        /* a span ignores aspect-ratio */
  position: relative;
  aspect-ratio: 3 / 1.04;                /* 26% of a 3:4 frame: the visible fade, no dead tail */
  overflow: hidden;
}
/* The mask is applied BEFORE the transform, so the flip turns the mask over
   too. It has to be authored upside-down: strong at the image's own bottom,
   which the flip then shows at the top. Fades out by 24% of the image —
   roughly 92% of this box — so the reflection dissolves before the box ends. */
.founder-echo img {
  position: absolute; top: 0; left: 0; width: 100%; height: auto;
  transform: scaleY(-1);
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,0.34), transparent 24%);
          mask-image: linear-gradient(to top, rgba(0,0,0,0.34), transparent 24%);
}
/* Tighter hand-off into the next section: about 70% of the previous gap. */
.founder + .sect { margin-top: calc(var(--stack) * 0.5); }

/* Stacked: the name leads, then the picture, its reflection, and the words. */
@media (max-width: 780px) {
  .founder {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    margin-right: calc(var(--pad-x) * -1);
  }
  .founder-name  { grid-column: 1; grid-row: 1; align-self: start;
                   padding: 0 var(--pad-x); margin-bottom: clamp(20px, 4vw, 34px); }
  .founder-media { grid-column: 1; grid-row: 2; }
  .founder-echo  { grid-column: 1; grid-row: 3; }
  .founder-text  { grid-column: 1; grid-row: 4; max-width: none;
                   padding: clamp(22px, 5vw, 40px) var(--pad-x) 0; }
}

/* tag row */
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
.tags li { list-style: none; padding: 6px 14px; border: 1px solid var(--hairline); font-size: var(--t-meta); }

/* long-term collaborators — a row of marks at one height. Until the logo
   files land they are set as names. */
.partners {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(28px, 4vw, 64px);
  list-style: none;
  font-family: "realistwide", "realist", sans-serif;
  font-size: var(--t-h3); line-height: 1;
}
.partners a { display: block; transition: opacity 0.2s; }
.partners a:hover { opacity: 0.6; }
.partners { --mark: clamp(30px, 2.8vw, 44px); }          /* base height */
.partners img { display: block; height: calc(var(--mark) * var(--k, 1)); width: auto; }

/* definition rows (initiatives, contact) */
.rows { border-top: 1px solid var(--hairline); }
.row {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 20px;
  padding: 16px 0; border-bottom: 1px solid var(--hairline);
}
.row dt { flex: 1 1 16ch; font-family: "realistwide","realist",sans-serif; }
.row dd { margin-left: auto; }

/* ─── case study ─────────────────────────────────────────────────────── */
.case-hero {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 24 / 7;
  padding: var(--pad-x);
  background: var(--tile-bg, var(--bg));
}
.case-hero[data-kind="photo"] {
  background-color: #14100f;
  background-image: var(--tile-photo);
  background-size: cover; background-position: center;
}
@media (max-width: 620px) { .case-hero { aspect-ratio: 16 / 9; } }
.case-hero img { width: min(38%, 420px); }
/* One centred column. The padding is inside the max-width (border-box), so
   the content itself lands at exactly --case-max and every text block starts
   on the same left edge as the images. */
.case-body {
  max-width: calc(var(--case-max) + var(--pad-x) * 2);
  margin-inline: auto;
  padding: clamp(30px, 4vw, 56px) var(--pad-x) var(--stack);
}

/* the way back to the grid — same link as at the foot of the page */
.case-back { font-size: var(--t-meta); }

.case-kicker {
  margin-top: 22px;
  font-size: var(--t-meta); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-soft);
}

/* Images run the full width of the column and stack flush — no gaps between
   them, so an imported gallery reads as one continuous piece. Only text
   introduces space. */
.case-content { margin-top: clamp(28px, 3vw, 48px); }
.case-content > p { max-width: 62ch; margin-top: 1.1em; }
.case-content > p:first-child { margin-top: 0; }
.case-content { --h-gap: clamp(40px, 5vw, 80px); }   /* lead-in above a heading or label */
.case-h {
  max-width: 26ch;
  margin: var(--h-gap) 0 clamp(16px, 2vw, 28px);
  font-size: var(--t-h2); line-height: 1.18;
}
.case-fig { margin: 0; }
.case-fig img { display: block; width: 100%; height: auto; }
.case-content > p + .case-fig { margin-top: clamp(24px, 3vw, 44px); }

/* a smaller piece — diagram, mark — sits centred at a fraction of the column */
.case-fig img.mx { width: min(100%, var(--fig-max)); margin-inline: auto; }

/* a figure on its own coloured band, full column width */
.case-fig[data-band] { background: var(--fig-bg); padding: clamp(28px, 4.5vw, 80px) var(--pad-x); }

/* the opening question — one size up from a section heading */
.case-q {
  max-width: 16ch;
  margin: clamp(56px, 7vw, 120px) 0 clamp(20px, 2.6vw, 44px);
  font-size: clamp(38px, 5.4vw, 88px); line-height: 1.02; letter-spacing: -0.03em;
}

/* heading + text in one column, a picture in the other */
.case-pair {
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  gap: clamp(24px, 4vw, 64px);
  margin: clamp(24px, 3vw, 44px) 0;
}
.case-pair-text { max-width: 42ch; }
.case-pair-text .case-h { margin-top: 0; }
.case-pair img {
  display: block; width: 100%;
  aspect-ratio: var(--pair-ratio, 1);
  object-fit: cover;
}

/* a label sitting close beside its subject, optionally on a dark band */
.case-duo {
  display: flex; justify-content: center; align-items: center; flex-wrap: wrap;
  gap: clamp(20px, 3vw, 48px);
  padding: clamp(28px, 4.5vw, 80px) var(--pad-x);
  background: var(--duo-bg, transparent);
}
.case-duo .label   { display: block; width: min(100%, 400px); height: auto; flex: 0 1 auto; }
.case-duo .subject { display: block; width: min(100%, 414px); height: auto; flex: 0 1 auto; }

/* A group of pieces sitting on a dark glow. Black at --glow-mid (the first
   image's centre, set by site.js), fading to nothing at the top of the group
   and again just past its bottom — the tail is padding so the fade can run
   out under the last piece. */
.case-glow {
  position: relative; isolation: isolate;
  padding-bottom: var(--glow-tail, 48px);
}
/* Starts at the first image's centre and runs down only — nothing above it.
   The fade is eased, not linear: it holds near black through the first
   stretch and lets go faster toward the end, so the names sit on solid dark
   and the tail dissolves cleanly. */
.case-glow::before {
  content: ''; position: absolute; left: 0; right: 0; z-index: -1;
  top: var(--glow-mid, 30%); bottom: 0;
  background: linear-gradient(to bottom,
    rgba(12, 19, 19, 1)    0%,
    rgba(12, 19, 19, 0.94) 18%,
    rgba(12, 19, 19, 0.80) 38%,
    rgba(12, 19, 19, 0.56) 58%,
    rgba(12, 19, 19, 0.26) 80%,
    rgba(12, 19, 19, 0)    100%);
}
.case-glow > * + * { margin-top: var(--glow-gap, 40px); }

/* embedded video, 16:9 */
.case-video { aspect-ratio: 16 / 9; background: #000; }
.case-video iframe { display: block; width: 100%; height: 100%; border: 0; }

/* Pieces that need air. A case sets `spacing` (px) and every piece —
   figure, pair, duo, video — gets at least that much above it. Headings
   keep their own tight hand-off into the text that follows them. */
.case-content[data-spaced] > :is(.case-fig, .case-pair, .case-duo, .case-video, .case-h, .case-q) {
  margin-top: var(--fig-gap);
}
.case-content[data-spaced] > :first-child { margin-top: 0; }
.case-content[data-spaced] > :is(.case-h, .case-q) + :is(.case-fig, .case-pair, .case-duo, .case-video) {
  margin-top: clamp(20px, 2.6vw, 44px);
}
.case-content[data-spaced] > p + :is(.case-fig, .case-pair, .case-duo, .case-video) {
  margin-top: var(--fig-gap);
}

@media (max-width: 700px) {
  .case-pair { grid-template-columns: 1fr; justify-items: center; }
  .case-content[data-spaced] > :is(.case-fig, .case-pair, .case-duo, .case-video, .case-h, .case-q) {
    margin-top: calc(var(--fig-gap) * 0.6);
  }
}
.case-fig figcaption {
  margin: 14px 0 clamp(24px, 3vw, 44px);
  font-size: var(--t-meta); color: var(--ink-soft); max-width: 62ch;
}
.case-out { margin-top: clamp(28px, 3vw, 44px); }

/* small label sitting right above one piece — "research" over a moodboard */
.case-content > .case-label {                 /* specific enough to beat the generic p rule */
  max-width: none;
  margin: var(--h-gap) 0 14px;               /* same lead-in as .case-h */
  font-size: var(--t-meta); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-soft);
}
.case-label + .case-fig { margin-top: 0 !important; }

.case-hero .wordmark { font-size: clamp(24px, 3.4vw, 54px); }

/* ─── closing line ───────────────────────────────────────────────────── */
/* One line of Realist Wide Medium set to fill the measure exactly, padding to
   padding, at any viewport. The size is computed in site.js — the string is
   measured in the real font and scaled to the available width, because a
   vw-based guess drifts as soon as the string or the font changes. */
.bigline {
  padding: clamp(44px, 6vw, 104px) var(--pad-x) clamp(34px, 4.5vw, 76px);
}
.bigline span {
  display: inline-block;
  font-family: "realistwide", "realist", sans-serif;
  font-weight: 600;   /* the kit carries 400/600/700, no Medium — 600 is what has
                         always rendered; a 500 request would now fall to 400 */
  font-size: 6vw;                      /* pre-fit fallback, replaced on load */
  line-height: 1;
  letter-spacing: -0.025em;
  white-space: nowrap;
}

/* ─── footer ─────────────────────────────────────────────────────────── */
.ftr {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 18px 34px;
  padding: 30px var(--pad-x);
  border-top: 1px solid var(--hairline);
  font-size: var(--t-meta);
}
.ftr nav { display: flex; flex-wrap: wrap; gap: 10px 22px; }
.ftr a { transition: opacity 0.2s; }
.ftr a:hover { opacity: 0.55; }
.ftr .dim { color: var(--ink-soft); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
