/* ============================================================
   FRND — design tokens
   Mirrors Figma 153:2 "FRND — Website / Desktop 1440 · Landing v1".

   A CHILD of the Interact system, not a copy: the family resemblance is
   the Geist Mono eyebrow and the two-tone display headline. Everything
   else inverts — cream/serif/editorial becomes pink/Gabarito/sticker.
   ============================================================ */
:root{
  --pink:      #FF3E84;   /* primary. Sampled off the app splash, not invented */
  --pink-deep: #D4155C;
  --pink-soft: #FFE0EC;
  --ink:       #17110F;
  --page:      #FFF7F2;   /* cream — the ground the pink blooms out of */
  --yellow:    #FFD426;
  --cyan:      #4FE3FF;
  --violet:    #8B4DFF;
  --tangerine: #FF6A1F;

  --display: "Gabarito", "Arial Black", Impact, sans-serif;
  --sans:    "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono:    "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* One design pixel as a length — same token as the Interact build.
     Write calc(140 * var(--s)) with a UNITLESS number; calc(140px * var(--s))
     is px x px, invalid, and silently kills the whole declaration.
     100vw/1440 rather than 0.069444vw: the decimal drifts a quarter pixel
     over ~1000px of stacked offsets, which is enough to soften a hairline.
     Floored at its 1040 value so type never scales into illegibility —
     below 1040 the compact block re-expresses the big numbers in vw. */
  --s: clamp(0.7222222px, calc(100vw / 1440), 1.1666667px);

  --ease:   cubic-bezier(.16,1,.3,1);          /* long tail, no overshoot */
  --bounce: cubic-bezier(.34,1.56,.64,1);      /* the POP — slight overshoot */
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0; background:var(--page); color:var(--ink);
  font-family:var(--sans);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  /* `clip`, not `hidden`: hidden makes body a scroll container, which
     breaks position:sticky for any section added later. */
  overflow-x:clip;
}
a{ color:inherit; text-decoration:none; }
img{ max-width:100%; display:block; }

:focus-visible{ outline:3px solid var(--ink); outline-offset:3px; border-radius:2px; }
.fhero :focus-visible{ outline-color:#fff; }

.skip{
  position:absolute; left:50%; top:0; transform:translate(-50%,-120%);
  z-index:100; padding:10px 18px; border-radius:0 0 8px 8px;
  background:var(--ink); color:#fff; font-size:13px;
}
.skip:focus{ transform:translate(-50%,0); }

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

/* ============================================================
   Load sequence — ground → type → nav → faces → chips

   All of it is CSS keyed off one class, `is-ready` on <html>, so the
   <head> watchdog covers a failed frnd.js for every beat instead of
   leaving the hero permanently blank.

     0ms      the pink washes in over the cream page   (620ms)
     240ms    the type staggers up, --d per element    (900ms each)
     900ms    parent strip, then the nav pill drops in (800ms)
     1180ms   the four faces POP, one after another    (700ms each)
     1700ms   the six chips POP, alternating sides     (520ms each)

   Ends ~2.6s. Each beat is a distinct event on purpose — the brief was
   for a choreographed entrance, not a single fade.
   ============================================================ */

/* — beat 1: the ground. The faces' own corners are baked to this exact
   pink, so they can only melt into it once it is fully painted. */
.js .fhero__ground{ opacity:0; }
.js.is-ready .fhero__ground{ opacity:1; transition:opacity .62s cubic-bezier(.33,1,.68,1); }

/* — beat 2: type (and anything else that rises rather than pops) */
.js .pop{ opacity:0; transform:translateY(var(--ry, 16px)); will-change:opacity, transform; }
.js.is-ready .pop{
  opacity:1; transform:none;
  transition:opacity .9s var(--ease) var(--d, 0ms),
             transform .9s var(--ease) var(--d, 0ms);
}
.js.is-ready .pop.is-done{ will-change:auto; }

/* — beat 3: the nav pill drops from above, then its three groups rise */
.js .pstrip{ opacity:0; }
.js.is-ready .pstrip{ opacity:1; transition:opacity .7s var(--ease) 900ms; }

.js .fnav__pill{ opacity:0; transform:translateY(-18px); }
.js.is-ready .fnav__pill{
  opacity:1; transform:none;
  transition:opacity .8s var(--ease) 950ms, transform .8s var(--ease) 950ms;
}
.js .fnav__pill > *{ opacity:0; transform:translateY(-6px); }
.js.is-ready .fnav__pill > *{
  opacity:1; transform:none;
  transition:opacity .7s var(--ease) calc(950ms + var(--d, 0ms)),
             transform .7s var(--ease) calc(950ms + var(--d, 0ms));
}
.fnav__pill > :nth-child(1){ --d:0ms; }
.fnav__pill > :nth-child(2){ --d:80ms; }
.fnav__pill > :nth-child(3){ --d:150ms; }

/* — beats 4 & 5: the POP. Rotation is baked into both keyframe states so
   the interpolation is a pure scale — writing scale() alone would drop the
   rotation for the duration of the transition. */
.js .fface__img{ opacity:0; transform:rotate(var(--rot)) scale(.72); }
.js.is-ready .fface__img{
  opacity:1; transform:rotate(var(--rot)) scale(1);
  transition:opacity .55s ease-out var(--d, 0ms),
             transform .7s var(--bounce) var(--d, 0ms);
}
.js .fchip__pill{ opacity:0; transform:rotate(var(--rot)) scale(.5); }
.js.is-ready .fchip__pill{
  opacity:1; transform:rotate(var(--rot)) scale(1);
  transition:opacity .3s ease-out var(--d, 0ms),
             transform .52s var(--bounce) var(--d, 0ms);
}

/* ============================================================
   Shared atoms
   ============================================================ */
/* Eyebrow: an ink pill with white mono. On the pink grounds it flips ink;
   on light and ink grounds it is pink. Only the pink case exists so far. */
.eyebrow{
  margin:0;
  font-family:var(--mono); font-weight:500;
  /* px floors are INACTIVE at 1440 (11 > 10) and only bite once --s hits
     its floor at 1040. */
  font-size:max(10px, calc(11 * var(--s)));
  line-height:calc(14 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
}
.eyebrow--pill{
  display:inline-flex; align-items:center;
  padding:calc(9 * var(--s)) calc(18 * var(--s));
  border-radius:999px;
  background:var(--ink); color:#fff;
}

/* The sticker button. Hard 0-blur shadow is the page's one signature —
   every card, chip, pill and plate carries it. */
.sbtn{
  display:inline-flex; align-items:center; flex:none;
  border-radius:999px; white-space:nowrap;
  font-family:var(--sans); font-weight:800;
  letter-spacing:-.01em;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
.sbtn--white{
  height:calc(62 * var(--s));
  padding:0 calc(9 * var(--s)) 0 calc(30 * var(--s));
  gap:calc(14 * var(--s));
  background:#fff; color:var(--pink);
  font-size:max(14px, calc(17 * var(--s)));
  box-shadow:0 calc(6 * var(--s)) 0 var(--ink);
}
.sbtn--outline{
  height:calc(59 * var(--s));
  padding:0 calc(26 * var(--s)) 0 calc(30 * var(--s));
  gap:calc(10 * var(--s));
  color:#fff;
  box-shadow:inset 0 0 0 calc(2.5 * var(--s)) #fff;
  font-size:max(14px, calc(17 * var(--s)));
}
.sbtn--ink{
  height:calc(48 * var(--s));
  padding:0 calc(8 * var(--s)) 0 calc(22 * var(--s));
  gap:calc(10 * var(--s));
  background:var(--ink); color:#fff;
  font-size:max(12px, calc(14 * var(--s)));
}
.sbtn__knob{
  display:grid; place-items:center; flex:none;
  border-radius:999px;
  font-family:var(--mono); font-weight:600;
  color:var(--ink);
  transition:transform .3s var(--bounce);
}
.sbtn--white .sbtn__knob{ width:calc(44 * var(--s)); height:calc(44 * var(--s)); font-size:calc(18 * var(--s)); }
.sbtn--ink   .sbtn__knob{ width:calc(32 * var(--s)); height:calc(32 * var(--s)); font-size:calc(15 * var(--s)); }
.sbtn__knob--yellow{ background:var(--yellow); }
.sbtn__knob--pink{ background:var(--pink); }
.sbtn__arrow{ font-family:var(--mono); font-weight:600; font-size:calc(15 * var(--s)); line-height:1; }

/* Lift on hover, and the hard shadow grows with it — the sticker is being
   peeled off the page rather than glowing. */
.sbtn--white:hover{
  transform:translateY(calc(-2 * var(--s)));
  box-shadow:0 calc(9 * var(--s)) 0 var(--ink);
}
.sbtn--white:hover .sbtn__knob{ transform:translateY(calc(2 * var(--s))); }
.sbtn--outline:hover{ background:#fff; color:var(--pink); }
.sbtn--ink:hover{ transform:translateY(calc(-2 * var(--s))); }
.sbtn:hover .sbtn__arrow{ transform:translate(calc(2 * var(--s)), calc(-2 * var(--s))); }

/* ============================================================
   00 / Parent strip  (153:3 — 1440 x 36)
   ============================================================ */
.pstrip{
  position:relative; z-index:6;
  height:calc(36 * var(--s));
  background:var(--ink);
  display:flex; align-items:center; justify-content:space-between;
  padding:0 calc(100 * var(--s));
  font-family:var(--mono); font-weight:500;
  font-size:max(9px, calc(10 * var(--s)));
  line-height:calc(12 * var(--s));
  letter-spacing:.12em; text-transform:uppercase;
}
.pstrip__back{ color:#fff; display:inline-flex; align-items:center; }
.pstrip__caret{ display:inline-block; transition:transform .3s var(--ease); }
.pstrip__back:hover .pstrip__caret{ transform:translateX(calc(-3 * var(--s))); }
.pstrip__note{ color:rgba(255,255,255,.45); }

/* ============================================================
   01 / Hero  (153:4 — 1440 x 1080)

   Everything is absolutely placed off the comp, because the composition
   IS the design: the faces bleed past all four edges and the chips are
   scattered into the margins the type leaves behind. Layer order, bottom
   up: ground · faces · type · chips · nav.
   ============================================================ */
.fhero{
  position:relative; z-index:2;
  width:100%;
  aspect-ratio:1440 / 1080;
  min-height:calc(640px);
  overflow:hidden;
  isolation:isolate;
}
.fhero__ground{ position:absolute; inset:0; z-index:0; background:var(--pink); }

/* The hero was the ONLY section that scrolled away inert while all ten below
   it departed — the broken link in the hand-off chain, and the loudest thing
   on the page. Its three layers now leave at different rates: the type lifts
   and fades, the faces drift outward, the chips scatter. `--exit` is written
   by the hero-departure module in frnd.js; the chips' own load-sequence
   opacity lives on the inner .fchip__pill, so the two compose instead of
   fighting. */
.fhero__content, .fface, .fchip{ opacity:var(--exit, 1); }

/* faces — wrapper box is the Figma frame (which is already sized to the
   ROTATED bounds); the img inside is the unrotated square and carries the
   rotation, so the pop can scale about the same origin. */
.fface{
  position:absolute; z-index:1;
  left:calc(var(--x) * var(--s));
  top:calc(var(--y) * var(--s));
  width:calc(var(--w) * var(--s));
  height:calc(var(--w) * var(--s));
  display:grid; place-items:center;
  pointer-events:none;
}
.fface__img{
  width:calc(var(--n) * var(--s));
  height:calc(var(--n) * var(--s));
  max-width:none;
  object-fit:cover;
  transform:rotate(var(--rot));
  will-change:opacity, transform;
}

.fhero__content{
  position:absolute; inset:0; z-index:2;
  display:flex; flex-direction:column; align-items:center;
  text-align:center;
  padding-top:calc(200 * var(--s));   /* eyebrow pill top, per comp */
  pointer-events:none;                /* only the buttons take clicks */
}
.fhero__content a{ pointer-events:auto; }

.fhero__h1{
  margin:calc(50 * var(--s)) 0 0;
  font-family:var(--display); font-weight:900;
  font-size:calc(140 * var(--s));
  line-height:.92; letter-spacing:-.04em;
  color:#fff;
}
.fhero__h1 .line{ display:block; }
.fhero__h1 .line--ink{ color:var(--ink); }

.fhero__sub{
  margin:calc(44 * var(--s)) 0 0;
  width:calc(560 * var(--s));
  font-weight:500;
  font-size:max(15px, calc(19 * var(--s)));
  line-height:1.56; letter-spacing:-.01em;
  color:rgba(255,255,255,.88);
}

.fhero__actions{
  margin-top:calc(47 * var(--s));
  display:flex; align-items:center; gap:calc(14 * var(--s));
}

.fhero__trust{
  margin:calc(38 * var(--s)) 0 0;
  font-family:var(--mono); font-weight:500;
  font-size:max(10px, calc(11 * var(--s)));
  line-height:calc(14 * var(--s));
  letter-spacing:.14em;
  color:rgba(255,255,255,.62);
}

/* chips — positioned by the CENTRE of their Figma frame, because they are
   content-sized: translate(-50%,-50%) on the wrapper, rotation on the pill,
   so the two transforms never fight. */
.fchip{
  position:absolute; z-index:3;
  left:calc(var(--x) * var(--s));
  top:calc(var(--y) * var(--s));
  transform:translate(-50%,-50%);
  pointer-events:none;
}
/* The sticker chip. Shared atom — the hero scatters it, sections 03 and 05
   use it inline; only the positioning wrapper differs. */
.chip, .fchip__pill{
  display:inline-flex; align-items:center; white-space:nowrap;
  padding:calc(11 * var(--s)) calc(19 * var(--s));
  border-radius:999px;
  background:#fff; color:var(--ink);
  /* The 2.5 ink stroke is an INSET shadow, not a border: Figma's stroke is
     INSIDE, and a real border adds to an auto-sized box — it ran every chip
     4px wide. Same reason on the nav pill and the outline button. */
  box-shadow:0 calc(5 * var(--s)) 0 var(--ink),
             inset 0 0 0 calc(2.5 * var(--s)) var(--ink);
  font-family:var(--display); font-weight:900;
  font-size:calc(16 * var(--s));
  /* 1.2 is Gabarito's OWN normal line box — the comp's chip heights only
     resolve at that ratio (16 x 1.2 + 22 padding = 41.2, comp says 41). */
  line-height:1.2; letter-spacing:-.01em;
  will-change:opacity, transform;
}
.chip--cyan, .fchip--cyan{   background:var(--cyan); }
.chip--violet, .fchip--violet{ background:var(--violet); }
.chip--yellow, .fchip--yellow{ background:var(--yellow); }
.chip--lg, .fchip--lg{ font-size:calc(17 * var(--s)); }
/* ALL-CAPS chips get +3% tracking, sentence case -1% */
.chip--caps, .fchip--caps{ font-size:calc(15 * var(--s)); letter-spacing:.03em; }

/* ============================================================
   Nav  (154:4 — 1240 x 68 at 100,26, inside the hero)

   Kept absolute-in-hero exactly as the comp has it. The scroll state
   (shrink / re-ground once it leaves the pink) belongs with section 02,
   so it is deliberately not here yet.
   ============================================================ */
.fnav{
  position:fixed; z-index:40;
  left:calc(100 * var(--s)); top:calc(62 * var(--s));
  width:calc(1240 * var(--s));
  /* 62 = the comp's 26 inside the hero + the 36 parent strip above it, so at
     scrollY 0 it lands exactly where 154:4 draws it. */
  transition:top .45s var(--ease), transform .38s var(--ease);
}
.fnav.is-stuck{ top:calc(14 * var(--s)); }

/* Auto-hide: the bar leaves on the way down and comes back on the way up.

   The transform lives HERE, on the positioned wrapper, because
   `.fnav__pill` already owns one for the load sequence (it drops in from
   translateY(-18px)) — putting both on the pill would have the entry
   animation and the hide fighting over the same property.

   -200% of the bar's own height clears the pill and its hard shadow at
   both the resting and the stuck size, and at both breakpoints, without
   hard-coding a number that would drift when the pill resizes. */
.fnav.is-away{ transform:translateY(-200%); }

/* The behaviour is functional — it reclaims the page — so reduced motion
   keeps it and drops only the animation. */
@media (prefers-reduced-motion: reduce){
  .fnav{ transition:none; }
}
.fnav__pill{
  display:flex; align-items:center; justify-content:space-between;
  height:calc(68 * var(--s));
  padding:0 calc(10 * var(--s)) 0 calc(26 * var(--s));
  background:#fff;
  border-radius:calc(34 * var(--s));
  box-shadow:0 calc(6 * var(--s)) 0 var(--ink),
             inset 0 0 0 calc(2.5 * var(--s)) var(--ink);
  transition:height .45s var(--ease), border-radius .45s var(--ease),
             box-shadow .45s var(--ease);
}
.fnav.is-stuck .fnav__pill{
  height:calc(58 * var(--s));
  border-radius:calc(29 * var(--s));
  box-shadow:0 calc(5 * var(--s)) 0 var(--ink),
             inset 0 0 0 calc(2.5 * var(--s)) var(--ink);
}

.fbrand{ display:inline-flex; align-items:center; gap:calc(10 * var(--s)); flex:none; }
/* The supplied frnd script wordmark (Figma MVP 1017:9 pink / 1017:10 white),
   traced to SVG so it stays sharp from the nav to the full-span footer. */
.fbrand__logo{ display:block; height:calc(38 * var(--s)); width:auto; }

.fnav__links{
  display:flex; align-items:center; gap:calc(21 * var(--s));
  font-weight:700;
  font-size:max(11px, calc(14 * var(--s)));
  letter-spacing:-.01em;
  color:var(--ink); white-space:nowrap;
}
.fnav__links a{ position:relative; padding:calc(4 * var(--s)) 0; }
/* the hairline draws in from the left, same move as Interact's columns */
.fnav__links a::after{
  content:''; position:absolute; left:0; right:0; bottom:0;
  height:calc(2 * var(--s)); background:var(--pink);
  transform:scaleX(0); transform-origin:left;
  transition:transform .3s var(--ease);
}
.fnav__links a:hover::after,
.fnav__links a.is-active::after{ transform:scaleX(1); }
/* the active link also takes the brand colour, so the underline is not the
   only signal (it reads at a glance, and survives a colour-blind check) */
.fnav__links a.is-active{ color:var(--pink); }


/* ============================================================
   Below the fold — two systems, deliberately distinct

   ENTRY: one IntersectionObserver adds `.is-in` to every [data-reveal].
     · default          rise 22px + fade
     · data-reveal="pop"  scale from .58 with overshoot, for chips / seals /
                          language pills — anything that is a sticker
     · data-reveal="draw" scaleX(0->1) from the left, for the rules
   Each element carries its own `--d`, exactly like the hero's load beats.

   EXIT: every block fades and lifts as it clears the top of the screen.
   JS writes `--exit`; blocks read `opacity:var(--exit,1)`. It is anchored
   PER BLOCK rather than per section, because most of these sections are
   taller than the viewport — a section-wide progress would fade the cards
   while they are still the thing being read.
   ============================================================ */
/* 🔴 Selected by VALUE, not by :not(). The default flavour is a bare
   `data-reveal`, whose attribute value is the empty string, so `[data-reveal=""]`
   picks it out exactly.

   The first version guarded the default with
   `[data-reveal]:not([data-reveal="pop"]):not([data-reveal="draw"])` — and
   `:not()` contributes the specificity of its ARGUMENT, so that rule scored
   (0,4,0) and beat the resting `.is-in` rule at (0,3,0). Every default reveal
   on the page was therefore pinned at its hidden offset forever: only the
   opacity ever animated, and the 22px rise never happened. It looked like a
   plain fade, which is exactly why it went unnoticed. */
.js [data-reveal]{ opacity:0; }
/* --rx as well as --ry: Mission & Vision are a PAIR, and having them both
   rise identically wasted the `&` seal sitting on the seam between them. They
   now arrive from opposite sides and the seal reads as the join. */
.js [data-reveal=""]{ transform:translate(var(--rx, 0px), var(--ry, 22px)); }
.js [data-reveal="pop"]{ transform:rotate(var(--rot, 0deg)) scale(.58); }
.js [data-reveal="draw"]{ opacity:1; transform:scaleX(0); transform-origin:left center; }

.js [data-reveal].is-in{
  opacity:1;
  transition:opacity .9s var(--ease) var(--d, 0ms);
}
.js [data-reveal=""].is-in{
  transform:none;
  transition:opacity .9s var(--ease) var(--d, 0ms),
             transform .9s var(--ease) var(--d, 0ms);
}
.js [data-reveal="pop"].is-in{
  transform:rotate(var(--rot, 0deg)) scale(1);
  transition:opacity .34s ease-out var(--d, 0ms),
             transform .6s var(--bounce) var(--d, 0ms);
}
.js [data-reveal="draw"].is-in{
  transform:scaleX(1);
  transition:transform .8s var(--ease) var(--d, 0ms);
}

/* The pink ledge is the whole reason section 08 reads (an ink shadow on an
   ink ground is invisible), so it GROWS from nothing as the card arrives —
   the sticker visibly sets down on the page rather than arriving pre-shadowed.
   The base .sticker rule already transitions box-shadow, and box-shadow
   interpolates fine when only the custom property it is built from changes. */
.js .acard[data-reveal]{ --ledge:0; }
.js .acard[data-reveal].is-in{
  --ledge:9;
  transition:transform .9s var(--ease) var(--d, 0ms),
             opacity .9s var(--ease) var(--d, 0ms),
             box-shadow .7s var(--ease) calc(var(--d, 0ms) + 200ms);
}

/* Blocks that exit. `--exit` is written by JS; the transform is too, so
   there is no transition here on purpose — it must track scroll 1:1. */
[data-exit]{ opacity:var(--exit, 1); }

/* ============================================================
   Section shell
   Sections tile in document order, exactly as the Figma root's vertical
   auto-layout does, and each one owns its ground. Heights are the comp's,
   held with a fixed height + absolutely placed children, because in every
   one of these the COMPOSITION is the design.
   ============================================================ */
.sec{
  position:relative; z-index:2;
  width:100%;
  overflow:hidden;
  background:var(--page);
}
.sec--ink{ background:var(--ink); color:#fff; }
.sec--soft{ background:var(--pink-soft); }

/* The header pairing that appears in six sections and is the page's rhythm:
   eyebrow + two-line H2 left at x=100, with a 430 lead paragraph at x=910. */
.eyebrow--pink{
  display:inline-flex; align-items:center;
  padding:calc(9 * var(--s)) calc(18 * var(--s));
  border-radius:999px;
  background:var(--pink); color:#fff;
}
.sh{ position:absolute; left:calc(100 * var(--s)); }
.sh2{
  position:absolute; left:calc(100 * var(--s));
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(76 * var(--s));
  line-height:.94; letter-spacing:-.03em;
  color:var(--ink);
}
.sec--ink .sh2{ color:#fff; }
.sh2 .line{ display:block; }
.sh2 .line--pink, .sh2 .em{ color:var(--pink); }
.slead{
  position:absolute; left:calc(910 * var(--s));
  margin:0; width:calc(430 * var(--s));
  font-weight:400;
  font-size:max(15px, calc(18 * var(--s)));
  line-height:1.66;
  color:rgba(23,17,15,.72);
}

/* ============================================================
   The STICKER — every card, plate and pill on the page

   The signature is a 0-blur offset shadow: the thing is a sticker lying on
   the page. So it also has to behave like one — picked up under the cursor,
   pressed flat on click. Before this, hover existed only on buttons and
   links, and the four feature cards, eight year cards, eleven language
   pills, three investor plates, three AI cards and two statement cards were
   all completely inert.

   The whole shadow is parameterised so the interaction is ONE rule instead
   of six:
     --ledge        offset of the hard shadow
     --ledge-color  ink on light grounds, PINK on ink grounds (an ink shadow
                    on ink is invisible)
     --stroke       inside stroke; 0 on ink grounds, where the card's own
                    fill already separates it

   ⚠ The hover selector must out-specify the reveal. `.js [data-reveal].is-in`
   sets `transform:none` at (0,3,0); `.js .sticker.is-in:hover` is (0,4,0) and
   wins. Without that the hover silently never applies.
   ============================================================ */
.sticker{
  --ledge:7;
  --ledge-color:var(--ink);
  --stroke:2.5;
  box-shadow:
    0 calc(var(--ledge) * var(--s)) 0 var(--ledge-color),
    inset 0 0 0 calc(var(--stroke) * var(--s)) var(--ink);
  transition:transform .28s var(--ease), box-shadow .28s var(--ease);
}
.js .sticker.is-in:hover, .sticker:hover{
  transform:translateY(calc(-5 * var(--s)));
  box-shadow:
    0 calc((var(--ledge) + 4) * var(--s)) 0 var(--ledge-color),
    inset 0 0 0 calc(var(--stroke) * var(--s)) var(--ink);
}
/* pressed flat — the ledge collapses under it */
.js .sticker.is-in:active, .sticker:active{
  transform:translateY(calc(2 * var(--s)));
  box-shadow:
    0 calc(max(var(--ledge) - 6, 1) * var(--s)) 0 var(--ledge-color),
    inset 0 0 0 calc(var(--stroke) * var(--s)) var(--ink);
  transition-duration:.09s;
}

/* The sticker CARD — sections 03 and 05 share it. */
.scard{
  border-radius:calc(32 * var(--s));
  background:#fff; color:var(--ink);
  box-shadow:0 calc(8 * var(--s)) 0 var(--ink),
             inset 0 0 0 calc(2.5 * var(--s)) var(--ink);
}

/* ============================================================
   02 / Ticker  (153:5 — 1440 x 108)
   An auto-layout row far wider than the frame, centred so it overhangs
   both edges, tilted 1.6deg inside a clipped ink band. It scrolls: the
   content is duplicated and the row travels exactly one copy (-50%), so
   the loop is seamless. Separators are ELLIPSE NODES in the comp, not
   glyphs — so they are elements here too.
   ============================================================ */
.tick{
  position:relative; z-index:2;
  height:calc(108 * var(--s));
  background:var(--ink);
  overflow:hidden;
}
/* 🔴 The TILT and the SCROLL must be on different elements. Rotating the
   scrolling row itself rotates about the ROW's centre — and the row is ~5100
   wide, so the 1440 window sits a long way off that centre and the text
   drifts vertically as the animation runs (measured 36px high). The tilt
   wrapper is exactly viewport-wide, so it rotates about the centre of what
   you can actually see, and the row then only ever moves horizontally. */
.tick__tilt{
  position:absolute; left:0; right:0; top:50%;
  display:flex; justify-content:center;
  transform:translateY(-50%) rotate(1.6deg);
}
.tick__row{
  display:flex; align-items:center; gap:calc(26 * var(--s));
  width:max-content;
  white-space:nowrap;
  font-family:var(--display); font-weight:900;
  font-size:calc(30 * var(--s));
  line-height:1.2; letter-spacing:.02em;
  color:#fff;
  animation:tickscroll 44s linear infinite;
}
/* The content is duplicated, so travelling exactly one copy (-50%) loops
   seamlessly. */
@keyframes tickscroll{
  from{ transform:translateX(0); }
  to  { transform:translateX(-50%); }
}
.tick__row > span{ flex:none; }
.tick--pink{ color:var(--pink); }
.tick--yellow{ color:var(--yellow); }
.tick--cyan{ color:var(--cyan); }
.tick--violet{ color:var(--violet); }
.tick__dot{
  flex:none;
  width:calc(11 * var(--s)); height:calc(11 * var(--s));
  border-radius:50%; background:var(--pink);
}

/* ============================================================
   03 / What is FRND  (153:6 — 1440 x 986)
   ============================================================ */
/* ── the pin ──────────────────────────────────────────────────
   The section is sticky inside a taller stage, so it holds still while the
   extra height scrolls past and the cards are dealt. This is the same scene
   pattern the Interact hero uses.

   🔴 The travel MUST come from an in-flow spacer, not padding-bottom: a
   sticky element's range is bounded by its containing block's CONTENT box,
   and padding gives it exactly none — the section would scroll away like a
   normal block while every progress ratio still looked plausible.
   ------------------------------------------------------------ */
.what-stage{ position:relative; z-index:2; }
.what-stage::after{
  content:''; display:block;
  height:85vh;
  background:var(--page);      /* same ground, so the pin is seamless */
}
.what{
  position:sticky; top:0;
  height:calc(986 * var(--s));
}
.what__eyebrow{ top:calc(116 * var(--s)); }
.what__h2{ top:calc(176 * var(--s)); font-size:calc(86 * var(--s)); }
.what__lead{ top:calc(218 * var(--s)); }
/* "Read more" → about.html (2026-10-02): sits under the lead in the right column */
.what__more{ position:absolute; left:calc(910 * var(--s)); top:calc(334 * var(--s)); z-index:3; }
.what__chip{
  position:absolute;
  /* beside "Not a feed." — the longer "A social playground." line now runs where it used to sit */
  left:calc(640 * var(--s)); top:calc(300 * var(--s));
  transform:translate(-50%,-50%);
}

/* The four cards. The WRAPPER holds position + the home rotation and is what
   the deal animates; the INNER holds data-reveal. Splitting them this way is
   what stops the reveal's `transform:none` from wiping the layout — see the
   note on .ycard. */
.fcards{ position:absolute; inset:0; }
.fcard{
  position:absolute;
  top:calc(644.71 * var(--s));
  width:calc(236 * var(--s));
  transform:translate(-50%,-50%) rotate(var(--wrot));
}
/* five across (2026-10-02): 236 wide, 20 gutter, centred on 720 */
.fcard--1{ left:calc(208 * var(--s)); }
.fcard--2{ left:calc(464 * var(--s)); }
.fcard--3{ left:calc(720 * var(--s)); }
.fcard--4{ left:calc(976 * var(--s)); }
.fcard--5{ left:calc(1232 * var(--s)); }

.fcard__inner{
  display:flex; flex-direction:column; justify-content:space-between;
  height:calc(430 * var(--s));
  padding:calc(20 * var(--s));
  border-radius:calc(32 * var(--s));
  --ledge:8;
  will-change:transform, opacity;
}
.fcard--1 .fcard__inner{ background:var(--cyan); }
.fcard--2 .fcard__inner{ background:var(--yellow); }
.fcard--3 .fcard__inner{ background:var(--tangerine); }
.fcard--4 .fcard__inner{ background:#fff; }
.fcard--5 .fcard__inner{ background:var(--pink); }
.fcard--5 .fcard__num{ color:rgba(23,17,15,.6); }

.fcard__plate{
  height:calc(146 * var(--s));
  border-radius:calc(20 * var(--s));
  overflow:hidden;
  box-shadow:inset 0 0 0 calc(2 * var(--s)) var(--ink);
}
.fcard__plate img{ width:100%; height:100%; object-fit:cover; display:block; }

.fcard__copy{ display:flex; flex-direction:column; gap:calc(14 * var(--s)); }
.fcard__head{ display:flex; flex-direction:column; gap:calc(10 * var(--s)); }
.fcard__num{
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(10px, calc(11 * var(--s)));
  line-height:calc(14 * var(--s));
  letter-spacing:.14em;
  color:rgba(23,17,15,.55);
}
.fcard__title{
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(26 * var(--s));
  line-height:1.04; letter-spacing:-.02em;
  color:var(--ink);
}
.fcard__body{
  margin:0;
  font-weight:400;
  font-size:max(13px, calc(15.5 * var(--s)));
  line-height:1.58;
  color:rgba(23,17,15,.78);
}

/* ============================================================
   04 / Numbers  (153:7 — 1440 x 574, the first ink section)
   ============================================================ */
.nums{ height:calc(574 * var(--s)); }
.nums__eyebrow{ top:calc(92 * var(--s)); }
.nums__h2{ top:calc(148 * var(--s)); line-height:1; white-space:nowrap; }
.nums__asof{
  position:absolute; left:calc(1215 * var(--s)); top:calc(98 * var(--s));
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(9px, calc(10 * var(--s)));
  line-height:calc(13 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.4);
}
.nums__rule{
  position:absolute; left:calc(100 * var(--s)); top:calc(272 * var(--s));
  width:calc(1240 * var(--s)); height:calc(2 * var(--s));
  background:rgba(255,255,255,.18);
}
.nums__row{
  position:absolute; left:calc(100 * var(--s)); top:calc(314 * var(--s));
  width:calc(1240 * var(--s));
  display:flex; align-items:flex-start;
}
.stat{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:calc(16 * var(--s)); }
.stat__n{
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(96 * var(--s));
  line-height:.96; letter-spacing:-.04em;
  /* Gabarito's proportional digits span 0.378em ("1") to 0.610em ("4") — a
     22px spread at this size, which would make the reel column jump on every
     tick. Gabarito DOES carry tabular figures (measured spread: 0), so the
     reel gets a fixed advance for free. */
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
  white-space:nowrap;
}

/* ── the digit reel ──────────────────────────────────────────
   One window per digit, each clipping a vertical strip of 0-9 repeated N
   times. The strip RESTS on the final digit and animates to the same digit N
   cycles further down, so it spins without ever showing a wrong value at
   either end — no snap on trigger, and nothing to reset.
   Sized in `em`, so the whole thing follows --s on resize with no re-measure.
   ------------------------------------------------------------ */
.reel{ display:inline-flex; vertical-align:top; }
.reel__w{
  display:inline-block; overflow:hidden;
  height:.96em;                    /* = the numeral's own line box */
}
.reel__s{
  display:block; line-height:.96;
  will-change:transform;
}
.reel__s b{ display:block; font-weight:inherit; }
.reel__sfx{
  display:inline-block;
  transform:scale(1);
}
/* the suffix punctuates the landing rather than sitting there through the spin */
.stat__n.is-landed .reel__sfx{
  animation:sfxpop .42s var(--bounce);
}
@keyframes sfxpop{
  0%{ transform:scale(1); }
  30%{ transform:scale(1.16); }
  100%{ transform:scale(1); }
}
.stat--pink   .stat__n{ color:var(--pink); }
.stat--yellow .stat__n{ color:var(--yellow); }
.stat--cyan   .stat__n{ color:var(--cyan); }
.stat--violet .stat__n{ color:var(--violet); }
.stat__l{
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(9px, calc(10 * var(--s)));
  line-height:1.7; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.55);
}
.stat__l span{ display:block; }

/* ============================================================
   05 / Mission & Vision  (153:8 — 1440 x 780)
   Two statement cards. The ink card's own ink shadow is visible because
   the GROUND is cream — the invisible-shadow-on-ink problem only bites
   when the ground is ink (see the ticker / Numbers).
   ============================================================ */
.miss{ height:calc(696 * var(--s)); }   /* 780 → 696 with the shorter cards (2026-10-02) */
.miss__eyebrow{ top:calc(96 * var(--s)); }
.miss__h2{ top:calc(156 * var(--s)); }
.mcard{
  position:absolute; top:calc(356 * var(--s));
  width:calc(608 * var(--s)); height:calc(236 * var(--s));   /* 320 → 236: hugs the shorter mission/vision copy */
  display:flex; flex-direction:column; gap:calc(20 * var(--s));
  padding:calc(36 * var(--s)) calc(40 * var(--s));
  border-radius:calc(32 * var(--s));
  --ledge:8;
}
.mcard--mission{ left:calc(100 * var(--s)); background:var(--pink); --rx:-58px; --ry:0px; }
.mcard--vision{  left:calc(732 * var(--s)); background:var(--ink);  --rx:58px;  --ry:0px; }
.mcard__k{
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(10px, calc(11 * var(--s)));
  line-height:calc(14 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
}
.mcard--mission .mcard__k{ color:rgba(23,17,15,.6); }
.mcard--vision  .mcard__k{ color:rgba(255,255,255,.6); }
.mcard__p{
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(34 * var(--s));
  line-height:1.16; letter-spacing:-.02em;
}
.mcard--mission .mcard__p{ color:var(--ink); }
.mcard--vision  .mcard__p{ color:#fff; }

/* The seal sits ON the seam between the two cards, so it must outrank both. */
.seal{
  position:absolute; z-index:3;
  left:calc(715.08 * var(--s)); top:calc(474 * var(--s));   /* stays on the cards' vertical centre */
  transform:translate(-50%,-50%);
}
.seal__o{
  display:grid; place-items:center;
  width:calc(66 * var(--s)); height:calc(66 * var(--s));
  border-radius:50%;
  background:var(--yellow); color:var(--ink);
  box-shadow:0 calc(5 * var(--s)) 0 var(--ink),
             inset 0 0 0 calc(2.5 * var(--s)) var(--ink);
  font-family:var(--display); font-weight:900;
  font-size:calc(32 * var(--s)); line-height:1; letter-spacing:-.02em;
  padding-bottom:calc(3 * var(--s));
  transform:rotate(var(--rot));
}

/* ============================================================
   06 / Languages  (153:9 — 1440 x 677, pink-soft)
   TWO tilted auto-layout rows, not eleven individually tilted pills:
   auto-layout ignores rotation when it measures, so rotated siblings
   overlap. Rotate the ROW.
   ============================================================ */
.langs{ height:calc(677 * var(--s)); }
.langs__eyebrow{ top:calc(92 * var(--s)); }
.langs__h2{ top:calc(152 * var(--s)); }
.langs__lead{ top:calc(204 * var(--s)); color:rgba(23,17,15,.7); }
.lrow{
  position:absolute;
  display:flex; align-items:center; gap:calc(20 * var(--s));
  white-space:nowrap;
  transform:translate(-50%,-50%) rotate(var(--rot));
}
.lrow--1{ left:calc(656.68 * var(--s)); top:calc(423.17 * var(--s)); --rot:1.1deg; }
.lrow--2{ left:calc(673 * var(--s));    top:calc(520.5 * var(--s)); --rot:-1.1deg; }
.lpill{
  flex:none;
  display:inline-flex; align-items:center;
  padding:calc(20 * var(--s)) calc(32 * var(--s));
  border-radius:999px;
  background:#fff; color:var(--ink);
  font-family:var(--display); font-weight:900;
  font-size:calc(34 * var(--s));
  line-height:1.2; letter-spacing:-.02em;
}
.lpill--yellow{ background:var(--yellow); }
.lpill--cyan{   background:var(--cyan); }
.lpill--violet{ background:var(--violet); }
.lpill--tang{   background:var(--tangerine); }
.lpill--pink{   background:var(--pink); color:#fff; }


/* ============================================================
   07 / Journey  (153:10 — 1440 x 1094)
   4 x 2 year cards on a 316 pitch. Each card is placed by the CENTRE of its
   Figma frame and rotated about that centre, so the tilts never disturb the
   grid — auto-layout ignores rotation when it measures, which is what makes
   a tilted flex row collide with itself.
   ============================================================ */
/* Re-laid out from the comp's 1094 to 1030, for two reasons.

   1. The cards were 290 tall around ~168 of content, which left a 70-115px
      VOID between the year numeral and the copy — 24-40% of every card, worst
      on the shortest entries (2019, 2020, 2022, 2026 all measured ~113px).
      232 leaves ~16px for space-between to distribute, which is what that
      alignment is for.
   2. It is a TIMELINE and it behaved like eight identical rises. Two rails now
      draw left-to-right and each card arrives as the rail reaches its column,
      so the repetition becomes the point.

   The rails sit in the gaps the new rhythm opens: rail 1 above row 1, rail 2
   between the rows. They are only visible because the cards shrank. */
.jour{ height:calc(1030 * var(--s)); }

.jrail{
  position:absolute; z-index:0;
  left:calc(100 * var(--s));
  width:calc(1240 * var(--s));
  height:calc(3 * var(--s));
  background:rgba(23,17,15,.10);
  border-radius:999px;
}
.jrail--1{ top:calc(396 * var(--s)); }
.jrail--2{ top:calc(698 * var(--s)); }
.jrail__fill{
  position:absolute; inset:0;
  background:var(--pink);
  border-radius:999px;
  transform:scaleX(0);
  transform-origin:left center;
  will-change:transform;
}
/* one tick per column, so the rail reads as a timeline rather than a rule */
.jtick{
  position:absolute; z-index:1;
  width:calc(13 * var(--s)); height:calc(13 * var(--s));
  border-radius:50%;
  background:var(--pink);
  box-shadow:0 0 0 calc(3 * var(--s)) var(--page);
  transform:translate(-50%,-50%) scale(0);
  will-change:transform;
}
.jour__eyebrow{ top:calc(92 * var(--s)); }
.jour__h2{ top:calc(152 * var(--s)); }

/* 🔴 The wrapper owns position AND rotation; the CHILD owns data-reveal. An
   element cannot carry both, because the reveal's resting state is
   `transform:none` — it silently wipes translate(-50%,-50%) and every card
   lands half a card-width to the right. `--wrot`, not `--rot`, so the pop
   reveal's own rotate(var(--rot)) cannot inherit this tilt and double it. */
.ycard{
  position:absolute; z-index:1;
  width:calc(289 * var(--s));
  transform:translate(-50%,-50%) rotate(var(--wrot));
  opacity:var(--arrive, 1);
}
.ycard__in{
  display:flex; flex-direction:column; justify-content:space-between;
  height:calc(238 * var(--s));
  padding:calc(24 * var(--s));
  border-radius:calc(28 * var(--s));
  background:#fff;
}
/* The void cannot be closed by height alone: the entries' copy runs from 2
   to 5 lines, and equal-height cards with bottom-aligned copy — which is the
   right system, it gives the row a baseline — must fit the longest. 238 with a bigger
   numeral gets the range down to ~10-36px from 70-115. The RULE is what fixes the rest of
   it perceptually: it terminates the numeral so the space below reads as a
   card header's whitespace rather than as a gap in the middle of the card. */
.ycard__head{ display:flex; flex-direction:column; gap:calc(12 * var(--s)); }
.ycard__y{
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(56 * var(--s));
  line-height:1; letter-spacing:-.03em;
}
.ycard__rule{
  height:calc(3 * var(--s));
  border-radius:999px;
  background:currentColor;
  opacity:.22;
}
.ycard__copy{ display:flex; flex-direction:column; gap:calc(9 * var(--s)); }
.ycard__t{
  margin:0;
  font-family:var(--display); font-weight:900;
  font-size:calc(20 * var(--s));
  line-height:1.12; letter-spacing:-.02em;
  color:var(--ink);
}
.ycard__b{
  margin:0; font-weight:400;
  font-size:max(13px, calc(14.5 * var(--s)));
  line-height:1.56;
  color:rgba(23,17,15,.7);
}
/* 2026 was blank in the source. Designing it as the pink "still being
   written" card is a better answer than inventing a milestone. */
.ycard--now .ycard__in{ background:var(--pink); }
.ycard--now .ycard__y,
.ycard--now .ycard__t{ color:#fff; }
.ycard--now .ycard__b{ color:rgba(255,255,255,.85); }

.ycard--r1{ top:calc(530 * var(--s)); }
.ycard--r2{ top:calc(828 * var(--s)); }
.ycard--c1{ left:calc(244.5 * var(--s)); }
.ycard--c2{ left:calc(560.5 * var(--s)); }
.ycard--c3{ left:calc(876.5 * var(--s)); }
.ycard--c4{ left:calc(1192.5 * var(--s)); }

/* ============================================================
   08 / AI & Safety  (153:11 — 1440 x 872, ink)
   The ledge is PINK, not ink: an ink hard-shadow on an ink ground is
   invisible. A white-at-16% ledge was tried first and read as nothing.
   Making it pink also puts the brand colour back into a section where it
   would otherwise only be an accent. No strokes here either — the light
   card fills already separate from the ground.
   ============================================================ */
.ai{ height:calc(1050 * var(--s)); }   /* 872 → 1130: taller feature cards + the View more CTA (2026-10-02) */
.ai__eyebrow{ top:calc(92 * var(--s)); }
.ai__h2{ top:calc(152 * var(--s)); }
.ai__lead{ top:calc(204 * var(--s)); color:rgba(255,255,255,.66); }

/* The Trust & Safety page's cards, three of them: pastel fill, the generated
   scene in a framed plate, number + name + (placeholder) description.
   PINK ledge, no stroke — an ink shadow vanishes on this ink ground. */
.acard{
  position:absolute; top:calc(376 * var(--s));
  width:calc(397 * var(--s));
  display:flex; flex-direction:column; gap:calc(18 * var(--s));
  padding:calc(18 * var(--s)) calc(18 * var(--s)) calc(28 * var(--s));
  border-radius:calc(32 * var(--s));
  background:var(--bg, #fff); color:var(--ink); text-decoration:none;
  --ledge:9; --ledge-color:var(--pink); --stroke:0;
}
.acard--1{ left:calc(100 * var(--s)); }
.acard--2{ left:calc(521 * var(--s)); }
.acard--3{ left:calc(942 * var(--s)); }
.acard__plate{ position:relative; display:block; aspect-ratio:4/3; overflow:hidden; border-radius:calc(22 * var(--s)); }
.acard__plate::after{ content:''; position:absolute; inset:0; border-radius:inherit; box-shadow:inset 0 0 0 calc(2.5 * var(--s)) var(--ink); }
.acard__plate img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .9s var(--ease); }
.acard:hover .acard__plate img{ transform:scale(1.05); }
.acard__copy{ display:flex; flex-direction:column; gap:calc(8 * var(--s)); padding:0 calc(10 * var(--s)); }
.acard__n{ font-family:var(--mono); font-weight:500; font-size:max(10px, calc(12 * var(--s))); letter-spacing:.14em; color:rgba(23,17,15,.5); }
.acard__t{ margin:0; font-family:var(--display); font-weight:900; font-size:calc(30 * var(--s)); line-height:1.08; letter-spacing:-.02em; }
.acard__b{ font-weight:500; font-size:max(14px, calc(16 * var(--s))); line-height:1.55; color:rgba(23,17,15,.78); }
.ai__more{
  position:absolute; left:0; right:0; top:calc(878 * var(--s));
  display:flex; flex-direction:column; align-items:center; gap:calc(14 * var(--s));
}
.ai__more-note{ font-family:var(--mono); font-weight:500; font-size:max(10px, calc(12 * var(--s))); letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.6); }

/* ============================================================
   09 / Backed by  (153:12 — 1440 x 604)
   ⚠ These are NAME plates, not logos. Real investor marks cannot and should
   not be generated — drop in SVGs when they land.
   ============================================================ */
/* 548, not the comp's 604: content ended at y469, leaving 135px of trailing
   cream in the one section that has no imagery to carry it. */
.inv{ height:calc(580 * var(--s)); }
.inv__eyebrow{ top:calc(88 * var(--s)); }
.inv__h2{ top:calc(148 * var(--s)); }
.inv__lead{ top:calc(200 * var(--s)); color:rgba(23,17,15,.7); }
.iplate{
  position:absolute; top:calc(436 * var(--s));
  width:calc(397 * var(--s));
  transform:translate(-50%,-50%) rotate(var(--wrot));
}
/* official logos (2026-10-02): the investors' own marks from their sites —
   IQ (indiaquotient.in uses the mark alone), Elevation (header wordmark),
   Krafton (new corporate logo). The name sits under each in mono so the
   three plates read the same even though IQ's mark carries no wordmark. */
.iplate__in{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:calc(12 * var(--s));
  height:calc(168 * var(--s));
  border-radius:calc(24 * var(--s));
  background:#fff; color:var(--ink);
  font-family:var(--display); font-weight:900;
  font-size:calc(26 * var(--s));
  line-height:1.2; letter-spacing:-.02em;
}
.iplate__logo{ display:block; width:auto; }
.iplate__logo--iq{ height:calc(66 * var(--s)); }
.iplate__logo--el{ height:calc(40 * var(--s)); }
.iplate__logo--kr{ height:calc(70 * var(--s)); }
.iplate__name{ font-family:var(--mono); font-weight:500; font-size:max(10px, calc(11 * var(--s))); letter-spacing:.14em; text-transform:uppercase; color:rgba(23,17,15,.55); }
.iplate--1{ left:calc(298.5 * var(--s)); }
.iplate--2{ left:calc(719.5 * var(--s)); }
.iplate--3{ left:calc(1140.5 * var(--s)); }

/* ============================================================
   10 / Download  (153:13 — 1440 x 720, the second PINK section)
   Photography register, same as the hero: the plates' own grounds are baked
   to exactly #FF3E84 and feathered, so they carry no frame and no radius —
   the people simply bleed off the section edges.
   ============================================================ */
.dl{ height:calc(720 * var(--s)); background:var(--pink); }
/* On the pink grounds the eyebrow flips to an INK pill — which is exactly
   what .eyebrow--pill already is, so this only places it. */
.dl__eyebrow{
  position:absolute; left:calc(658 * var(--s)); top:calc(100 * var(--s));
}
.dl__h1{
  position:absolute; left:0; right:0; top:calc(158 * var(--s));
  margin:0; text-align:center;
  font-family:var(--display); font-weight:900;
  font-size:calc(90 * var(--s));
  line-height:.94; letter-spacing:-.03em;
  color:#fff;
}
.dl__h1 .line{ display:block; }
.dl__h1 .line--ink{ color:var(--ink); }
/* left/right:0 + text-align rather than left:50% + translateX(-50%): this
   element carries data-reveal, and the reveal would wipe the transform. */
.dl__sub{
  position:absolute; left:0; right:0; top:calc(362 * var(--s));
  margin:0; text-align:center;
  font-weight:500;
  font-size:max(16px, calc(20 * var(--s)));
  line-height:1.5; letter-spacing:-.01em;
  color:#fff;
}
.dl__stores{
  position:absolute; left:calc(521 * var(--s)); top:calc(432 * var(--s));
  display:flex; align-items:center; gap:calc(16 * var(--s));
}
.store{
  display:inline-flex; align-items:center; gap:calc(14 * var(--s));
  padding:calc(15 * var(--s)) calc(30 * var(--s)) calc(15 * var(--s)) calc(24 * var(--s));
  border-radius:999px;
  background:var(--ink); color:#fff;
  box-shadow:0 calc(6 * var(--s)) 0 var(--ink);
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
.store:hover{
  transform:translateY(calc(-2 * var(--s)));
  box-shadow:0 calc(9 * var(--s)) 0 rgba(23,17,15,.55);
}
.store__i{
  flex:none;
  width:calc(30 * var(--s)); height:calc(30 * var(--s));
  border-radius:calc(9 * var(--s));
  background:rgba(255,255,255,.2);
}
.store__l{ display:flex; flex-direction:column; gap:calc(2 * var(--s)); }
.store__k{
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(8px, calc(8 * var(--s)));
  line-height:calc(11 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.6);
}
.store__n{
  margin:0; font-weight:800;
  font-size:max(14px, calc(17 * var(--s)));
  line-height:calc(22 * var(--s)); letter-spacing:-.01em;
}
/* people plates — same wrapper/child split as the hero faces */
.dperson{
  position:absolute; z-index:0;
  width:calc(336.992 * var(--s)); height:calc(534.83 * var(--s));
  display:grid; place-items:center;
  pointer-events:none;
}
.dperson img{
  width:calc(262 * var(--s)); height:calc(500 * var(--s));
  max-width:none; object-fit:cover;
  transform:rotate(var(--rot));
}
.dperson--l{ left:calc(-32.22 * var(--s)); top:calc(330 * var(--s)); }
.dperson--r{ left:calc(1132 * var(--s));   top:calc(300 * var(--s)); }
.dl__content{ position:relative; z-index:2; }
.dl__chips{ position:relative; z-index:3; }

/* ============================================================
   11 / Footer  (153:14 — 1440 x 953)
   Row is brand + four link columns on a 202 pitch, then a rule, the legal
   line, and the full-span wordmark clipped by the section's bottom.
   ============================================================ */
.foot{
  position:relative; z-index:2;
  height:calc(610 * var(--s));   /* giant wordmark removed 2026-09-30. Legal line + 124: the reveal fires 8% above the viewport bottom, so less than that and the © line never appears */
  background:var(--ink); color:#fff;
  overflow:hidden;
}
.fbrandcol{
  position:absolute; left:calc(100 * var(--s)); top:calc(96 * var(--s));
  display:flex; flex-direction:column; align-items:flex-start;
  gap:calc(24 * var(--s));
}
.fbrandcol .fbrand__logo{ height:calc(50 * var(--s)); }
.fbrandcol .fbrand{ gap:calc(11 * var(--s)); }
.fblurb{
  margin:0; width:calc(290 * var(--s));
  font-weight:400;
  font-size:max(13px, calc(15.5 * var(--s)));
  line-height:1.66;
  color:rgba(255,255,255,.55);
}
.fsocials{ display:flex; gap:calc(10 * var(--s)); }
.fsocial{
  display:grid; place-items:center;
  width:calc(42 * var(--s)); height:calc(42 * var(--s));
  border-radius:999px;
  background:rgba(255,255,255,.09);
  box-shadow:inset 0 0 0 calc(1.5 * var(--s)) rgba(255,255,255,.2);
  font-family:var(--display); font-weight:900;
  font-size:max(11px, calc(13 * var(--s))); line-height:1;
  color:rgba(255,255,255,.85);
  transition:background-color .3s ease, transform .3s var(--ease);
}
.fsocial:hover{ background:var(--pink); transform:translateY(calc(-2 * var(--s))); }
.fback{
  display:inline-flex; align-items:center; gap:calc(9 * var(--s));
  padding:calc(12 * var(--s)) calc(18 * var(--s));
  border-radius:999px;
  box-shadow:inset 0 0 0 calc(1.5 * var(--s)) rgba(255,255,255,.26);
  font-weight:500;
  font-size:max(13px, calc(14 * var(--s))); line-height:calc(18 * var(--s));
  letter-spacing:-.01em;
  color:rgba(255,255,255,.9);
  transition:background-color .3s ease;
}
.fback:hover{ background:rgba(255,255,255,.08); }
.fback span:last-child{ font-family:var(--mono); font-weight:600; font-size:calc(13 * var(--s)); color:rgba(255,255,255,.7); }

.fcol{
  position:absolute; top:calc(96 * var(--s));
  display:flex; flex-direction:column; gap:calc(15 * var(--s));
}
.fcol--1{ left:calc(560 * var(--s)); }
.fcol--2{ left:calc(762 * var(--s)); }
.fcol--3{ left:calc(964 * var(--s)); }
.fcol--4{ left:calc(1166 * var(--s)); }
.fcol__h{
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(9px, calc(10 * var(--s)));
  line-height:calc(13 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.42);
}
/* Both line-height AND font-size go on the LIST: an inline <a> cannot shrink
   its own <li>'s line box, and the inherited size's strut then runs the
   whole column long. */
.fcol ul{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:calc(13 * var(--s));
  font-size:max(13px, calc(15 * var(--s)));
  line-height:calc(19 * var(--s));
}
.fcol a{ font-weight:500; letter-spacing:-.01em; color:rgba(255,255,255,.8); transition:color .25s ease; }
.fcol a:hover{ color:var(--pink); }

.foot__rule{
  position:absolute; left:calc(100 * var(--s)); top:calc(436 * var(--s));
  width:calc(1240 * var(--s)); height:calc(2 * var(--s));
  background:rgba(255,255,255,.13);
}
.flegal{
  position:absolute; top:calc(472 * var(--s));
  margin:0;
  font-family:var(--mono); font-weight:500;
  font-size:max(9px, calc(10 * var(--s)));
  line-height:calc(13 * var(--s));
  letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.4);
}
.flegal--l{ left:calc(100 * var(--s)); }
.flegal--r{ left:calc(1163 * var(--s)); }


/* ============================================================
   Compact  (< 1040)
   Not a scaled comp — a re-layout. --s is FLOORED at 0.7222, so every
   comp-sized number stops shrinking here: calc(140 * var(--s)) is still
   101px on a 390 phone. Anything driven off the comp's large numbers is
   therefore re-expressed in vw, and small type goes back to px.
   ============================================================ */
@media (max-width:1040px){
  .fhero{ aspect-ratio:auto; min-height:100svh; }

  .pstrip{
    height:34px; padding:0 20px; font-size:9px; line-height:12px;
    letter-spacing:.1em; gap:12px;
  }
  .pstrip__note{ display:none; }

  .fnav{ left:16px; right:16px; top:48px; width:auto; }
  .fnav.is-stuck{ top:12px; }
  .fnav__pill{
    height:58px; padding:0 8px 0 18px;
    border-radius:29px;
    box-shadow:0 5px 0 var(--ink), inset 0 0 0 2px var(--ink);
  }
  /* A drawer is deferred until the pages these link to exist — the brand
     and the download CTA carry the bar on their own, exactly as on the
     Interact site. */
  .fnav__links{ display:none; }
  .fbrand__logo{ height:32px; }
  .sbtn--ink{ height:42px; padding:0 6px 0 16px; gap:8px; font-size:13px; }
  .sbtn--ink .sbtn__knob{ width:30px; height:30px; font-size:14px; }

  /* 🔴 The STUCK pill height was never overridden in this block, so it fell
     through to the desktop rule — and at this width the --s floor lands
     calc(58 * var(--s)) on exactly 42px, which is the ink CTA's own fixed
     height. The button filled the white pill edge to edge and its 999px ends
     burst straight through the pill's corner radius. Both shrink together
     now, so the inset survives the stuck state.

     Whenever a compact block hard-codes a REST size, check that it also
     overrides every state that scales off --s, or the floor decides for you. */
  .fnav.is-stuck .fnav__pill{
    height:48px;
    border-radius:24px;
    box-shadow:0 4px 0 var(--ink), inset 0 0 0 2px var(--ink);
  }
  .fnav.is-stuck .sbtn--ink{ height:34px; padding:0 5px 0 14px; }
  .fnav.is-stuck .sbtn--ink .sbtn__knob{ width:26px; height:26px; font-size:13px; }

  /* Extend, never replace: .sbtn already transitions transform + box-shadow
     for its press state. */
  .fnav .sbtn--ink{
    transition:transform .3s var(--ease), box-shadow .3s var(--ease),
               height .45s var(--ease), padding .45s var(--ease);
  }
  .fnav .sbtn--ink .sbtn__knob{
    transition:width .45s var(--ease), height .45s var(--ease);
  }

  /* Centred, not top-hung: the bottom padding RESERVES the band the two
     large face plates occupy, and the type block then centres in the rest.
     Top-hanging it left ~120px of empty pink above the plates on a 844
     viewport, and more on anything taller. */
  .fhero__content{ padding:96px 22px 176px; justify-content:center; }
  .eyebrow--pill{ padding:8px 15px; font-size:10px; line-height:13px; }
  .fhero__h1{
    margin-top:26px;
    /* 140/1440 = 9.7vw, opened up because the measure is much narrower */
    font-size:clamp(42px, 13.2vw, 118px);
    line-height:.94; letter-spacing:-.03em;
  }
  .fhero__sub{ margin-top:22px; width:min(440px, 100%); font-size:16px; line-height:1.55; }
  .fhero__actions{ margin-top:30px; flex-direction:column; align-items:stretch; gap:12px; width:min(340px, 100%); }
  .sbtn--white, .sbtn--outline{
    height:56px; justify-content:center; padding:0 10px 0 24px; font-size:16px;
    box-shadow:0 5px 0 var(--ink);
  }
  .sbtn--outline{ padding:0 24px; box-shadow:inset 0 0 0 2px #fff; }
  .sbtn--white .sbtn__knob{ width:40px; height:40px; font-size:17px; }
  .fhero__trust{ margin-top:26px; font-size:10px; line-height:13px; }

  /* Faces: the wrapper is always the img's ROTATED bbox (n x 1.144), which
     is why the two numbers are not the same. The bottom pair is deliberately
     LARGER than the top pair — it has to fill the band under the type block,
     which is much deeper on a tall phone than it is in the 1440 comp. */
  .fface{ width:52vw; height:52vw; }
  .fface__img{ width:45vw; height:45vw; }
  .fface--1, .fface--2{ width:40vw; height:40vw; }
  .fface--1 .fface__img, .fface--2 .fface__img{ width:35vw; height:35vw; }
  .fface--1{ left:-13vw;  top:5vh;  }
  .fface--2{ left:auto; right:-13vw; top:3vh; }
  .fface--3{ left:-15vw;  top:auto; bottom:-2vw; }  /* compact is unaffected */
  .fface--4{ left:auto; right:-15vw; top:auto; bottom:-5vw; }

  /* Four chips, not six — at this width the middle pair collides with the
     headline, and a chip that overlaps type stops reading as a sticker.

     The eyebrow pill is centred and ~200 wide, i.e. it spans most of a 390
     frame, so the two surviving top chips have to clear it VERTICALLY: both
     live entirely in the 96px band between the nav and the eyebrow. */
  .fchip__pill{ padding:9px 15px; font-size:14px;
                box-shadow:0 4px 0 var(--ink), inset 0 0 0 2px var(--ink); }
  .chip--lg, .fchip--lg{ font-size:14px; }
  .chip--caps, .fchip--caps{ font-size:13px; }
  /* 2026-10-02 (user's Figma F02 edit): the two TOP faces are gone — they
     collided with the nav and the headline — and the two speech chips now sit
     with the BOTTOM faces, anchored to the hero's bottom edge like the faces. */
  .fface--1, .fface--2{ display:none; }
  .fchip--1{ left:28.7vw; top:auto; bottom:80px; }   /* the wrapper is centred (translate -50%), so these are chip CENTRES */
  .fchip--2{ left:68.7vw; right:auto; top:auto; bottom:25px; }
  /* the Figma tilts flip on mobile (they lean into their faces) */
  .fchip--1 .fchip__pill{ --rot:-8deg !important; }
  .fchip--2 .fchip__pill{ --rot:9deg !important; }
  .fchip--3,
  .fchip--4{ display:none; }
  .fchip--5{ left:20vw; top:auto; bottom:11vh; }
  .fchip--6{ left:auto; right:10vw; top:auto; bottom:6vh; }

  /* ── sections 02-11 ──────────────────────────────────────
     Every section below the hero is a fixed height with absolutely placed
     children at 1440, because there the COMPOSITION is the design. Here they
     all become ordinary flow columns. Nothing is scaled: --s is floored at
     0.7222, so comp numbers stop shrinking below 1040 and every large one
     has to be re-expressed.
     ------------------------------------------------------- */
  .sec{ height:auto; padding:64px 22px 72px; }

  /* the shared header pairing collapses to a single column */
  .sh, .sh2, .slead{ position:static; left:auto; top:auto; width:auto; }
  .sh2{
    margin:18px 0 0;
    font-size:clamp(34px, 9.2vw, 62px);
    line-height:.96; letter-spacing:-.025em;
  }
  .slead{ margin:20px 0 0; max-width:46ch; font-size:16px; line-height:1.62; }
  .what__h2{ font-size:clamp(36px, 10vw, 68px); }
  .eyebrow--pink{ padding:8px 15px; }

  /* 02 / Ticker */
  .tick{ height:64px; }
  .tick__row{ gap:16px; font-size:19px; }
  .tick__dot{ width:7px; height:7px; }

  /* 03 / What is FRND — the deal AND the pin stand down here (see frnd.js);
     the cards become an ordinary stack, two-up as soon as there is room. */
  .what{ position:static; }
  .what-stage::after{ display:none; }
  .what__chip{ position:static; transform:none; margin:22px 0 0; }
  .what__more{ position:static; margin:22px 0 0; align-self:flex-start; }
  /* a horizontal snap carousel (2026-10-02): bleeds to the screen edges,
     one card + a peek of the next, the tilt kept */
  .fcards{ position:static; inset:auto; display:flex; gap:16px; margin:40px -22px 0;
           padding:14px 22px 22px; overflow-x:auto; overscroll-behavior-x:contain;
           scroll-snap-type:x mandatory; scroll-padding-inline:22px; scrollbar-width:none; }
  .fcards::-webkit-scrollbar{ display:none; }
  .fcard{ position:static; flex:0 0 76%; max-width:320px; width:auto; transform:rotate(var(--wrot)); scroll-snap-align:start; }
  .fcard__inner{ height:auto; min-height:400px; padding:20px; border-radius:26px; }
  .fcard__plate{ height:0; padding-bottom:71.8%; border-radius:16px; position:relative; }
  .fcard__plate img{ position:absolute; inset:0; }
  .fcard__copy{ gap:12px; margin-top:22px; }
  .fcard__title{ font-size:24px; }
  .fcard__body{ font-size:14.5px; }

  /* 04 / Numbers — 2 x 2, because four 96px numerals will not sit in a row */
  .nums__asof{ position:static; margin:14px 0 0; }
  .nums__rule{ position:static; width:100%; height:2px; margin:26px 0 0; }
  .nums__row{ position:static; width:auto; margin:32px 0 0;
              display:grid; grid-template-columns:1fr 1fr; gap:34px 20px; }
  .stat{ gap:10px; }
  .stat__n{ font-size:clamp(48px, 15vw, 88px); }

  /* 05 / Mission & Vision */
  .miss__cards{ display:flex; flex-direction:column; gap:26px; margin-top:40px; position:relative; }
  .mcard{ position:static; width:auto; height:auto; padding:26px 24px; border-radius:26px; }
  .mcard__p{ font-size:clamp(21px, 5.6vw, 30px); }
  /* the seal moves onto the seam BETWEEN the stacked cards */
  .seal{ left:50%; top:50%; }

  /* 06 / Languages — one wrapping row, not two tilted ones. Eleven pills at
     34px cannot fit two rows at this width, and a tilted flex row that wraps
     collides with itself. */
  .langs__rows{ margin-top:36px; }
  /* keep the tilt — it is the section's whole character. Rotation is applied
     AFTER wrapping is computed, so a wrapping row can still be tilted safely;
     at 0.7deg on a 346-wide block the corners move ~1.5px. */
  .lrow{
    position:static;
    flex-wrap:wrap; justify-content:flex-start;
    gap:12px;
  }
  .lrow--1{ transform:rotate(-0.7deg); }
  .lrow--2{ transform:rotate(0.7deg); margin-top:14px; }
  .lpill{ padding:12px 20px; font-size:clamp(18px, 5.4vw, 26px); --ledge:5; --stroke:2; }

  /* 07 / Journey */
  .jour__grid{ display:grid; gap:22px; margin-top:40px; }
  .ycard{ position:static; width:auto; transform:rotate(var(--wrot)); }
  .ycard__in{ height:auto; min-height:0; padding:22px; border-radius:24px; gap:26px; }
  .ycard{ opacity:1; }
  .jrail, .jtick{ display:none; }   /* the timeline is a desktop gesture */
  .ycard__y{ font-size:40px; }

  /* 08 / AI & Safety */
  .ai__cards{ display:grid; gap:24px; margin-top:40px; }
  .acard{ position:static; width:auto; padding:14px 14px 22px; border-radius:26px; gap:14px; --ledge:7; }
  .acard__plate{ border-radius:18px; }
  .acard__copy{ padding:0 8px; }
  .acard__t{ font-size:26px; }
  .acard__b{ font-size:14.5px; }
  .ai__more{ position:static; margin-top:36px; }

  /* 09 / Backed by */
  .inv__plates{ display:grid; gap:18px; margin-top:40px; }
  .iplate{ position:static; width:auto; transform:rotate(var(--wrot)); }
  .iplate__in{ height:128px; border-radius:20px; gap:10px; --ledge:6; --stroke:2; }
  .iplate__logo--iq{ height:48px; } .iplate__logo--el{ height:26px; } .iplate__logo--kr{ height:50px; }
  .iplate__name{ font-size:10px; }

  /* 10 / Download */
  .dl{ padding-bottom:26vh; text-align:center; }
  .dl__eyebrow{ position:static; }
  /* 8.2vw, not 9.4: at 9.4 "Somebody out there is" runs ~380px in a 346
     column and wraps one word onto its own line, which breaks the phrase. */
  .dl__h1{ position:static; margin:18px 0 0; font-size:clamp(30px, 8.2vw, 64px); line-height:.98; }
  .dl__sub{ position:static; margin:18px 0 0; font-size:17px; }
  .dl__stores{ position:static; margin:28px 0 0; flex-direction:column; align-items:stretch; gap:12px; }
  .store{ justify-content:center; padding:13px 24px; }
  .dl__chips{ display:flex; flex-wrap:wrap; justify-content:center; gap:12px; margin-top:30px; }
  .dl__chips .fchip{ position:static; transform:none; }
  /* the two people anchor the bottom, the way the hero's bottom pair does */
  .dperson{ width:46vw; height:46vw; top:auto; bottom:0; }
  .dperson img{ width:34vw; height:65vw; }
  .dperson--l{ left:-11vw; }
  .dperson--r{ left:auto; right:-11vw; }

  /* 11 / Footer */
  .foot{ height:auto; padding:64px 22px 88px; }   /* ≥ the reveal observer’s 8% bottom inset */
  .fbrandcol{ position:static; gap:18px; }
  .fblurb{ width:auto; max-width:34ch; }
  .fcol{ position:static; }
  .foot__cols{ display:grid; grid-template-columns:1fr 1fr; gap:32px 20px; margin-top:40px; }
  .foot__rule{ position:static; width:100%; margin:36px 0 0; }
  .flegal{ position:static; margin:18px 0 0; }
  .flegal--r{ margin-top:6px; }
  /* 🔴 --s is floored, so calc(547 * var(--s)) is still 395px on a 390 phone.
     Anything sized off the comp's large numbers must go to viewport units:
     547/1440 = 38vw. */
  .fbrandcol .fbrand__logo{ height:44px; }

  @media (min-width:700px){
    .jour__grid{ grid-template-columns:1fr 1fr; }
    .inv__plates{ grid-template-columns:1fr 1fr; }
    .miss__cards{ flex-direction:row; }
    .mcard{ flex:1 1 0; }
    .dl__stores{ flex-direction:row; justify-content:center; }
  }
}


/* Landscape phones: the hero has no vertical room for a 100svh stack. */
@media (max-width:1040px) and (max-height:520px){
  .fhero{ min-height:auto; padding:0 0 8vh; }
  .fhero__content{ padding-top:96px; }
  .fhero__h1{ font-size:clamp(38px, 8vw, 72px); }
  .fface{ display:none; }
  .fchip{ display:none; }
}

/* ============================================================
   Reduced motion — the choreography is decoration, so it goes. The page
   arrives fully formed instead.
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .js .fhero__ground,
  .js .pop, .js .pstrip, .js .fnav__pill, .js .fnav__pill > *{
    opacity:1 !important; transform:none !important; transition:none !important;
  }
  .js .fface__img{ opacity:1 !important; transform:rotate(var(--rot)) !important; transition:none !important; }
  .js .fchip__pill{ opacity:1 !important; transform:rotate(var(--rot)) !important; transition:none !important; }
}

/* ============================================================
   Mobile hamburger + drawer (2026-10-02) — like the Interact page:
   ≤1040 the bar is brand + hamburger; all links AND Download App
   move into the drawer.
   ============================================================ */
.fnav__toggle{ display:none; }
.fdrawer{ display:none; }
/* real store glyphs inside the dark tile */
.store__i{ display:inline-flex; align-items:center; justify-content:center; }
.store__svg{ width:58%; height:58%; display:block; }
@media (max-width:1040px){
  .fnav__cta{ display:none; }
  .fnav__toggle{
    display:flex; flex-direction:column; justify-content:center; align-items:center; gap:4px;
    width:42px; height:42px; border-radius:21px; border:0; cursor:pointer;
    background:var(--ink); padding:0;
  }
  .fnav.is-stuck .fnav__toggle{ width:34px; height:34px; }
  .fnav__toggle span{ display:block; width:16px; height:2px; border-radius:2px; background:#fff;
    transition:transform .35s var(--ease), opacity .2s; }
  html.is-menu .fnav__toggle span:nth-child(1){ transform:translateY(6px) rotate(45deg); }
  html.is-menu .fnav__toggle span:nth-child(2){ opacity:0; }
  html.is-menu .fnav__toggle span:nth-child(3){ transform:translateY(-6px) rotate(-45deg); }
  .fnav__pill{ justify-content:space-between; }

  .fdrawer{
    position:fixed; inset:0; z-index:90;
    display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:28px;
    padding:120px 28px 48px;
    background:var(--pink);
    opacity:0; transition:opacity .3s var(--ease);
  }
  .fdrawer[hidden]{ display:none; }
  html.is-menu .fdrawer{ opacity:1; }
  html.is-menu{ overflow:hidden; }
  html.is-menu .fnav{ transform:none !important; z-index:100; }
  .fdrawer__links{ display:flex; flex-direction:column; gap:6px; }
  .fdrawer__links a{
    font-family:var(--display); font-weight:900; font-size:34px; line-height:1.15;
    letter-spacing:-.02em; color:#fff;
    opacity:0; transform:translateY(14px);
    transition:opacity .4s var(--ease), transform .5s var(--ease);
  }
  .fdrawer__links a[aria-current="page"]{ color:var(--ink); }
  html.is-menu .fdrawer__links a{ opacity:1; transform:none; }
  html.is-menu .fdrawer__links a:nth-child(2){ transition-delay:.04s; }
  html.is-menu .fdrawer__links a:nth-child(3){ transition-delay:.08s; }
  html.is-menu .fdrawer__links a:nth-child(4){ transition-delay:.12s; }
  html.is-menu .fdrawer__links a:nth-child(5){ transition-delay:.16s; }
  html.is-menu .fdrawer__links a:nth-child(6){ transition-delay:.2s; }
  html.is-menu .fdrawer__links a:nth-child(7){ transition-delay:.24s; }
  .fdrawer__cta{ height:52px !important; padding:0 8px 0 22px !important; font-size:15px !important;
    box-shadow:0 5px 0 var(--ink), inset 0 0 0 2px #fff; }
}

/* What is FRND — carousel pagination (mobile only, 2026-10-02) */
.fcards__dots{ display:none; }
@media (max-width:1040px){
  .fcards__dots{ display:flex; justify-content:center; gap:8px; margin-top:6px; }
  .fcards__dots i{ width:8px; height:8px; border-radius:4px; background:rgba(23,17,15,.22); transition:width .3s var(--ease), background .3s; }
  .fcards__dots i.is-on{ width:24px; background:var(--pink); }

  /* 07 / Journey — the stack gets a vertical timeline: a rail down the left,
     a pink dot per card, and the cards set in from it */
  .jour__grid{ position:relative; padding-left:30px; }
  .jour__grid::before{ content:''; position:absolute; left:8px; top:6px; bottom:6px; width:3px; border-radius:2px;
    background:linear-gradient(180deg, var(--pink), rgba(255,62,132,.25)); }
  .ycard{ position:relative; left:auto !important; top:auto !important; }
  .ycard::before{ content:''; position:absolute; left:-29px; top:30px; width:15px; height:15px; border-radius:50%;
    background:var(--pink); box-shadow:0 0 0 4px var(--page); z-index:2; }
}

/* TAP TARGETS (audit 2026-10-02): footer links were 17px tall and the parent
   strip 12px on a phone. Padding grows the hit area; the equal negative margin
   keeps the layout exactly where it was. */
@media (max-width:1040px){
  .fcol a{ display:inline-block; padding:7px 0; margin:-7px 0; }
  .pstrip__back{ padding:10px 0; margin:-10px 0; }
}

/* ============================================================
   10 / FAQ   (Figma "10 / FAQ" 1295:2 desktop / 1295:28 mobile)

   Sits between Backed by and Download, so the ground rhythm runs
   ink (AI & Safety) → cream (Backed by) → INK → pink (Download).

   The only section on this page that is not a fixed-height
   composition: an accordion's height depends on which row is
   open, so it flows. The eyebrow and the two-tone H2 are the
   page's standard pairing, just not absolutely placed.
   The rows themselves are the shared atom in frnd-faq.css.
   ============================================================ */
.lfaq{ padding:calc(92 * var(--s)) calc(100 * var(--s)) calc(120 * var(--s)); }
.lfaq__h2{
  margin:calc(26 * var(--s)) 0 calc(86 * var(--s));
  font-family:var(--display); font-weight:900;
  font-size:calc(76 * var(--s)); line-height:.94; letter-spacing:-.03em;
  color:#fff;
}
.lfaq__h2 .line{ display:block; }
.lfaq__h2 .line--pink{ color:var(--pink); }

@media (max-width:1040px){
  .lfaq{ padding:56px 22px 64px; }
  .lfaq__h2{ margin:16px 0 28px; font-size:clamp(30px, 10vw, 38px); }
}

/* A footer entry that is NOT a link yet. The blog lives on the old site and
   will not exist at launch, so it stays in the column as a label — present,
   greyed, and not clickable — rather than sending people somewhere that is
   about to 404. Same device as the Interact footer's `.foot__soon`. */
.fcol span.fcol__soon{
  display:inline-block;
  font-weight:500; letter-spacing:-.01em;
  color:rgba(255,255,255,.38);
  cursor:default;
}
@media (max-width:1040px){
  .fcol span.fcol__soon{ padding:7px 0; margin:-7px 0; }
}
