/* ============================================================
   BUNDIGITAL — kinetic poster
   Visual world: Swiss print signage. Ink, bone, one acid yellow,
   one signal red. Everything is set on a hard 12-column grid with
   a visible rule structure, the way a printed poster is trapped
   inside its margins — and exactly one stage breaks out of it.

   COLOUR CONTRACT (measured, not eyeballed — WCAG 2.1):
     bone on ink   17.45  AAA   any size
     acid on ink   17.61  AAA   any size
     ink  on bone  17.45  AAA   any size
     ink  on acid  17.61  AAA   any size
     ink  on red    5.53  AA    any size   <- body copy on red MUST be ink
     bone on red    3.16  AA-large only    <- display type only
     acid on red    3.19  AA-large only    <- display type only
     dim  on bone    4.78  AA   any size
     conc on ink     6.03  AA   any size
     #3B0B03 on red  4.78  AA   any size   (quiet labels, red stage)
     #4A5200 on acid 7.52  AAA  any size   (quiet labels, acid stage)
   The rule that follows: on the red stage, running text is ink.
   Bone and acid appear there only at poster scale.
   Verified end-to-end in-browser: 114 rendered text nodes measured
   against their painted ground, 0 failing.

   MOTION CONTRACT: nothing is hidden by CSS alone. Every hidden-start
   state is nested under `.js-motion`, a class main.js sets only when
   motion is both wanted and supported. No-JS and reduced-motion users
   get the complete page, fully legible, hierarchy intact.
   ============================================================ */

/* ---------- 1. TOKENS ---------- */
:root {
  /* Substrate */
  --ink:      #0B0B0B;
  --ink-lift: #141414;
  --bone:     #F4F1EA;
  --bone-dim: #E2DED4;

  /* The two signals. Acid = attention, energy, the metric.
     Red = the ask, the turn, the thing to act on. Used sparingly
     so it still means something when it arrives. */
  --acid: #E8FF35;
  --red:  #FF3B20;

  /* Quiet type — each measured against its own ground (see contract) */
  --dim:  #6E6A60;   /* on bone */
  --conc: #8A8F94;   /* on ink  */

  --rule-ink:  rgba(244, 241, 234, 0.16);
  --rule-bone: rgba(11, 11, 11, 0.16);

  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Fluid poster scale. The composition depends on the top of this
     scale genuinely dominating the viewport at every width, so these
     are viewport-driven, not stepped-down fixed sizes. --t-mega is
     deliberately allowed to run large enough to crop. */
  /* Capped against BOTH axes. A poster headline that dominates the
     width is useless if it pushes the CTA below the fold, so the vh
     term is what actually governs on short/wide viewports. */
  --t-mega:  clamp(4rem, min(17vw, 21vh), 15rem);
  --t-huge:  clamp(2.75rem, min(10vw, 13vh), 8.5rem);
  --t-big:   clamp(2.25rem, min(6.5vw, 9vh), 5rem);
  --t-mid:   clamp(1.25rem, min(2.9vw, 4.2vh), 2.25rem);
  --t-body:  clamp(1rem, 1.25vw, 1.1875rem);
  --t-small: clamp(0.8125rem, 0.95vw, 0.9375rem);
  --t-micro: clamp(0.625rem, 0.72vw, 0.6875rem);

  --gut: clamp(1.15rem, 4.5vw, 4rem);
  --maxw: 1560px;

  /* Named curves, chosen for what they carry. */
  --ease-cut:   cubic-bezier(0.86, 0, 0.07, 1);    /* wipes — fast middle, hard stop */
  --ease-rise:  cubic-bezier(0.16, 1, 0.3, 1);     /* type rising into place */
  --ease-snap:  cubic-bezier(0.33, 1.3, 0.42, 1);  /* small UI, slight overshoot */

  color-scheme: dark;
}

/* ---------- 2. RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-display);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.5;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }

h1, h2, h3, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }

:focus-visible {
  outline: 3px solid var(--acid);
  outline-offset: 3px;
}
/* On acid ground an acid ring is invisible — swap it for ink. */
.stage--acid :focus-visible { outline-color: var(--ink); }

.skip-link {
  position: fixed;
  top: 0; left: 0;
  z-index: 200;
  padding: 0.85rem 1.35rem;
  background: var(--acid);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-120%);
}
.skip-link:focus { transform: translateY(0); }

.vh {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- 3. STAGE SYSTEM ----------
   Each stage is a full-bleed colour block and one scroll-snap stop.
   Snapping is `proximity`, never `mandatory`: a stage should land like
   punctuation when you come to rest near it, but must never fight or
   swallow a deliberate fast scroll. Stages taller than the viewport
   opt out entirely (see .stage--tall). */
.snap-root {
  scroll-snap-type: y proximity;
}
@media (prefers-reduced-motion: reduce) {
  .snap-root { scroll-snap-type: none; }
}

.stage {
  position: relative;
  scroll-snap-align: start;
  scroll-snap-stop: normal;   /* never `always` — that is the cage */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(4.5rem, 9vh, 7rem) 0 clamp(3rem, 6vh, 5rem);
  overflow: hidden;           /* the crop edge for oversized type */
  isolation: isolate;
}

/* Content taller than a viewport must not snap — it would hide its own
   overflow behind the next stop. */
.stage--tall {
  min-height: 0;
  scroll-snap-align: none;
  padding-block: clamp(5rem, 12vh, 9rem);
}

.stage__in {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* Colour grounds. Each carries its own local text tokens so any
   component dropped inside inherits a compliant pairing. */
.stage--ink  { background: var(--ink);  color: var(--bone); --local-quiet: var(--conc); --local-rule: var(--rule-ink); }
.stage--bone { background: var(--bone); color: var(--ink);  --local-quiet: var(--dim);  --local-rule: var(--rule-bone); }
.stage--acid { background: var(--acid); color: var(--ink);  --local-quiet: #4A5200;     --local-rule: rgba(11,11,11,0.22); }
/* --local-quiet on red is #3B0B03 (4.78 on red), not a lighter tint:
   the quiet labels run at ~11px, so they need the full 4.5 small-text
   threshold. Measured, not eyeballed. */
.stage--red  { background: var(--red);  color: var(--ink);  --local-quiet: #3B0B03;     --local-rule: rgba(11,11,11,0.24); }

/* ---------- 4. GRID ----------
   12 columns, hard margins. Every stage obeys it. Stage 05 breaks it
   exactly once, on purpose — that is the whole point of having it. */
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(0.75rem, 1.6vw, 1.5rem);
}
@media (max-width: 760px) {
  .grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* ---------- 5. TYPE ---------- */
.display {
  font-weight: 800;
  line-height: 0.84;
  letter-spacing: -0.038em;
  text-transform: uppercase;
  text-wrap: balance;
}
.display--mega { font-size: var(--t-mega); }
.display--huge { font-size: var(--t-huge); }
.display--big  { font-size: var(--t-big); letter-spacing: -0.03em; line-height: 0.9; }

/* The quiet counterweight. Every poster moment is paired with type at
   this size — the scale contrast IS the composition. */
.tag {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--local-quiet, var(--conc));
}

.lede {
  font-size: var(--t-mid);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.018em;
  text-wrap: pretty;
}

.body {
  font-size: var(--t-body);
  line-height: 1.6;
  max-width: 62ch;
  text-wrap: pretty;
}
.body + .body { margin-top: 1em; }

.mono {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: 0.02em;
}

.rule {
  border: 0;
  border-top: 1px solid var(--local-rule, var(--rule-ink));
  margin: 0;
}

/* Stage marker — the registration mark of the poster series. */
.marker {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding-bottom: 1.1rem;
  margin-bottom: clamp(1.5rem, 3.5vh, 2.75rem);
  border-bottom: 1px solid var(--local-rule);
}
.marker__num {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.18em;
}
.marker__label {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--local-quiet);
  margin-left: auto;
  text-align: right;
}

/* ---------- 6. SIGNATURE MOTION ----------
   Two primitives, repeated with variation across the page. Not one
   trick per section — a small vocabulary, used deliberately.

   (A) LINE-MASK RISE. Headlines split BY LINE, never by character.
       Each line sits in an overflow-hidden mask and rises in. Splitting
       by line keeps the transform count tiny (one per line, not one per
       glyph) and the DOM shallow. Accessibility: the visible spans are
       aria-hidden decoration; the real sentence is exposed once,
       unfragmented, to assistive tech.

   (B) BLOCK WIPE. Colour and panels arrive as a hard-edged clip-path
       wipe on --ease-cut, never a fade. This is what makes a stage
       snap into place instead of dissolving.

   Both animate only transform / opacity / clip-path — compositor
   properties. No layout is read or written during animation. */

/* Base (no-JS / reduced motion): fully visible, final position. */
.line-mask { display: block; overflow: hidden; }
.line-mask__i { display: block; will-change: auto; }

.js-motion .line-mask__i {
  transform: translate3d(0, 105%, 0);
  will-change: transform;
}
.js-motion .is-in .line-mask__i,
.js-motion .line-mask.is-in .line-mask__i {
  transform: translate3d(0, 0, 0);
  transition: transform 0.9s var(--ease-rise);
  transition-delay: var(--d, 0ms);
}

/* Wipe — reveals along the inline axis with a hard edge. */
.js-motion .wipe {
  clip-path: inset(0 100% 0 0);
  will-change: clip-path;
}
.js-motion .is-in.wipe,
.js-motion .is-in .wipe {
  clip-path: inset(0 0 0 0);
  transition: clip-path 0.78s var(--ease-cut);
  transition-delay: var(--d, 0ms);
}

/* Quiet supporting elements get a restrained lift — deliberately
   understated so it never competes with the two signature moves. */
.js-motion .lift { opacity: 0; transform: translate3d(0, 1.1rem, 0); }
.js-motion .is-in.lift,
.js-motion .is-in .lift {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s linear, transform 0.7s var(--ease-rise);
  transition-delay: var(--d, 0ms);
}

/* Once an element has arrived, release the compositor hint. */
.js-motion .is-settled .line-mask__i,
.js-motion .is-settled.wipe,
.js-motion .is-settled .wipe { will-change: auto; }

/* ---------- 7. NAV ---------- */
/* The nav rides over four different grounds. mix-blend-mode:difference
   was tried and rejected — over acid and red it produces a muddy blue
   that fails contrast. Instead main.js reports the ground currently
   under the nav and we set a real, measured colour per ground. */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  pointer-events: none;
  color: var(--bone);
  transition: color 0.3s linear;
}
[data-ground="bone"] .nav,
[data-ground="acid"] .nav,
[data-ground="red"]  .nav { color: var(--ink); }

/* No-JS / no-IntersectionObserver fallback: without ground tracking a
   bone nav would vanish on the acid and bone stages. Give the bar its
   own ink backdrop so it is legible over every ground unconditionally.
   The class is added by main.js, so JS users never see this. */
html:not(.js-ground) .nav__in {
  background: var(--ink);
  color: var(--bone);
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
}

.nav__in {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: clamp(1rem, 2.2vh, 1.6rem) var(--gut);
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.nav__in > * { pointer-events: auto; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}
.brand__mark { width: 18px; height: 18px; flex: none; }

.nav__prog {
  flex: 1;
  height: 2px;
  background: currentColor;
  opacity: 0.3;
  max-width: 340px;
  margin-inline: auto;
}
.nav__prog span {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  background: currentColor;
  opacity: 1;
}
@media (max-width: 860px) { .nav__prog { display: none; } }

.nav__cta {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.55rem 0.9rem;
  border: 1.5px solid currentColor;
  white-space: nowrap;
  margin-left: auto;
}
/* On narrow screens the CTA crowds the wordmark. Stage 07 carries the
   same action a short scroll away, so the nav copy is dropped rather
   than shrunk into illegibility. */
@media (max-width: 560px) {
  .nav__cta { display: none; }
}

/* ---------- 8. STAGE 01 — OPENING POSTER ---------- */
.hero { justify-content: space-between; gap: clamp(1rem, 3vh, 2.5rem); }
.hero__top { display: flex; justify-content: space-between; gap: 1.5rem; align-items: flex-start; }
/* No fixed margin: the flex gap above already spaces the three blocks,
   and on short viewports an extra margin is what pushed the lede out. */
.hero__h { margin: 0; }

/* The word that carries the claim. Its width axis animates once, on
   arrival — Archivo is a true variable font (wght 400-900,
   font-stretch 62%-125%), so this is a real axis, not a fake scale. */
.stretch {
  display: block;
  font-variation-settings: "wght" 800, "wdth" 125;
  font-stretch: 125%;
  color: var(--acid);
}
.js-motion .stretch {
  font-stretch: 62%;
  font-variation-settings: "wght" 800, "wdth" 62;
}
.js-motion .is-in .stretch {
  font-stretch: 125%;
  font-variation-settings: "wght" 800, "wdth" 125;
  transition: font-stretch 1.15s var(--ease-rise) 0.35s,
              font-variation-settings 1.15s var(--ease-rise) 0.35s;
}

.hero__foot {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(0.75rem, 1.6vw, 1.5rem);
  row-gap: 1.5rem;
  align-items: end;
  padding-top: 1.25rem;
  border-top: 1px solid var(--local-rule);
}
.hero__claim { grid-column: 1 / 6; }
.hero__meta  { grid-column: 8 / 13; text-align: right; }
@media (max-width: 760px) {
  .hero__claim, .hero__meta { grid-column: 1 / -1; text-align: left; }
}

.scroll-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--local-quiet);
}
.scroll-hint svg { width: 10px; height: 14px; }
.js-motion .scroll-hint svg { animation: nudge 2.4s var(--ease-rise) infinite; }
@keyframes nudge {
  0%, 62%, 100% { transform: translateY(0); }
  76%           { transform: translateY(4px); }
}

/* ---------- 9. STAGE 02 — THE METRIC ----------
   The one literal moment: a number that counts. Earned because the
   number IS the claim. tabular-nums locks digit width so nothing
   around it reflows while it runs. */
/* Left-aligned like every other stage — the system holds here. The
   number earns its emphasis from scale, not from a centring exception. */
.metric__n {
  /* One short line with nothing below it but a caption row, so it can
     take far more height than the multi-line --t-mega headlines. This
     is the biggest single element on the page, by intent. */
  font-size: clamp(6rem, min(30vw, 42vh), 24rem);
  font-weight: 900;
  line-height: 0.8;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  display: block;
}
.metric__unit {
  font-size: clamp(1.75rem, min(7vw, 10vh), 6rem);
  font-weight: 800;
  letter-spacing: -0.02em;
}
.metric__cap {
  margin-top: clamp(1.5rem, 4vh, 2.75rem);
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(0.75rem, 1.6vw, 1.5rem);
  row-gap: 1rem;
  border-top: 1px solid var(--local-rule);
  padding-top: 1.25rem;
}
.metric__cap > *:nth-child(1) { grid-column: 1 / 5; }
.metric__cap > *:nth-child(2) { grid-column: 5 / 9; }
.metric__cap > *:nth-child(3) { grid-column: 9 / 13; }
@media (max-width: 760px) {
  .metric__cap > * { grid-column: 1 / -1 !important; }
}

/* ---------- 10. STAGE 03 — THE METHOD (tall, non-snapping) ---------- */
.method__h { grid-column: 1 / 8; margin-bottom: clamp(2rem, 5vh, 3.5rem); }
.method__list { grid-column: 1 / 13; }
@media (max-width: 760px) {
  .method__h, .method__list { grid-column: 1 / -1; }
}

.step {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(1rem, 3vw, 2.5rem);
  align-items: start;
  padding: clamp(1.6rem, 3.5vh, 2.4rem) 0;
  border-top: 1px solid var(--local-rule);
}
.step:last-child { border-bottom: 1px solid var(--local-rule); }
.step__n {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--local-quiet);
  padding-top: 0.35em;
}
.step__t {
  font-size: clamp(1.35rem, 2.6vw, 2.1rem);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.024em;
  text-transform: uppercase;
}
.step__d { color: var(--local-quiet); }
@media (max-width: 860px) {
  .step { grid-template-columns: 3rem minmax(0, 1fr); }
  .step__d { grid-column: 2 / -1; }
}

/* ---------- 11. STAGE 04 — PROOF ---------- */
.proof__h { grid-column: 1 / 9; margin-bottom: clamp(2rem, 5vh, 3rem); }
.proof__grid {
  grid-column: 1 / 13;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--local-rule);
  border: 1px solid var(--local-rule);
}
/* Once the cells stack they are taller than a viewport, so this stage
   must stop snapping and stop claiming 100svh — otherwise it hides its
   own last cell behind the following snap point. */
@media (max-width: 860px) {
  .proof__grid { grid-template-columns: 1fr; }
  .stage--proof {
    min-height: 0;
    scroll-snap-align: none;
    padding-block: clamp(4.5rem, 11vh, 8rem);
  }
  .proof__cell { min-height: 0; }
}
@media (max-width: 760px) { .proof__h, .proof__grid { grid-column: 1 / -1; } }

.proof__cell {
  background: var(--ink);
  padding: clamp(1.4rem, 3vw, 2.2rem);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  min-height: clamp(11rem, 22vh, 15rem);
}
.proof__n {
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 900;
  line-height: 0.86;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--acid);
}
.proof__cell:nth-child(2) .proof__n { color: var(--bone); }
.proof__cell:nth-child(3) .proof__n { color: var(--red); }
.proof__d { color: var(--conc); font-size: var(--t-small); line-height: 1.5; margin-top: auto; }

/* ---------- 12. STAGE 05 — THE RULE-BREAK ----------
   Every other stage is trapped inside the 12-column margins and set
   left. This one — and only this one — breaks the grid: the type runs
   past the right margin and crops against the viewport edge, and the
   supporting text sits under it rather than beside it. It is placed at
   the page's turn, where the studio states what it refuses to do.
   Breaking the rule once is what makes the rule read as intentional. */
.break { justify-content: center; }
.break__in {
  width: 100%;
  padding-left: var(--gut);
  padding-right: 0;      /* the margin is deliberately abandoned */
  max-width: none;
  margin-inline: 0;
}
.break__h {
  font-size: var(--t-mega);
  font-weight: 900;
  line-height: 0.82;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  white-space: nowrap;   /* forces the overrun rather than wrapping */
  color: var(--bone);
}
/* The one outlined word. Knocked back to the red ground with an ink
   outline so it reads as a counter-form against the solid bone lines
   — deliberately quieter, never invisible. */
.break__h em {
  font-style: normal;
  color: var(--red);
  -webkit-text-stroke: clamp(2px, 0.35vw, 5px) var(--ink);
  paint-order: stroke fill;
}
/* Each line is pushed further out — the crop deepens down the stage. */
.break__h--2 { margin-left: 8vw; }
.break__h--3 { margin-left: 18vw; }

/* Marker and footnote stay inside the margins the rest of the page
   uses. Only .break__h abandons them. */
.break__marker {
  max-width: var(--maxw);
  padding-right: var(--gut);
  margin-bottom: clamp(1.25rem, 3vh, 2.25rem);
}

.break__foot {
  max-width: var(--maxw);
  margin-top: clamp(2rem, 6vh, 4rem);
  padding-right: var(--gut);
}
.break__note {
  max-width: 46ch;
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--ink);       /* CONTRACT: running text on red is ink */
  font-weight: 500;
}

/* ---------- 13. STAGE 06 — WORK ---------- */
.work__h { grid-column: 1 / 9; margin-bottom: clamp(1.75rem, 4vh, 2.5rem); }
.work__list { grid-column: 1 / 13; }
@media (max-width: 760px) { .work__h, .work__list { grid-column: 1 / -1; } }

.work__row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) 7rem;
  gap: clamp(1rem, 3vw, 2rem);
  align-items: baseline;
  padding: clamp(1.1rem, 2.4vh, 1.6rem) 0;
  border-top: 1px solid var(--local-rule);
}
.work__row:last-child { border-bottom: 1px solid var(--local-rule); }
.work__name {
  font-size: clamp(1.25rem, 2.4vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.022em;
  text-transform: uppercase;
  line-height: 1.05;
}
.work__what { color: var(--local-quiet); font-size: var(--t-small); }
.work__yr {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--local-quiet);
  text-align: right;
}
@media (max-width: 760px) {
  .work__row { grid-template-columns: minmax(0, 1fr) 5rem; }
  .work__what { grid-column: 1 / -1; }
}

/* ---------- 14. STAGE 07 — THE ASK ---------- */
.ask { justify-content: center; }
.ask__h { margin-bottom: clamp(1.75rem, 4.5vh, 3rem); }
.ask__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.25rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--local-rule);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: clamp(1rem, 2vh, 1.35rem) clamp(1.5rem, 3vw, 2.25rem);
  background: var(--ink);
  color: var(--acid);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  transition: transform 0.28s var(--ease-snap), background-color 0.28s linear;
}
.btn:hover, .btn:focus-visible { transform: translate3d(0, -3px, 0); }
.btn svg { width: 15px; height: 13px; flex: none; transition: transform 0.28s var(--ease-snap); }
.btn:hover svg { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
  .btn, .btn svg { transition: none; }
  .btn:hover, .btn:focus-visible { transform: none; }
}

.ask__alt {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  color: var(--ink);
  font-weight: 500;
}
.ask__alt a { font-weight: 700; text-underline-offset: 4px; }

/* ---------- 15. FOOT ---------- */
.foot {
  background: var(--ink);
  color: var(--conc);
  padding: clamp(2.5rem, 6vh, 4rem) 0 clamp(1.75rem, 4vh, 2.5rem);
  scroll-snap-align: none;
}
.foot__in {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.5rem;
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.foot__in a { text-decoration: none; }
.foot__in a:hover { color: var(--bone); }

/* ---------- 16. REDUCED MOTION ----------
   Belt and braces. .js-motion is never applied when reduce is set, so
   no hidden state exists in the first place; this hard-stops any
   decorative animation that might still be running (e.g. the hint). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .line-mask__i { transform: none !important; }
  .wipe { clip-path: none !important; }
  .lift { opacity: 1 !important; transform: none !important; }
  .stretch { font-stretch: 125% !important; font-variation-settings: "wght" 800, "wdth" 125 !important; }
}

/* ---------- 17. PRINT ---------- */
@media print {
  .nav, .scroll-hint { display: none; }
  .stage { min-height: 0; page-break-inside: avoid; padding: 1.5rem 0; }
  body { background: #fff; color: #000; }
}
