/* =========================================================
   FLUFFANUTTAH — Nº001
   Spec sheet for a sandwich that makes music.
   Tokens first. Change the system here, not in the components.
   ========================================================= */

:root{
  /* ---- ink & paper ---- */
  --ink:        #17191C;
  --ink-soft:   #24272B;
  --paper:      #F6F1E7;
  --paper-2:    #EBE3D4;
  --fluff:      #FFFFFF;

  /* ---- signature ----
     blue / pb / orange corrected to the Figma variables (hero-desktop 1:4).
     The last three are the hero swatch strip only — --gray is left alone
     because the catalog and spec panels still ride on it. */
  --blue:       #15A5E6;
  --blue-lift:  #6FCDF4;
  --blue-wash:  #D6EEFA;
  --pb:         #FDBA74;
  --pb-deep:    #A46B31;
  --orange:     #F26020;
  --orange-lift:#FF8A44;
  --gray:       #A3AEB4;
  --swatch-gray:#C7C2B8;
  --salmon:     #F8AA88;
  --blue-soft:  #89CBE8;
  /* tier card tints, want-one-desktop (38:1019) */
  --blue-pale:  #B3E4FA;
  --blue-mid:   #6BC8F2;

  /* ---- type ---- */
  --font-display: 'Gabarito', system-ui, sans-serif;
  --font-body:    'Rubik', system-ui, sans-serif;
  --font-mono:    'Space Mono', ui-monospace, monospace;

  /* ---- system ---- */
  --stroke: 1.5px solid var(--ink);
  --r:   14px;   /* panel radius */
  --r-s: 8px;
  --gut: clamp(14px, 2.4vw, 30px);
  --pad: clamp(18px, 2.4vw, 34px);
}

*,*::before,*::after{ box-sizing:border-box }

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

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:clamp(15px,1.02vw,17px);
  line-height:1.55;
  overflow-x:hidden;
  /* faint paper tooth — analog under the futurism */
  background-image:radial-gradient(var(--paper-2) 0.5px, transparent 0.5px);
  background-size:5px 5px;
}

img{ max-width:100%; height:auto; display:block }
.sprite{ position:absolute; width:0; height:0 }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}
.skip{
  position:absolute; left:-9999px; top:10px; z-index:200;
  background:var(--ink); color:var(--paper); padding:12px 20px; border-radius:var(--r-s);
  font-family:var(--font-mono); font-size:12px; text-transform:uppercase;
}
.skip:focus{ left:10px }

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

/* ---------- shared bits ---------- */

.mono{
  font-family:var(--font-mono); font-size:clamp(9.5px,.72vw,11.5px);
  text-transform:uppercase; letter-spacing:.16em; line-height:1.4;
}

h1,h2,h3{ font-family:var(--font-display); font-weight:900; margin:0;
  text-transform:uppercase; letter-spacing:-.02em; line-height:.92 }

p{ margin:0 0 .85em }
p:last-child{ margin-bottom:0 }

.lede{ font-size:clamp(17px,1.55vw,23px); font-weight:500; line-height:1.35; letter-spacing:-.01em }
.fine{ font-size:clamp(13.5px,.92vw,15px); line-height:1.6; opacity:.82 }

/* barcode — pure CSS, no asset */
.rail__bars{
  display:block; height:22px; min-width:70px; flex:1;
  background-image:repeating-linear-gradient(90deg,
    var(--ink) 0 1px, transparent 1px 3px, var(--ink) 3px 5px, transparent 5px 6px,
    var(--ink) 6px 9px, transparent 9px 11px, var(--ink) 11px 12px, transparent 12px 15px);
  opacity:.9;
}

/* Section header block: mono label, display heading, supporting line.
   Used by the not-yet-redesigned made / reels / hire sections. */
.sec-head{
  max-width:1400px; margin:0 auto clamp(24px,3vw,44px);
  display:flex; flex-direction:column; gap:.55em;
}
.sec-head h2{ font-size:clamp(34px,5.4vw,74px) }
.sec-head .fine{ max-width:62ch }

/* panels — the specimen-sheet container */
.panel{
  position:relative; border:var(--stroke); border-radius:var(--r);
  padding:calc(var(--pad) + 16px) var(--pad) var(--pad);
  background:var(--fluff);
}
.panel__tag{
  position:absolute; top:11px; left:var(--pad);
  opacity:.7;
}
.panel--blue{ background:var(--blue); color:var(--ink) }
.panel--blue .fine{ opacity:.9 }
.panel--pb{ background:var(--pb); color:var(--ink) }
.panel--paper{ background:var(--paper-2) }
.panel--spec{ background:var(--gray); display:flex; flex-direction:column }
.panel--ink{ background:var(--ink); color:var(--paper) }
.panel--ink .panel__tag{ opacity:.6 }

/* buttons */
.btn{
  display:inline-flex; align-items:center; gap:.7em;
  font-family:var(--font-display); font-weight:800; text-transform:uppercase;
  font-size:clamp(13px,1.05vw,16px); letter-spacing:.01em;
  border:var(--stroke); border-radius:100px; padding:.85em 1.5em;
  background:var(--fluff); color:var(--ink); text-decoration:none; cursor:pointer;
  transition:transform .18s cubic-bezier(.2,.8,.2,1), background .18s, color .18s, box-shadow .18s;
}
.btn:hover{ transform:translateY(-2px); box-shadow:4px 5px 0 var(--ink) }
.btn:active{ transform:translateY(0); box-shadow:2px 2px 0 var(--ink) }
.btn--dark{ background:var(--ink); color:var(--paper) }
.btn--dark:hover{ box-shadow:4px 5px 0 var(--pb-deep) }
.btn--orange{ background:var(--orange); color:var(--fluff) }
.btn--lg{ font-size:clamp(15px,1.5vw,22px); padding:1em 1.9em }
.btn__i{ width:1.1em; height:1.1em; flex:none }
.btn__i, .step__ico svg, .tier__ico svg, .coin svg{ fill:none }


/* ---------- section frames ----------
   Every section is a full-bleed charcoal ground carrying one centred frame.
   The frame is the Figma board; --s scales the board's own numbers.

   TWO units, not one, and the difference matters. A custom property is
   substituted where it is USED, so the `100cqw` inside --s resolves against
   whatever query container the *using* element sits in:

     - a CHILD of the frame resolves it against the frame. That is --s.
     - the FRAME'S OWN padding and margin resolve it against the frame's
       ANCESTOR, because an element is never its own query container. Those
       need a unit measured on the section. That is --sf.

   Feeding --s to a frame's own padding is what made the catalog and how
   sections shrink away from the hero everywhere between 520px and the
   breakpoint: their gutters were scaling off the viewport while their
   contents scaled off the capped frame, so the two drifted apart the wider
   the viewport got. Measured 480 wide against 435 at 1023px.

   So the section is the container, and the mobile 520 cap sits on the
   section's CONTENT box — which makes that box and the frame's border box
   the same width, and the two units agree again. */

.hero, .cat, .how, .hire, .foot{ container-type:inline-size }

@media (max-width:1023.98px){
  .hero, .cat, .how, .hire, .foot{ padding-inline:max(0px, (100% - 520px) / 2) }
}

/* =========================================================
   HERO
   A 1:1 mirror of Figma `hero-desktop` (1:4, 1440x810) and
   `hero-mobile` (23:116, 393x852).

   Every length below is the raw Figma number multiplied by --s,
   one design unit. --s is derived from the frame's own width, so
   the whole composition scales proportionally and both frames stay
   exact at any viewport. A number here is the number in Figma.

   Charcoal ground. Beige L across the top with a tab down the left.
   Blue well for the sandwich. Swatch strip at the right.
   Nothing in this section is stroked — the reference has no borders
   except on the listen links.
   ========================================================= */

.hero{ background:var(--ink); display:flex; justify-content:center }

.hero__frame{
  position:relative; overflow:hidden;
  container-type:inline-size;
  width:100%;
  aspect-ratio:1440 / 810;
}
/* one design unit, inherited by everything inside */
.hero__frame > *{ position:absolute; --s:calc(100cqw / 1440) }

/* ---------- the beige L ---------- */

.nav{
  left:calc(27 * var(--s)); top:calc(27 * var(--s));
  width:calc(1386 * var(--s)); height:calc(265 * var(--s));
  background:var(--paper);
  /* bottom-LEFT stays square: the tab continues down from it, so the two
     boxes share one unbroken left edge. Every other corner is free. */
  border-radius:calc(20 * var(--s)) calc(20 * var(--s)) calc(20 * var(--s)) 0;
}
/* the tab trailing down the left, carrying AI PARODY */
.nav__tab{
  position:absolute; left:0; top:calc(265 * var(--s));
  width:calc(94 * var(--s)); height:calc(287 * var(--s));
  background:var(--paper);
  /* both top corners are the seam with the slab; the foot is free */
  border-radius:0 0 calc(20 * var(--s)) calc(20 * var(--s));
  display:flex; align-items:center; justify-content:center;
}
/* Concave fillet (r19) where the tab leaves the slab. The arc is painted
   into a radial-gradient rather than masked — a mask leaves an unresolved
   edge at fractional --s values. */
.nav__fillet{
  position:absolute; left:calc(94 * var(--s)); top:calc(265 * var(--s));
  width:calc(19 * var(--s)); height:calc(19 * var(--s));
  background:radial-gradient(circle at 100% 100%,
    transparent 0 calc(19 * var(--s)), var(--paper) calc(19 * var(--s)));
}
.tab__txt{
  font-family:var(--font-display); font-weight:900;
  font-size:calc(48 * var(--s));
  text-transform:uppercase; line-height:1; white-space:nowrap;
  writing-mode:vertical-rl; transform:rotate(180deg);
}

/* ---------- nav content ---------- */

.topbar{
  position:absolute; left:calc(29 * var(--s)); right:calc(29 * var(--s));
  top:calc(20 * var(--s)); height:calc(20.45 * var(--s));
  display:flex; align-items:center; gap:calc(6 * var(--s));
}
.topbar__ico{ flex:none; width:calc(19 * var(--s)); height:calc(20.45 * var(--s)) }
.topbar__rule{ flex:1; height:max(1px, calc(1 * var(--s))); background:var(--ink) }
.topbar__txt{
  flex:none; margin:0 calc(4 * var(--s));
  font-family:var(--font-mono); font-size:calc(16 * var(--s));
  text-transform:uppercase; line-height:1; white-space:nowrap;
}

/* Wordmark — inset left and right so it always fills the slab's measure.
   The height is stated rather than left to auto: an inline <svg> with only
   a viewBox has no intrinsic height to resolve against an inset width, so
   `height:auto` collapses it. 134 is the glyph height at full measure. */
.wm{
  position:absolute; left:calc(29 * var(--s)); right:calc(29 * var(--s));
  top:calc(61.74 * var(--s)); height:calc(134 * var(--s));
}
.wm__l{ fill:var(--ink) }
.wm--l1, .wm--l2{ display:none }

/* Tagline left, listen links right, one row.
   z-index because the sandwich figure's box reaches up over this row. The
   figure is already pointer-events:none, but raising the links means they win
   the hit test on stacking order too, not just on pointer-events. No visual
   change — the art does not reach this far right. */
.meta{
  z-index:4;
  position:absolute; left:calc(29 * var(--s)); right:calc(29 * var(--s));
  top:calc(211 * var(--s)); height:calc(35 * var(--s));
  display:flex; align-items:center; justify-content:space-between;
  gap:calc(20 * var(--s));
}
.tagline{
  display:flex; align-items:center; gap:calc(18 * var(--s));
  margin:0; font-family:var(--font-mono); font-size:calc(16 * var(--s));
  text-transform:uppercase; line-height:1; white-space:nowrap;
}
.tagline__knife{ flex:none; width:calc(143.87 * var(--s)); height:calc(17.87 * var(--s)) }

.socials{ list-style:none; margin:0; padding:0; display:flex; gap:calc(12 * var(--s)) }
.slink{
  display:block; text-decoration:none; color:var(--ink);
  border:max(1px, calc(1 * var(--s))) solid var(--ink);
  border-radius:calc(30 * var(--s));
  padding:calc(7.25 * var(--s)) calc(15 * var(--s)) calc(7.75 * var(--s));
  font-family:var(--font-mono); font-size:calc(12 * var(--s));
  line-height:calc(20 * var(--s)); letter-spacing:calc(.48 * var(--s));
  text-transform:uppercase; white-space:nowrap;
  transition:background .18s, color .18s;
}
.slink:hover{ background:var(--ink); color:var(--paper) }

/* ---------- left column: barcode bar + about card ---------- */

.lcol{
  left:calc(27 * var(--s)); top:calc(319 * var(--s));
  width:calc(267 * var(--s)); height:calc(464 * var(--s));
}
/* the narrow bar the barcode runs down */
.lcol::before{
  content:''; position:absolute; z-index:0;
  left:calc(118 * var(--s)); top:0;
  width:calc(149 * var(--s)); height:calc(297 * var(--s));
  background:var(--pb);
  border-radius:calc(10 * var(--s)) calc(10 * var(--s)) 0 0;
}
/* the card the copy sits on */
.lcol::after{
  content:''; position:absolute; z-index:0;
  left:0; top:calc(287 * var(--s));
  width:calc(267 * var(--s)); height:calc(177 * var(--s));
  background:var(--pb);
  border-radius:calc(20 * var(--s)) 0 calc(20 * var(--s)) calc(20 * var(--s));
}
/* convex shoulder (r41) flaring the bar out into the card */
.lcol__fillet{
  position:absolute; z-index:0;
  left:calc(77 * var(--s)); top:calc(246 * var(--s));
  width:calc(41 * var(--s)); height:calc(41 * var(--s));
  background:radial-gradient(circle at 0 0,
    transparent 0 calc(41 * var(--s)), var(--pb) calc(41 * var(--s)));
}

.code__bars{
  position:absolute; z-index:1;
  left:calc(135 * var(--s)); top:calc(18 * var(--s));
  width:calc(97 * var(--s)); height:calc(268 * var(--s));
}
.code__price, .code__name{
  position:absolute; z-index:1;
  left:calc(234 * var(--s)); width:calc(24 * var(--s));
  font-family:var(--font-mono); font-size:calc(16 * var(--s));
  line-height:calc(24 * var(--s));
  text-transform:uppercase; white-space:nowrap;
  writing-mode:vertical-rl; transform:rotate(180deg);
}
.code__price{ top:calc(19 * var(--s));  height:calc(49 * var(--s)) }
.code__name { top:calc(169 * var(--s)); height:calc(118 * var(--s)) }

.about{
  position:absolute; z-index:1;
  left:calc(21 * var(--s)); top:calc(308 * var(--s));
  width:calc(234 * var(--s)); margin:0;
  font-family:var(--font-display); font-weight:400;
  font-size:calc(13 * var(--s)); line-height:normal;
  text-transform:uppercase;
}
/* Black on desktop, ExtraBold on mobile — that is how the two frames are set.
   At 12px the two are near-identical, so this follows the file rather than
   picking one. */
.about b{ font-weight:900 }

/* ---------- blue well + the sandwich ---------- */

.well{
  left:calc(321 * var(--s)); top:calc(319 * var(--s));
  width:calc(927 * var(--s)); height:calc(464 * var(--s));
  background:var(--blue); border-radius:calc(20 * var(--s));
}
/* the sandwich breaks the top edge of the well — its box starts 81 units
   above the well and clips, exactly as in the reference */
.fig{
  left:calc(398 * var(--s)); top:calc(238 * var(--s));
  width:calc(726 * var(--s)); height:calc(545 * var(--s));
  margin:0; overflow:hidden;
  /* This box paints after .nav and reaches up to y=238, so it sits squarely
     on top of the Spotify and Apple Music links. The art is transparent
     there, but the box still swallowed the clicks. It is decorative. */
  pointer-events:none;
}
.fig img{
  position:absolute; left:-7.32%; top:-30.64%;
  width:121.93%; max-width:none; height:auto;
}

/* ---------- swatch strip ---------- */

.swatch{
  left:calc(1276 * var(--s)); top:calc(319 * var(--s));
  width:calc(134 * var(--s)); height:calc(464 * var(--s));
  background:var(--paper); border-radius:calc(20 * var(--s));
  padding:calc(21 * var(--s)) calc(20 * var(--s)) calc(19 * var(--s));
  display:flex; flex-direction:column; gap:calc(17 * var(--s));
}
.swatch i{ flex:1; display:block; border-radius:calc(4 * var(--s)) }

/* The orange chip answers back. Cream type set INSIDE the chip, so the strip
   never changes size and the joke stays a secret until you land on it.
   Absolutely positioned and clipped, so the copy can never push the box out. */
.swatch__joke{ position:relative; overflow:hidden; cursor:help }
.swatch__tip{
  position:absolute; inset:0;
  display:grid; place-items:center;
  /* wider side padding narrows the measure so the line breaks evenly after
     GLAD instead of orphaning HERE? on its own line */
  padding:calc(4 * var(--s)) calc(16 * var(--s));
  color:var(--paper);
  font-family:var(--font-mono); font-size:calc(6 * var(--s));
  line-height:1.02; letter-spacing:.02em;
  text-transform:uppercase; text-align:center;
  /* No transition on the rest state on purpose. Declared here it fires a
     1 -> 0 fade on first style resolution, which flashes the secret for 200ms
     on every page load. Declaring it only on the revealed state means it
     fades in on hover and snaps away on leave. */
  opacity:0; pointer-events:none;
}
.swatch__joke:hover .swatch__tip,
.swatch__joke:focus-visible .swatch__tip{ opacity:1; transition:opacity .2s }

/* ---------- exploded-view callouts ---------- */
/* Two annotations sitting beside the sandwich: keyed circle, part name, note.
   No leader lines or anchor dots — they read as spec-sheet notes rather than
   as pointers, so neither block has to sit next to the part it names. */
.call{
  z-index:3;
  display:flex; gap:calc(7 * var(--s));
  font-family:var(--font-mono); font-size:calc(11 * var(--s));
  line-height:1.4; text-transform:uppercase; color:var(--ink);
}
.call__k{
  flex:none; width:calc(15 * var(--s)); height:calc(15 * var(--s));
  border:max(1px, calc(1 * var(--s))) solid var(--ink); border-radius:50%;
  display:grid; place-items:center;
  font-size:calc(8 * var(--s)); line-height:1;
}
.call__n{ display:block; font-weight:700; letter-spacing:.12em }

/* Both blocks clear the art by its measured alpha extents, not by eye.
   Crust sits in the bottom-right, where the sandwich has pulled away to
   x=767 by y=720 — far more room than the top-left, where the toast's
   leading edge cuts in diagonally and forced a cramped two-line measure. */
.call--crust{ left:calc(1000 * var(--s)); top:calc(676 * var(--s)); width:calc(230 * var(--s)) }
.call--drip{  left:calc(336 * var(--s));  top:calc(676 * var(--s)); width:calc(136 * var(--s)) }

/* Below 1200 the 11-unit mono drops under ~9px and the well has no room for
   these. The callouts go entirely; the orange chip's tip stops being a popover
   — there is no hover on touch, the strip runs horizontally so there is
   nowhere for it to sit, and at 190 units it overran the frame. The text stays
   in the accessibility tree, so the joke still reads for screen readers.
   One number to move if you want them held longer. */
@media (max-width:1199.98px){
  .call{ display:none }
  /* the tip lives inside the chip now, so it needs no repositioning here —
     there is no hover on touch, so it simply never fires */
  .swatch__joke{ cursor:auto }
}

/* ---------- mobile: Figma `hero-mobile` 23:116, 393x852 ----------
   The composition caps at 520 so it can't inflate on a tablet; the
   charcoal ground stays full-bleed behind it. */

@media (max-width:1023.98px){
  .hero__frame{ aspect-ratio:393 / 852 }
  .hero__frame > *{ --s:calc(100cqw / 393) }

  .nav{
    left:calc(15 * var(--s)); top:calc(15 * var(--s));
    width:calc(363 * var(--s)); height:calc(265 * var(--s));
  }
  .nav__tab{
    width:calc(52.207 * var(--s)); height:calc(245 * var(--s));
    border-radius:0 0 calc(11.15 * var(--s)) calc(11.15 * var(--s));
  }
  .nav__fillet{ left:calc(52.207 * var(--s)) }
  .tab__txt{ font-size:calc(41.202 * var(--s)) }

  .topbar{
    left:calc(19 * var(--s)); right:calc(19 * var(--s));
    top:calc(14.77 * var(--s));
  }
  .topbar__txt{ font-size:calc(12 * var(--s)) }

  /* each line is justified to the same 325 measure, so the two lines carry
     different scales — hence different stated heights */
  .wm--full{ display:none }
  .wm--l1, .wm--l2{
    display:block;
    left:calc(19 * var(--s)); right:calc(19 * var(--s));
  }
  .wm--l1{ top:calc(48.81 * var(--s));  height:calc(70.29 * var(--s)) }
  .wm--l2{ top:calc(130.76 * var(--s)); height:calc(62.22 * var(--s)) }

  .meta{
    left:calc(19 * var(--s)); right:calc(19 * var(--s));
    top:calc(200 * var(--s)); height:auto;
    flex-direction:column; align-items:stretch; gap:calc(12 * var(--s));
  }
  .tagline{ justify-content:space-between; font-size:calc(12.182 * var(--s)) }
  .tagline__knife{ width:calc(109.5 * var(--s)); height:calc(13.6 * var(--s)) }
  .socials{ gap:calc(9 * var(--s)) }
  .slink{
    border-width:max(1px, calc(.757 * var(--s)));
    padding:calc(5.298 * var(--s)) calc(11.353 * var(--s)) calc(6.055 * var(--s));
    font-size:calc(9.08 * var(--s)); line-height:calc(15 * var(--s));
    letter-spacing:calc(.3632 * var(--s));
  }

  .well{
    left:calc(82 * var(--s)); top:calc(295 * var(--s));
    width:calc(296 * var(--s)); height:calc(230 * var(--s));
    border-radius:calc(8 * var(--s));
  }
  .fig{
    left:calc(49 * var(--s)); top:calc(262 * var(--s));
    width:calc(388 * var(--s)); height:calc(291.267 * var(--s));
  }

  /* on mobile the left column flattens to one plain card */
  .lcol{
    left:calc(15 * var(--s)); top:calc(538 * var(--s));
    width:calc(363 * var(--s)); height:calc(158 * var(--s));
  }
  .lcol::before, .lcol__fillet{ display:none }
  .lcol::after{
    left:0; top:0;
    width:calc(363 * var(--s)); height:calc(158 * var(--s));
    /* the bar and the shoulder are gone here, so this is a standalone card
       and its top-left is a free corner like the other three */
    border-radius:calc(20 * var(--s));
  }
  .code__bars{
    left:calc(18 * var(--s)); top:calc(22 * var(--s));
    width:calc(41.958 * var(--s)); height:calc(111.521 * var(--s));
  }
  .code__price, .code__name{
    left:calc(60.66 * var(--s)); width:calc(10.341 * var(--s));
    font-size:calc(6.894 * var(--s)); line-height:calc(10.341 * var(--s));
  }
  .code__price{ top:calc(22 * var(--s));    height:calc(21.114 * var(--s)) }
  .code__name { top:calc(82.73 * var(--s)); height:calc(50.846 * var(--s)) }
  .about{
    left:calc(85 * var(--s)); top:calc(19 * var(--s));
    width:calc(259 * var(--s));
    font-size:calc(12 * var(--s)); line-height:calc(17 * var(--s));
  }
  .about b{ font-weight:800 }

  .swatch{
    left:calc(15 * var(--s)); top:calc(711 * var(--s));
    width:calc(363 * var(--s)); height:calc(126 * var(--s));
    border-radius:calc(12 * var(--s));
    padding:calc(19 * var(--s)) calc(20 * var(--s)) calc(19 * var(--s)) calc(19 * var(--s));
    flex-direction:row-reverse; gap:calc(12 * var(--s));
  }
  .swatch i{ border-radius:calc(3.129 * var(--s)) }
}

/* =========================================================
   CATALOG
   Mirrors Figma catalog-desktop (27:279, 1440 wide) and
   catalog-mobile (32:613, 393 wide).

   Same --s design unit as the hero, so every number here is the
   number in Figma. Rows sit in normal flow rather than absolutely
   placed: it is a repeating list, and flow keeps filtering and
   variable title lengths from breaking the grid.

   No top padding — the hero frame's own bottom margin carries the
   gap between the two sections.
   ========================================================= */

.cat{ background:var(--ink); display:flex; justify-content:center }

.cat__frame{
  position:relative;
  container-type:inline-size;
  width:100%;
  padding:0 calc(27 * var(--sf)) calc(27 * var(--sf));
  /* --s is read by children, where cqw is this frame's CONTENT box, so it
     divides by the design content width (1440-54) rather than the frame
     width. --sf is read here, where cqw is the section. See section frames. */
  --sf:calc(100cqw / 1440);
  --s:calc(100cqw / 1386);
}

/* ---------- header: title panel + info panel ---------- */

.cat__head{
  display:grid;
  grid-template-columns:calc(670 * var(--s)) minmax(0, 1fr);
  gap:calc(27 * var(--s));
  align-items:stretch;
  margin-bottom:calc(27 * var(--s));
}
.cat__title, .cat__info{
  border-radius:calc(20 * var(--s));
  min-height:calc(130 * var(--s));
}
.cat__title{
  background:var(--paper);
  display:flex; align-items:center;
  padding:0 calc(25 * var(--s));
  overflow:hidden;
}
.cat__title h2{
  font-family:var(--font-display); font-weight:900;
  font-size:calc(98.715 * var(--s));
  line-height:calc(90.489 * var(--s));
  letter-spacing:0; text-transform:uppercase; white-space:nowrap;
  margin:0;
}

.cat__info{
  background:var(--pb);
  padding:calc(25 * var(--s)) calc(27 * var(--s)) calc(25 * var(--s));
  display:flex; flex-direction:column; gap:calc(20 * var(--s));
}
.cat__intro{
  margin:0; max-width:calc(638 * var(--s));
  font-family:var(--font-body); font-weight:400;
  font-size:calc(13 * var(--s)); line-height:normal;
  text-transform:uppercase; color:var(--ink);
}
.cat__intro b{ font-weight:700 }

/* Nine chips instead of the designed eight (POP added so every song is
   reachable by a filter). At 1440 that no longer fits one line, so the row
   wraps and both header panels grow together off min-height. Mobile already
   wraps this row in the frame, so the behaviour is consistent. */
.cat__filters{ display:flex; flex-wrap:wrap; gap:calc(10 * var(--s)) }
.fchip{
  font-family:var(--font-mono); font-size:calc(12 * var(--s));
  line-height:calc(20 * var(--s)); letter-spacing:calc(.48 * var(--s));
  text-transform:uppercase; white-space:nowrap;
  padding:calc(7.25 * var(--s)) calc(15 * var(--s)) calc(7.75 * var(--s));
  border:max(1px, calc(1 * var(--s))) solid var(--ink);
  border-radius:calc(30 * var(--s));
  background:transparent; color:var(--ink); cursor:pointer;
  transition:background .16s, color .16s;
}
/* fills solid on hover, the same as the selected chip — matched to the listen
   chips. Focus is deliberately NOT included: tabbing the filter row would
   light each chip as if it were the one applied, and the orange focus ring
   already says where you are. */
.fchip:hover:not([disabled]){ background:var(--ink); color:var(--paper) }
/* genres that do not exist yet — visible so the row reads as a full set, but
   dimmed and inert. Swap the labels as songs land. */
.fchip[disabled]{ opacity:.32; cursor:not-allowed }
.fchip.is-on{ background:var(--ink); color:var(--paper) }

/* ---------- song rows ---------- */

.tracks{
  list-style:none; margin:0 0 calc(27 * var(--s)); padding:0;
  display:flex; flex-direction:column; gap:calc(6 * var(--s));
}
.track.is-off{ display:none }

.track__a{
  position:relative; isolation:isolate; overflow:hidden;
  display:grid; align-items:center;
  grid-template-columns:calc(60 * var(--s)) minmax(0, 1fr)
                        calc(433 * var(--s)) calc(158 * var(--s)) calc(32 * var(--s));
  min-height:calc(87 * var(--s));
  padding:0 calc(26 * var(--s)) 0 calc(29 * var(--s));
  background:var(--paper); border-radius:calc(20 * var(--s));
  text-decoration:none; color:var(--ink);
}
/* the bar fills blue from the bottom */
.track__a::before{
  content:''; position:absolute; inset:0; z-index:-1;
  background:var(--blue);
  transform:scaleY(0); transform-origin:bottom;
  transition:transform .32s cubic-bezier(.2,.8,.2,1);
}
.track__a:hover::before, .track__a:focus-visible::before{ transform:scaleY(1) }

.track__n{
  font-family:var(--font-mono); font-size:calc(16 * var(--s));
  line-height:1; text-transform:uppercase;
}
.track__t{
  font-family:var(--font-display); font-weight:900;
  font-size:calc(45 * var(--s)); line-height:1.05;
  text-transform:uppercase; letter-spacing:0; white-space:nowrap;
  transition:transform .32s cubic-bezier(.2,.8,.2,1);
}
.track__a:hover .track__t, .track__a:focus-visible .track__t{
  transform:translateX(calc(14 * var(--s)));
}
.track__d{
  max-width:calc(373 * var(--s));
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:normal; text-transform:uppercase;
}
/* genre is Gabarito Black here, not mono — changed in the 08-18 frame */
.track__g{
  font-family:var(--font-display); font-weight:900;
  font-size:calc(16 * var(--s)); line-height:1;
  text-transform:uppercase;
}
.track__i{
  width:calc(32 * var(--s)); height:calc(32 * var(--s));
  color:var(--ink); fill:currentColor;
  transition:color .25s, transform .25s;
}
/* once the bar is blue the arrow goes white */
.track__a:hover .track__i, .track__a:focus-visible .track__i{
  color:var(--fluff); transform:translateX(calc(4 * var(--s)));
}

/* Touch has no hover, so the row nearest the middle of the screen carries the
   same blue fill instead and hands it to the next one as you scroll. Same
   three moves as :hover above, driven by .is-centered from main.js. */
@media (hover:none){
  .track.is-centered .track__a::before{ transform:scaleY(1) }
  .track.is-centered .track__t{ transform:translateX(calc(14 * var(--s))) }
  .track.is-centered .track__i{
    color:var(--fluff); transform:translateX(calc(4 * var(--s)));
  }
}

/* ---------- listen bar ---------- */

.listen{
  position:relative;
  background:var(--orange); border-radius:calc(20 * var(--s));
  min-height:calc(49 * var(--s));
  padding:calc(7 * var(--s));
  display:flex; align-items:center; gap:calc(12 * var(--s));
}
.lchip{
  font-family:var(--font-mono); font-size:calc(12 * var(--s));
  line-height:calc(20 * var(--s)); letter-spacing:calc(.48 * var(--s));
  text-transform:uppercase; white-space:nowrap; text-decoration:none;
  padding:calc(7.25 * var(--s)) calc(15 * var(--s)) calc(7.75 * var(--s));
  border:max(1px, calc(1 * var(--s))) solid var(--ink);
  border-radius:calc(30 * var(--s));
  background:var(--ink); color:var(--paper);
  transition:background .18s, color .18s, border-color .18s;
}
/* hollows out rather than inverting — the orange bar becomes the fill */
.lchip:hover, .lchip:focus-visible{
  background:transparent; color:var(--ink); border-color:var(--ink);
}
/* Mirrored so the blade points the other way to the hero's.
   Offsets are measured from the bar's PADDING box, not its border box —
   absolute positioning resolves against the padding box, and .listen carries
   7 units of padding, so these were verified by measuring the rendered box
   against the bar rather than derived on paper. */
.listen__knife{
  position:absolute; right:calc(21 * var(--s)); top:50%;
  width:calc(144 * var(--s)); height:calc(17.87 * var(--s));
  transform:translateY(-50%) scaleX(-1);
}

/* cursor-following album cover. Unchanged — the JS keys off .track[data-img]. */
.peek{
  position:fixed; top:0; left:0; z-index:80; width:clamp(220px,23vw,340px);
  aspect-ratio:1; pointer-events:none; opacity:0; will-change:transform;
  border:var(--stroke); border-radius:var(--r); overflow:hidden;
  box-shadow:0 24px 60px rgba(23,25,28,.28);
}
.peek img{ width:100%; height:100%; object-fit:cover }
@media (hover:none),(max-width:820px){ .peek{ display:none } }

/* ---------- mobile: Figma catalog-mobile 32:613, 393 wide ---------- */

@media (max-width:1023.98px){
  .cat__frame{
    --sf:calc(100cqw / 393);
    --s:calc(100cqw / 363);
    padding:0 calc(15 * var(--sf)) calc(15 * var(--sf));
  }

  .cat__head{
    grid-template-columns:minmax(0, 1fr);
    gap:calc(15 * var(--s));
    margin-bottom:calc(15 * var(--s));
  }
  .cat__title{ min-height:calc(71 * var(--s)); padding:0 calc(18.21 * var(--s)) }
  .cat__title h2{
    font-size:calc(51.871 * var(--s)); line-height:calc(47.548 * var(--s));
  }
  .cat__info{
    min-height:calc(230 * var(--s));
    padding:calc(25 * var(--s)) calc(19 * var(--s));
    gap:calc(24 * var(--s));
  }
  .cat__intro{ max-width:calc(315 * var(--s)) }

  .tracks{ gap:calc(6 * var(--s)); margin-bottom:calc(15 * var(--s)) }

  /* the row becomes a card: number, then title + blurb, then genre and
     arrow on a footer row. min-height rather than the frame's fixed 262 so a
     three-line title (MARGARITAS IN THE WINTAH) cannot clip. */
  .track__a{
    grid-template-columns:minmax(0, 1fr) calc(32 * var(--s));
    grid-template-rows:auto auto auto;
    align-items:start;
    row-gap:calc(11 * var(--s));
    min-height:calc(262 * var(--s));
    padding:calc(14 * var(--s)) calc(19 * var(--s));
  }
  .track__n{ grid-column:1 / -1; grid-row:1 }
  .track__t{
    grid-column:1 / -1; grid-row:2;
    white-space:normal; font-size:calc(45 * var(--s));
    line-height:calc(43 * var(--s));
  }
  .track__a:hover .track__t{ transform:none }
  .track__d{ grid-column:1 / -1; grid-row:3; max-width:calc(325 * var(--s)) }
  .track__g{ grid-column:1; grid-row:4; align-self:end }
  .track__i{ grid-column:2; grid-row:4; align-self:end }

  .listen{
    min-height:calc(175 * var(--s));
    flex-direction:column; align-items:flex-start;
    gap:calc(16 * var(--s));
    padding:calc(40 * var(--s)) calc(32 * var(--s));
  }
  /* The knife stands up on the right edge here. Keep the artwork's natural
     144x17.87 box and rotate it — swapping the width and height as well would
     squash the drawing before turning it. Rotation is about the centre, so the
     offsets place the pre-rotation box so the rotated result lands at
     x 315-333, y 16-160 of the bar. Verified by measurement. */
  .listen__knife{
    left:calc(252 * var(--s)); right:auto; top:calc(79 * var(--s));
    width:calc(144 * var(--s)); height:calc(17.87 * var(--s));
    transform:rotate(90deg) scaleX(-1);
    transform-origin:center;
  }
}

/* =========================================================
   HOW THE MUSIC GETS MADE
   Mirrors Figma how-desktop (1:7) and how-mobile (38:465),
   plus their read-more states (38:737 / 38:922).

   Desktop is a fixed composition like the hero — absolutely
   placed against the frame's numbers, and the read-more panel
   OVERLAYS the steps rather than reflowing them, so the section
   height never changes. Mobile is a flow column, because the
   long copy genuinely makes the page taller there.

   The two desktop unions differ by one number: the beige tab is
   266 wide closed and 1289 open. That is the whole transition.
   ========================================================= */

.how{ background:var(--ink); display:flex; justify-content:center }

.how__frame{
  position:relative; box-sizing:border-box;
  container-type:inline-size;
  /* No padding on desktop: children are absolutely placed, and offsets on a
     padded container did not resolve against the padding box here. Dropping it
     lets every child carry its raw Figma page coordinate, which is simpler to
     check against the frame anyway. aspect-ratio rather than a --s height,
     because the frame's own declarations resolve cqw against its ancestor. */
  width:100%; aspect-ratio:1440 / 1015; padding:0;
  /* The catalog already ends on a 27 gutter and this section opens with
     another, which doubled the gap. Pull back one of them. */
  margin-top:calc(-27 * var(--sf));
  --sf:calc(100cqw / 1440);
  --s:calc(100cqw / 1440);
}
.how__frame > *{ position:absolute }

/* ---------- the beige union ---------- */

.how__panel{
  left:calc(27 * var(--s)); top:calc(27 * var(--s));
  width:calc(1386 * var(--s)); height:calc(488 * var(--s));
  --tab:calc(266 * var(--s));
}
/* full-width bar */
.how__panel::before{
  content:''; position:absolute; left:0; top:0;
  width:100%; height:calc(146 * var(--s));
  background:var(--paper);
  border-radius:calc(20 * var(--s)) calc(20 * var(--s)) calc(20 * var(--s)) 0;
}
/* The tab hanging off the left — this is what grows on open. z-index:0 because
   ::after paints AFTER the element's children, so without it the tab covers
   the copy sitting on top of it. */
.how__panel::after{
  content:''; z-index:0; position:absolute; left:0; top:calc(146 * var(--s));
  width:var(--tab); height:calc(342 * var(--s));
  background:var(--paper);
  /* top corners are the seam with the bar above; the foot is free */
  border-radius:0 0 calc(20 * var(--s)) calc(20 * var(--s));
  transition:width .55s cubic-bezier(.2,.8,.2,1);
}
/* concave r20 fillet where the tab leaves the bar, same trick as the hero */
.how__fillet{
  position:absolute; left:var(--tab); top:calc(146 * var(--s));
  width:calc(20 * var(--s)); height:calc(20 * var(--s));
  background:radial-gradient(circle at 100% 100%,
    transparent 0 calc(20 * var(--s)), var(--paper) calc(20 * var(--s)));
  transition:left .55s cubic-bezier(.2,.8,.2,1);
}
/* Open, the panel has to sit ABOVE the steps — it covers step 3's left
   portion, leaving only the strip that carries the close button. */
.how__panel[data-open="true"]{ --tab:calc(1289 * var(--s)); z-index:2 }

.how__title{
  position:absolute; left:calc(26 * var(--s)); top:calc(27 * var(--s));
  margin:0; font-family:var(--font-display); font-weight:900;
  font-size:calc(100 * var(--s)); line-height:calc(90.489 * var(--s));
  letter-spacing:0; text-transform:uppercase; white-space:nowrap;
}

.how__sub{
  margin:0; font-family:var(--font-display); font-weight:900;
  line-height:normal; text-transform:uppercase; letter-spacing:0;
}
.how__copy, .how__col p{
  margin:0; font-family:var(--font-display); font-weight:400;
  font-size:calc(14 * var(--s)); line-height:normal; text-transform:uppercase;
}
/* The whole argument is first person, so it gets signed. Bumped to the same
   weight as the sub-heads so it reads as a signature and not as one more
   line of the paragraph above it. */
.how__col p.how__sign{ font-weight:900; margin-top:calc(6 * var(--s)) }

.how__brief, .how__more{
  position:absolute; z-index:1;
  left:calc(28 * var(--s)); top:calc(156 * var(--s));
}
.how__brief{
  width:calc(206 * var(--s));
  display:flex; flex-direction:column; align-items:flex-start;
  gap:calc(17 * var(--s));
}
/* a class rule setting display beats the UA [hidden] rule, so state it */
.how__brief[hidden]{ display:none }
.how__brief .how__sub{ font-size:calc(18 * var(--s)) }

/* Lifted 6 from the board's 156, and the column gap below tightened, to open
   up the 9 of clearance the pinned Close chip needs under column one. */
.how__more{ width:calc(1236 * var(--s)); top:calc(150 * var(--s)) }
.how__more[hidden]{ display:none }
.how__more .how__sub{ font-size:calc(14 * var(--s)); margin-bottom:calc(17 * var(--s)) }
.how__cols{
  display:grid;
  grid-template-columns:repeat(2, calc(610 * var(--s)));
  column-gap:calc(16 * var(--s));
}
.how__col{ display:flex; flex-direction:column; align-items:flex-start; gap:calc(8 * var(--s)) }

/* Read more sits at panel 28,433 with a 102.4 x 37 footprint. Close is pinned
   to the same spot and given the same footprint, so wherever inside the chip
   the pointer landed, it is still inside the chip after the panel opens. */
.how__close{
  position:absolute; left:0; top:calc(283 * var(--s));
  min-width:calc(102.4 * var(--s));
}

.hchip{
  font-family:var(--font-mono); font-size:calc(12 * var(--s));
  line-height:calc(20 * var(--s)); letter-spacing:calc(.48 * var(--s));
  text-transform:uppercase; white-space:nowrap;
  padding:calc(7.25 * var(--s)) calc(15 * var(--s)) calc(7.75 * var(--s));
  border:max(1px, calc(1 * var(--s))) solid var(--ink);
  border-radius:calc(30 * var(--s));
  background:transparent; color:var(--ink); cursor:pointer;
  transition:background .16s, color .16s;
}
.hchip:hover{ background:var(--ink); color:var(--paper) }

/* the star marks the panel's open corner, so it moves with the tab */
.how__star{
  position:absolute; z-index:1;
  left:calc(222 * var(--s)); top:calc(437 * var(--s));
  width:calc(26 * var(--s)); height:calc(26 * var(--s));
  color:var(--ink); fill:currentColor;
  transition:left .55s cubic-bezier(.2,.8,.2,1), top .55s cubic-bezier(.2,.8,.2,1);
}
.how__panel[data-open="true"] .how__star{
  left:calc(1244 * var(--s)); top:calc(444 * var(--s));
}

/* ---------- the three steps ---------- */

.steps{
  list-style:none; margin:0; padding:0; z-index:1;
  left:calc(320 * var(--s)); top:calc(200 * var(--s));
  display:flex; gap:calc(27 * var(--s));
}
.steps{ perspective:1400px }
.step{
  position:relative; flex:none;
  width:calc(347 * var(--s)); height:calc(315 * var(--s));
  background:var(--blue-soft); border-radius:calc(20 * var(--s));
  transition:opacity .35s;
  transform-style:preserve-3d;
}
/* Highlight that follows the pointer. ::before rather than ::after so it sits
   under the card's copy — pseudo-elements paint after children otherwise. */
.step::before{
  content:''; position:absolute; inset:0; border-radius:inherit;
  background:radial-gradient(circle at var(--mx, 50%) var(--my, 50%),
    rgba(255,255,255,.5), rgba(255,255,255,0) 62%);
  opacity:0; transition:opacity .35s; pointer-events:none;
}
.step:hover::before{ opacity:1 }
/* step 1 tucks against the beige tab, so its top-left is tighter */
.step[data-step="1"]{ border-radius:calc(10 * var(--s)) calc(20 * var(--s)) calc(20 * var(--s)) calc(20 * var(--s)) }

.step__ic{
  position:absolute; left:calc(27.5 * var(--s)); top:calc(28.5 * var(--s));
  width:calc(38 * var(--s)); height:calc(38 * var(--s));
  color:var(--ink);
}
.step h3{
  position:absolute; left:calc(33 * var(--s)); top:calc(84 * var(--s));
  width:calc(282 * var(--s)); margin:0;
  font-family:var(--font-display); font-weight:900;
  font-size:calc(30 * var(--s)); line-height:normal;
  text-transform:uppercase; letter-spacing:0;
}
.step p{
  position:absolute; left:calc(33 * var(--s)); top:calc(135 * var(--s));
  width:calc(282 * var(--s)); margin:0;
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:normal; text-transform:uppercase;
}
/* the close affordance only exists while the long version is open */
/* Step 3 is the only card the open panel leaves exposed, so the strip that
   peeks out is itself the close target. The chip pinned at Read more's
   coordinate remains the labelled control. */
.how[data-open="true"] .step[data-step="3"]{ cursor:pointer }
.how[data-open="true"] .step[data-step="1"],
.how[data-open="true"] .step[data-step="2"]{ opacity:0; pointer-events:none }

/* ---------- orange bar over the videos ---------- */

.vbar{
  left:calc(27 * var(--s)); top:calc(542 * var(--s));
  width:calc(1386 * var(--s)); height:calc(49 * var(--s));
  background:var(--pb); border-radius:calc(20 * var(--s));
  overflow:hidden;
}
.vbar__rings{
  position:absolute; left:calc(17 * var(--s)); top:calc(10 * var(--s));
  width:calc(128.728 * var(--s)); height:calc(29.84 * var(--s));
  color:var(--ink); fill:currentColor;
}
.vbar__txt{
  position:absolute; left:50%; top:calc(15 * var(--s)); transform:translateX(-50%);
  margin:0; font-family:var(--font-display); font-weight:900;
  font-size:calc(16 * var(--s)); line-height:normal;
  text-transform:uppercase; text-align:center; white-space:nowrap;
}
/* Six tiles fill 1386 exactly at this breakpoint, so there is nothing to
   scroll and the arrows would be inert — they appear only on mobile. The
   rings take that gutter instead, mirroring the pair on the left. */
.vbar__nav{ display:none }
.vbar__rings--r{ left:auto; right:calc(17 * var(--s)) }

/* ---------- the video row ---------- */

.reels{
  list-style:none; margin:0; padding:0;
  left:calc(27 * var(--s)); top:calc(618 * var(--s));
  display:flex; gap:calc(27 * var(--s));
}
.reel{
  position:relative; flex:none; overflow:hidden;
  width:calc(208.431 * var(--s)); height:calc(369.964 * var(--s));
  border-radius:calc(20 * var(--s));
  background:#848484;
}
.reel img{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
}
/* a scrim so the title holds against the artwork */
.reel::after{
  content:''; position:absolute; inset:auto 0 0 0; height:45%;
  background:linear-gradient(transparent, rgba(23,25,28,.75));
}
.reel__t{
  position:absolute; z-index:1; left:calc(15 * var(--s)); bottom:calc(12 * var(--s));
  width:calc(179 * var(--s));
  font-family:var(--font-display); font-weight:900;
  font-size:calc(20 * var(--s)); line-height:1.1;
  text-transform:uppercase; color:var(--paper);
}
.reel__play{
  position:absolute; z-index:1; right:calc(15 * var(--s)); top:calc(13 * var(--s));
  width:calc(32.7 * var(--s)); height:calc(32.7 * var(--s));
  display:grid; place-items:center;
  border:max(1px, calc(2 * var(--s))) solid var(--paper);
  border-radius:calc(25 * var(--s));
  color:var(--paper); fill:currentColor; background:transparent;
  transition:background .22s, color .22s, transform .22s;
}
.reel img{ transition:transform .65s cubic-bezier(.2,.8,.2,1) }
.reel:hover img, .reel:focus-within img{ transform:scale(1.09) }

/* The loop sits directly over the still, under the scrim and the grain, and
   rides the same hover scale so the two read as one image. It fades up on the
   video's own `playing` event rather than on load, so a clip that never
   decodes leaves the still showing instead of a black rectangle. */
.reel__v{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
  opacity:0; pointer-events:none;
  transition:opacity .3s ease, transform .65s cubic-bezier(.2,.8,.2,1);
}
.reel.is-playing .reel__v{ opacity:1 }
.reel:hover .reel__v, .reel:focus-within .reel__v{ transform:scale(1.09) }

/* the tiles play on touch too now; reduced motion still keeps the stills */
@media (prefers-reduced-motion:reduce){ .reel__v{ display:none } }
.reel:hover .reel__play, .reel:focus-within .reel__play{
  background:var(--paper); color:var(--ink); transform:scale(1.08);
}
.reel__play svg{
  width:calc(13.852 * var(--s)); height:calc(13.852 * var(--s));
  transform:rotate(90deg);
}

/* ---------- mobile: how-mobile 38:465 / 38:922, 393 wide ---------- */

@media (max-width:1023.98px){
  .how__frame{
    --sf:calc(100cqw / 393);
    --s:calc(100cqw / 363);
    aspect-ratio:auto; height:auto; margin-top:0;
    padding:0 calc(15 * var(--sf)) calc(15 * var(--sf));
    display:flex; flex-direction:column; gap:calc(15 * var(--s));
  }
  .how__frame > *{ position:relative; left:auto; top:auto }

  /* no union here — the panel is just a card that grows when opened */
  .how__panel{
    width:auto; height:auto; min-height:calc(423 * var(--s));
    background:var(--paper); border-radius:calc(20 * var(--s));
    padding:calc(19 * var(--s)) calc(18 * var(--s)) calc(24 * var(--s));
  }
  .how__panel::before, .how__panel::after, .how__fillet{ display:none }

  .how__title{
    position:relative; left:auto; top:auto;
    font-size:calc(51.871 * var(--s)); line-height:calc(47.548 * var(--s));
    white-space:normal;
  }
  .how__brief, .how__more{
    position:relative; left:auto; top:auto; width:auto;
    margin-top:calc(40 * var(--s));
  }
  .how__cols{ grid-template-columns:minmax(0, 1fr); row-gap:calc(14 * var(--s)) }
  .how__close{ position:static; min-width:0; margin-top:calc(14 * var(--s)) }
  .vbar__rings--r{ display:none }
  .how__star{
    position:absolute; left:auto; right:calc(19 * var(--s));
    top:auto; bottom:calc(23 * var(--s));
  }
  .how__panel[data-open="true"] .how__star{ left:auto; top:auto }

  .steps{
    position:relative; left:auto; top:auto;
    flex-direction:column; gap:calc(15 * var(--s));
  }
  .step{
    width:auto; height:calc(300 * var(--s));
    border-radius:calc(20 * var(--s));
  }
  .step__ic{ left:calc(16 * var(--s)); top:calc(28.5 * var(--s)) }
  .step h3, .step p{ left:calc(19 * var(--s)); width:calc(325 * var(--s)) }
  /* the mobile frame closes from the panel's own button, so no × on the card */

  /* Desktop hides steps 1 and 2 while the panel is open because the panel
     physically expands over them. Here it grows in flow and covers nothing,
     so hiding them just punched two 300-unit holes in the column. */
  .how[data-open="true"] .step[data-step="1"],
  .how[data-open="true"] .step[data-step="2"]{ opacity:1; pointer-events:auto }

  .vbar{
    width:auto; height:calc(196 * var(--s));
    border-radius:calc(20 * var(--s));
  }
  .vbar__rings{ left:calc(19 * var(--s)); top:calc(18 * var(--s)) }
  .vbar__txt{
    left:calc(20 * var(--s)); right:calc(38 * var(--s)); top:calc(62 * var(--s));
    transform:none; text-align:left; white-space:normal;
    width:calc(305 * var(--s));
  }
  /* here the row genuinely overflows, so the arrows do something */
  .vbar__nav{
    display:flex; gap:calc(10 * var(--s));
    position:absolute; left:calc(270 * var(--s)); top:calc(143 * var(--s));
  }
  .vbar__arrow{
    width:calc(32 * var(--s)); height:calc(32 * var(--s));
    display:grid; place-items:center; padding:0;
    border:0; background:transparent; color:var(--ink); cursor:pointer;
  }
  .vbar__arrow svg{ width:100%; height:100%; fill:currentColor }
  .vbar__arrow--prev svg{ transform:rotate(180deg) }

  .reels{
    position:relative; left:auto; top:auto;
    gap:calc(15 * var(--s));
    overflow-x:auto; scroll-snap-type:x mandatory;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
    scroll-padding-left:calc(15 * var(--s));
  }
  .reels::-webkit-scrollbar{ display:none }
  .reel{
    scroll-snap-align:start;
    width:calc(296.901 * var(--s)); height:calc(527 * var(--s));
    border-radius:calc(28.489 * var(--s));
  }
  .reel__t{
    left:calc(21.37 * var(--s)); bottom:calc(18 * var(--s));
    width:calc(255 * var(--s)); font-size:calc(28.489 * var(--s));
  }
  .reel__play{
    right:calc(21 * var(--s)); top:calc(18.52 * var(--s));
    width:calc(46.6 * var(--s)); height:calc(46.6 * var(--s));
    border-width:max(1px, calc(1 * var(--s)));
    border-radius:calc(35.612 * var(--s));
  }
  .reel__play svg{ width:calc(19.731 * var(--s)); height:calc(19.731 * var(--s)) }
}

/* ---------- mobile: the steps stack up as you scroll ----------
   Each card pins a little lower than the one before it, so the next slides
   over the top and leaves a strip of the one underneath showing. By the third
   they sit as a stack, hold for a beat, then the group releases and leaves.

   position:sticky and nothing else — no pinning, no scroll handler, no state
   to unwind. Where it is not supported the cards are simply a column, which
   is what they were.

   --tail is the scroll distance the finished stack holds for. It is also dead
   space in the layout underneath it, so it stays short enough to read as
   section spacing rather than a gap.

   Desktop is left alone: the three cards sit side by side on a fixed board
   there, with no vertical relationship between them to stack.

   Guarded on viewport height, not just width — the cards are 300 units tall,
   and pinning something taller than the viewport strands its own bottom edge
   where no amount of scrolling can reach it. */

@media (max-width:1023.98px) and (min-height:640px){
  .steps{
    --stack-top:40;   /* where the first card comes to rest */
    --peek:26;        /* strip of each card left showing under the next */
    --tail:120;       /* how long the finished stack holds */
  }
  /* The column keeps its 15-unit gap. Closing it up made the stacking maths
     tidier but left the cards flush against each other whenever they were NOT
     stacked — one solid blue block with three headings in it, most obvious on
     the way back up. The gap costs nothing: card 1 pins before card 2 reaches
     it either way, so the overlap still closes on its own. */

  /* The tail has to be CONTENT, not padding: a sticky element is constrained
     to its containing block's content box, so padding-bottom here added the
     space without adding any travel — card 3 slid straight past its resting
     spot and the stack never actually formed. A flex item does both. */
  .steps::after{ content:''; flex:none; height:calc(var(--tail) * var(--s)) }
  .step{
    position:sticky; top:calc(var(--stack-top) * var(--s));
    /* All three cards are the same blue with no stroke, so stacked they read
       as one tall card with three headings in it. The shadow is what makes
       the seam — cast upward, since the card underneath sits above this one
       on screen. */
    box-shadow:0 calc(-6 * var(--s)) calc(20 * var(--s)) rgba(23,25,28,.5);
  }
  .step[data-step="2"]{ top:calc((var(--stack-top) + var(--peek)) * var(--s)) }
  .step[data-step="3"]{ top:calc((var(--stack-top) + 2 * var(--peek)) * var(--s)) }
}

/* =========================================================
   COMMISSIONS — want-one-desktop (38:1019) / want-one-mobile (41:1539)

   Built the same way as the how section above: the frame owns --s and every
   child carries its raw Figma coordinate, so the layout can be diffed against
   the board without arithmetic.
   ========================================================= */

.hire{ background:var(--ink); display:flex; justify-content:center }

.hire__frame{
  position:relative; box-sizing:border-box;
  container-type:inline-size;
  /* board is 1440 x 810 with the composition sitting between y=27 and y=703,
     so the frame is cropped to a 27 gutter top and bottom. */
  width:100%; aspect-ratio:1440 / 730; padding:0;
  /* the how frame already closes on a 27 gutter and this one opens with
     another — collapse one, same as how does against the catalog. */
  margin-top:calc(-27 * var(--sf));
  --sf:calc(100cqw / 1440);
  --s:calc(100cqw / 1440);
}
.hire__frame > *{ position:absolute }

/* ---------- the beige slab ---------- */
/* One notched shape: banner across the top, tab running down the right for
   CUSTOM to sit in. */
.hire__slab{
  left:calc(27 * var(--s)); top:calc(27 * var(--s));
  width:calc(1386 * var(--s)); height:calc(447 * var(--s));
}
.hire__slab--m{ display:none }

/* ---------- ticket stubs punched along the top edge ---------- */

.hire__stub{
  top:calc(54 * var(--s)); height:calc(21 * var(--s));
  border:max(1px, calc(1 * var(--s))) solid var(--ink); border-bottom:0;
}
.hire__stub--1{ left:calc(56 * var(--s));  width:calc(444 * var(--s)) }
.hire__stub--2{ left:calc(499 * var(--s)); width:calc(445 * var(--s)) }
.hire__stub--3{ left:calc(943 * var(--s)); width:calc(444 * var(--s)) }

.hire__punch{
  margin:0; top:calc(57 * var(--s)); transform:translateX(-50%);
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:normal; text-transform:uppercase; white-space:nowrap;
  text-align:center; color:var(--ink);
}
.hire__punch--1{ left:calc(278 * var(--s)) }
.hire__punch--2{ left:calc(720.5 * var(--s)) }
.hire__punch--3{ left:calc(1162 * var(--s)) }

/* ---------- headline ---------- */

.hire__h{
  margin:0; left:calc(56 * var(--s)); top:calc(87 * var(--s));
  font-family:var(--font-display); font-weight:900;
  /* board draws this at 106, which stops 52 short of CUSTOM's right edge.
     Scaled 1.0402 so the question mark lands with CUSTOM and the subtext. */
  font-size:calc(110.26 * var(--s)); line-height:calc(94.13 * var(--s));
  text-transform:uppercase; white-space:nowrap; color:var(--ink);
}
.hire__lede{
  margin:0; left:calc(56 * var(--s)); top:calc(193 * var(--s));
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:normal; text-transform:uppercase; white-space:nowrap;
  color:var(--ink);
}

/* ---------- CUSTOM, reading up the right tab ---------- */

.hire__custom{
  left:calc(1338 * var(--s)); top:calc(253 * var(--s));
  width:calc(58 * var(--s)); height:calc(195 * var(--s));
  display:grid; place-items:center;
  writing-mode:vertical-rl; transform:rotate(180deg);
  font-family:var(--font-display); font-weight:900;
  font-size:calc(48 * var(--s)); line-height:normal;
  text-transform:uppercase; white-space:nowrap; color:var(--ink);
}

/* ---------- the three tier cards ---------- */

.tcard{
  top:calc(268 * var(--s));
  width:calc(346 * var(--s)); height:calc(388 * var(--s));
  border-radius:calc(20 * var(--s));
  color:var(--ink);
}
/* The board starts this one at x=21 while the slab above it starts at 27:
   three 346 cards, two 30 gaps and the 267 price tag run 6 wider than the
   1386 slab, and the board absorbs the difference on this edge. Left as
   drawn rather than silently snapped to 27. */
.tcard--cowrite{ left:calc(21 * var(--s));  background:var(--blue-pale) }
.tcard--gag{     left:calc(397 * var(--s)); background:var(--blue-mid) }
.tcard--jingle{  left:calc(773 * var(--s)); background:var(--blue) }

.tcard__txt{
  position:absolute; z-index:1;
  left:calc(33 * var(--s)); top:calc(44 * var(--s)); width:calc(282 * var(--s));
  display:flex; flex-direction:column; align-items:flex-start;
  gap:calc(17 * var(--s));
}
.tcard__txt h3{
  margin:0; font-family:var(--font-display); font-weight:900;
  font-size:calc(30 * var(--s)); line-height:normal; text-transform:uppercase;
}
.tcard__txt p{
  margin:0; font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:normal; text-transform:uppercase;
}

/* The sandwiches hang past the rounded bottom onto the dark ground — that
   overhang is the point, so nothing clips them here. */
.tcard__ph{ position:absolute; display:block }
/* wrapper holds the board coordinate and the scroll float; the image inside is
   free for the pointer to push around, so the two never fight over y. */
.tcard__ph img{ display:block; width:100%; height:100%; object-fit:cover;
  will-change:transform }
.tcard--cowrite .tcard__ph{
  left:calc(108 * var(--s)); top:calc(249 * var(--s));
  width:calc(249 * var(--s)); height:calc(186 * var(--s));
}
.tcard--jingle .tcard__ph{
  left:calc(120 * var(--s)); top:calc(242 * var(--s));
  width:calc(240 * var(--s)); height:calc(180 * var(--s));
}
/* the gag sandwich is cropped on the board, so its frame and its leaf are
   two different boxes — keep them separate. The oversized leaf is what gives
   the pointer somewhere to travel without exposing an edge. */
.tcard--gag .tcard__ph{
  left:calc(127 * var(--s)); top:calc(252 * var(--s));
  width:calc(233 * var(--s)); height:calc(174 * var(--s));
  overflow:hidden;
}
.tcard--gag .tcard__ph img{
  position:absolute; max-width:none; object-fit:fill;
  left:-7.32%; top:-30.64%; width:121.93%; height:153.58%;
}

/* ---------- the price tag ---------- */

.hire__union{
  left:calc(1146 * var(--s)); top:calc(268 * var(--s));
  width:calc(267 * var(--s)); height:calc(388 * var(--s));
}
.hire__union--m{ display:none }

.hire__code{
  left:calc(1170 * var(--s)); top:calc(290 * var(--s));
  width:calc(93 * var(--s)); height:calc(213 * var(--s));
  display:block;
}
.hire__code img{
  position:absolute; left:50%; top:50%; max-width:none;
  width:calc(213 * var(--s)); height:calc(93 * var(--s));
  transform:translate(-50%,-50%) rotate(-90deg);
}

.hire__price{
  left:calc(1265 * var(--s)); width:calc(19.093 * var(--s));
  display:grid; place-items:center;
  writing-mode:vertical-rl; transform:rotate(180deg);
  font-family:var(--font-mono); font-size:calc(12.729 * var(--s));
  line-height:normal; text-transform:uppercase; white-space:nowrap;
  color:var(--ink);
}
.hire__price--n{ top:calc(290.8 * var(--s));  height:calc(38.981 * var(--s)) }
.hire__price--w{ top:calc(410.13 * var(--s)); height:calc(93.874 * var(--s)) }

.hire__note{
  margin:0; left:calc(1170 * var(--s)); top:calc(520 * var(--s));
  width:calc(227 * var(--s));
  font-family:var(--font-display); font-weight:400;
  font-size:calc(16 * var(--s)); line-height:normal;
  text-transform:uppercase; color:var(--ink);
}
.hire__note strong{ font-weight:900 }

/* ---------- mobile: want-one-mobile 41:1539, 393 wide ---------- */

@media (max-width:1023.98px){
  .hire__frame{
    --sf:calc(100cqw / 393);
    --s:calc(100cqw / 393);
    /* last card closes at 1691; the sandwiches are clipped here, so the board
       ends on the same 15 gutter it opened with rather than leaving room for
       an overhang that never renders. */
    aspect-ratio:393 / 1706;
    /* the how frame closes on a 15 gutter and this one opens with another —
       collapse one, so every mobile section boundary is a single 15. */
    margin-top:calc(-15 * var(--sf));
  }

  .hire__slab--d{ display:none }
  .hire__slab--m{
    display:block;
    left:calc(15 * var(--s)); top:calc(15 * var(--s));
    width:calc(363 * var(--s)); height:calc(473 * var(--s));
  }

  .hire__stub{ top:calc(34 * var(--s)); height:calc(31 * var(--s)); width:calc(109 * var(--s)) }
  .hire__stub--1{ left:calc(34 * var(--s)) }
  .hire__stub--2{ left:calc(142 * var(--s)) }
  .hire__stub--3{ left:calc(250 * var(--s)) }

  .hire__punch{
    top:calc(38 * var(--s)); font-size:calc(12 * var(--s));
    line-height:calc(15 * var(--s)); white-space:normal;
  }
  .hire__punch--1{ left:calc(88 * var(--s));  width:calc(82 * var(--s)) }
  .hire__punch--2{ left:calc(196 * var(--s)); width:calc(92 * var(--s)) }
  .hire__punch--3{ left:calc(304 * var(--s)); width:calc(102 * var(--s)) }

  .hire__h{
    left:calc(34 * var(--s)); top:calc(80 * var(--s)); width:calc(325 * var(--s));
    font-size:calc(49 * var(--s)); line-height:calc(47.5 * var(--s));
    white-space:normal;
  }
  .hire__lede{
    left:calc(34 * var(--s)); top:calc(188 * var(--s)); width:calc(321 * var(--s));
    line-height:calc(19 * var(--s)); white-space:normal;
  }

  .hire__custom{
    left:calc(329 * var(--s)); top:calc(310 * var(--s));
    width:calc(49 * var(--s)); height:calc(167 * var(--s));
    font-size:calc(41.202 * var(--s));
  }

  .hire__union--d{ display:none }
  .hire__union{ display:none }
  .hire__union--m{
    display:block;
    left:calc(15 * var(--s)); top:calc(318 * var(--s));
    width:calc(296 * var(--s)); height:calc(170 * var(--s));
  }

  .hire__code{
    left:calc(27.85 * var(--s)); top:calc(332 * var(--s));
    width:calc(53.279 * var(--s)); height:calc(141.61 * var(--s));
  }
  .hire__code img{ width:calc(141.61 * var(--s)); height:calc(53.279 * var(--s)) }

  .hire__price{ left:calc(82.02 * var(--s)); width:calc(13.132 * var(--s));
    font-size:calc(8.754 * var(--s)) }
  .hire__price--n{ top:calc(332.02 * var(--s)); height:calc(26.81 * var(--s)) }
  .hire__price--w{ top:calc(409.11 * var(--s)); height:calc(64.564 * var(--s)) }

  .hire__note{
    left:calc(111 * var(--s)); top:calc(339 * var(--s)); width:calc(187 * var(--s));
    font-size:calc(14 * var(--s)); line-height:calc(21 * var(--s));
  }

  /* cards stack down the board at a fixed 401 pitch (386 tall, 15 apart) */
  .tcard{
    left:calc(16 * var(--s));
    width:calc(361 * var(--s)); height:calc(386 * var(--s));
    border-radius:calc(20 * var(--s)) calc(10 * var(--s))
                  calc(20 * var(--s)) calc(20 * var(--s));
    /* on desktop the sandwiches spill onto the dark ground; here the next
       card is only 15 below, so the overhang would land on top of it. */
    overflow:hidden;
  }
  .tcard--cowrite{ top:calc(503 * var(--s)) }
  .tcard--gag{     top:calc(904 * var(--s)) }
  .tcard--jingle{  top:calc(1305 * var(--s)) }

  .tcard__txt{
    left:calc(19 * var(--s)); top:calc(27 * var(--s)); width:calc(322 * var(--s));
  }

  .tcard--cowrite .tcard__ph,
  .tcard--jingle .tcard__ph{
    width:calc(265 * var(--s)); height:calc(199 * var(--s));
  }
  .tcard--cowrite .tcard__ph{ left:calc(109 * var(--s)); top:calc(214 * var(--s)) }
  .tcard--jingle  .tcard__ph{ left:calc(111 * var(--s)); top:calc(216 * var(--s)) }
  .tcard--gag .tcard__ph{
    left:calc(110 * var(--s)); top:calc(218 * var(--s));
    width:calc(265 * var(--s)); height:calc(199 * var(--s));
  }
}

/* =========================================================
   FOOTER — footer (53:98) / footer-mobile (53:363)
   Same construction as the two sections above: the frame owns --s and every
   child carries its raw Figma coordinate.
   ========================================================= */

.foot{ background:var(--ink); display:flex; justify-content:center }

.foot__frame{
  position:relative; box-sizing:border-box;
  container-type:inline-size;
  width:100%; aspect-ratio:1440 / 274; padding:0;
  /* the commission frame closes on a 27 gutter and this one opens with
     another — collapse one, as how does against the catalog. */
  margin-top:calc(-27 * var(--sf));
  --sf:calc(100cqw / 1440);
  --s:calc(100cqw / 1440);
}
.foot__frame > *{ position:absolute }

/* ---------- the hairline and the two sandwiches that bracket it ---------- */

.foot__ic{
  top:calc(27 * var(--s));
  width:calc(19 * var(--s)); height:calc(20.452 * var(--s));
}
.foot__ic--l{ left:calc(27 * var(--s)) }
.foot__ic--r{ left:calc(1395 * var(--s)) }
.foot__ic img{ display:block; width:100%; height:100% }

.foot__rule{
  left:calc(51.5 * var(--s)); top:calc(38 * var(--s));
  width:calc(1334 * var(--s)); height:0;
  border-top:max(1px, calc(1 * var(--s))) solid var(--paper);
}

/* ---------- the wordmark ---------- */

.foot__mark{
  left:calc(27 * var(--s)); top:calc(64 * var(--s));
  width:calc(1387 * var(--s)); height:calc(139.956 * var(--s));
}
.foot__mark--m1, .foot__mark--m2, .foot__code--m{ display:none }

/* ---------- the bottom line ---------- */

.foot__nav{
  left:calc(745 * var(--s)); top:calc(226 * var(--s));
  display:flex; align-items:center; gap:calc(30 * var(--s));
}
.foot__nav a{
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:calc(21 * var(--s)); text-transform:uppercase;
  color:var(--paper); text-decoration:none; white-space:nowrap;
  transition:color .16s;
}
.foot__nav a:hover, .foot__nav a:focus-visible{ color:var(--blue) }

.foot__legal{
  margin:0; left:calc(27 * var(--s)); top:calc(226 * var(--s));
  font-family:var(--font-mono); font-size:calc(14 * var(--s));
  line-height:calc(21 * var(--s)); text-transform:uppercase;
  color:var(--paper); white-space:nowrap;
}
.foot__built{ color:var(--blue) }

.foot__code{
  left:calc(1249 * var(--s)); top:calc(227 * var(--s));
  width:calc(165 * var(--s)); height:calc(18 * var(--s));
}

/* ---------- mobile: footer-mobile 53:363, 393 wide ---------- */

@media (max-width:1023.98px){
  .foot__frame{
    --sf:calc(100cqw / 393);
    --s:calc(100cqw / 393);
    aspect-ratio:393 / 341;
    /* was inheriting the desktop -27, which pulled the footer up into the
       last tier card. Same single-15 boundary as every other section. */
    margin-top:calc(-15 * var(--sf));
  }

  .foot__ic{ top:calc(15 * var(--s)) }
  .foot__ic--l{ left:calc(15 * var(--s)) }
  .foot__ic--r{ left:calc(359 * var(--s)) }

  .foot__rule{
    left:calc(43 * var(--s)); top:calc(25 * var(--s)); width:calc(308.5 * var(--s));
  }

  .foot__nav{
    left:calc(17 * var(--s)); top:calc(49 * var(--s)); gap:calc(13.22 * var(--s));
  }
  .foot__nav a{ font-size:calc(12.235 * var(--s)); line-height:calc(18 * var(--s)) }

  /* the wordmark breaks over two lines here */
  .foot__mark--d{ display:none }
  .foot__mark--m1{
    display:block; left:calc(17 * var(--s)); top:calc(79 * var(--s));
    width:calc(360.416 * var(--s)); height:calc(77.952 * var(--s));
  }
  .foot__mark--m2{
    display:block; left:calc(17 * var(--s)); top:calc(170.03 * var(--s));
    width:calc(361 * var(--s)); height:calc(69.12 * var(--s));
  }

  .foot__legal{
    left:calc(17 * var(--s)); top:calc(253 * var(--s));
    font-size:calc(12.734 * var(--s)); line-height:calc(19 * var(--s));
  }

  .foot__code--d{ display:none }
  .foot__code--m{
    display:block; left:calc(18 * var(--s)); top:calc(284 * var(--s));
    width:calc(359 * var(--s)); height:calc(39.164 * var(--s));
  }
}

/* =========================================================
   MOTION LAYER
   Analog surface over a futurist grid: blinds that open like a
   window shade, CRT scanlines, and grain that resolves on hover.
   Every piece degrades to a static, fully-visible state.
   ========================================================= */

/* ---------- blinds ----------
   One repeating mask whose opaque band grows from nothing to the full pitch.
   --open sits at the pitch by default, so if GSAP never runs the element is
   simply visible — the animation is subtractive, never load-bearing. */
.blinds{
  --pitch:12.5%;
  --open:var(--pitch);
  -webkit-mask-image:repeating-linear-gradient(to bottom,
    #000 0 var(--open), transparent var(--open) var(--pitch));
  mask-image:repeating-linear-gradient(to bottom,
    #000 0 var(--open), transparent var(--open) var(--pitch));
}

/* ---------- catalog rows tip in like dominoes ---------- */
.tracks{ perspective:calc(900 * var(--s)) }

/* ---------- CRT ----------
   A constant scanline grid plus a band that sweeps the viewport every few
   seconds. White at very low alpha so it reads on the ink sections and all
   but disappears on paper, which is where copy density is highest. */
.crt{
  position:fixed; inset:0; z-index:60; pointer-events:none;
  background-image:repeating-linear-gradient(to bottom,
    rgba(255,255,255,.075) 0 1px, transparent 1px 3px);
}
.crt__sweep{
  position:absolute; left:0; right:0; top:0; height:20vh; opacity:0;
  background:linear-gradient(to bottom,
    transparent,
    rgba(255,255,255,.035) 42%,
    rgba(255,255,255,.085) 50%,
    rgba(255,255,255,.035) 58%,
    transparent);
}
/* A second, harder band on its own clock. The two periods do not divide into
   each other, so they drift and only occasionally cross — which is the point:
   a regular pulse would read as a page element rather than a bad signal. */
.crt__sweep--thin{
  height:5vh;
  background:linear-gradient(to bottom,
    transparent,
    rgba(255,255,255,.05) 35%,
    rgba(255,255,255,.14) 50%,
    rgba(255,255,255,.05) 65%,
    transparent);
}

/* ---------- grain ----------
   feTurbulence as a data URI: no request, no asset to keep in sync. Resolves
   on hover so the reels feel like tape rather than stills. */
.reel::before, .peek::before{
  content:''; position:absolute; inset:0; z-index:2; pointer-events:none;
  opacity:0; transition:opacity .35s ease;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;
}
.reel:hover::before, .reel:focus-within::before{ opacity:.42 }
.peek::before{ opacity:.3 }

/* the sandwiches ride slightly against the scroll — declared here so the
   transform origin is stable before GSAP touches them */
[data-float]{ will-change:transform }

/* ---------- the hero's held state ----------
   Set by the inline script in <head> and cleared by main.js the instant it has
   written the same state inline, so the handover is seamless. Only the hero
   needs this: everything else that starts at opacity 0 is below the fold,
   where there is nothing to flash. See the note on the script itself for why
   this is the one piece of motion that is not purely subtractive. */
.hero-armed .nav,
.hero-armed .well,
.hero-armed .fig,
.hero-armed .lcol,
.hero-armed .swatch,
.hero-armed .call{ opacity:0 }

/* =========================================================
   REDUCED MOTION — respect it fully
   ========================================================= */

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto }
  *,*::before,*::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important }
  .peek{ display:none }
  .crt__sweep{ display:none }
  .blinds{ -webkit-mask-image:none; mask-image:none }
  [data-float]{ will-change:auto; transform:none !important }
}
