/* ============================================================
   THE ULTIMATE BREW, landing page (v2, the bag turn)
   ============================================================ */
body.light{background:var(--parchment);color:var(--ink);--frame:clamp(12px,1.35vw,28px)}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gut)}
.soft{color:var(--stone)}
.dark .soft{color:var(--on-dark-faint)}
section.dark{background:var(--ink);color:var(--on-dark)}
/* Light sections are parchment cards inset by the same frame as the hero, so the ink page shows around them and everything blends */
main{background:var(--ink);display:flow-root}   /* flow-root keeps the last card's frame margin inside the ink instead of collapsing out as a parchment strip */
/* Mobile hero: a plain full-bleed photo replacing the desktop 3D bag-turn, which doesn't translate to a phone.
   Hidden by default; the media query below swaps it in for .turn at phone widths. */
.mobile-hero{display:none}
.mobile-cta{display:none}   /* the phone's Sprouts card, above the photo hero; the desktop turn carries the same call as its first chapter */
@media (max-width:720px){
  .mobile-hero{display:block;position:relative;height:100svh;min-height:560px;max-height:880px;overflow:hidden}
  .mobile-hero img{width:100%;height:100%;object-fit:cover;object-position:50% 30%;display:block}
  .mobile-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(31,25,21,.1) 0%,rgba(31,25,21,.32) 45%,rgba(31,25,21,.92) 100%)}
  .mobile-hero-in{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:28px 20px calc(28px + env(safe-area-inset-bottom,0px))}
  .mobile-hero-in .kicker{color:var(--ink);background:var(--yellow);border-color:var(--yellow)}
  .mobile-hero-in h2{color:var(--on-dark);font-size:clamp(32px,9vw,44px);letter-spacing:-.03em;line-height:1.04;margin:14px 0}   /* an h2 since the Sprouts card above took the page's h1 (2026-10-11); same look */
  .mobile-hero-in h2 .disp{font-family:var(--display);font-weight:900;letter-spacing:-.01em;font-size:1.02em}
  .mobile-hero-in .sub{color:var(--on-dark-soft);font-size:16px;line-height:1.5;max-width:36ch;margin:0 0 22px}
  .mobile-hero-in .cta-row{gap:10px;flex-wrap:wrap}
  .mobile-hero-in .cta-row .btn{flex:1 1 auto;min-width:0}
  .mobile-hero-in .btn-ghost{border-color:rgba(252,250,245,.5)}
  .mobile-hero + .turn{display:none}   /* scoped to the home page's own .turn, which sits right after .mobile-hero in the DOM — .turn is reused as a static hero on about/contact/event and must stay visible there */
  /* The Sprouts card (2026-10-11): the phone's first screen, a parchment card like the desktop hero, with the three bags to look for
     on the endcap, then the call and the finder. The photo hero ("What's not in your coffee matters") follows it. */
  /* Oct 19 (owner): the Sprouts opening is a full-screen photo like .mobile-hero (Gary beside the endcap, arms crossed, the coffee on its top shelf; owner's pick, event-5966), no frame: the photo,
     a fade to the ink at the bottom, and the copy and the ZIP finder over it in light type */
  .mobile-cta{display:block;position:relative;height:100svh;min-height:640px;max-height:920px;overflow:hidden;color:var(--on-dark)}
  .mcta-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:56% 14%}
  .mobile-cta::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(31,25,21,.35) 0%,rgba(31,25,21,0) 16%,rgba(31,25,21,0) 34%,rgba(31,25,21,.78) 56%,rgba(31,25,21,.96) 74%,#1F1915 100%)}
  .mcta-copy{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:0 20px calc(92px + env(safe-area-inset-bottom,0px))}   /* clears the chat button in the corner */
  .mcta-copy h1{color:var(--on-dark)}
  .mcta-copy .endcap-tag{color:var(--on-dark)}
  .mcta-copy .sub{color:var(--on-dark-soft)!important}
  .mcta-copy .finder-msg{color:var(--on-dark-soft)}
  .mcta-copy .kicker{color:var(--ink);background:var(--yellow);border-color:var(--yellow)}
  .mcta-copy h1{font-size:clamp(32px,9vw,44px);letter-spacing:-.03em;line-height:1.04;margin:14px 0 16px}
  .mcta-copy h1 .disp{font-family:var(--display);font-weight:900;letter-spacing:-.01em;font-size:1.02em}
  .mcta-copy .sub{font-size:16px;line-height:1.5;max-width:36ch;margin:0 0 22px}
  .mcta-copy .finder{margin-top:20px}
  .mcta-copy .finder-note{margin-top:14px}
  .mcta-copy .cta-row{gap:14px 24px}
}
section.light{background:var(--parchment);color:var(--ink);margin:var(--frame);border-radius:clamp(16px,1.7vw,32px)}
.dark .kicker{color:var(--on-dark);border-color:var(--on-dark)}
.dark .lede{color:var(--on-dark-soft)}
.dark .body{color:var(--on-dark-soft)}
h2{font-size:clamp(40px,5.6vw,84px);letter-spacing:-.03em}
.big{font-size:clamp(26px,3vw,42px);font-weight:600;letter-spacing:-.02em;line-height:1.18}
.cta-row{display:flex;flex-wrap:wrap;align-items:center;gap:14px 28px}

/* ============================== THE TURN ============================== */
/* The hero is a rounded parchment card framed by umber on every side; the frame is --frame wide */
.turn{position:relative;height:520vh;background:var(--ink);padding:0 var(--frame) var(--frame)}
.tstage{position:sticky;top:var(--frame);height:calc(100vh - 2*var(--frame));height:calc(100svh - 2*var(--frame));overflow:hidden;padding:calc(84px + env(safe-area-inset-top,0px)) var(--gut) 24px;background:var(--parchment);border-radius:clamp(16px,1.7vw,32px)}
/* Layout: bag column dead center, copy columns either side */
.tstage{display:grid;grid-template-columns:minmax(0,1fr) var(--bagcol);grid-template-rows:1fr;align-items:center;column-gap:clamp(24px,4vw,72px);--bagcol:clamp(300px,min(38vw,58vh),520px)}

/* The film sits behind everything in the stage, cover-fitted; the bag inside it lands where the render bag stands */
.film{position:absolute;inset:0;z-index:1;opacity:0;transition:opacity .9s var(--ease-out);pointer-events:none;mix-blend-mode:darken}
/* Fallback (no canvas filters): darken blend, the film's parchment disappears into the page and the dark bag stays */
.film video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:100% 100%;will-change:transform;transform:translateZ(0)}
.film canvas{display:none;position:absolute;inset:0;width:100%;height:100%}
/* Matte path: the canvas shows colour through the alpha matte, the video only feeds it; no blend, so nothing bleeds through the bag */
.film.matte{mix-blend-mode:normal}
.film.matte video{visibility:hidden;object-fit:fill}
.film.matte canvas{display:block}
/* Roast swap: the outgoing bag's last frame sits on top and dissolves once the new film has drawn its first frame */
#filmPrev{z-index:2;opacity:0;transition:opacity .8s var(--ease-out);pointer-events:none}
#filmPrev.show{transition:none;opacity:1}
.tstage.film-on .film{opacity:1}
.tstage.film-on .bag3d{opacity:0;transition:opacity .28s var(--ease-out)}
/* Hybrid: on a hold the exact render shows and the film hides; the swap is a short crossfade */
.tstage.film-on .film{transition:opacity .28s var(--ease-out)}
.tstage.film-on.on-hold .film{opacity:0}
.tstage.film-on.on-hold .bag3d{opacity:1}
.tstage.film-on.on-hold .bag-shadow{opacity:1}
.bag-wrap.aligned{position:absolute;grid-column:auto;grid-row:auto;left:var(--fx);bottom:var(--fb);top:auto;right:auto;width:var(--fw);--bagcol:var(--fw);align-self:auto;align-content:end;padding:0;z-index:2}
.bag-wrap.aligned .roast-toggle{position:absolute;left:50%;top:100%;transform:translate(-50%,40px)}
/* Aligned to the film: flat projection so the resting faces are exactly the film bag's size, and a side depth matched to the film's sides */
.bag-wrap.aligned{perspective:none}
.bag-wrap.aligned .bag3d{--d:calc(var(--w)*.485);transform:scaleX(var(--sx,1)) rotateY(var(--ry,0deg))}
.bag-wrap.aligned .bag-shadow{bottom:0}
.tstage.film-on .ghost span{color:var(--ghost-on-film,#F3F0E7)}
.bag3d{transition:opacity .6s var(--ease-out)}

/* A context photo above a chapter's copy (rounded tile, cropped landscape); it rides the same entrance as the copy */
.ch-photo{position:relative;width:100%;aspect-ratio:16/9;border-radius:18px;overflow:hidden;margin:0;background:var(--surface)}   /* 16:9, capped on short screens so the quote never rides under the nav */
.ch-photo img{width:100%;height:100%;object-fit:cover;object-position:50% 38%;display:block}
.ch-photo .ch-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}   /* the waterfall loop sits over its own first frame; reduced motion keeps the still */
@media (prefers-reduced-motion:reduce){.ch-photo .ch-vid{display:none}}
.ch-photo figcaption{position:absolute;left:22px;bottom:20px;display:grid;gap:4px;color:#FCFAF5;text-shadow:0 1px 10px rgba(0,0,0,.5)}
.ch-photo figcaption strong,.ch-photo figcaption .mono{color:#FCFAF5;opacity:1}
.ch-photo figcaption strong{font-size:17px;font-weight:600;letter-spacing:-.01em}
.ch-photo figcaption .mono{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:#FCFAF5}
.ch-photo figcaption{z-index:1}
/* The proof chapter: quote on top, body and button in a row, the photo panel beneath on the bag's baseline */
.chapter.ch-1 .ch-r,.chapter.ch-1 .sub{max-width:none}.chapter.ch-1 .sub{white-space:nowrap}.chapter.ch-1 .ch-r{margin-top:16px}   /* same breath under the headline as the other chapters */   /* the opening summary is pinned to two lines */
.ch-2 .ch-l,.ch-2 .ch-r{max-width:none}
.chapter.ch-2 blockquote p{font-size:clamp(40px,3.96vw,74px);letter-spacing:-.045em;line-height:1.0;font-weight:600;margin:0 0 14px}   /* same scale as the opening headline */
/* The photo panel is 16:9 when there is room; site.js trims its height (--ch2ph) so the quote always clears the nav */
.ch-2 .ch-r{margin-top:0;gap:18px}
.ch-2 .ch-photo{aspect-ratio:16/9;width:var(--ch2pw,50%);height:auto;margin:0 0 26px}
.chapter.ch-2 .ch-l{padding-top:0}
.ch-2 .ch-row{display:block}.ch-2 .ch-row .sub{max-width:none}.ch-2 .ch-row .cta-row{margin-top:22px}
/* Chapter 3 (testing): the headline at hero scale, then a compact preview of the results gauges that replays each time the chapter comes up */
.ch-3 .ch-l,.ch-3 .ch-r{max-width:none}
.chapter.ch-3 h2{font-size:clamp(40px,3.96vw,74px);letter-spacing:-.045em;line-height:1.0;font-weight:600;margin:0;white-space:nowrap}
.ch-3 .ch-r{margin-top:20px;display:grid;gap:16px}
.ch-3 .ch-r .sub{max-width:none}
.gauge-list.mini{margin:0;width:80%;border-top:1px solid var(--rule-light)}
.mini .gauge{grid-template-columns:minmax(150px,.7fr) minmax(0,2fr) auto;gap:22px;padding:15px 0;opacity:0;transform:translateY(8px)}
.mini.run .gauge{opacity:1;transform:none}
.mini.run .gauge:nth-child(2){transition-delay:.08s}.mini.run .gauge:nth-child(3){transition-delay:.16s}.mini.run .gauge:nth-child(4){transition-delay:.24s}
.mini .g-name strong{font-size:16px}
.mini .g-name span{font-size:12px;margin-top:2px}
.mini .g-track{height:10px}
.mini .g-marker{top:-4px;height:18px}
.mini .g-result{grid-auto-flow:column;align-items:center;gap:12px;min-width:120px;justify-content:start}
.mini .g-val{font-size:17px;min-height:17px}
.mini .gauge.filling .g-val{font-size:13px}
.ch-3 .ch-r .cta-row{margin:6px 0 0}
@media (max-width:860px){.ch-1 .sub br,.ch-3 h2 br,.ch-3 .sub br,.ch-4 h2 br{display:none}.chapter.ch-1 .sub{white-space:normal}.chapter.ch-4 h2{white-space:normal}.gauge-list.mini{width:100%}.chapter.ch-3 h2{white-space:normal}.mini .gauge{grid-template-columns:1fr;gap:8px}.mini .g-result{min-width:0}}
/* Chapter 4 (the coffee) follows the same pattern: photo above the headline, chips and summary below */
.ch-4 .ch-l,.ch-4 .ch-r{max-width:none}
.chapter.ch-4 .ch-l{padding-top:0}
.ch-4 .ch-photo{aspect-ratio:16/9;width:var(--ch4pw,50%);height:auto;margin:0 0 26px}
.ch-2 .ch-photo .kicker,.ch-4 .ch-photo .kicker{position:absolute;left:14px;bottom:14px;margin:0;z-index:2}
.chapter.ch-4 h2{font-size:clamp(40px,3.96vw,74px);letter-spacing:-.045em;line-height:1.0;font-weight:600;margin:0;white-space:nowrap}
.ch-4 .ch-r{margin-top:22px;display:grid;gap:22px}
.ch-4 .ch-r .sub{max-width:none}
.ch-4 .ch-r .cta-row{margin:0}
/* The Sprouts chapter (2026-10-11), first in the turn: kicker and headline, then the endcap tag, the store finder and a quiet link to the
   testing page; from October 28 the online-ordering line and its button. One more chapter's worth of scroll (105vh each, as before), so
   every turning chapter keeps its old length; the bag holds its front through it (site.js: LEAD) */
.turn.with-lead{height:625vh}
.ch-lead .ch-l,.ch-lead .ch-r{max-width:var(--copyroom,720px)}   /* --copyroom: site.js, the space left of the film bag */
.chapter.ch-lead h1{font-size:min(clamp(48px,4.95vw,92px),calc(var(--copyroom,9999px)/9))}   /* the opening headline's size, but never wider than the room left of the bag: "for a limited time." runs about 8.7 times the type size, so it stays on two lines */
.ch-lead .ch-r{margin-top:24px;gap:18px;grid-template-columns:minmax(0,1fr)}   /* a definite track, so the finder can shrink to the room left of the bag */
.ch-lead .finder{margin-top:2px;width:min(520px,100%)}
.ch-lead .finder-note{margin-top:12px}
.ch-lead .sub{max-width:none}
.ch-lead .cta-row{margin-top:2px}
.ch-lead ~ .ch-1 > .ghost{display:none}   /* .ghost-hold stands behind both, so the word doesn't blink between them */
/* The endcap tag: a small yellow pill in the sans (the kicker above is the mono one); the last three days it turns ink, for urgency */
.endcap-tag{display:inline-flex;align-items:flex-start;max-width:34em;text-wrap:balance;gap:9px;justify-self:start;margin:0;color:var(--ink);font-size:15px;font-weight:600;letter-spacing:-.005em;line-height:1.2}   /* plain text, not a chip: the kicker above is the only pill */
.endcap-tag::before{content:"";width:7px;height:7px;margin-top:.43em;border-radius:50%;background:currentColor;flex:none}   /* the dot stays on the first line when the copy wraps */
.spr-next{margin-top:30px}   /* the bottom Sprouts section, from October 28: the list's button where the finder was */

/* Bag */
/* The bag sits low so the ghost word's upper half stays readable above it, like a word on a shelf behind the pack */
.bag-wrap{grid-column:2;grid-row:1;position:relative;z-index:2;display:grid;justify-items:center;align-content:end;align-self:stretch;gap:22px;padding-bottom:22px;perspective:2000px;perspective-origin:50% 40%}
.bag3d{--w:var(--bagcol);--d:calc(var(--w)*.5);position:relative;width:var(--w);height:calc(var(--w)*1.112);transform-style:preserve-3d;transform:rotateY(var(--ry,0deg));will-change:transform}
.face{position:absolute;top:0;left:50%;height:100%;width:var(--w);margin-left:calc(var(--w)*-.5);backface-visibility:hidden;-webkit-backface-visibility:hidden;object-fit:contain;object-position:center bottom;transform-origin:center;filter:drop-shadow(0 46px 44px rgba(31,25,21,.2));transition:opacity .35s var(--ease-out)}
.f-front{transform:translateZ(calc(var(--d)/2))}
.f-back{transform:rotateY(180deg) translateZ(calc(var(--d)/2))}
.f-right,.f-left{width:var(--d);margin-left:calc(var(--d)*-.5)}
.f-right{transform:rotateY(90deg) translateZ(calc(var(--w)/2))}
.f-left{transform:rotateY(-90deg) translateZ(calc(var(--w)/2))}
.face.swapping{opacity:0;transition:opacity .25s}
.bag3d.cull-js{transform:scaleX(var(--sx,1))!important;transform-style:flat}   /* Safari: the turn is drawn in 2D by site.js (cullFaces); --sx is the film-matching stretch */
.bag3d.cull-js .face{backface-visibility:visible;-webkit-backface-visibility:visible}

.roast-toggle{display:inline-flex;gap:2px;padding:4px;border-radius:999px;background:var(--surface)}
.roast-toggle button{height:38px;padding:0 16px;border-radius:999px;font-size:13.5px;font-weight:500;color:var(--ink);transition:background-color .35s var(--ease-out),color .35s var(--ease-out)}
.roast-toggle button:hover{color:var(--ink)}
.roast-toggle button[aria-checked="true"]{background:var(--ink);color:var(--parchment)}
@media (pointer:coarse){.roast-toggle button{min-height:44px}}

/* Soft contact shadow under the render bag, matching the film */
.bag-shadow{position:absolute;left:50%;bottom:calc(22px + 62px);width:calc(var(--bagcol)*1.1);height:calc(var(--bagcol)*.12);transform:translate(-50%,50%);border-radius:50%;background:radial-gradient(ellipse at center,rgba(42,36,32,.34),rgba(42,36,32,.14) 45%,transparent 72%);filter:blur(6px);pointer-events:none;z-index:0;transition:opacity .6s var(--ease-out)}

/* Pages with no bag (contact.html): a still photo, genuinely replacing the bag/film DOM (see the matching
   null-guards in site.js) rather than something painted over it. Unlike the real .bag-wrap — which sits in
   #tstage's own column 2, flush with the card's outer edge — this is pinned to the SAME 1400px column the
   rest of the site aligns to (matching .chapters' own max-width:1400px;margin:0 auto), right-aligned within
   it, so the photo's right edge lands where the nav/footer content column ends, not past it. */
.contact-photo{grid-column:1/-1;grid-row:1;width:100%;max-width:1400px;margin:0 auto;position:relative;z-index:2;display:flex;align-items:flex-end;justify-content:flex-end;padding-bottom:max(0px,calc((var(--bagbottom,150px) - 54px) * .45));pointer-events:none;transform:translateY(calc((1 - var(--k0,0))*24px))}   /* bottom-anchored like the chapter copy, but only half its offset — full offset (level with the CTA row) read as too high; the same small bump-up as the chapter-0 text, driven by --k0 mirrored from site.js */
.contact-photo img{pointer-events:auto;width:var(--bagcol);height:auto;aspect-ratio:4/5;object-fit:cover;border-radius:20px}
@media (max-width:860px){.contact-photo{padding:12vw 0 0;justify-content:center}}
.tstage.film-on .bag-shadow{opacity:0}
/* Stage-level ghost for phones */
.ghost-stage{display:none}

/* Chapters: full row, three columns, bag column left empty */
/* Copy lives in a centred 1400px container; the film and the ghost word stay full-bleed */
.chapters{grid-column:1/-1;grid-row:1;position:relative;align-self:stretch;display:grid;width:100%;max-width:1400px;margin:0 auto}
.chapter{grid-area:1/1;display:grid;grid-template-columns:minmax(0,1fr) var(--bagcol);column-gap:clamp(24px,4vw,72px);align-items:center;opacity:0;pointer-events:none;height:100%}
.chapter.on{pointer-events:auto}
.ch-l,.ch-r{grid-column:1;position:relative;z-index:2;transform:translateY(calc((1 - var(--k,0))*24px));max-width:720px}
.ch-r{display:grid;gap:22px;align-content:start;margin-top:26px}
.chapter .ch-l + .ch-r{grid-row:2}
.chapter .kicker{font-size:10px;letter-spacing:.1em;margin-bottom:14px;background:var(--yellow);border-color:var(--yellow);color:var(--ink)}   /* hero only: filled Ultimate Yellow, no outline */
/* Copy sits on the bag's baseline: the CTA row ends where the bag meets the floor (--bagbottom comes from the film geometry) */
.chapter{grid-template-rows:auto auto;align-content:end;padding-bottom:max(0px,calc(var(--bagbottom,150px) - 54px))}   /* the column ends 30px under the bag's foot (24px is the stage's own bottom padding) */   /* 24px stage padding, plus the bag's rounded foot */
/* The ghost word: the bag's own CLEAN band, echoed in a darker parchment */
.ghost{position:absolute;left:calc(50% - 50vw + var(--frame));right:calc(50% - 50vw + var(--frame));top:0;height:calc(var(--gfs,19vw)*.76);overflow:hidden;z-index:0;pointer-events:none;-webkit-user-select:none;user-select:none;transform:translateY(calc((1 - var(--k,0))*-1vw))}
.ghost span{display:block;font-family:var(--sans);font-weight:600;font-size:var(--gfs,19vw);line-height:.78;letter-spacing:-.01em;text-transform:uppercase;text-align:center;color:#F3F0E7;white-space:nowrap;transform:translate(var(--gx,0px),var(--gy,0px))}
.chapter h1{font-size:clamp(48px,4.95vw,92px);letter-spacing:-.045em;line-height:1.0;margin:18px 0 0;max-width:none}
.chapter h2{font-size:clamp(36px,3.6vw,64px);letter-spacing:-.045em;line-height:1.02;margin:16px 0 0}
.ch-l .body{margin-top:18px}
.chapter .sub{font-size:clamp(18px,1.35vw,24px);line-height:1.45;color:var(--umber);max-width:34ch;margin:0}
.chapter .cta-row{margin-top:4px}
.rtag{font-size:17px;color:var(--umber)}
.mono-list{list-style:none;display:grid;gap:10px;font-family:var(--mono);font-weight:600;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);margin:0}
.mono-list li::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--yellow);box-shadow:0 0 0 1px var(--ink);margin-right:10px;vertical-align:middle;position:relative;top:-1px}
.chapter blockquote p{font-size:clamp(28px,2.6vw,46px);font-weight:600;letter-spacing:-.025em;line-height:1.14;margin:16px 0 20px}
.chapter blockquote footer{display:flex;flex-direction:column;gap:6px}
.chapter blockquote .mono{font-size:10.5px;color:var(--stone)}
.ch-r .link{justify-self:start}
.specs-inline{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin:0}
.specs-inline li{font-size:11px;padding:9px 12px;border:1px solid var(--ink);border-radius:999px;letter-spacing:.14em}

/* Progress dots and cue */
.progress{list-style:none;position:absolute;right:max(var(--gut),min(calc((100% - 1400px)/2),120px));top:50%;transform:translateY(-50%);display:grid;gap:12px;z-index:4}   /* tracks the 1400px column's edge up to a point; past that (very wide monitors) it stops chasing the column out into empty space and settles near the real page edge instead */
.progress li{width:5px;height:5px;border-radius:50%;background:var(--sand);transition:background .4s,transform .4s}
.progress li.on{background:var(--ink);transform:scale(1.5)}
.cue{position:absolute;left:50%;bottom:calc(18px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;color:var(--stone);font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;transition:opacity .6s;z-index:4}
.cue .ring-wrap{display:block;width:30px;height:30px;color:var(--ink)}
.cue .ring{width:30px;height:30px;transform:rotate(-90deg)}
.cue .ring circle{transition:stroke-dashoffset .2s linear}
.cue .chev{width:12px;height:12px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;animation:chev 2.4s var(--ease-io) infinite}
@keyframes chev{0%,100%{transform:translateY(-3px) rotate(45deg);opacity:.5}50%{transform:translateY(3px) rotate(45deg);opacity:1}}
.tstage.past .cue{opacity:0}
@media (max-height:560px){.cue,.progress{display:none}}

/* Phones and portrait tablets: ghost word, bag, then copy stacked, still scroll-driven */
@media (max-width:860px),(orientation:portrait) and (max-width:1024px){
  .turn{height:500vh}
  .turn.with-lead{height:600vh}   /* 100vh a chapter here, the lead included */
  .chapters > .ghost{display:none}   /* the shared ghost goes with the chapter ghosts; .ghost-stage takes over */
  .tstage{overflow:hidden;grid-template-columns:minmax(0,1fr)}
  .chapter{grid-template-columns:minmax(0,1fr);min-width:0}
  .chapter h1,.chapter h2,.chapter .sub,.chapter blockquote p{white-space:normal}.chapter h2 br,.chapter .sub br,.chapter blockquote br{display:none}
  .chapter.ch-2 h2,.chapter.ch-3 h2,.chapter.ch-4 h2{font-size:clamp(26px,7vw,36px)}
  .specs-inline{flex-wrap:wrap;white-space:normal}.ch-1 .cta-row,.ch-r .cta-row{flex-wrap:wrap}
  .tstage{grid-template-columns:1fr;grid-template-rows:auto 1fr;align-items:start;padding-top:calc(60px + env(safe-area-inset-top,0px));padding-bottom:28px;row-gap:10px;--bagcol:min(58vw,300px)}
  .bag-wrap{grid-column:1;grid-row:1;gap:12px;padding:12vw 0 0;align-content:start;align-self:start}
  .chapters{grid-column:1;grid-row:2;align-self:start}
  .chapter{grid-template-columns:1fr;grid-template-rows:auto auto;row-gap:14px;align-items:start;align-content:start;height:auto}
  .ch-l,.ch-r{grid-column:1;max-width:none}
  .ch-r{margin-top:0}
  .chapter .ghost{display:none}
  .ch-photo{display:none}
  .chapter{align-content:start;padding-bottom:0}
  .roast-toggle{padding:4px}.roast-toggle button{height:40px;padding:0 14px;font-size:14px}
  .tstage{border-radius:clamp(16px,4vw,24px)}
  .ghost-stage{display:block;top:calc(48px + env(safe-area-inset-top,0px));z-index:0}
  .bag-shadow{bottom:calc(12px + 56px)}
  .chapter h1{font-size:clamp(30px,8.4vw,42px);max-width:none;margin-top:10px}
  .chapter h2{font-size:clamp(26px,7vw,36px);margin-top:8px}
  .chapter blockquote p{font-size:clamp(21px,5.6vw,28px)}
  .chapter .body{font-size:15px}
  .chapter .sub{font-size:14px}
  .progress{display:none}
  .signup-light .signup-row{flex-direction:column}
  .signup.signup-light label{font-size:14.5px;margin-bottom:10px}
  .hero-static .tstage{height:auto;overflow:visible}   /* about/contact/event reuse the turn hero as one static, non-scroll-jacked chapter; stacked mobile copy (headline+lede+CTAs) regularly runs taller than one screen, and the base .tstage's fixed 100svh height plus overflow:hidden was clipping the bottom of it (e.g. the CTA row on event.html) */
}

/* Reduced motion and no JS: stack the chapters, faces static */
.turn.static{height:auto}
.turn.static .tstage{position:relative;height:auto;display:block;padding-top:calc(96px + env(safe-area-inset-top,0px))}
.turn.static .progress,.turn.static .cue,.turn.static .ghost,.turn.static .bag-shadow{display:none}
.turn.static .bag3d{transform:none}
.turn.static .face:not(.f-front){display:none}
.turn.static .f-front{position:static;margin:0 auto;transform:none}
.turn.static .chapters{display:grid;gap:64px;margin-top:48px}
.turn.static .chapter{grid-area:auto;grid-template-columns:1fr 1fr;opacity:1;pointer-events:auto;height:auto}
.turn.static .ch-l,.turn.static .ch-r{transform:none}
@media (max-width:860px){.turn.static .chapter{grid-template-columns:1fr}}

/* ============================== A. RECEIPTS ============================== */
.receipts{padding:clamp(96px,12vw,160px) 0}
.rec-intro{max-width:760px}
.rec-intro h2{margin:14px 0 22px}
/* The receipts preview: the same compact gauges as hero chapter 3, run once when the section scrolls into view */
.rec-preview{margin-top:clamp(36px,4vw,56px);max-width:900px}
.rec-preview .gauge-list.mini{width:100%}
.receipts .mini .gauge{padding:16px 0}
.rec-note{margin-top:18px;font-size:13px;line-height:1.55;color:var(--stone);max-width:60ch}
.rec-preview .cta-row{margin-top:26px}

/* ============================== B. TESTS ============================== */
.tests{padding:clamp(96px,12vw,160px) 0}
.tests-head h2{margin-top:14px}
.tests-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:clamp(40px,5vw,72px)}
.tcard{position:relative;background:var(--surface);border-radius:14px;padding:28px 24px 24px;min-height:340px;display:flex;flex-direction:column;transition:transform .7s var(--ease-out),box-shadow .7s var(--ease-out)}
.tcard:hover{transform:translateY(-6px);box-shadow:0 30px 60px rgba(31,25,21,.08)}
.tnum{position:absolute;top:24px;right:24px;font-size:11px;color:var(--stone)}
.tcard h3{font-size:12px;color:var(--umber);margin-bottom:22px}
.tcard ul{list-style:none;display:grid;gap:10px;font-size:15.5px}
.tcard li::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--ink);margin-right:10px;vertical-align:middle;position:relative;top:-1px}
.tfoot{margin-top:auto;padding-top:24px;font-size:13.5px;color:var(--umber);border-top:1px solid var(--sand)}
@media (max-width:1000px){.tests-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.tests-grid{grid-template-columns:1fr}.tcard{min-height:0}}
.tests-close{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(28px,5vw,72px);align-items:center}
.tests-close-section{padding:clamp(96px,12vw,160px) 0}   /* the scan photo + verify-the-claim copy stays on the page's dark background, split out of the light .tests card above it */
.scan{border-radius:14px;overflow:hidden;aspect-ratio:4/5;background:var(--surface)}
.scan img{width:100%;height:100%;object-fit:cover}
.tests-close-copy .big{max-width:22ch;font-size:clamp(32px,3.8vw,54px)}
.tests-close-copy .body{margin:22px 0 30px}
@media (max-width:860px){.tests-close{grid-template-columns:1fr}.scan{aspect-ratio:4/3}}

/* ============================== C. ROASTS (editorial) ============================== */
.roasts{padding:clamp(96px,12vw,160px) 0}
.roasts-head h2{margin-top:14px}
/* The range as a product grid: three cards, each bag turns 360 on hover (a looping render), like a catalogue shelf */
.roast-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin-top:clamp(40px,5vw,72px)}
.rcard{--card:#FCFAF5;color:var(--ink);display:flex;flex-direction:column;align-items:center;text-align:center;background:var(--card);border-radius:22px;padding:30px 28px 32px;transition:transform .6s var(--ease-out),background-color .6s var(--ease-out)}
.rcard:hover,.rcard:focus-within{transform:translateY(-6px)}   /* the card colour stays put */
/* Cream cards on the ink band (2026-10-02, the owner's pick): the black bags stand out; text, pills and buttons in ink, NEW in yellow on ink */
.rcard h3{color:var(--ink)}
.rcard .body{color:var(--umber)}
.rcard .kicker{color:var(--ink);border-color:rgba(31,25,21,.55)}
.rcard .btn-ghost{color:var(--ink);border-color:rgba(31,25,21,.35);background:transparent}
.rcard .btn-ghost:hover,.rcard .btn-ghost:focus-visible{background:var(--ink);color:var(--parchment);border-color:var(--ink)}
.rcard{position:relative}
.rnew{position:absolute;top:18px;left:18px;font-family:var(--mono);font-weight:600;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--yellow);background:var(--ink);border-radius:999px;padding:5px 10px 4px;line-height:1.2}
.rcard h3{font-size:clamp(24px,2vw,32px);letter-spacing:-.025em;margin:16px 0 0}
/* The render leaves air above and below the bag; the box is shorter than the square and the square is centred in it, so that air is halved */
.rmedia{position:relative;width:100%;max-width:420px;aspect-ratio:1.24;margin:14px auto 14px;overflow:hidden;background:transparent}
.rmedia canvas{position:absolute;left:0;top:50%;width:100%;aspect-ratio:1;height:auto;transform:translateY(-50%) scale(0.94);transition:transform .7s var(--ease-out)}
.rmedia img,.rmedia video{position:absolute;left:0;top:50%;width:100%;aspect-ratio:1/2;height:auto;transform:translateY(-25%);opacity:0;pointer-events:none}   /* draw sources; the fallback shows the poster's colour half */
.rmedia.nomatte img{opacity:1;clip-path:inset(0 0 50% 0);transform:translateY(-25%) scale(0.94)}
.rmedia.nomatte canvas{display:none}
.rcard:hover .rmedia canvas{transform:translateY(-50%) scale(0.98)}.rcard:hover .rmedia.nomatte img{transform:translateY(-25%) scale(0.98)}
.rmedia.nomatte.still img{top:0;height:100%;aspect-ratio:auto;object-fit:contain;clip-path:none;transform:scale(0.94);transition:transform .7s var(--ease-out)}   /* no canvas filter (Safari): the transparent front shot instead of the stacked loop, whose colour half carries the old dark card colour */
.rcard:hover .rmedia.nomatte.still img{transform:scale(0.98)}
.rcard .body{font-size:16px;max-width:34ch;margin:0}
.rcard .btn{margin-top:26px}
@media (max-width:1000px){.roast-grid{grid-template-columns:1fr;max-width:460px;margin-left:auto;margin-right:auto}}
@media (prefers-reduced-motion:reduce){.rcard,.rmedia canvas,.rmedia img{transition:none}.rcard:hover{transform:none}.rcard:hover .rmedia canvas{transform:translateY(-50%) scale(0.94)}.rcard:hover .rmedia.nomatte img{transform:translateY(-25%) scale(0.94)}}

/* ============================== D. SPROUTS ============================== */
.sprouts{padding:clamp(96px,12vw,160px) 0;background:var(--surface)}
.sprouts-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,6vw,96px);align-items:center}
.sprouts-copy h2{margin:14px 0 22px}
.finder{margin-top:32px;max-width:520px}
/* One pill, the button nested inside it on the right (the Huberman Lab newsletter pattern) */
.finder-row{display:flex;align-items:center;gap:6px;padding:5px 5px 5px 8px;border-radius:999px;border:1px solid var(--sand);background:#fff;transition:border-color .25s,box-shadow .25s}
.finder-row:focus-within{border-color:var(--ink);box-shadow:0 0 0 3px rgba(31,25,21,.08)}
.finder .finder-row input{border:0;background:transparent;box-shadow:none;padding:0 16px;height:52px;border-radius:999px}
.finder .finder-row input:focus{outline:none;border:0;box-shadow:none}
.finder-row .btn{height:52px;padding:0 22px;flex:none}
.finder input,.signup input{flex:1;min-width:0;font:inherit;font-size:16px;padding:14px 18px;border-radius:999px;border:1px solid var(--sand);background:var(--parchment);color:var(--ink);transition:border-color .3s,box-shadow .3s}
.finder input:focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px rgba(31,25,21,.08)}
.finder-alt{display:flex;flex-wrap:wrap;align-items:baseline;gap:18px;margin-top:14px;font-size:14px}
.finder-alt:has(.finder-msg:empty){display:none}   /* only the status line lives here now; no gap until it has something to say */
.finder-msg{color:var(--umber)}
.finder-note{margin-top:18px;font-size:13px;color:var(--stone)}
.sprouts-photo{border-radius:14px;overflow:hidden;aspect-ratio:4/3;background:var(--sand)}
.sprouts-photo img{width:100%;height:100%;object-fit:cover}
@media (max-width:860px){.sprouts-grid{grid-template-columns:1fr}.sprouts-photo{order:-1}.finder-row{flex-direction:column;align-items:stretch;border:0;background:transparent;padding:0;gap:10px;box-shadow:none}.finder .finder-row input{flex:none;height:52px;border:1px solid var(--sand);background:#fff;padding:0 18px}.finder-row .btn{width:100%}}   /* .finder .finder-row: as specific as the desktop rule that takes the input's own border off (it sits in the white pill there), or stacked on a phone the field had no outline at all */

/* ============================== E. LIST ============================== */
@keyframes breathe{from{transform:translate(-50%,-50%) scale(.92)}to{transform:translate(-50%,-50%) scale(1.06)}}
.check{width:28px;height:28px;border-radius:50%;background:var(--yellow);flex:none;position:relative}
.check::after{content:"";position:absolute;left:10px;top:6px;width:6px;height:12px;border-right:2px solid var(--ink);border-bottom:2px solid var(--ink);transform:rotate(45deg)}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
@media (max-width:860px){.list-grid{grid-template-columns:1fr}}

/* ============================== F. CLOSE ============================== */

/* Reduced motion, honored completely */
@media (prefers-reduced-motion:reduce){
  .rbag,.doc-cta,.dr-val .val,.doc-row::after,.face{transition:none}
  .list::before{animation:none}
  .cue .chev{animation:none}
}

/* ---- The test-card grid now lives on its own light card; only the closing scan photo stays on ink ---- */
.tests-close-section .scan{background:var(--ink-2)}

/* The proof chapter's pinned line breaks are for desktop widths only */
.chapter.ch-2 blockquote p{white-space:nowrap}
@media (max-width:860px){.ch-2 blockquote br,.ch-2 .sub br{display:none}.chapter.ch-2 blockquote p{white-space:normal}}


/* Roasts page: the cards carry two extra lines, and the hero borrows the chapter chips */
.rcard .rbest{font-size:15px;line-height:1.5;color:var(--umber);margin:12px 0 0;max-width:34ch}
.rcard .rbest strong{color:var(--ink);font-weight:600}
.rcard .rbrew{font-size:11px;letter-spacing:.12em;color:var(--stone);margin:10px 0 18px}
.rcta{display:grid;justify-content:center;gap:10px;margin-top:26px}   /* View <roast> (its page, coffee/<roast>), with the small Sprouts link under it */
.rcard .rcta .btn{margin-top:0}
.rcard .rlink::after{content:"";position:absolute;inset:0;border-radius:22px}   /* the whole card opens the roast's page; still one tab stop */
.rcard.reveal > .rcta{transform:none}   /* no slide-in for the button row (it still fades): a transform would make it the box the link's overlay fills, so the card would not open until the entrance ended */
.rcard .rcta .rbuy{position:relative;z-index:1}   /* the Sprouts line stays clickable above that */
.rcard .rbuy{justify-self:center;font-size:13.5px;line-height:1.4;color:var(--umber);text-decoration:underline;text-decoration-color:rgba(31,25,21,.3);text-underline-offset:3px;padding:4px 2px;transition:color .3s var(--ease-out),text-decoration-color .3s var(--ease-out)}   /* one button per card (View <roast>); where to buy is a small link under it */
.rcard .rbuy:hover,.rcard .rbuy:focus-visible{color:var(--ink);text-decoration-color:var(--ink)}
.rhero-specs{margin-top:24px}
.rhero-specs li{border-color:rgba(252,250,245,.32);color:var(--on-dark)}
.how.dark .how-head h2{color:var(--on-dark)}
.how.dark .steps{border-top-color:var(--rule-dark)}
.how.dark .step{border-right-color:var(--rule-dark)}
.how.dark .step p{color:var(--on-dark-soft)}
.how.dark .snum{color:var(--on-dark-faint)}
.how.dark .kicker{color:var(--on-dark);border-color:var(--on-dark)}

/* ---- Long-read pages (about, and the story block on the testing page) ---- */
.essay{padding:clamp(72px,9vw,128px) 0 clamp(56px,7vw,96px)}
.essay-grid{display:grid;grid-template-columns:240px minmax(0,1fr);gap:clamp(32px,6vw,120px)}
.essay-toc{position:sticky;top:calc(96px + env(safe-area-inset-top,0px));align-self:start}
.essay-toc .kicker{margin-bottom:18px}
.essay-toc ol{list-style:none;display:grid;gap:10px;font-size:14px}
.essay-toc a{display:flex;gap:12px;color:var(--stone);transition:color .3s}
.essay-toc a:hover{color:var(--ink)}
.essay-toc .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;padding-top:3px}
.essay-body{max-width:72ch}
.essay-body .chapter-block{padding:0 0 clamp(40px,5vw,72px);scroll-margin-top:110px}
.essay-body .chapter-block+.chapter-block{padding-top:clamp(40px,5vw,72px);border-top:1px solid var(--rule-light)}
.essay-body .cnum{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--stone);margin-bottom:16px}
.essay-body h2{font-size:clamp(32px,3.2vw,52px);letter-spacing:-.03em;line-height:1.02;margin:0 0 26px;max-width:20ch}
.essay-body h2 .disp{font-size:1.02em}
.essay-body p{font-size:clamp(17px,1.25vw,20px);line-height:1.62;color:var(--umber);margin:0 0 20px}
.essay-body p.lead-in{font-size:clamp(20px,1.6vw,25px);line-height:1.45;color:var(--ink)}
.essay-body blockquote{margin:36px 0;padding:0 0 0 28px;border-left:3px solid var(--yellow);font-family:var(--display);font-weight:900;font-size:clamp(24px,2.2vw,34px);line-height:1.18;letter-spacing:-.01em;color:var(--ink)}
.essay-body blockquote p{font:inherit;color:inherit;margin:0}
.essay-two{display:grid;grid-template-columns:1fr 1fr;gap:24px 40px;margin-top:clamp(36px,4vw,56px)}
.essay-two h3{font-size:clamp(20px,1.6vw,24px);letter-spacing:-.02em;margin-bottom:14px}
.essay-two ul{list-style:none;display:grid;gap:12px}
.essay-two li{position:relative;padding-left:26px;font-size:16.5px;line-height:1.5;color:var(--umber)}
.essay-two li::before{content:"";position:absolute;left:0;top:.5em;width:12px;height:12px;border-radius:50%;background:var(--yellow)}
.essay-two .wont li::before{background:none;border:1.5px solid var(--stone);width:10px;height:10px}
.dark .essay-body p{color:var(--on-dark-soft)}.dark .essay-body p.lead-in,.dark .essay-body h2,.dark .essay-body blockquote{color:var(--on-dark)}
.dark .essay-two li{color:var(--on-dark-soft)}.dark .essay-two h3{color:var(--on-dark)}
.dark .essay-body .chapter-block+.chapter-block{border-top-color:var(--rule-dark)}
@media (max-width:1000px){.essay-grid{grid-template-columns:1fr}.essay-toc{position:static;display:none}}
@media (max-width:640px){.essay-two{grid-template-columns:1fr}}
/* Story block: two columns of body copy under a wide heading */
.story-cols{columns:2;column-gap:48px;margin-top:clamp(32px,4vw,56px)}
.story-cols p{break-inside:avoid;font-size:17px;line-height:1.6;color:var(--umber);margin:0 0 18px}
.dark .story-cols p{color:var(--on-dark-soft)}
@media (max-width:760px){.story-cols{columns:1}}
/* FAQ: plain details, ruled */
.faq-list{margin-top:clamp(36px,4vw,56px);border-top:1px solid var(--rule-dark)}
.faq-list details{border-bottom:1px solid var(--rule-dark)}
.faq-list summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:24px;padding:24px 0;font-size:clamp(18px,1.4vw,22px);font-weight:600;letter-spacing:-.015em;color:var(--on-dark)}
.faq-list summary::-webkit-details-marker{display:none}
.faq-list summary::after{content:"";flex:none;width:26px;height:26px;color:var(--on-dark-faint);background:linear-gradient(currentColor,currentColor) center/2px 60% no-repeat,linear-gradient(currentColor,currentColor) center/60% 2px no-repeat;transition:transform .6s cubic-bezier(.4,0,.2,1)}   /* drawn as two bars in a square box, not a text glyph, so it rotates around a true visual centre instead of a font glyph's off-centre box */
.faq-list details.is-open summary::after{transform:rotate(225deg)}   /* a touch past 180° so it visibly spins through rather than just flipping in place */
.faq-list details p{max-width:70ch;font-size:16.5px;line-height:1.6;color:var(--on-dark-soft);margin:-6px 0 26px;overflow:hidden}
.light .faq-list,.light .faq-list details{border-color:var(--rule-light)}.light .faq-list summary{color:var(--ink)}.light .faq-list details p{color:var(--umber)}.light .faq-list summary::after{color:var(--stone)}
.essay-cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:clamp(36px,4vw,56px)}
.rhero.about .rhero-copy{max-width:1040px}
.rhero.about h1{font-size:clamp(46px,5.4vw,100px);white-space:nowrap}
@media (max-width:760px){.rhero.about h1{white-space:normal}.rhero.about h1 br{display:none}}
.origin-photo{margin:36px 0 8px}
.origin-photo img{width:100%;height:auto;object-fit:cover;display:block;border-radius:20px;background:var(--ink-2)}
.origin-photo figcaption{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--stone);padding:12px 0 0}

/* Phone and portrait tablet: every hero headline wraps, whatever the desktop pinning above says (last, so it wins the tie) */
@media (max-width:860px),(orientation:portrait) and (max-width:1024px){.turn .chapter h1,.turn .chapter h2,.turn .chapter .sub,.turn .chapter blockquote p{white-space:normal}.turn .chapter h2 br,.turn .chapter .sub br,.turn .chapter blockquote br{display:none}}

/* Feature rows (origin page): copy on the left, a photo pinned on the right while four stages of copy scroll past it, across the full 1400px column */
.feats-sticky-grid{--media-h:min(680px,74vh);--media-top:max(calc(var(--frame) + 106px), calc((100vh - var(--media-h)) / 2));display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(32px,5vw,88px);max-width:1400px;margin:0 auto;padding:clamp(56px,7vw,104px) var(--gut) clamp(40px,5vw,72px);align-items:start}   /* --media-top centres the photo vertically (equal padding above and below) once the viewport is tall enough to clear the nav; on short viewports it falls back to the minimum nav clearance instead of crowding it */
.feats-text{order:1;display:grid}
.feats-media{order:2;position:sticky;top:var(--media-top);height:var(--media-h);border-radius:24px;overflow:hidden;background:var(--ink-2)}
.fm-img{position:absolute;inset:0;opacity:0;transition:opacity 1.15s var(--ease-out)}
.fm-img.active{opacity:1}
.fm-img img{width:100%;height:100%;object-fit:cover;display:block}
.feat-block{min-height:100vh;margin-bottom:14vh;scroll-margin-top:110px}   /* the tall scroll spacer that gives each stage room to hold; the actual copy lives in .feat-inner below — every stage, including the last, gets the same spacer so the roast stage doesn't feel like a shorter scroll than the ones before it */
.feat-inner{position:sticky;top:var(--media-top);height:var(--media-h);display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-start}   /* mirrors the photo's own top+height exactly, so it sticks and releases in lockstep with it (rather than computing an offset in JS, which only matched on some viewports) and bottom-aligns the shorter text within that same box */
.feat-inner .kicker{font-size:10px;line-height:1;color:var(--ink);margin:0 0 18px;max-width:none}   /* the row body-copy rule is more specific than .kicker, so pin the pill back to its normal size */
.feat-inner h2{font-size:clamp(32px,3.2vw,52px);letter-spacing:-.03em;line-height:1.02;margin:0 0 24px;max-width:18ch}
.feat-inner h2 .disp{font-size:1.02em}
.feat-inner p{font-size:clamp(19px,1.45vw,23px);line-height:1.62;color:var(--umber);margin:0 0 18px;max-width:56ch}
.feat-inner p.lead-in{line-height:1.45;color:var(--ink)}
.feat-inner .essay-cta{margin-top:28px}
.feat-photo{display:none}
@media (max-width:860px){.feats-sticky-grid{grid-template-columns:1fr;gap:0}.feats-media{display:none}.feat-block{min-height:0}.feat-inner{position:static;height:auto;justify-content:flex-start;padding:28px 0}
  .feat-photo{display:block;aspect-ratio:16/10;border-radius:20px;overflow:hidden;background:var(--ink-2)}
  .feat-photo img{width:100%;height:100%;object-fit:cover;display:block}
}   /* the desktop panel's fixed height + bottom-alignment (for the sticky-photo sync) must not carry over here — on mobile the text stacks in normal flow below its own photo, and a leftover fixed height with justify-content:flex-end let long copy overflow upward past the container's own top edge. The single sticky .feats-media crossfade doesn't translate to mobile scroll (it just scrolls away after the first stage), so each stage gets its own static .feat-photo instead */


/* ---- About page v2: cinematic and editorial, few words ---- */
.ab2-hero .rhero-copy{max-width:900px}
.ab2-hero .rhero-in{padding-bottom:clamp(56px,7vw,110px)}
.ab2-hero .lede{max-width:52ch}
/* Meet Gary: its own full-bleed dark section (not the page-results auto-card), so it sits flush against the
   hero above and the light idea+quote card below — light, dark, light, dark, the same rhythm as the home page */
.ab2-meet-section{padding:clamp(72px,9vw,130px) 0}
.ab2-meet{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(32px,6vw,110px);align-items:center}
.ab2-portrait{margin:0;border-radius:24px;overflow:hidden;aspect-ratio:4/5}
.ab2-portrait img{width:100%;height:100%;object-fit:cover;object-position:50% 15%;display:block}
.ab2-meet-copy h2{font-size:clamp(28px,2.6vw,44px);letter-spacing:-.03em;line-height:1.1;margin:18px 0 26px;text-wrap:pretty}
.ab2-meet-copy h2 .disp{font-size:1.02em}
.ab2-meet-copy p{font-size:clamp(17px,1.25vw,20px);line-height:1.6;color:var(--on-dark-soft);max-width:52ch;margin:0 0 18px}
.ab2-meet-copy .kicker{font-size:10px}   /* the .kicker pill is itself a <p>, so the rule above (more specific than the base .kicker) was blowing it up to body-copy size */
.ab2-sig{display:flex;flex-direction:column;gap:4px;font-size:15px;color:var(--umber)}
.ab2-sig .mono{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
/* The idea and the promise: one continuous light card — the wide photo/principles block bleeds straight into
   the quote block below it, divided only by a hairline, not a background change */
.ab2-idea{padding:clamp(72px,9vw,140px) 0 clamp(80px,10vw,150px)}
.ab2-wide{margin:0 0 clamp(48px,6vw,96px);border-radius:24px;overflow:hidden;aspect-ratio:21/9;background:var(--ink-2)}
.ab2-wide img{width:100%;height:100%;object-fit:cover;object-position:50% 35%;display:block}
.ab2-idea-grid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:clamp(28px,5vw,96px);align-items:start}
.ab2-idea h2{font-size:clamp(36px,4.2vw,74px);letter-spacing:-.04em;line-height:1;margin:0;color:var(--ink);max-width:12ch}
.ab2-idea h2 .disp{font-size:1.02em}
.ab2-idea-copy p{font-size:clamp(17px,1.25vw,20px);line-height:1.6;color:var(--umber);margin:0 0 18px;max-width:50ch}
.ab2-idea .principles{margin-top:clamp(48px,6vw,88px);border-top-color:var(--rule-light)}
.ab2-idea .principles li{border-right-color:var(--rule-light);color:var(--umber)}
.ab2-idea .principles strong{display:block;color:var(--ink);font-weight:600;margin-bottom:6px}
.ab2-quote{margin-top:clamp(64px,8vw,110px);padding-top:clamp(56px,7vw,96px);border-top:1px solid var(--rule-light)}
.ab2-quote-in{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(32px,6vw,110px);align-items:center}
.ab2-quote-photo{margin:0;border-radius:24px;overflow:hidden;aspect-ratio:4/5}
.ab2-quote-photo img{width:100%;height:100%;object-fit:cover;display:block}
.ab2-quote blockquote{margin:0}
.ab2-quote blockquote p{font-family:var(--display);font-weight:900;font-size:clamp(32px,3.6vw,64px);line-height:1.04;letter-spacing:-.015em;color:var(--ink);margin:0 0 26px;max-width:18ch}
.ab2-cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:clamp(32px,4vw,48px)}
@media (max-width:860px){.ab2-meet,.ab2-quote-in,.ab2-idea-grid{grid-template-columns:1fr;gap:28px}.ab2-wide{aspect-ratio:4/3}.ab2-idea h2{max-width:none}.ab2-portrait{aspect-ratio:4/5}}
.ab2-hero .rhero-bg::before{background:rgba(31,25,21,.18)}
.ab2-hero .rhero-bg::after{background:linear-gradient(180deg,rgba(31,25,21,.25) 0%,rgba(31,25,21,.3) 50%,rgba(31,25,21,.78) 100%)}
.ab2-wide{aspect-ratio:16/9}.ab2-wide img{object-position:50% 45%}

/* ---- Event page ---- */
/* What's happening: dark, flush against the turn hero above; the when/where/cost row reuses the same
   ruled .steps divider treatment as the "how we test"/"four habits" sections elsewhere on the site */
.ev-what{padding:clamp(72px,9vw,130px) 0}
.ev-steps{grid-template-columns:repeat(3,minmax(0,1fr))}   /* three items now that the giveaways column is gone, instead of the shared four-column .steps grid leaving an empty slot */
@media (max-width:1000px){.ev-steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.ev-steps{grid-template-columns:1fr}}   /* must come after the 1000px rule above (same specificity, and index.css loads after site.css) or it never wins at phone widths */
/* What to expect: reuses the coffee page's .feats-sticky/.feat-block sticky-photo scroll as-is, no page-specific CSS needed */
.ev-logo{display:block;width:min(520px,78%);height:auto;filter:invert(1) sepia(.08) brightness(1.06);margin:0 0 18px -2px}   /* the event logo is single-colour ink; inverted it lands on parchment white over the photo */
.ev-with{display:block;font-size:clamp(30px,3.2vw,56px);letter-spacing:-.035em;line-height:1.02;font-weight:600}
@media (max-width:640px){.ev-logo{width:88%}}
/* Home: the Coffee Brecka gets its own two-column row under the finder, photo left, copy right */
.ev-row{margin-top:clamp(64px,8vw,120px);padding-top:clamp(48px,6vw,88px)}
.ev-row-photo{aspect-ratio:4/3}
.ev-row-photo img{object-position:60% 40%}
.ev-row-logo{display:block;width:min(380px,82%);height:auto;margin:0 0 12px -2px}
.ev-row-h{font-size:clamp(30px,2.6vw,44px);line-height:1.04;white-space:nowrap}
.ev-row-h .disp{display:block;font-size:1.55em;line-height:1.05;margin:.04em 0 .08em -.01em}
.ev-row-with{display:block;font-size:1em;letter-spacing:-.03em;line-height:1.04;font-weight:600;color:var(--stone);font-family:var(--sans)}
.ev-row-meta{display:grid;grid-template-columns:1fr 1.4fr;gap:16px 28px;margin:26px 0 0;max-width:600px}
.ev-row-meta dt{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--stone);margin-bottom:6px}
.ev-row-meta dd{margin:0;font-size:15.5px;line-height:1.45;color:var(--ink)}
.ev-row-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
@media (max-width:860px){.ev-row{grid-template-columns:1fr}.ev-row-meta{grid-template-columns:1fr}}
.sprouts-copy .spr-h{font-size:clamp(30px,2.6vw,44px);line-height:1.08;letter-spacing:-.03em}
@media (max-width:640px){.sprouts-copy .spr-h br{display:none}}

/* Sprouts finder, parked pre-launch: swaps for the real form via .pre/.post (site-wide launch-phase toggle) */
.finder-parked{margin:4px 0 0;padding:20px 22px;border:1px solid var(--sand);border-radius:16px;background:var(--parchment);font-size:15.5px;line-height:1.5;color:var(--umber);max-width:420px}
.dark .finder-parked{background:rgba(252,250,245,.04);border-color:rgba(252,250,245,.16);color:var(--on-dark-soft)}
/* home benefits teaser: continues the roasts' ink band, so it tucks up under the roast cards instead of opening a new section */
.home-benefits{padding-top:clamp(8px,2vw,24px)}
.home-benefits .why-head{border-top:1px solid var(--rule-dark,rgba(252,250,245,.12));padding-top:clamp(56px,7vw,96px)}
.home-benefits-cta{margin-top:clamp(28px,3.5vw,44px)}

/* ---- Phones: square photos, the page-top photo lined up with the text, and less empty space between sections (2026-09-29) ----
   Mobile only; desktop is untouched. Stacked on a phone, the desktop section padding (96px+ top and bottom, plus the 12px frame
   between cards) added up to 200px+ empty bands between sections, and the event/coffee story blocks kept a 14vh spacer below
   each block that only the desktop sticky-photo scroll needs (~190px of blank under every block and under the last button). */
@media (max-width:860px){
  .feat-block{margin-bottom:0}   /* the spacer that lets the desktop photo hold while the copy scrolls; stacked, it was pure empty space */
  .feat-block + .feat-block{margin-top:24px}
}
@media (max-width:640px){
  .hero-static .contact-photo{justify-content:flex-start;padding-bottom:16px}   /* about/benefits/contact/event: was a narrower photo centred in the card, so its edges didn't line up with the text below */
  .hero-static .contact-photo img{width:100%;aspect-ratio:1/1}
  .hero-static .contact-photo img[src$="photo-gary.jpg"]{object-position:50% 24%}   /* benefits: the photo is too tall for a square to hold both Gary's face and the whole bag; keep his face and the bag's label, lose its bottom strip */
  .feats-sticky .feat-photo{aspect-ratio:1/1}   /* the event and coffee story photos go square, like the page-top photo */
  .ev-feats [data-stage="taste"] .feat-photo img{object-position:30% 50% !important}   /* keep the "Exceptional coffee" shelf card in the square crop */
  .ev-feats [data-stage="shelf"] .feat-photo img{object-position:30% 30% !important}   /* keep the whole "The Ultimate Human" endcap sign the copy points to, plus Gary's face and pointing hand */
  .why,.how,.standard,.tests,.tests-close-section,.roasts,.sprouts,.ev-what,.ab2-meet-section{padding-top:56px;padding-bottom:56px}
  .ab2-idea{padding-top:56px;padding-bottom:64px}
  .home-benefits{padding-top:8px}
  .home-benefits .why-head{padding-top:48px}
  .steps .step:last-child{margin-bottom:0}
  .ev-row,.ab2-quote{margin-top:40px;padding-top:40px}
  .close{padding-top:64px}
  .hero-static{margin-bottom:-1px}   /* the shorter hero ends on a fractional pixel; overlap the next dark section so no hairline seam shows */
  .hero-static .tstage{padding-bottom:56px}   /* same space under the last button as the other cards */
  .page-results .feats-sticky-grid{padding:0}   /* coffee: <main> already pads this card, so the story was padded twice (112px above the first photo) */
  .page-results .gauges{padding-bottom:24px}   /* testing + lab report: main's own padding already follows */
  html:not(.launched) .sprouts-copy .finder{margin-top:0}   /* the store finder is hidden until launch, but its margin still left a blank */
  #brew .why-grid{row-gap:40px}   /* coffee "How to brew": unboxed cards, so each photo needs air above it to read as the start of the next card */
}

/* ---- Reviews: shoppers tasting at Sprouts (2026-10-17). Ink, between the roast cards and the benefits teaser, tucked up the same way.
   Five 9:16 cards in a row on desktop; narrower screens swipe them sideways (scroll-snap) rather than stack five tall videos. ---- */
.reviews{padding:clamp(8px,2vw,24px) 0 clamp(32px,4vw,56px)}
.reviews-head{border-top:1px solid var(--rule-dark);padding-top:clamp(56px,7vw,96px)}
.reviews-head h2{margin:14px 0 18px}
.review-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:16px;margin-top:clamp(40px,5vw,72px)}
.vcard{background:var(--ink-2);border-radius:20px;overflow:hidden;margin:0;display:flex;flex-direction:column}
.vcard-media{position:relative;aspect-ratio:9/16;background:var(--ink);cursor:pointer}
.vcard-media img,.vcard-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.vcard-media video{opacity:0}
.vcard.playing video{opacity:1}
.vcard.playing img,.vcard.playing .vcard-play,.vcard.playing .vcard-len{display:none}
.vcard-play{position:absolute;left:14px;bottom:14px;display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 16px 0 12px;border-radius:999px;background:var(--yellow);color:var(--ink);font:600 14px/1 inherit;border:0;cursor:pointer;transition:opacity .45s var(--ease-out)}
.vcard-play:hover{opacity:.86}
.vcard-play svg{width:16px;height:16px}
.vcard-len{position:absolute;right:12px;top:12px;font-size:10px;letter-spacing:.1em;color:var(--on-dark);background:rgba(31,25,21,.55);border-radius:999px;padding:5px 9px 4px}
.vcard figcaption{padding:20px 20px 22px;display:flex;flex-direction:column;gap:12px;flex:1}
.vcard blockquote{margin:0;font-size:clamp(17px,1.25vw,20px);line-height:1.38;letter-spacing:-.01em;color:var(--on-dark)}
.vcard .vwho{margin:auto 0 0;font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--on-dark-faint)}
@media (max-width:1100px){
  .review-grid{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:12px;margin-left:calc(-1 * var(--gut));margin-right:calc(-1 * var(--gut));padding:0 var(--gut) 4px;scroll-padding:0 var(--gut);scrollbar-width:none}
  .review-grid::-webkit-scrollbar{display:none}
  .vcard{flex:0 0 min(300px,30%);scroll-snap-align:start}
}
@media (max-width:720px){.vcard{flex-basis:72%}}
@media (max-width:640px){.reviews{padding-top:8px;padding-bottom:16px}.reviews-head{padding-top:48px}}
