/* ============================================================
   Pura Soda — demo build
   Everything is measured off the Figma frames. See SPEC.md.

   --u is one design pixel. The frames are drawn at 1440 wide, so
   1440 * 0.069444vw = 1px, and every value below can be written as
   calc(<design px> * var(--u)). Proportions then hold at any width.
   ============================================================ */

/* every <img> carries width/height attributes (stamped at build for CLS —
   review, 14 Sep); CSS owns the rendered size, the attributes only supply
   the aspect ratio. Without this the height attribute acts as a size hint
   wherever CSS sets width alone (and vice versa). */
img{width:auto;height:auto}
@font-face{
  font-family:"Noir Pro"; src:url("assets/fonts/NoirPro-Bold.woff2") format("woff2");
  font-weight:700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Noir Pro"; src:url("assets/fonts/NoirPro-Medium.woff2") format("woff2");
  font-weight:500; font-style:normal; font-display:swap;
}

:root{
  --u:0.069444vw;              /* 1 design px */

  --teal:#00b9c3;
  --foot-a:#10576f;
  --foot-b:#002d3c;
  --foot-link:#f8d359;
  --yellow:#f8d359;
  --orange:#f79650;
  --coral:#f37046;

  --ease:cubic-bezier(.22,1,.36,1);
}
/* no wide-screen cap: the layout is fully proportional (--u is vw-based),
   so it must stay that way at every width — a px cap leaves the right edge
   of every section exposed and breaks the scroll-anchor math */

*,*::before,*::after{box-sizing:border-box}
/* overflow-x on html as well as body: iOS Safari ignores body-only
   overflow-x and still pans sideways to the ribbon overhangs (Lee, 8 Sep) */
html{scroll-behavior:smooth; overflow-x:clip}
body{
  margin:0; background:#fff; color:#fff; overflow-x:hidden;
  font-family:"Noir Pro", ui-rounded, system-ui, sans-serif; font-weight:700;
  -webkit-font-smoothing:antialiased;
}
img,svg,video{display:block; max-width:100%}
h1,h2,p,ul{margin:0}
ul{list-style:none;padding:0}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;border:0;background:none;cursor:pointer}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;background:#fff;color:#000;padding:12px 18px;z-index:300}

/* ── NAV ─────────────────────────────────────────────── */
.nav{position:fixed; inset:0 0 auto 0; z-index:80; height:calc(160*var(--u))}
.nav__logo{position:absolute; left:calc(651*var(--u)); top:calc(21*var(--u));
  width:calc(137.76*var(--u)); height:calc(110.93*var(--u))}
.nav__logo img{width:100%;height:100%}

.pill{
  position:absolute; left:calc(80*var(--u)); top:calc(52*var(--u));
  width:calc(163*var(--u)); height:calc(49*var(--u));
  background:var(--teal); border-radius:calc(10*var(--u));
  transition:filter .3s var(--ease);
}
.pill:hover{filter:brightness(1.08)}
/* inset white outline removed per Lee 8 Sep (2300:72687) */
.pill span{
  position:absolute; left:calc(31*var(--u)); top:calc(13*var(--u));
  font-weight:500; font-size:calc(24*var(--u)); line-height:.92; color:#fff;
}

.burger{
  position:absolute; left:calc(1308*var(--u)); top:calc(58*var(--u));
  width:calc(52*var(--u)); height:calc(52*var(--u));
  display:grid; place-content:center; gap:calc(7*var(--u));
  background:var(--teal); border-radius:50%;   /* blue circle, per the design */
  transition:filter .3s var(--ease);
}
.burger:hover{filter:brightness(1.08)}
.burger i{display:block; width:calc(30*var(--u)); height:calc(3*var(--u));
  background:#fff; border-radius:calc(2*var(--u));
  transition:transform .4s var(--ease), opacity .3s var(--ease)}
body.menu-open .burger i:nth-child(1){transform:translateY(calc(10*var(--u))) rotate(45deg)}
body.menu-open .burger i:nth-child(2){opacity:0}
body.menu-open .burger i:nth-child(3){transform:translateY(calc(-10*var(--u))) rotate(-45deg)}

/* ── STRIPES ─────────────────────────────────────────────
   The ribbons taper, so they stay filled shapes; each is revealed
   by animating a mask along its own centreline (see tools/mask_stripes.py).
   Geometry and rotation are exactly as placed in the frame.
   ------------------------------------------------------ */
.stripes{position:absolute; z-index:6; pointer-events:none;
  display:flex; align-items:center; justify-content:center}
/* Lee's export is already rotated and sized to 2226 × 2272, so the artwork
   fills its wrapper with no rotation of ours. Bands are ~156px here versus
   ~212px in the earlier file, which is what made the ribbon too fat. */
.stripes__art{width:100%; height:100%; flex:none}
.stripes svg{width:100%; height:100%; overflow:visible}
/* gap LONGER than the path (1.1 > 1): with dasharray 1 1 every offset puts a
   dash boundary somewhere on the path, and round linecaps paint fat dots
   there — the "stray fragments". At offset 1.05 the hidden state now clears
   the path by 0.05 on both sides, so nothing paints until the draw starts. */
.stripes .spine{stroke-dasharray:1 1.1; stroke-dashoffset:calc(var(--dir,1) * 1.05 * (1 - var(--p,0)))}
/* an undrawn host (--p ~ 0) paints round-linecap DOTS at each segment start —
   the "stray fragments before scroll". JS stamps .art0 while p is ~0. */
.art0 .spine{opacity:0}

/* the ribbon occupies y 970–1457 inside the 2272 artboard, so this lands it
   across the hero/grid seam rather than down over the cans */
.stripes--1,.stripes--p1{left:calc(-560*var(--u)); top:calc(-330*var(--u));
  width:calc(2226*var(--u)); height:calc(2272*var(--u))}

/* second ribbon is its own artwork, 2223 x 2182, and draws in from the right */
.stripes--2,.stripes--p2{left:calc(-390*var(--u)); width:calc(2223*var(--u));
  height:calc(2182*var(--u))}
.stripes--2{top:calc(1230*var(--u))}
/* on the product page it divides the lifestyle pair from the facts section */
.stripes--p2{top:calc(2660*var(--u))}

/* ── HERO ────────────────────────────────────────────── */
.hero{position:relative; height:calc(1024*var(--u)); overflow:hidden; background:#0b3c48}
.hero__media{position:absolute; left:calc(-48*var(--u)); top:calc(-2*var(--u));
  width:calc(1869*var(--u)); height:calc(1047*var(--u))}
.hero__media video,.hero__media img{width:100%;height:100%;object-fit:cover}
.hero__scrim{position:absolute; inset:0; background:rgba(0,0,0,.1)}
.hero__title{
  position:absolute; left:calc(336*var(--u)); top:calc(321*var(--u)); width:calc(780*var(--u));
  font-size:calc(94*var(--u)); line-height:.92; color:#fff; z-index:4;
}
.hero__title .l{display:block; overflow:hidden}
.hero__title .l>span{display:block; transform:translateY(105%);
  animation:rise 1s var(--ease) forwards}
.hero__title .l:nth-child(2)>span{animation-delay:.12s}
@keyframes rise{to{transform:translateY(0)}}

/* product hero */
.phero{position:relative; height:calc(1010*var(--u)); overflow:hidden; background:#fff49f}
.phero__media{position:absolute; left:calc(-66*var(--u)); top:calc(-2*var(--u));
  width:calc(1743*var(--u)); height:calc(977*var(--u))}
.phero__media video,.phero__media img{width:100%;height:100%;object-fit:cover}
.phero__title{position:absolute; left:calc(92*var(--u)); top:calc(341*var(--u));
  width:calc(780*var(--u)); font-size:calc(94*var(--u)); line-height:.92; color:#fff; z-index:4}
.phero__title .l{display:block; overflow:hidden}
.phero__title .l>span{display:block; transform:translateY(105%); animation:rise 1s var(--ease) forwards}
.phero__title .l:nth-child(2)>span{animation-delay:.12s}

/* ── FLAVOUR GRID ────────────────────────────────────── */
.grid{display:grid; grid-template-columns:repeat(3,1fr); position:relative; z-index:2}
/* aspect-ratio rather than a fixed height, so the tile keeps the frame's
   480 × 675 proportion at any column width without breakpoint juggling */
.tile{
  position:relative; aspect-ratio:480/675; overflow:hidden;
  background:transparent; cursor:pointer; isolation:isolate;
  container-type:inline-size;   /* so type inside can size off the tile */
}
/* menudurable's mechanic: an oversized panel parked off to the left at
   translateX(-105%) and slid to 0. The panel is permanently skewed, so its
   leading edge is a diagonal — which is the "diagonal fill" in the brief.
   (Theirs is .menu-item-background at width:300% translateX(-101%) with a
   rotated triangle on the leading edge; skew gets the same read in one node.) */
.tile__fill{
  position:absolute; left:-25%; top:-10%; width:150%; height:120%; z-index:1;
  background:linear-gradient(180deg, var(--fill-a), var(--fill-b));
  transform:translateX(-105%) skewX(-10deg);
  transition:transform .8s var(--ease);
}
.tile:hover .tile__fill,.tile:focus-within .tile__fill{transform:translateX(0) skewX(-10deg)}

/* sized as a proportion of the tile: 144/480 wide, 339/675 tall, top 158/675 */
.tile__can{
  position:absolute; z-index:3; left:50%; top:23.41%;
  width:30%; height:50.22%; margin-left:-15%;
  transform:rotate(0deg);
  transition:transform .8s var(--ease);
  filter:drop-shadow(0 1.2vw 2vw rgba(0,0,0,.22));
}
.tile__can img{width:100%;height:100%;object-fit:contain}
/* the can tilts to the right — it does not grow */
.tile:hover .tile__can,.tile:focus-within .tile__can{transform:rotate(9deg)}

.fizz{position:absolute; inset:0; z-index:4; opacity:0; transition:opacity .5s var(--ease)}
.tile:hover .fizz,.tile:focus-within .fizz{opacity:1}

.tile__name{
  position:absolute; z-index:5; left:0; right:0; top:80%;
  text-align:center; color:#fff; font-size:7.5cqw; line-height:.92;
  text-transform:lowercase;
  opacity:0; transform:translateY(6%);
  transition:opacity .45s var(--ease), transform .55s var(--ease);
}
.tile:hover .tile__name,.tile:focus-within .tile__name{opacity:1; transform:none}

/* block reveal — same left-to-right sweep as menudurable, staggered.
   The tile has no background of its own so the sweep is what fills it. */
.tile__wash{
  position:absolute; left:-25%; top:-10%; width:150%; height:120%; z-index:0;
  background:var(--rest);
  transform:translateX(-105%) skewX(-10deg);
  transition:transform .95s var(--ease);
}
.tile.is-in .tile__wash{transform:translateX(0) skewX(-10deg)}
.tile:nth-child(1) .tile__wash{transition-delay:0s}
.tile:nth-child(2) .tile__wash{transition-delay:.1s}
.tile:nth-child(3) .tile__wash{transition-delay:.2s}
.tile:nth-child(4) .tile__wash{transition-delay:.3s}
.tile:nth-child(5) .tile__wash{transition-delay:.4s}
.tile:nth-child(6) .tile__wash{transition-delay:.5s}

/* ── BUBBLES ─────────────────────────────────────────────
   Schweppes draws theirs on a canvas (c-backgroundCanvas): many small,
   low-contrast discs rising continuously. DOM elements with radial
   gradients read as soap bubbles, which is what was wrong before.
   ------------------------------------------------------ */
.fizz,.menu__bubbles{pointer-events:none}
.fizz canvas,.menu__bubbles canvas{width:100%; height:100%; display:block}

/* ── OUR PROMISE ─────────────────────────────────────── */
.promise{position:relative; height:calc(899*var(--u)); overflow:hidden; background:#0b3c48}
.promise__media{position:absolute; left:calc(-175*var(--u)); top:calc(-38*var(--u));
  width:calc(1790*var(--u)); height:calc(997*var(--u))}
.promise__media video,.promise__media img{width:100%;height:100%;object-fit:cover}
.promise__inner{position:absolute; left:calc(255*var(--u)); top:calc(301*var(--u));
  width:calc(938*var(--u)); display:flex; flex-direction:column; align-items:center;
  gap:calc(81*var(--u)); z-index:3}
.promise__title{font-size:calc(74*var(--u)); line-height:.92; color:#fff}
.promise__row{display:flex; gap:calc(165*var(--u)); align-items:flex-start; width:100%;
  justify-content:center}
.promise__col{display:flex; flex-direction:column; align-items:center; text-align:center; color:#fff}
.promise__col:nth-child(1){width:calc(201*var(--u)); gap:calc(94*var(--u))}
.promise__col:nth-child(2){width:calc(225*var(--u)); gap:calc(48*var(--u))}
.promise__col:nth-child(3){width:calc(182*var(--u)); gap:calc(48*var(--u))}
.promise__col p{font-size:calc(32*var(--u)); line-height:.92; text-transform:lowercase}
.promise__col img{height:auto}
.promise__col:nth-child(1) img{width:calc(120*var(--u))}
.promise__col:nth-child(2) img{width:calc(174.75*var(--u))}
.promise__col:nth-child(3) img{width:calc(167.17*var(--u))}
.reveal{opacity:0; transform:translateX(calc(-28*var(--u)));
  transition:opacity .8s var(--ease), transform .8s var(--ease)}
.reveal.is-in{opacity:1; transform:none}

/* site-wide text reveal (Lee, 6 Sep): fade + swipe in from the left for hero
   and section text that has no reveal of its own. Elements centred with
   translateX(-50%) declare --tx:-50% so the slide composes with it; the
   two-class selectors out-rank the element rules that set those transforms. */
.treveal{transition:opacity .7s var(--ease), transform .7s var(--ease)}
.treveal:not(.is-in){opacity:0; transform:translateX(calc(var(--tx,0%) - 28*var(--u)))}
/* hero text is hidden from the very first paint (html.js is set inline in
   <head>), so it can never flash before site.js catches up on a slow line;
   the rule stops matching the moment is-in lands, handing back to .treveal */
html.js .chero h1:not(.is-in), html.js .chero .sub:not(.is-in),
html.js .phero__title:not(.is-in){opacity:0;
  transform:translateX(calc(var(--tx,0%) - 28*var(--u)))}
html.js .chero h1:not(.is-in), html.js .chero .sub:not(.is-in){--tx:-50%}
/* section text is likewise hidden from first paint — JS adding .treveal
   after paint caused a visible flash-then-hide on slower devices (QA, 8 Sep) */
html.js .catg7 h2:not(.is-in), html.js .catg7__col:not(.is-in),
html.js .catcta h2:not(.is-in), html.js .intro3 p:not(.is-in),
html.js .covered3 p:not(.is-in), html.js .article h1:not(.is-in),
html.js .ncard:not(.is-in), html.js .policy h1:not(.is-in),
html.js .pdesc__can:not(.is-in){opacity:0;
  transform:translateX(calc(-28*var(--u)))}
.treveal.is-in{opacity:1; transform:translateX(var(--tx,0%))}
.chero h1.treveal,.chero .sub.treveal,.intro3 p.treveal,.covered3 p.treveal{--tx:-50%}
/* hero text holds a beat after load so the entrance reads (Lee, 6 Sep);
   the sub follows the headline */
.chero h1.treveal,.phero__title.treveal{transition-delay:.25s}
.chero .sub.treveal{transition-delay:.5s}
.pdesc__can.treveal{transition-delay:.15s}
/* product description text swipes in with the site-wide language once its
   wash section lands (has-wash already owns its opacity) */
.pdesc.has-wash > p{transform:translateX(calc(-28*var(--u)));
  transition:opacity .55s var(--ease) .3s, transform .6s var(--ease) .3s}
.pdesc.has-wash.is-in > p{transform:none}
.promise__col:nth-child(2).reveal{transition-delay:.1s}
.promise__col:nth-child(3).reveal{transition-delay:.2s}

/* ── PURA SOCIALS ────────────────────────────────────── */
/* the section's wavy top edge and blue→white gradient are a single piece of
   artwork in the frame (Mask group, 1451.919 × 834.5 at y3273) — used directly
   so the wave is exactly the designed shape rather than an approximation */
.socials{position:relative; height:calc(1044*var(--u)); overflow:hidden;
  background:transparent; margin-top:calc(-95*var(--u)); z-index:4}
.socials::before{
  content:""; position:absolute; left:0; top:0;
  width:100%; height:100%;
  background:url("assets/art/turq-bg.png") no-repeat top center/100% 100%;
}
.socials__inner{position:absolute; left:calc(88*var(--u)); top:calc(126*var(--u));
  width:calc(1284.298*var(--u)); display:flex; flex-direction:column; align-items:center;
  gap:calc(56*var(--u))}
.socials__title{font-size:calc(74*var(--u)); line-height:.92; color:#fff}

/* the fan — offsets and rotations measured off the frame.
   --k is driven from scroll every frame (as landonorris.com does it) rather
   than run as a one-shot transition, so the deck opens with the user's scroll.
   No transition on transform: that would fight the per-frame updates. */
.deck{position:relative; width:calc(1284.298*var(--u)); height:calc(520*var(--u))}
/* --dx/--dy are measured from each card's visual centre, not its bounding-box
   corner: the boxes are all different widths because the cards are rotated,
   so using the corner threw the whole fan off-centre. --sc is Lando's
   falloff, so the cards shrink as they fan outwards. --px is the sideways
   nudge the hover applies to open a gap. */
.card{
  position:absolute; top:0; left:50%;
  width:calc(307*var(--u)); height:calc(385*var(--u));
  margin-left:calc(-153.5*var(--u));
  border-radius:calc(30*var(--u)); overflow:hidden;
  box-shadow:0 calc(18*var(--u)) calc(34*var(--u)) rgba(0,0,0,.22);
  transform:
    translate(calc((var(--dx) * var(--u) + var(--px,0px)) * var(--k,1)),
              calc((var(--dy) * var(--u) - var(--lift,0px)) * var(--k,1)))
    rotate(calc(var(--rot) * var(--k,1)))
    scale(calc(1 - (1 - var(--sc)) * var(--k,1) + var(--pop,0)));
  transition:box-shadow .4s;
  will-change:transform; backface-visibility:hidden;
}
/* hover: the card lifts and grows, the ones between it and the centre are
   pushed aside — measured off landonorris.com */
.card{--px:0px; --lift:0px; --pop:0}
.deck.is-hovering .card{transition:box-shadow .4s}
.card img{width:100%;height:100%;object-fit:cover}
/* centre card sits on top, stacking down symmetrically either side */
.card:nth-child(4){z-index:10}
.card:nth-child(3),.card:nth-child(5){z-index:9}
.card:nth-child(2),.card:nth-child(6){z-index:8}
.card:nth-child(1),.card:nth-child(7){z-index:7}
.card:hover{z-index:11; box-shadow:0 calc(26*var(--u)) calc(46*var(--u)) rgba(0,0,0,.3)}
.socials__links{display:flex; gap:calc(34*var(--u)); font-size:calc(24*var(--u))}
.socials__links a:first-child{color:var(--foot-a)}
.socials__links a:last-child{color:#ff5d50}

/* ── FOOTER ──────────────────────────────────────────── */
/* the footer's wavy top edge is a mask over the gradient in the frame */
.foot{position:relative; height:calc(640.504*var(--u));
  background:linear-gradient(180deg,var(--foot-a),var(--foot-b)); overflow:hidden;
  -webkit-mask:url("assets/art/footer-mask.svg") no-repeat top center/100% 100%;
  mask:url("assets/art/footer-mask.svg") no-repeat top center/100% 100%;
  margin-top:calc(-120*var(--u)); z-index:5}
.foot__inner{position:absolute; left:calc(89*var(--u)); top:calc(180*var(--u));
  width:calc(1249*var(--u)); display:flex; justify-content:space-between; align-items:flex-start}
.foot__left{display:flex; flex-direction:column; gap:calc(131*var(--u)); width:calc(480*var(--u))}
.foot__brand{display:flex; flex-direction:column; gap:calc(26*var(--u))}
.foot__logo{width:calc(137.76*var(--u)); height:calc(110.93*var(--u))}
.foot__tag{font-size:calc(54*var(--u)); line-height:.92; color:#fff}
.foot__fine{font-size:calc(18*var(--u)); line-height:.92; color:#fff}
.foot__right{display:flex; flex-direction:column; gap:calc(6*var(--u)); width:calc(209*var(--u))}
.foot__nav{display:flex; flex-direction:column; font-size:calc(30*var(--u));
  line-height:1.32; color:var(--foot-link)}
.foot__nav a{transition:opacity .25s}
.foot__nav a:hover{opacity:.7}
.foot__social{width:calc(122*var(--u)); height:calc(45*var(--u)); margin-top:calc(24*var(--u))}

/* ── FULL-SCREEN NAV ─────────────────────────────────── */
.menu{position:fixed; inset:0; z-index:90; overflow:hidden;
  opacity:0; visibility:hidden; transition:opacity .5s var(--ease), visibility .5s}
.menu.is-open{opacity:1; visibility:visible}
.menu__base{position:absolute; inset:0; background:linear-gradient(180deg,#00b9c3,#fff)}
.menu__wash{position:absolute; inset:0; opacity:0; transition:opacity .55s var(--ease);
  background:linear-gradient(180deg,var(--m-a,#A3D065),var(--m-b,#079D54))}
.menu.is-hot .menu__wash{opacity:1}
.menu__bubbles{position:absolute; inset:0; opacity:0;
  transition:opacity .55s var(--ease)}
.menu.is-hot .menu__bubbles{opacity:1}
/* shifted up from the frame's y379.84 so the whole can clears the fold */
.menu__can{position:absolute; left:calc(979.59*var(--u)); top:calc(210*var(--u));
  width:calc(197.734*var(--u)); height:calc(464.936*var(--u));
  opacity:0; transform:translateX(calc(70*var(--u))) rotate(12deg);
  transition:opacity .5s var(--ease), transform .8s var(--ease);
  filter:drop-shadow(0 calc(20*var(--u)) calc(30*var(--u)) rgba(0,0,0,.25))}
.menu__can.is-on{opacity:1; transform:translateX(0) rotate(6deg)}
.menu__logo{position:absolute; left:calc(1212*var(--u)); top:calc(34*var(--u));
  width:calc(137.76*var(--u)); height:calc(110.93*var(--u))}
.menu__title{position:absolute; left:calc(92*var(--u)); top:calc(55*var(--u));
  font-size:calc(74*var(--u)); line-height:.92; color:#fff}
.menu__close{position:absolute; right:calc(24*var(--u)); top:calc(24*var(--u));
  width:calc(43*var(--u)); height:calc(43*var(--u)); z-index:6; cursor:pointer;
  background:none; border:0; padding:0; transition:opacity .25s var(--ease)}
.menu__close svg{width:100%; height:100%; display:block}
.menu__close:hover{opacity:.7}
/* scroll is the safety net; single-open groups keep it from engaging */
.menu__list{position:absolute; left:calc(92*var(--u)); top:calc(185*var(--u));
  width:calc(780*var(--u)); color:#fff; z-index:5;
  max-height:calc(100vh - 220*var(--u)); max-height:calc(100dvh - 220*var(--u));
  overflow-y:auto; overscroll-behavior:contain}
.menu__grouprow{display:flex; align-items:baseline; gap:calc(24*var(--u))}
.menu__head{display:block; font-size:calc(54*var(--u)); line-height:1.12; color:#fff;
  transition:opacity .35s var(--ease)}
/* always-visible route to the category page — the heading itself toggles the
   accordion, so it can't be the link (Lee, 6 Sep); identical on mobile */
.menu__viewall{font-size:calc(20*var(--u)); color:#fff; opacity:.55;
  white-space:nowrap; transition:opacity .25s var(--ease)}
.menu__viewall:hover{opacity:1}
.menu.is-hot .menu__viewall{opacity:.35}
.menu__more{display:inline-block; margin-top:calc(40*var(--u));
  font-size:calc(26*var(--u)); color:#fff; opacity:.7; transition:opacity .25s var(--ease)}
.menu__more:hover{opacity:1}
.menu__flavours{padding-left:calc(26*var(--u)); overflow:hidden;
  max-height:0; transition:max-height .6s var(--ease)}
.menu__group.is-open .menu__flavours{max-height:calc(420*var(--u))}
.menu__flavours a{display:block; font-size:calc(44*var(--u)); line-height:1.12; color:#fff;
  transition:opacity .35s var(--ease), transform .35s var(--ease)}
/* every item dims to 40%; the hovered one stays solid white.
   Applied per item rather than to the list, so the hovered link is
   genuinely full opacity instead of inheriting the parent's fade. */
.menu__head,.menu__flavours a{transition:opacity .4s var(--ease), transform .4s var(--ease)}
.menu.is-hot .menu__head,.menu.is-hot .menu__flavours a{opacity:.4}
.menu.is-hot .menu__flavours a.is-hot{opacity:1; transform:translateX(calc(26*var(--u)))}
/* open sequence: items slide in one at a time (Lee, 6 Sep).
   fill-mode backwards only covers the delay — once each animation ends the
   element returns to the cascade, so the is-hot dimming still works */
@keyframes menuItemIn{from{opacity:0; transform:translateX(calc(-46*var(--u)))}}
.menu.is-open .menu__title,
.menu.is-open .menu__grouprow,
.menu.is-open .menu__flavours a,
.menu.is-open .menu__more{animation:menuItemIn .5s var(--ease) backwards}
.menu.is-open .menu__title{animation-delay:.05s}
.menu.is-open .menu__group:nth-child(1) .menu__grouprow{animation-delay:.12s}
.menu.is-open .menu__flavours a:nth-child(1){animation-delay:.18s}
.menu.is-open .menu__flavours a:nth-child(2){animation-delay:.23s}
.menu.is-open .menu__flavours a:nth-child(3){animation-delay:.28s}
.menu.is-open .menu__flavours a:nth-child(4){animation-delay:.33s}
.menu.is-open .menu__flavours a:nth-child(5){animation-delay:.38s}
.menu.is-open .menu__flavours a:nth-child(6){animation-delay:.43s}
.menu.is-open .menu__group:nth-child(2) .menu__grouprow{animation-delay:.5s}
.menu.is-open .menu__group:nth-child(3) .menu__grouprow{animation-delay:.56s}
.menu.is-open .menu__more{animation-delay:.62s}
@media (prefers-reduced-motion:reduce){
  .menu.is-open .menu__title,
  .menu.is-open .menu__grouprow,
  .menu.is-open .menu__flavours a,
  .menu.is-open .menu__more{animation:none}
}
.menu__stripes{position:absolute; left:calc(-589*var(--u)); top:calc(-240*var(--u));
  width:calc(2225.754*var(--u)); height:calc(2271.828*var(--u));
  display:flex; align-items:center; justify-content:center; pointer-events:none; z-index:1}
.menu__stripes .stripes__art{transform:rotate(-120.31deg)}

/* ── PRODUCT PAGE SECTIONS ───────────────────────────── */
/* margin-top pulls the yellow up under the video so there is no seam */
.pintro{position:relative; height:calc(1030*var(--u)); background:#fff49f;
  display:flex; align-items:center; justify-content:center; overflow:hidden; z-index:2;
  margin-top:calc(-24*var(--u))}
.pintro__row{display:flex; gap:calc(170*var(--u)); align-items:center}
.pintro__can{width:calc(242*var(--u)); height:calc(570*var(--u))}
.pintro__can img{width:100%;height:100%;object-fit:contain}
.pintro__copy{width:calc(625*var(--u)); font-size:calc(40*var(--u));
  line-height:calc(48*var(--u)); color:#78610e}

.pnutri{position:relative; height:calc(928*var(--u)); display:grid;
  grid-template-columns:1fr 1fr; background:#f8e359; z-index:2}
.pnutri__lead{align-self:center; padding-left:calc(119*var(--u)); width:calc(474*var(--u));
  font-size:calc(36*var(--u)); line-height:calc(44*var(--u)); color:#78610e}
.pnutri__lead h2{font-size:calc(36*var(--u)); line-height:calc(44*var(--u));
  margin-bottom:calc(44*var(--u))}
.pnutri__marks{display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:calc(80*var(--u))}
.pnutri__mark{display:flex; flex-direction:column; align-items:center; gap:calc(16*var(--u));
  text-align:center; color:#78610e; font-size:calc(32*var(--u)); line-height:.92;
  text-transform:lowercase}
.pnutri__mark:nth-child(1){width:calc(359*var(--u))}
.pnutri__mark:nth-child(2){width:calc(372*var(--u))}
.pnutri__mark:nth-child(1) img{width:calc(167.17*var(--u))}
.pnutri__mark:nth-child(2) img{width:calc(174.75*var(--u))}
/* icons in the same brown as the copy: #78610e */
.pnutri__mark img{filter:brightness(0) saturate(100%)
  invert(38%) sepia(38%) saturate(1100%) hue-rotate(6deg) brightness(92%) contrast(94%)}

.ppair{display:grid; grid-template-columns:calc(715*var(--u)) 1fr;
  height:calc(846*var(--u)); position:relative; z-index:2}
.ppair figure{margin:0; overflow:hidden}
.ppair img{width:100%;height:100%;object-fit:cover}

.facts{position:relative; height:calc(928*var(--u)); background:#fff49f;
  display:grid; place-items:center; z-index:2}
.facts__card{background:#fff; color:#78610e; width:calc(430*var(--u));
  border-radius:calc(22*var(--u)); padding:calc(32*var(--u));
  box-shadow:0 calc(20*var(--u)) calc(46*var(--u)) rgba(0,0,0,.1)}
.facts__name{font-size:calc(28*var(--u)); line-height:1; text-transform:uppercase}
.facts__serve{font-size:calc(15*var(--u)); line-height:1.3; padding:calc(7*var(--u)) 0
  calc(8*var(--u)); border-bottom:calc(2*var(--u)) solid currentColor}
.facts__bar{height:calc(8*var(--u)); background:currentColor; margin:calc(7*var(--u)) 0}
.facts__cal{display:flex; justify-content:space-between; align-items:baseline;
  font-size:calc(19*var(--u))}
.facts__cal b{font-size:calc(30*var(--u))}
.facts__dv{text-align:right; font-size:calc(13*var(--u)); padding:calc(5*var(--u)) 0;
  border-bottom:calc(2*var(--u)) solid currentColor}
.facts__row{display:flex; justify-content:space-between; gap:calc(12*var(--u));
  font-size:calc(13.5*var(--u)); padding:calc(4.5*var(--u)) 0;
  border-bottom:calc(1.5*var(--u)) solid currentColor}
.facts__row--in{padding-left:calc(18*var(--u))}
.facts__note{font-size:calc(11.5*var(--u)); line-height:1.35; margin-top:calc(9*var(--u))}

/* ── RESPONSIVE ──────────────────────────────────────────
   No mobile frames exist yet, so this follows the reference
   sites: menudurable stacks its blocks and keeps the reveal;
   Lando collapses the fanned deck into a swipe rail.
   ------------------------------------------------------ */
/* Between the 1440 desktop frames and the 400 mobile frames there is NO
   tablet design: the desktop layout scales proportionally (--u stays
   100vw/1440) all the way down to 641px. A leftover "reference 900" unit
   override here rendered the 1440 layout at 160% of the viewport on
   every page between 641 and 1100px (Lee, 14 Sep). The remaining rules
   in this block are legacy v1 selectors, kept inert. */
@media (max-width:1100px){
  .grid{grid-template-columns:repeat(2,1fr)}
  .stripes--2,.stripes--p2{display:none}
  .hero,.phero{height:auto; aspect-ratio:1440/900}
  .hero__media,.phero__media{left:0; top:0; width:100%; height:100%}
  .hero__title{left:calc(70*var(--u)); top:auto; bottom:calc(120*var(--u));
    width:calc(760*var(--u)); font-size:calc(78*var(--u))}
  .phero__title{left:calc(70*var(--u)); top:auto; bottom:calc(120*var(--u));
    width:calc(760*var(--u)); font-size:calc(78*var(--u))}
  .promise{height:auto; padding:calc(110*var(--u)) 0}
  .promise__media{left:0; top:0; width:100%; height:100%}
  .promise__inner{position:relative; left:auto; top:auto; margin:0 auto; width:calc(780*var(--u))}
  .socials{height:auto; padding:calc(90*var(--u)) 0}
  .socials__inner{position:relative; left:auto; top:auto; margin:0 auto; width:calc(820*var(--u))}
  .deck{width:calc(820*var(--u)); height:calc(400*var(--u))}
  .card{width:calc(220*var(--u)); height:calc(276*var(--u))}
  .foot{height:auto; padding:calc(90*var(--u)) 0}
  .foot__inner{position:relative; left:auto; top:auto; margin:0 auto; width:calc(780*var(--u))}
  .pintro{height:auto; padding:calc(90*var(--u)) 0}
  .pintro__row{flex-direction:column; gap:calc(60*var(--u))}
  .pnutri{grid-template-columns:1fr; height:auto; padding:calc(80*var(--u)) 0; gap:calc(70*var(--u))}
  .pnutri__lead{padding:0 calc(60*var(--u)); width:auto}
  .ppair{grid-template-columns:1fr; height:auto}
  .ppair figure{aspect-ratio:16/11}
  .facts{height:auto; padding:calc(90*var(--u)) 0}
  .facts__card{width:calc(600*var(--u))}
  /* the nav is absolutely placed at frame coordinates; re-anchor it */
  .nav{height:calc(150*var(--u))}
  .nav__logo{left:50%; margin-left:calc(-68.88*var(--u))}
  .burger{left:auto; right:calc(60*var(--u))}
  .menu__logo{left:auto; right:calc(60*var(--u))}
  .menu__title{left:calc(70*var(--u))}
  .menu__list{left:calc(70*var(--u)); width:calc(760*var(--u))}
  .menu__bubbles{left:auto; right:calc(40*var(--u)); width:calc(360*var(--u))}
}

@media (max-width:640px){
  :root{--u:0.25vw}              /* reference 400 — the mobile design frames */
  .grid{grid-template-columns:1fr}
  .stripes--1,.stripes--p1{opacity:.9}
  .hero,.phero{aspect-ratio:9/13}
  .hero__title,.phero__title{left:calc(36*var(--u)); bottom:calc(70*var(--u));
    width:calc(410*var(--u)); font-size:calc(50*var(--u))}
  .promise__inner{width:calc(410*var(--u)); gap:calc(56*var(--u))}
  .promise__title{font-size:calc(50*var(--u))}
  .promise__row{flex-direction:column; gap:calc(64*var(--u)); align-items:center}
  .promise__col,.promise__col:nth-child(1),.promise__col:nth-child(2),
  .promise__col:nth-child(3){width:calc(320*var(--u)); gap:calc(28*var(--u))}
  .promise__col p{font-size:calc(26*var(--u))}
  .socials__inner{width:calc(420*var(--u))}
  .socials__title{font-size:calc(50*var(--u))}
  .foot__inner{flex-direction:column; gap:calc(60*var(--u)); width:calc(410*var(--u))}
  .foot__tag{font-size:calc(40*var(--u))}
  .foot__nav{font-size:calc(24*var(--u))}
  .facts__card{width:calc(410*var(--u))}
  .pnutri__lead{padding:0 calc(36*var(--u)); font-size:calc(28*var(--u));
    line-height:calc(34*var(--u)); width:auto}
  .pintro__copy{width:calc(400*var(--u)); font-size:calc(28*var(--u));
    line-height:calc(34*var(--u))}

  /* no hover on touch — the dressed state lands with the block */
  .tile.is-in .tile__fill{transform:rotate(-45deg) translateY(0)}
  .tile.is-in .tile__name{opacity:1; transform:none}
  .tile.is-in .fizz{opacity:1}
  .tile.is-in .tile__can{transform:rotate(-9deg)}

  /* Lando's fan becomes a swipe rail, as their own mobile build does */
  .deck{display:flex; gap:calc(20*var(--u)); overflow-x:auto; height:auto; width:100%;
    scroll-snap-type:x mandatory; padding-bottom:calc(20*var(--u))}
  .deck::-webkit-scrollbar{display:none}
  .card{position:static; flex:0 0 62vw; width:62vw; height:auto; aspect-ratio:307/385;
    transform:none !important; scroll-snap-align:center}

  .menu__can{left:auto; right:calc(-40*var(--u)); top:auto; bottom:calc(60*var(--u));
    width:calc(190*var(--u)); height:auto; opacity:0}
  .menu__can.is-on{opacity:.5}
  /* no room for the logo next to the title at 400 — the ✕ owns the corner */
  /* both overlays: the fixed nav logo already shows — the menu's own copy
     doubled it up (Lee, 8 Sep: "2 logos" on the page menu) */
  .menu .menu__logo, .pagemenu .menu__logo{display:none}
  .menu__title{font-size:calc(50*var(--u))}
  .menu__list{width:auto; right:calc(38*var(--u))}
  .menu__head{font-size:calc(38*var(--u))}
  /* 26u keeps "Lemon & Elderflower" inside the 400 frame */
  .menu__flavours a{font-size:calc(26*var(--u))}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important}
  .hero__title .l>span,.phero__title .l>span{transform:none}
  .tile__wash{transform:scaleY(1)}
  .stripes .spine{stroke-dashoffset:0}
  .reveal{opacity:1; transform:none}
}


/* ── SECTION BLOCK REVEAL ────────────────────────────────
   menudurable slides a coloured panel up into each block
   (.background-reveal-container, parked at translateY(100px)).
   Same here: the section is transparent and its colour panel
   rises into place, with the content following just behind.
   ------------------------------------------------------ */
/* z:-1 keeps the wash behind STATIC children too — the mobile re-flow
   strips position:relative from band children, and a z:0 wash (appended
   last) painted over their text: visible on first paint, covered once JS
   ran. Desktop children are positioned z1 and unaffected. */
.wash{position:absolute; inset:0; z-index:-1; overflow:visible}
.wash svg{width:100%; height:100%; display:block}

.has-wash{background:transparent !important; position:relative; overflow:hidden}
.has-wash > *:not(.wash){position:relative; z-index:1;
  opacity:0; transition:opacity .55s var(--ease) .3s}
.has-wash.is-in > *:not(.wash){opacity:1}


/* ── cookie consent (Lee, 14 Sep): bottom-left card in the location-popup
   idiom (teal glass, white type). Below the cart drawer + menu. ─────── */
.consent { position: fixed; left: calc(32 * var(--u)); bottom: calc(32 * var(--u)); z-index: 80;
  width: calc(440 * var(--u)); box-sizing: border-box;
  background: rgba(32, 180, 194, .94); backdrop-filter: blur(6px); color: #fff;
  border-radius: calc(22 * var(--u)); padding: calc(30 * var(--u)) calc(32 * var(--u)) calc(28 * var(--u));
  box-shadow: 0 calc(12 * var(--u)) calc(40 * var(--u)) rgba(0, 45, 60, .25);
  opacity: 0; transform: translateY(calc(24 * var(--u)));
  transition: opacity .4s var(--ease), transform .4s var(--ease); }
.consent.is-in { opacity: 1; transform: none; }
.consent__title { margin: 0 0 calc(10 * var(--u)); font-weight: 700; font-size: calc(24 * var(--u)); line-height: 1.2; }
.consent__body { margin: 0 0 calc(22 * var(--u)); font-weight: 500; font-size: calc(17 * var(--u)); line-height: 1.4; }
.consent__body a { color: #fff; text-decoration: underline; }
.consent__row { display: flex; gap: calc(12 * var(--u)); }
.consent__accept, .consent__essential { flex: 1 1 0; height: calc(52 * var(--u)); border: 0; cursor: pointer;
  border-radius: calc(16 * var(--u)); font-weight: 700; font-size: calc(19 * var(--u)); font-family: inherit;
  transition: transform .2s var(--ease), background .2s var(--ease); }
.consent__accept { background: #fff; color: #20b4c2; }
.consent__essential { background: rgba(255, 255, 255, .22); color: #fff; font-weight: 500; }
.consent__accept:hover, .consent__essential:hover { transform: translateY(-2px); }
.consent__essential:hover { background: rgba(255, 255, 255, .32); }
.consent__accept:focus-visible, .consent__essential:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (max-width: 640px) {
  .consent { left: calc(16 * var(--u)); right: calc(16 * var(--u)); bottom: calc(16 * var(--u)); width: auto;
    padding: calc(24 * var(--u)) calc(24 * var(--u)) calc(22 * var(--u)); }
  .consent__title { font-size: calc(22 * var(--u)); }
  .consent__body { font-size: calc(16 * var(--u)); }
  .consent__accept, .consent__essential { height: calc(50 * var(--u)); font-size: calc(18 * var(--u)); }
}

/* Sanity text fields: editors' line breaks render (one newline = line
   break, blank line = paragraph gap). Scoped to text-only paragraphs so
   markup whitespace inside data-block containers stays collapsed (Lee, 14 Sep) */
p[data-block] { white-space: pre-line; }
