/* Registered so it computes to a real length: an unregistered custom
   property defined with calc() comes back from getComputedStyle unresolved,
   and parseFloat on "calc(...)" is NaN. The wave reads this in JS. */
@property --wave-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@property --wave-spread {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@property --wave-weight {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@property --band-y {
  syntax: '<length>';
  inherits: true;
  initial-value: 0px;
}
/* ============================================================
   WYVE — wyvedrink.com

   Ground is sky and only sky.
   WAVE RULE: a wave only appears composed with content — behind or around
   a can, framing type, anchoring a block. Never a band on its own between
   two sections. Section separation comes from spacing, not from ink.
   Type is #1F6583 only; hierarchy comes from weight and size.
   ============================================================ */

:root{
  --sky-top:#C6E9FA;
  --sky-mid:#E4F4FD;
  --sky-bot:#F8FBFD;

  --wave:#EF7522;
  --slate:#1F6583;
  --cola:#B3202A;
  --lime:#146C37;
  --green:#4F9D45;
  --amber:#FAB53C;
  --yellow:#FBF075;
  --brown:#592F15;
  --ink:#241300;          /* labels on orange only — 6.2:1 */
  --deep:#0E3A4D;         /* the one dark ground, on the partner block */

  /* ---- spacing scale: 4px base, used for every gap and pad ---- */
  --s1:4px;  --s2:8px;   --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px;  --s8:64px; --s9:96px; --s10:128px;
  --sec-y:clamp(72px,10vh,144px);
  /* The lockup drives the header's height, and the stage has to clear it —
     one source so the two cannot drift apart. 1.825 is the artwork's own
     aspect (280.67 / 153.79 ink units); 28px is the header's and the mark's
     own padding. */
  --lockup-w:clamp(102px,7.4vw,122px);
  --head-h:calc(var(--lockup-w) / 1.825 + 28px);
  /* The stage wave sits BEHIND the cans now, around their upper third, so it
     no longer needs a reserved strip of its own above them — that height goes
     back to the product. Only the header still has to be cleared. */
  --stage-top-gap:clamp(24px,4vh,56px);
  /* DELIBERATELY heavier than the w1-w5 set. The stage wave is the animated
     canvas, not an SVG contour, and it is scaled up here so the ink reads at
     product scale. It no longer matches the 34.5px contour weight the SVG set
     was normalised to, and #partners stays at that weight — this is intended,
     not a drift. Do not "correct" it back.
     --wave-spread is what keeps the two contours apart: at this weight the
     source spacing equals the thickness, so without it they fuse into one
     mass with a hairline seam. */
  --wave-scale:0.45;
  --wave-weight:1.7;
  --wave-spread:1.95;
  /* Wave-cut mask for the sea shot's inner edge. Opaque on the right (kept),
     transparent on the left (cut). Four broad lobes swinging roughly 8-26%
     across the width — the same slow undulation as the stage wave, not a
     decorative scallop. preserveAspectRatio=none so it stretches to whatever
     the photo's box is. */
  --wave-cut:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 1000" preserveAspectRatio="none"><path d="M100 0 H22 C6 90 34 190 20 280 C7 366 40 452 26 540 C13 624 44 706 24 792 C8 862 32 934 18 1000 H100 Z" fill="black"/></svg>');
  /* Same wave, turned for the stacked layout where the photo sits below the
     copy: the cut runs along its TOP edge. Two broad lobes, not four — across
     390px the tighter path read as bunting.
     It is a BAND of fixed height (--wave-band-h), not a mask stretched over
     the whole photo. Stretched, its depth was a percentage of the box, so a
     taller box cut deeper — at 390 it reached 35% down and took the can's
     rim and logo band off. As a band it can never go deeper than its own
     height, and the photo's crops keep the rim well below that. */
  --wave-band:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 100" preserveAspectRatio="none"><path d="M0 100 V72 C170 6 340 98 500 50 C660 2 840 94 1000 41 V100 Z" fill="black"/></svg>');
  /* everything under the cans: gap + caption + gap + progress + bottom pad.
     The can is whatever height is left, so the stack can never overflow. */
  --stack-below:clamp(244px,27.5vh,278px);
  --wrap:clamp(20px,5vw,72px);
  /* pull an element from the centred wrap out to the viewport edge.
     `calc(50% - 50vw)` cannot be used here: inside a grid item the 50%
     resolves against the grid AREA, not the container, which overshot the
     right edge by 511px at 1440 and put the can entirely off-screen. */
  --bleed-r:calc((100vw - min(1180px, 100vw)) / -2 - var(--wrap));

  --t-slow:900ms;
  --t-mid:520ms;
  --t-fast:260ms;
  --ease:cubic-bezier(.22,.61,.36,1);
}

/* every section restarts the gradient, so contrast never drifts with
   scroll position. Worst case is the top band: #1F6583 on #C6E9FA = 5.06:1 */
.stage,.sec,.foot{
  background-image:linear-gradient(180deg,
    var(--sky-top) 0%, var(--sky-mid) 52%, var(--sky-bot) 100%);
}

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

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:96px;
}
body{
  margin:0;
  font-family:Poppins,system-ui,-apple-system,"Segoe UI",sans-serif;
  font-weight:400;
  color:var(--slate);
  background:var(--sky-bot);
  line-height:1.55;
  overflow-x:hidden;
}
img{max-width:100%;height:auto;display:block}
h1,h2,h3{margin:0;line-height:1.05;letter-spacing:-.02em;font-weight:700}
p{margin:0}

:where(a,button,input,summary):focus-visible{
  outline:3px solid var(--slate);
  outline-offset:3px;
  border-radius:4px;
}
.dark :where(a,button,input):focus-visible{outline-color:var(--sky-top)}

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

.wrap{
  max-width:1180px;
  margin-inline:auto;
  padding-inline:var(--wrap);
  position:relative;
  z-index:2;                      /* copy always above wave ink */
}
.wrap--narrow{max-width:760px}

.skip{
  position:absolute;left:-9999px;top:0;
  background:var(--slate);color:#fff;
  padding:14px 20px;z-index:200;font-weight:700;
}
.skip:focus{left:12px;top:12px}

/* ---------- placeholders: deliberately loud ---------- */
.placeholder{
  display:inline-block;
  font-size:.78rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;
  color:var(--slate);
  border:2px dashed var(--wave);
  padding:var(--s2) var(--s3);
  margin-top:var(--s4);
  background:rgba(255,255,255,.55);
}
.placeholder::before{content:"placeholder · " attr(data-ph) " · "}
.placeholder--block{display:block}

/* ============================================================
   PRELOADER — the counter is the largest paint, by design
   ============================================================ */
.preloader{
  position:fixed;inset:0;z-index:150;display:none;place-items:center;
  background-image:linear-gradient(180deg,var(--sky-top) 0%,var(--sky-mid) 52%,var(--sky-bot) 100%);
}
.preloader.is-on{display:grid}
.preloader.is-done{opacity:0;pointer-events:none;transition:opacity var(--t-mid) var(--ease)}
.preloader__inner{text-align:center;padding:var(--wrap)}
.preloader__count{
  font-weight:900;font-size:clamp(5rem,22vw,16rem);
  line-height:.9;letter-spacing:-.05em;
  color:var(--slate);font-variant-numeric:tabular-nums;
}
.preloader__pct{font-size:.32em;vertical-align:super;font-weight:700}
.preloader__rule{width:min(420px,72vw);height:4px;margin:var(--s6) auto 0;background:rgba(31,101,131,.18)}
.preloader__bar{display:block;height:100%;width:0%;background:var(--wave);transition:width 180ms linear}

/* ============================================================
   HEADER + OVERLAY MENU
   ============================================================ */
.head{
  position:fixed;top:0;left:0;right:0;z-index:120;
  display:flex;align-items:center;justify-content:space-between;
  padding:10px var(--wrap);
  pointer-events:none;background:transparent;
  transition:background-color var(--t-mid) var(--ease);
}
.head.is-stuck{background-color:var(--sky-top);box-shadow:0 1px 0 rgba(31,101,131,.16)}
/* over the dark partner block the sky bar cut a pale strip across the
   moment of arrival — invert it so the block arrives whole */
.head.is-invert.is-stuck{background-color:var(--deep);box-shadow:0 1px 0 rgba(198,233,250,.2)}
.head.is-invert .menu-btn{color:var(--sky-bot);background:rgba(255,255,255,.06);border-color:var(--sky-top)}
.head.is-invert .menu-btn__bars i{background:var(--sky-bot)}
.head > *{pointer-events:auto}

/* The lockup is permanent now, not something that appears once the stage has
   gone — it is the page's only painted identity. */
.head__mark{
  padding:4px;min-height:44px;display:grid;place-items:center;
}
.lockup{
  display:block;
  width:var(--lockup-w);
  height:auto;
}
/* Three inked groups, three channels. The header inverts over #partners, and
   slate strapline on #0E3A4D measures 1.88:1 — invisible — so the strapline
   is driven by a property and lifted to sky-top (9.50:1) in that state.
   The drawn wordmark stays orange in both: 4.18:1 on the dark ground, which
   is fine for a mark at this size. */
.lockup__mark {fill:var(--lk-mark,  var(--wave))}
.lockup__strap{fill:var(--lk-strap, var(--slate))}
.lockup__desc {fill:var(--lk-desc,  var(--wave))}
.head.is-invert{--lk-strap:#C6E9FA}

/* ---------- header nav ----------
   Same bar height as before: every item is a 44px target inside the
   existing padding, so the links add width, never height. Pairs:
     on the sky bar   : links #1F6583 5.06:1 · CTA #F8FBFD on #1F6583 6.22:1
     inverted (#0E3A4D): links #F8FBFD 11.67:1 · CTA #241300 on #FAB53C 10.05:1 */
.head__nav{margin-left:auto;margin-right:var(--s4)}
.head__links{list-style:none;margin:0;padding:0;display:flex;gap:var(--s1)}
.head__links a{
  display:inline-flex;align-items:center;min-height:44px;padding:0 10px;
  font-weight:600;font-size:.8rem;letter-spacing:.02em;color:var(--slate);text-decoration:none;
  border-radius:6px;
}
.head__links a:hover{text-decoration:underline;text-underline-offset:6px}
.head__links a[aria-current="true"]{font-weight:800;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:6px}
.head__right{display:flex;align-items:center;gap:var(--s2)}
.head__cta{
  display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s4);
  font-weight:700;font-size:.76rem;letter-spacing:.06em;text-transform:uppercase;text-decoration:none;white-space:nowrap;
  color:var(--sky-bot);background:var(--slate);border-radius:999px;
}
.head__cta:hover{background:var(--deep)}
.head__cta-short{display:none}
/* colours fade with the bar (same duration as its background), so text and
   ground never pass through a low-contrast pair when the header inverts */
.head__links a,.head__cta,.menu-btn,.menu-btn__bars i{transition:color var(--t-mid) var(--ease),background-color var(--t-mid) var(--ease),border-color var(--t-mid) var(--ease)}
.head.is-invert .head__links a{color:var(--sky-bot)}
.head.is-invert .head__cta{color:var(--ink);background:var(--amber)}
.head.is-invert .head__cta:hover{background:var(--yellow)}
.head.is-invert :where(.head__links a,.head__cta):focus-visible{outline-color:var(--sky-top)}
@media (max-width:899px){.head__nav{display:none}.head__right{margin-left:auto}}
@media (max-width:520px){.head__cta-long{display:none}.head__cta-short{display:inline}.head__cta{padding:0 14px}}
.menu-btn{
  display:inline-flex;align-items:center;gap:8px;
  /* the pill was oversized for what it does. Type and padding come down;
     min-height stays at 44px so the touch target does not. */
  min-height:44px;padding:6px 14px;
  font:inherit;font-weight:700;font-size:.76rem;
  letter-spacing:.08em;text-transform:uppercase;
  color:var(--slate);background:rgba(255,255,255,.7);
  border:2px solid var(--slate);border-radius:999px;cursor:pointer;
}
.menu-btn__bars{display:grid;gap:3px}
.menu-btn__bars i{display:block;width:15px;height:2px;background:var(--slate)}
.menu-btn[aria-expanded="true"]{background:var(--slate);color:var(--sky-bot)}
.menu-btn[aria-expanded="true"] i{background:var(--sky-bot)}

.menu{
  position:fixed;inset:0;z-index:110;display:grid;place-items:center;
  background-image:linear-gradient(180deg,var(--sky-top) 0%,var(--sky-mid) 52%,var(--sky-bot) 100%);
}
.menu[hidden]{display:none}
.menu__list{list-style:none;margin:0;padding:var(--wrap);text-align:center}
.menu__list a{
  display:block;padding:10px 4px;min-height:44px;
  font-weight:900;font-size:clamp(1.6rem,6vw,3rem);
  letter-spacing:-.03em;color:var(--slate);text-decoration:none;
}
.menu__list a:hover{color:var(--cola)}

/* ============================================================
   WAVES — composed with content only
   Measured ink bounds (getBBox):
     w1 y 0–685/1080 · w2 y 392–1084 · w3 full frame
     w4 x 0–1237/1564 · w5 y 0–535/1080
   Contour thickness is constant relative to artboard width, so the artboard
   is never rescaled and never cropped horizontally — only the empty part of
   the canvas is trimmed, vertically. Anything else changes the line weight.
   ============================================================ */
.wave-behind{
  position:absolute;
  pointer-events:none;
  overflow:hidden;
  z-index:0;
}
.wave-behind .wavelayer{position:absolute;left:0;right:0;bottom:0}
.wave-behind svg{display:block;width:100%;height:auto}
.wave-behind path,.wave-behind polygon{fill:var(--wave)}

/* drift: each band moves along its own flow at its own speed */
@keyframes drift{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(var(--dx,26px),var(--dy,0),0)}
}
.wave-behind path,.wave-behind polygon{
  animation:drift var(--dur,14s) var(--ease) infinite alternate;
  animation-delay:var(--del,0s);
  will-change:transform;
}

/* ============================================================
   FLAVOUR STAGE — pinned, scroll-driven
   ============================================================ */
.stage-pin{
  position:relative;
  height:300vh;              /* the scroll distance the fan is mapped onto */
}
.stage{
  position:sticky;top:0;
  height:100svh;
  /* as large as the budget allows, never larger: viewport minus the header,
     the wave strip and the caption stack. */
  --can-h:clamp(190px, calc(100svh - var(--head-h) - var(--stage-top-gap) - var(--stack-below)), 620px);
  --cw:calc(var(--can-h) * .3812);      /* 1092/2864 from the source render */
  --rx-mult:2.45;      /* ellipse radius, in can-widths. Plain number, not a
                          calc(): getComputedStyle returns a custom property
                          unresolved, so a calc() here would parse as NaN. */
  /* Only the header has to be cleared now. The wave sits behind the cans
     rather than above them, so it takes no vertical budget of its own and
     the product gets that height back. */
  padding:calc(var(--head-h) + var(--stage-top-gap)) 0 calc(var(--s5) + 52px);
  display:grid;
  grid-template-rows:1fr auto auto;
  justify-items:center;
  gap:var(--s4);
  overflow:hidden;
  isolation:isolate;
}

/* the stage wave is composed WITH the fan: ink passes behind the cans and
   is cropped by both side edges. Not a separator. */


/* ---------- the carousel ---------- */
.fan{
  position:relative;z-index:3;
  width:100%;
  /* the group stands low in the stage so the wave has an upper band to run
     through above the can tops, rather than being forced across them */
  align-self:center;
  display:grid;place-items:center;
  min-height:var(--can-h);
}
.fan__ring{
  position:absolute;inset:0;
  display:grid;place-items:center;
  pointer-events:none;
}

/* Every can is positioned by JS from one shared angle: transform, opacity,
   filter and z-index are written each frame. Nothing here encodes a slot,
   because there are no slots — the ring rotates as a whole.
   Strictly 2D. No rotateY, no perspective: these are orthographic renders
   and a 3D turn would read as a playing card rather than a cylinder. */
.can{
  position:absolute;
  height:var(--can-h);
  width:auto;
  transform-origin:50% 60%;
  will-change:transform,opacity,filter;
  backface-visibility:hidden;
}
/* pre-paint fallback: before the first frame runs, show only the front can
   so nothing flashes as a nine-can pile */
.can:not([data-placed]){opacity:0}
.can[data-i="0"]:not([data-placed]){opacity:1}

/* ---------- phase two: the side panel, zoomed ----------
   The ring is the browse; this is the reward for holding the scroll. The
   front can turns to its side panel and grows until the printed fun fact
   is readable. Scroll drives it in both directions. */
/* Group on the left, text in a right-hand column. The three cans overlap
   front-to-back at deliberately uneven offsets and baselines — an even row
   on a shared baseline reads as a product shot, not as three cans put down
   together. No blur and no falloff: this is a group standing together, not
   a receding ring. */
.zoom{
  position:absolute;inset:0;
  display:grid;
  align-content:center;
  justify-items:center;
  padding:12vh min(46%,560px) 12vh var(--wrap);
  pointer-events:none;
  opacity:0;
  z-index:1200;
  --zoom-h:min(58vh, 38vw);
}
.zoom__row{
  position:relative;
  height:var(--zoom-h);
  width:calc(var(--zoom-h) * .3812 * 2.25);   /* group span, in can widths */
  will-change:transform;
}
/* one connected pool under the whole group — three separate ellipses read as
   three objects; a single pool is what makes them one */
.zoom__row::after{
  content:"";position:absolute;
  left:50%;bottom:-3%;
  width:116%;height:7%;
  transform:translateX(-50%);
  background:radial-gradient(ellipse at center,rgba(31,101,131,.26) 0%,rgba(31,101,131,.13) 46%,rgba(31,101,131,0) 72%);
}
.zoom__slot{
  position:absolute;
  left:50%;bottom:0;
  transform-origin:50% 100%;
  transform:
    translateX(-50%)
    translate(var(--zx,0px), var(--zy,0px))
    rotate(var(--zr,0deg))
    scale(var(--zs,1));
  z-index:var(--zz,1);
}
.zoom__can{
  display:block;
  height:var(--zoom-h);width:auto;
  /* each can casts onto whatever sits behind it, which is the contact
     shadow that makes the overlap read as depth */
  filter:drop-shadow(-14px 10px 16px rgba(31,101,131,.30));
}
/* ---------- the fun fact, as real text ---------- */
/* The group overlaps rather than lining up, so the right-hand column is
   free again — the text sits beside the cans, not under them. */
.funfact{
  position:absolute;
  right:var(--wrap);
  top:50%;
  transform:translateY(-50%);
  width:min(420px, 38vw);
  z-index:1300;
  opacity:0;
  pointer-events:none;
  text-align:left;
}
.funfact__k{
  font-size:.72rem;font-weight:700;
  letter-spacing:.3em;text-transform:uppercase;
  color:var(--slate);
}
.funfact__list{
  list-style:none;margin:var(--s3) 0 0;padding:0;
  display:grid;gap:var(--s1);
}
.funfact__list li{
  font-weight:700;
  font-size:clamp(1rem,2.2vw,1.45rem);
  color:var(--slate);letter-spacing:-.01em;
}
.funfact__badges{
  list-style:none;margin:var(--s4) 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:var(--s2);
}
.funfact__badges li{
  font-size:.7rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--slate);
  border:2px solid rgba(31,101,131,.32);
  border-radius:999px;
  padding:5px 12px;
}

/* soft elliptical ground shadow, no hard floor line */
.fan::after{
  content:"";position:absolute;
  left:50%;top:calc(50% + var(--can-h) * .47);
  width:calc(var(--cw) * 6.2);height:calc(var(--can-h) * .07);
  transform:translate(-50%,-50%);
  background:radial-gradient(ellipse at center,rgba(31,101,131,.18) 0%,rgba(31,101,131,0) 70%);
  pointer-events:none;z-index:1;
}

.fan__scroll{
  position:absolute;inset:0;z-index:40;
  display:none;                       /* touch only — enabled below */
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
  touch-action:pan-x;overscroll-behavior-x:contain;
}
.fan__scroll::-webkit-scrollbar{display:none}
.fan__scroll i{flex:0 0 100%;scroll-snap-align:center}

/* ---------- flavour copy ---------- */
.stage__copy{
  position:relative;z-index:4;
  display:grid;padding-inline:var(--wrap);text-align:center;
}
/* staggered, not crossfaded: two captions sharing one grid cell at partial
   opacity read as a double exposure */
.fcopy{
  grid-area:1/1;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity 170ms var(--ease),transform 170ms var(--ease),visibility 170ms;
}
.fcopy.is-on{opacity:1;visibility:visible;transform:none;transition-delay:180ms}
.fcopy__name{
  font-weight:900;font-size:clamp(1.8rem,5.4vw,3.4rem);
  color:var(--slate);letter-spacing:-.035em;
}
.fcopy__line{margin-top:var(--s2);font-weight:500;font-size:clamp(.95rem,2.2vw,1.2rem);color:var(--slate)}

/* ---------- progress indicator, which is also the control ---------- */
.prog{position:relative;z-index:4;display:flex;gap:var(--s2);padding-inline:var(--wrap)}
.prog__seg{
  min-width:56px;min-height:44px;
  display:grid;align-items:center;
  padding:0;border:0;background:none;cursor:pointer;
}
.prog__seg i{
  display:block;height:3px;border-radius:2px;
  /* the bar reflects real scroll position, not just which segment is active */
  background:linear-gradient(to right,var(--slate) calc(var(--fill,0) * 100%),rgba(31,101,131,.26) 0);
  transition:height var(--t-fast) var(--ease);
}
.prog__seg:hover i{background:rgba(31,101,131,.5)}
.prog__seg[aria-current="true"] i{background:var(--slate);height:5px}

/* Pulled out of the grid flow: it is decorative and aria-hidden, and as a
   fourth row it was taking ~70px of height away from the product. */
.cue{
  position:absolute;left:0;right:0;bottom:var(--s3);z-index:4;
  display:grid;justify-items:center;gap:var(--s1);
  font-size:.66rem;font-weight:700;letter-spacing:.28em;text-transform:uppercase;
  color:var(--slate);
}
.cue i{display:block;width:1px;height:26px;background:rgba(31,101,131,.42)}

/* ============================================================
   GENERIC SECTION
   ============================================================ */
.sec{position:relative;padding:var(--sec-y) 0;overflow:hidden;isolation:isolate}
.eyebrow{
  font-size:.8rem;font-weight:700;letter-spacing:.22em;text-transform:uppercase;
  color:var(--slate);margin-bottom:var(--s4);
}
.sec__title{
  font-weight:900;letter-spacing:-.035em;color:var(--slate);
  font-size:clamp(1.9rem,6vw,3.7rem);max-width:20ch;
}
/* the page had one heading size everywhere; section heads now sit clearly
   below the flavour name and the reveal figures */
.sec__title--sm{font-size:clamp(1.45rem,3.4vw,2.3rem);max-width:22ch}

/* ============================================================
   CROSSED OUT
   Each pair is bound: almost no space between the struck word and its
   replacement, a lot between pairs. It should read as a correction.
   ============================================================ */
/* copy left, photo full-bleed right. Named areas so the mobile reorder is
   a one-line change rather than a source reshuffle. */
.no-grid{
  display:grid;gap:var(--s6);align-items:center;
  grid-template-columns:minmax(0,1fr) minmax(0,46%);
  grid-template-areas:"copy shot";
}
/* One block, one composition with the photo. The headline is sized to fill
   the copy column (so the column never reads empty), the two lines sit under
   it at body scale as a single paragraph. On desktop the block is pushed
   RIGHT, against the photo's wave edge, and lifted so its centre sits at the
   can's height rather than the section's middle (see --can-lift below). */
.no-copy{grid-area:copy;min-width:0;container-type:inline-size}
.no-head{
  margin:0;font-weight:900;color:var(--slate);
  /* sized to the column, not the viewport: "Catch it." is ~4.02em wide,
     so 24cqi would fill ~97% of the column; set to 18cqi (25% smaller) */
  font-size:18cqi;
  line-height:.9;letter-spacing:-.045em;
}
.no-sub{
  margin-top:var(--s4);
  font-size:clamp(1rem,2vw,1.2rem);font-weight:500;line-height:1.35;
  color:var(--slate);max-width:34ch;
}
/* the trade line: subordinate to the headline, clear space above it */
.no-trade{margin-top:var(--s7);display:grid;justify-items:start;gap:var(--s3)}
.no-trade__q{font-size:clamp(.9rem,1.6vw,1rem);font-weight:700;color:var(--slate)}
/* #F8FBFD on #1F6583: 6.22:1 */
.btn-stock{
  display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s5);
  font-weight:700;font-size:.9rem;letter-spacing:.06em;text-transform:uppercase;text-decoration:none;
  color:var(--sky-bot);background:var(--slate);border-radius:999px;
}
.btn-stock:hover{background:var(--deep)}
.btn-stock:focus-visible{outline:3px solid var(--slate);outline-offset:4px}
/* ---------- the deep-sea shot ----------
   The section becomes two columns: copy left, photo hard against the right
   viewport edge, full bleed top to bottom.

   The mask is the important part. Deep navy water butting straight onto
   #C6E9FA sky reads as a hole cut in the page; a wave-shaped inner edge
   makes it a framed image instead. Broad lobes, not a tight ripple, so it
   is recognisably the same undulation as the stage wave rather than a
   generic scallop. mask-type is luminance-free: the SVG is opaque black on
   the kept side and transparent on the cut side. */
.no-shot{
  margin:0;
  position:relative;
  grid-area:shot;
  align-self:stretch;
  /* out to the viewport edge on the right, and past the section's own
     vertical padding so it bleeds top to bottom */
  margin-right:var(--bleed-r);
  /* full bleed, top AND bottom (requested). NOTE: #partners sits directly
     below and its hairline field starts at its top edge, so this puts wave
     ink on both sides of that seam. Full bleed was requested 2026-09-24;
     the seam conflict is flagged and still open. */
  margin-block:calc(var(--sec-y) * -1);
  min-height:clamp(420px,64vh,760px);
}
.no-shot__img{
  display:block;
  width:100%;height:100%;
  object-fit:cover;
  object-position:56% 50%;      /* keeps the hand and can off the masked edge */
  -webkit-mask-image:var(--wave-cut);
          mask-image:var(--wave-cut);
  -webkit-mask-size:100% 100%;
          mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;
          mask-repeat:no-repeat;
}

/* ============================================================
   THE REVEAL — "protein is the reveal" given its literal form
   ============================================================ */
/* Can left, facts right — at every width, phones included, so the facts are
   on screen while the can turns and 10g / 0g can land on the back panel.
   Desktop: the heading sits over the facts. Phones: it spans both columns. */
.turn{
  display:grid;
  grid-template-columns:auto minmax(0,1fr);
  grid-template-areas:"stage head" "stage facts" "switch facts";
  grid-template-rows:auto 1fr auto;
  column-gap:clamp(var(--s5),6vw,var(--s10));
  row-gap:var(--s5);
  align-items:start;
}
.turn__head{grid-area:head}
.turn__stage{grid-area:stage;justify-self:center}
.turn__switch{grid-area:switch}
.turn__facts{grid-area:facts;min-width:0}
.turn__facts .figs{margin-top:0}

/* The can. A real button. */
.turn__can{
  display:block;position:relative;
  height:clamp(340px,70vh,700px);aspect-ratio:198/520;
  padding:0;border:0;background:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.turn__can:focus-visible{outline:3px solid var(--slate);outline-offset:8px;border-radius:12px}
.turn__body{
  position:absolute;inset:0;display:block;
  filter:drop-shadow(0 26px 30px rgba(31,101,131,.22));
}
/* frames stacked; 4c sets each one's opacity from the progress value */
.turn__frame{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;opacity:0}

/* flavour switcher under the can: small, but 44px targets 8px apart */
.turn__switch{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s2)}
.turn__flavour{
  min-height:44px;padding:0 var(--s4);
  font:inherit;font-size:.82rem;font-weight:700;letter-spacing:.04em;
  color:var(--slate);background:transparent;
  border:2px solid rgba(31,101,131,.28);border-radius:999px;cursor:pointer;
}
.turn__flavour[aria-pressed="true"]{border-color:var(--slate);background:rgba(31,101,131,.08)}
.turn__flavour:hover{border-color:var(--slate)}

.turn__sign{
  margin-top:var(--s5);
  font-weight:700;font-size:clamp(1rem,2.2vw,1.2rem);color:var(--slate);
}

/* Staggered reveal of the facts. Only once JS arms it (.is-armed) — with no
   JS they are simply there. Opacity only hides them from sight: they stay
   in the accessibility tree and readable from the start. */
.turn.is-armed .turn__in{opacity:0;transform:translateY(14px)}
.turn.is-armed.is-told .turn__in{
  opacity:1;transform:none;
  transition:opacity 420ms var(--ease),transform 520ms var(--ease);
  transition-delay:calc(var(--d) * 130ms);
}
.figs{margin:var(--s6) 0 0;display:grid;gap:var(--s5)}
.fig{display:grid;gap:0}
.fig__k{
  font-size:.78rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--slate);
}
/* keeps scaling past 960px — the previous cap meant the one element that
   must dominate stopped growing exactly where there was most room */
.fig__v{
  margin:0;font-weight:900;
  font-size:clamp(4.6rem,12.5vw,14rem);
  line-height:.8;letter-spacing:-.055em;color:var(--slate);
}
.fig__u{font-size:.24em;font-weight:700;margin-left:.06em;letter-spacing:0}

.minor{
  list-style:none;margin:var(--s6) 0 0;padding:var(--s4) 0 0;
  display:grid;gap:var(--s2);
  border-top:2px solid rgba(31,101,131,.2);
  max-width:46ch;
}
.minor li{font-size:clamp(.92rem,2vw,1rem);font-weight:400}
.minor span{font-weight:700}


/* ============================================================
   OUR STORY — one illustration per step
   ============================================================ */
/* The source grid is two columns; there are three steps, so it is three
   across wherever there is room and one stacked column on narrow screens.
   Explicit rather than auto-fit so it can never land on a 2 + 1 orphan. */
.story{
  list-style:none;margin:var(--s8) 0 0;padding:0;
  display:grid;gap:var(--s8);
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:781px){
  .story{grid-template-columns:repeat(3,minmax(0,1fr));column-gap:var(--s7)}
}
/* align-content:start — the list stretches every step to the tallest one's
   height, and without this the shorter steps' auto rows absorb the extra and
   push their rule 8.5px below step 1's at 1440. */
.story__step{display:grid;justify-items:start;align-content:start;gap:0}
/* The illustrations are real <button>s: hover, focus-visible and tap all
   drive the same animation. Only the section rules are taken from the source
   file — its html/body gradient, its own type scale and its 993 KB webfont
   are not ours and are not here. */
.illustration{
  display:block;position:relative;
  width:clamp(150px,17vh,210px);aspect-ratio:418/401;
  height:auto;
  padding:0;margin:0 0 var(--s5);
  border:0;background:none;color:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
/* Slate, not the source's orange: a focus ring is UI, and #EF7522 on sky is
   2.27:1 — under the 3:1 non-text minimum. Slate is 5.06:1 at worst. */
.illustration:focus-visible{
  outline:3px solid var(--slate);outline-offset:5px;border-radius:8px;
}
.illustration svg{display:block;width:100%;height:100%;overflow:visible}
/* step 3 only: orbit lines, star glow, star and hand are vector and animate;
   the can body is a raster laid over them. Same box, same viewBox origin, so they stay registered. */
.illustration--split svg{position:absolute;inset:0}
.illustration__still{
  position:relative;display:block;
  width:100%;height:100%;object-fit:contain;
  pointer-events:none;
}
/* The step number sits in the heading and takes its slate: orange type on
   sky is 2.27:1 and fails at any size. The orange stays on the rule above.
   aria-hidden, because the <ol> already announces the order. */
.story__num{font-weight:900;color:inherit}
.story__head{
  font-weight:900;font-size:clamp(1.15rem,2.8vw,1.5rem);
  letter-spacing:-.02em;text-transform:uppercase;color:var(--slate);
  padding-top:var(--s4);
  border-top:3px solid var(--wave);
  width:100%;
}
.story__body{
  margin-top:var(--s3);
  font-size:clamp(.95rem,2vw,1.03rem);
  max-width:38ch;
}
/* Sign-off. Hierarchy by weight and size only, in the one body colour. */
.story__sign{
  margin-top:var(--s8);
  font-weight:900;font-size:clamp(1.35rem,3.2vw,1.9rem);
  letter-spacing:-.02em;line-height:1.15;color:var(--slate);
}

/* ============================================================
   PARTNER ROUTE — the one dark block
   Measured on #0E3A4D:
     #F8FBFD 11.67:1 body and spec values
     #C6E9FA  9.50:1 labels and de-emphasised rows
     #FAB53C  6.78:1 figures that matter
     #EF7522  4.18:1 LARGE TEXT ONLY (>=24px)
   ============================================================ */
.dark{background-image:none;background-color:var(--deep);color:var(--sky-bot)}
.dark .eyebrow{color:var(--sky-top)}
.trade-head{position:relative}
.sec__title--trade{
  color:var(--wave);
  font-size:clamp(1.9rem,5vw,3.2rem);   /* min 30.4px — never below large-text */
  max-width:22ch;position:relative;z-index:2;
}
/* Measured on #0E3A4D: #F8FBFD 11.67:1 body, #C6E9FA 9.50:1 labels,
   #FAB53C 6.78:1 figures, #EF7522 4.18:1 LARGE TEXT ONLY. Nothing below. */
.partners__lead{
  margin-top:var(--s5);max-width:60ch;
  font-size:clamp(1rem,2.2vw,1.2rem);line-height:1.5;color:var(--sky-bot);
}
.trade__h{
  font-size:.76rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sky-top);
}
.trade__body{margin-top:var(--s3);font-size:clamp(.95rem,2vw,1.05rem);line-height:1.5;color:var(--sky-bot)}
.trade__meet{margin-top:var(--s3);font-size:clamp(.98rem,2.2vw,1.1rem);line-height:1.45;color:var(--sky-bot)}
.trade__meet b{color:var(--amber);font-weight:900}

.trade-cols{
  margin-top:var(--s8);display:grid;gap:var(--s7);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));
}
.shows{list-style:none;margin:var(--s3) 0 0;padding:0;display:grid;gap:var(--s2)}
.contact{list-style:none;margin:var(--s3) 0 0;padding:0;display:grid;gap:var(--s2)}
.shows li,.contact li{font-size:clamp(.95rem,2vw,1.05rem);color:var(--sky-bot)}
/* real touch targets: these were 20px tall inline links */
.contact li{display:flex}
.contact a{
  display:inline-flex;align-items:center;min-height:44px;
  color:var(--sky-bot);text-decoration-thickness:2px;text-underline-offset:3px;
}
.contact a:hover{color:var(--amber)}

.trade{margin-top:var(--s8);display:grid;gap:var(--s8)}
.spec-rows{margin:0;display:grid;gap:0}
.spec-row{
  display:grid;gap:var(--s1);padding:var(--s4) 0;
  border-top:1px solid rgba(198,233,250,.26);
}
.spec-row:last-child{border-bottom:1px solid rgba(198,233,250,.26)}
.spec-row dt{
  font-size:.76rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sky-top);
}
.spec-row dd{margin:0;font-size:clamp(.98rem,2.2vw,1.1rem);font-weight:500;color:var(--sky-bot)}
.spec-row dd b{color:var(--amber);font-weight:900}

.trade__cta{position:relative;display:grid;gap:var(--s3);justify-items:start}
/* #FAB53C fill, --ink label (see the pair check in the brief reply) */
.btn-wa{
  position:relative;z-index:1;
  display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s5);margin-top:var(--s2);
  font-weight:700;font-size:.92rem;letter-spacing:.04em;text-decoration:none;
  color:var(--ink);background:var(--amber);border-radius:999px;
}
.btn-wa:hover{background:var(--yellow)}
.btn-wa:focus-visible{outline:3px solid var(--sky-top);outline-offset:4px}
.routes{list-style:none;margin:var(--s2) 0 0;padding:0;display:grid;gap:0;position:relative;z-index:1}
.routes li{font-size:clamp(.95rem,2vw,1.05rem);color:var(--sky-bot)}
.routes a{display:inline-flex;align-items:center;min-height:44px;color:var(--sky-bot);text-underline-offset:4px}
.routes a:hover{color:var(--amber)}

.dark .placeholder{color:var(--sky-bot);background:rgba(255,255,255,.08);border-color:var(--wave)}

/* origin + certification: trade credibility, moved out of a consumer section */
.origin{
  margin-top:var(--s9);padding-top:var(--s6);
  border-top:1px solid rgba(198,233,250,.26);
}
/* ---------- distributor application ----------
   Copy left on the dark ground; the form in a contrasting light block.
   Pairs, all from the established set:
     on #0E3A4D  : #F8FBFD 11.67:1 body · #C6E9FA 9.50:1 eyebrow · #EF7522
                   4.18:1 headline (LARGE TEXT ONLY — min 30px here)
     on #F8FBFD  : #1F6583 6.22:1 all panel text, labels, borders, focus
     on #E4F4FD  : #1F6583 input text (inputs sit on sky-mid)
     button      : #F8FBFD on #1F6583 6.22:1
   Errors are slate bold with aria-invalid — no red enters the palette. */
.apply{margin-top:var(--s9);display:grid;gap:var(--s7);grid-template-columns:minmax(0,1fr);align-items:start}
@media (min-width:781px){.apply{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:var(--s8)}}
.apply__h{margin-top:var(--s3);font-weight:900;font-size:clamp(1.9rem,4vw,2.8rem);line-height:1.05;letter-spacing:-.03em;color:var(--wave)}
.apply__lead{margin-top:var(--s4);font-size:clamp(1rem,2vw,1.15rem);line-height:1.55;color:var(--sky-bot);max-width:44ch}
.apply__panel{background:var(--sky-bot);color:var(--slate);border-radius:16px;padding:clamp(var(--s5),4vw,var(--s7))}
.apply__title{font-weight:900;font-size:clamp(1.3rem,2.6vw,1.6rem);letter-spacing:-.02em}
.apply__sub{margin-top:var(--s2);font-size:1rem}
.aform{margin-top:var(--s4)}
.aform__req{font-size:.85rem;margin-bottom:var(--s4)}
.aform__grid{display:grid;gap:var(--s4);grid-template-columns:minmax(0,1fr)}
@media (min-width:600px){.aform__grid{grid-template-columns:1fr 1fr}}
.aform__row{display:grid;gap:var(--s2);min-width:0}
.aform__row--wide{grid-column:1/-1}
/* author display:grid beats the UA [hidden] rule — restore it */
.aform__row[hidden]{display:none}
.aform__label{font-size:.8rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--slate)}
.aform__hint{text-transform:none;letter-spacing:0;font-weight:500}
.aform__input{
  width:100%;min-height:48px;padding:10px 14px;
  font:inherit;font-size:1rem;color:var(--slate);
  background:var(--sky-mid);border:2px solid var(--slate);border-radius:10px;
}
select.aform__input{appearance:auto;cursor:pointer}
.aform__input:focus-visible,.aform__check input:focus-visible{outline:3px solid var(--slate);outline-offset:3px}
.aform__input[aria-invalid="true"],.aform__set[aria-invalid="true"]{border-color:var(--slate);box-shadow:0 0 0 2px var(--slate)}
.aform__set{border:0;margin:0;padding:0;border-radius:10px}
.aform__set legend{margin-bottom:var(--s2);padding:0}
.aform__checks{display:grid;grid-template-columns:minmax(0,1fr);column-gap:var(--s4)}
@media (min-width:600px){.aform__checks{grid-template-columns:1fr 1fr}}
.aform__check{display:flex;align-items:center;gap:var(--s3);min-height:44px;font-size:.98rem;cursor:pointer}
.aform__check input{width:22px;height:22px;flex:none;accent-color:var(--slate);margin:0}
.aform__consent{align-items:flex-start;padding-block:var(--s2);line-height:1.45}
.aform__consent input{margin-top:1px}
.aform__consent a{color:var(--slate);text-underline-offset:3px;display:inline-block;padding-block:12px;margin-block:-12px}
.btn-apply{
  margin-top:var(--s5);display:inline-flex;align-items:center;gap:var(--s2);min-height:48px;padding:0 var(--s6);
  font:inherit;font-weight:700;font-size:1rem;color:var(--sky-bot);background:var(--slate);
  border:0;border-radius:999px;cursor:pointer;
}
.btn-apply:hover{background:var(--deep)}
.btn-apply:focus-visible{outline:3px solid var(--slate);outline-offset:4px}
.aform__msg{margin-top:var(--s3);font-weight:700;color:var(--slate)}
/* the confirmation replaces the form inside the light panel */
.apply__panel .form-done{color:var(--slate)}
/* orange on #0E3A4D is 4.18:1 — fine for a button's own ground, and the
   label on it is --ink at 6.2:1, the same pairing used on the sky buttons */
.btn--onDark{background:var(--wave);color:var(--ink);border-color:var(--wave)}
.btn--onDark:hover{background:var(--amber);color:var(--ink);border-color:var(--amber)}

.origin__mark{
  display:block;width:clamp(96px,11vw,132px);height:auto;
  margin-bottom:var(--s4);
}
/* the h3 is gone from .origin — the logo carries it now */
.origin__h{
  font-size:.76rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sky-top);
}
.origin__line{margin-top:var(--s2);font-size:clamp(.98rem,2.2vw,1.1rem);color:var(--sky-bot)}
/* Credentials set as type, not chips: no fills, no pills, and no colour
   outside the palette (the old green pills were the only green on the
   page). On #0E3A4D: #C6E9FA 9.50:1; the #EF7522 separators are rules,
   not text. One line on desktop, two rows of two on phones. */
.certs{margin-top:var(--s6);padding-top:var(--s3);border-top:1px solid var(--sky-top);container-type:inline-size}
.certs__label{font-size:.72rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--sky-top)}
.certs__list{list-style:none;margin:var(--s3) 0 0;padding:0;display:flex;flex-wrap:wrap;row-gap:var(--s2)}
.certs__list li{
  /* sized to the column so all four hold one line down to ~260px */
  font-weight:700;font-size:clamp(.82rem,5.4cqi,1.1rem);letter-spacing:.16em;text-transform:uppercase;
  color:var(--sky-top);padding:0 var(--s3);border-left:1px solid var(--wave);line-height:1.2;
}
.certs__list li:first-child{padding-left:0;border-left:0}
@media (max-width:480px){
  .certs__list{display:grid;grid-template-columns:repeat(2,max-content)}
  .certs__list li:nth-child(odd){padding-left:0;border-left:0}
}

/* ---------- faq ---------- */
.faq{margin-top:var(--s6);border-top:2px solid rgba(31,101,131,.22)}
.faq__item{border-bottom:2px solid rgba(31,101,131,.22)}
.faq__h{margin:0;font-size:inherit;font-weight:inherit}
.faq__btn{
  width:100%;min-height:44px;
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:var(--s5) 2px;
  font:inherit;font-weight:700;font-size:clamp(.98rem,2.3vw,1.18rem);
  text-align:left;color:var(--slate);background:none;border:0;cursor:pointer;
}
.faq__sign{position:relative;flex:0 0 22px;height:22px}
.faq__sign::before,.faq__sign::after{
  content:"";position:absolute;inset:50% 0 auto 0;height:3px;background:var(--wave);
  transform:translateY(-50%);
}
.faq__sign::after{transform:translateY(-50%) rotate(90deg);transition:transform var(--t-fast) var(--ease)}
.faq__btn[aria-expanded="true"] .faq__sign::after{transform:translateY(-50%) rotate(0)}
.faq__body{padding:0 2px var(--s5);max-width:60ch}
.faq__body p{font-weight:400;font-size:clamp(.95rem,2.2vw,1.05rem)}

/* ---------- newsletter ---------- */
.signup{margin-top:var(--s6);display:grid;gap:var(--s4);justify-items:start;max-width:520px}
.signup__row{display:grid;gap:var(--s2);width:100%}
.signup__label{font-weight:700;font-size:.84rem;letter-spacing:.12em;text-transform:uppercase}
.signup__input{
  width:100%;min-height:52px;padding:14px 16px;
  font:inherit;font-size:1rem;color:var(--slate);
  background:#fff;border:2px solid var(--slate);border-radius:6px;
}
.signup__msg{font-weight:700;min-height:1.4em}

.btn{
  display:inline-grid;place-items:center;min-height:52px;padding:14px 30px;
  font:inherit;font-weight:700;letter-spacing:.06em;text-transform:uppercase;font-size:.9rem;
  border-radius:999px;border:2px solid transparent;cursor:pointer;text-decoration:none;
}
.btn--primary{background:var(--wave);color:var(--ink);border-color:var(--wave)}
.btn--primary:hover{background:var(--ink);color:#fff;border-color:var(--ink)}

/* ---------- footer ---------- */
.foot{padding:clamp(52px,8vh,90px) 0 clamp(34px,5vh,56px)}
.foot__wrap{display:grid;gap:var(--s3);justify-items:start}
.foot__mark{width:clamp(76px,9vw,104px)}
.foot__line{font-weight:500;max-width:52ch}
.foot__legal{margin-top:var(--s3);font-size:.86rem;font-weight:500}

/* ---------- reveals ---------- */
.reveal{opacity:0;transform:translateY(24px);transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease)}
.reveal.is-in{opacity:1;transform:none}

/* ============================================================
   LAYOUT UP
   ============================================================ */
@media (min-width:780px){
  .no-grid{grid-template-columns:1fr minmax(200px,.62fr)}
  .trade{grid-template-columns:1fr minmax(240px,.62fr);gap:var(--s9);align-items:start}
}

/* ============================================================
   TOUCH AND NARROW — no pin, real swipe scroller.
   Keyed on width as well as pointer: a narrow desktop window was getting the
   pinned side-column zoom at 390px, which it cannot hold.
   ============================================================ */
@media (hover:none),(pointer:coarse),(max-width:780px){
  /* overflow-x:clip — the stage goes static here, so it stops being the
     containing block for the wave layer, and the wave's -14% overhang
     escaped the stage's own overflow:hidden. Phones then widened the layout
     viewport to 445px and scaled the whole page to 88% with a white strip on
     the right. clip (not hidden) makes no scroll container, so overflow-y
     stays visible and nothing else about the stage changes. */
  .stage-pin{height:auto;overflow-x:clip}
  /* No pin, so no zoom phase to earn. The row of three is kept — the cans
     are illustrative at this size and the text below carries the message on
     its own — and both simply sit in the flow. */
  .zoom{
    position:static;inset:auto;
    opacity:1 !important;
    display:block;padding:0;
    margin-top:var(--s7);
    --zoom-gap:clamp(8px,2.5vw,16px);
    --zoom-h:min(300px, calc(((100vw - 2 * var(--wrap) - 2 * var(--zoom-gap)) / 3) * 2.6233));
  }
  .zoom__row{transform:none !important}
  .funfact{
    position:static;transform:none;opacity:1;pointer-events:auto;
    width:auto;margin-top:var(--s5);padding-inline:var(--wrap);
  }
  /* Narrow screens have the least room between the header and the can tops,
     and the wave has to run through that band without touching either. The
     cans come down and the group drops, which is the trade the brief asked
     for: shrink the product rather than let the wave crop it. */
  /* the same height budget as desktop; the cue is hidden here so the stack
     below the cans is shorter and the product gets that space back */
  /* A short viewport cannot carry the heavy stage wave AND a full-height can
     AND the caption. The wave stays lighter here — the desktop contour would
     be too heavy against a can this size on a short screen. */
  .stage{
    position:static;height:auto;min-height:100svh;
    --stack-below:clamp(200px,23vh,240px);
    --wave-scale:0.34;
    --wave-weight:1.15;
    --wave-spread:1.95;
  }
  .fan__scroll{display:flex}
  .fan{--rx-mult:1.95}   /* the ring tightens as the screen narrows */
  .cue{display:none}
}

/* ---------- #inside on narrow screens ----------
   Still can-left / facts-right: the turn only pays off if 10g and 0g are on
   screen as the can reaches its back panel. The can takes ~36% of the
   content width (128px at 390, leaving ~200px for the facts); the heading
   spans both columns and the switcher runs full width under the can. */
@media (max-width:780px){
  .turn{
    /* can-first, as on desktop: #story above now opens text-first */
    grid-template-areas:"stage head" "stage facts" "switch switch";
    grid-template-rows:auto 1fr auto;
    column-gap:var(--s5);
  }
  .turn__can{height:min(calc((100vw - 2 * var(--wrap)) * .36 / .3808), 62svh)}
  .turn__switch{justify-content:flex-start}
}


/* #no, side by side. The photo box sets the section's height, so a shorter
   box is a shorter section: 60vh (540 at 900) instead of the list-era ~800.
   object-position 27% keeps rows ~110-940 of the frame — rim, can, hand,
   bracelet and star — and puts the can's centre ~36% down the box. The copy
   is lifted by the difference (14% of the box) so it centres on the can. */
@media (min-width:781px){
  .no-shot{min-height:0;height:var(--shot-h)}
  .no-shot__img{object-position:56% 27%}
  /* translate, not transform: the scroll reveal sets transform:none */
  .no-copy{translate:0 calc(var(--shot-h) * -.14)}
  .no-grid{--shot-h:clamp(380px,60vh,640px)}
}
/* ---------- #no stacked: photo below the copy ----------
   Width only, NOT the touch query above. A touch tablet in landscape
   (1024x768) used to get this stacked layout too: a 1024px-wide box, which
   either runs taller than the screen or cuts the can. It now gets the
   two-column layout, which holds the whole subject at 1024.
   Every crop below is measured against the subject in the 900x1238 frame:
   rim y208, base y615, bracelet + star y725-860, hand x445-700. */
@media (max-width:780px){
  .no-grid{grid-template-columns:1fr;grid-template-areas:"copy" "shot"}
  .no-shot{
    --wave-band-h:clamp(56px,16vw,96px);
    margin-right:var(--bleed-r);margin-left:var(--bleed-r);
    margin-block:var(--s6) calc(var(--sec-y) * -1);
    min-height:0;
    /* 521-780: the full frame. 900:1000 shows 1000 of its 1238 rows, and
       object-position 29% puts rows ~69-1069 in the box — rim ~116px below
       the top at 768, star and the arm entering the water both inside. */
    aspect-ratio:900/1000;
  }
  .no-shot picture{display:contents}
  .no-shot__img{
    object-position:50% 29%;
    /* the wave band on top, solid below it */
    -webkit-mask-image:var(--wave-band),linear-gradient(#000,#000);
            mask-image:var(--wave-band),linear-gradient(#000,#000);
    -webkit-mask-size:100% var(--wave-band-h),100% 100%;
            mask-size:100% var(--wave-band-h),100% 100%;
    -webkit-mask-position:0 0,0 calc(var(--wave-band-h) - 1px);
            mask-position:0 0,0 calc(var(--wave-band-h) - 1px);
  }
}
/* <=520: the tall art-directed crop (see the <picture>). The box takes the
   crop's own shape, so nothing is cropped again on top of it. */
@media (max-width:520px){
  .no-shot{aspect-ratio:600/870}
  .no-shot__img{object-position:50% 0%}
}

/* ============================================================
   REDUCED MOTION — disabled, not softened.
   No pin at all; the three flavours stack vertically.
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  /* the row of three is static content, not motion — it stays */
  .zoom{
    position:static;inset:auto;opacity:1 !important;
    display:block;padding:0;margin-top:var(--s7);
    --zoom-gap:clamp(8px,2.5vw,24px);
    --zoom-h:min(300px, calc(((100vw - 2 * var(--wrap) - 2 * var(--zoom-gap)) / 3) * 2.6233));
  }
  .zoom__row{transform:none !important}
  .funfact{
    position:static;transform:none;opacity:1;pointer-events:auto;
    width:auto;margin-top:var(--s5);padding-inline:var(--wrap);
  }
  .preloader{display:none !important}
  *,*::before,*::after{animation:none !important;transition:none !important}

  .stage-pin{height:auto;overflow-x:clip}   /* same containment as above */
  .stage{position:static;height:auto;min-height:0;display:block;padding-bottom:var(--sec-y)}
  .fan__scroll,.prog,.cue,.fan::after,.zoom{display:none}
  .fan{display:block;min-height:0;margin-top:var(--s7)}
  .fan__ring{position:static;display:grid;gap:var(--s8);inset:auto}
  .can{
    position:static;
    transform:none !important;opacity:1 !important;filter:none !important;
    height:clamp(280px,44vh,460px);margin-inline:auto;
  }
  .fcopy{
    grid-area:auto;opacity:1 !important;visibility:visible !important;transform:none !important;
    margin-top:var(--s4);
  }
  .stage__copy{display:block}
  .reveal{opacity:1;transform:none}
}
/* ============================================================
   HAIRLINE FIELD — #partners only
   A dense field of thin S-curves on the one solid ground the page has.
   It is the panel's ground, not a band and not a separator: it fades up
   out of nothing below the heading, so there is no edge to read as a seam.

   It never sits under the orange heading. That block already carries the
   w4 ribbon; stacking an animated field behind it is where the two wave
   idioms would start arguing with each other.
   ============================================================ */
.hair{
  position:absolute;inset:0;z-index:0;
  display:block;width:100%;height:100%;
  pointer-events:none;
}
.sec--partners > .wrap{position:relative;z-index:1}

/* ============================================================
   WAVE MOTION BEHIND THE PRODUCTS — .fan only
   The supplied asset ships as position:fixed over the whole viewport.
   That is a full-bleed wash, which the wave rule does not allow, so it is
   contained to the product group instead: absolute inside .fan, behind the
   ring, bleeding past the fan's own box and cropped by the stage's
   overflow rather than by a container edge.

   It stops short of the fan's lower edge on purpose. The flavour caption
   sits below in slate, and slate on #EF7522 is 2.23:1 — orange ink must
   never pass under that type.
   ============================================================ */
.fan__waves{
  position:absolute;
  /* wider than the viewport on both sides: the ribbons are cropped by the
     viewport edge, never by this box, so no start or end point is visible */
  left:-14%;right:-14%;
  /* one full stage tall, so the band lands in the same place at every width
     instead of drifting with the fan's own height */
  top:0;bottom:0;
  z-index:1;                 /* behind .fan (z-index 3), above the sky */
  /* CSS owns where the band sits: the same tokens the stage reserves its
     top padding from, so the strip and the ribbons cannot drift apart. */
  /* the band centre lands at roughly the cans upper third, measured from the
     stage top — the same tokens the layout uses, so they cannot drift */
  --band-y:calc(var(--head-h) + var(--stage-top-gap) + var(--can-h) * 0.38);
  pointer-events:none;
}
/* the ring is already position:absolute — only the stacking order is new.
   Setting position here collapsed its inset:0 box and zeroed the can widths. */
.fan__ring{z-index:1}

/* ============================================================
   FORMS — Netlify states
   ============================================================ */
/* honeypot: off-screen and out of the accessibility tree (aria-hidden in the
   markup, tabindex -1 on the input) — never display:none, which some bots skip */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* required marker takes the label's own colour: orange text fails on sky */
.req{font-weight:700}
button[type="submit"]:disabled{opacity:.6;cursor:progress}
/* confirmation replaces the form in the same space; inherits the section's
   ink (slate on sky, #F8FBFD on the dark panel) */
.form-done{padding:var(--s5) 0;outline:none}
.form-done:focus-visible{outline:3px solid currentColor;outline-offset:6px;border-radius:4px}
.form-done__h{font-weight:900;font-size:clamp(1.3rem,3vw,1.7rem);letter-spacing:-.02em}
.form-done__p{margin-top:var(--s2);font-size:clamp(1rem,2vw,1.1rem)}

/* consent line under both forms; takes the section's ink */
.consent{margin-top:var(--s3);font-size:.88rem;max-width:52ch}
.consent a{color:inherit;text-underline-offset:3px;display:inline-block;padding-block:12px;margin-block:-12px}
.dark .consent{color:var(--sky-top)}
.foot__legal a{color:inherit;text-underline-offset:3px;display:inline-block;padding-block:12px;margin-block:-12px}

/* ============================================================
   PRIVACY — a document, not a brand moment. One readable column, the sky
   ground, Poppins, slate type. No waves, no product, no motion.
   ============================================================ */
.doc-page{background-image:linear-gradient(180deg,var(--sky-top) 0%,var(--sky-mid) 40%,var(--sky-bot) 100%);background-attachment:scroll}
.doc-head{padding:var(--s4) 0}
.doc-head__wrap{display:flex;align-items:center;justify-content:space-between;gap:var(--s4)}
.doc-head__home{display:inline-flex;min-height:44px;align-items:center}
.doc-head__home img{width:77px;height:auto}
.doc-head__back{display:inline-flex;align-items:center;min-height:44px;font-weight:700;font-size:.9rem;color:var(--slate);text-underline-offset:4px}
.doc{padding:var(--s6) 0 var(--s9)}
.doc__wrap{max-width:720px}
.doc__title{font-weight:900;font-size:clamp(2rem,5vw,3rem);letter-spacing:-.03em}
.doc__meta{margin-top:var(--s3);font-size:.95rem}
.doc h2{margin-top:var(--s7);font-weight:700;font-size:clamp(1.2rem,2.6vw,1.45rem);letter-spacing:-.01em;line-height:1.25}
.doc p,.doc li{font-size:1.05rem;line-height:1.65;max-width:65ch}
.doc p{margin-top:var(--s3)}
.doc ul{margin:var(--s3) 0 0;padding-left:1.2em;display:grid;gap:var(--s2)}
.doc a{color:var(--slate);text-underline-offset:3px}
.doc .placeholder--block{margin-top:var(--s3);font-size:.95rem;line-height:1.5;text-transform:none;letter-spacing:0;font-weight:500;padding:var(--s4)}

/* footer contact — the header's Contact anchor lands here */
.contact-block{margin-top:var(--s5);display:grid;gap:var(--s3)}
.contact-block__h{font-weight:900;font-size:clamp(1.15rem,2.4vw,1.4rem);letter-spacing:-.02em}
.contact-block__list{list-style:none;margin:0;padding:0;display:grid;gap:0}
.contact-block__list li{display:flex;flex-wrap:wrap;align-items:center;column-gap:var(--s3);min-height:44px;font-size:1rem}
.contact-block__k{min-width:5.5em;font-size:.76rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
.contact-block__list a{color:var(--slate);display:inline-flex;align-items:center;min-height:44px;text-underline-offset:3px}
