/* =====================================================================
   BREAK OF DAWN — brand site
   Design language: Lasala restraint × Joy Rush product-play × Unseen motion
   Palette + type tied to BOD's own sunrise identity.
   ===================================================================== */

/* ---------- Fonts ---------- */
/* DM Serif Text — display · Fira Sans — body/UI · Recursive — accent/data */

/* ---------- Tokens ---------- */
:root {
  --paper:      #F4EDE1;   /* warm cream page bg           */
  --paper-2:    #EFE6D6;   /* slightly deeper cream        */
  --sand:       #E7D8C2;   /* card / divider neutral       */
  --ink:        #211B17;   /* warm near-black text         */
  --ink-soft:   #4A4038;   /* secondary text               */
  --grey:       #5C5C5C;   /* captions / muted. #8C8C8C -> #6C6C6C cleared 4.5:1 on --paper
                              only (4.51). It still FAILED on every darker band it actually
                              sits on: --paper-2 4.24, the press strip #E9DFCB 3.97, --sand
                              3.75. Now 5.75 / 5.40 / 5.06 / 4.78 — passes on all four.     */

  --aqua:       #A1CDC8;   /* primary brand                */
  --aqua-deep:  #7FB8B2;
  --teal:       #166B80;   /* midnight blue / dark sections*/
  --teal-ink:   #0E4C5B;
  --coral:      #EB5B4D;   /* accent / CTA / sunrise outer */
  /* Contrast-corrected 2026-07-27. These are the SMALLEST shifts that reach WCAG AA 4.5:1;
     the identity is deliberately unchanged beyond that. --maroon was #B55453, which failed
     on both papers (4.14 / 3.89) and badly on the aqua footer (2.77). Because no single
     maroon passes on aqua without going near-brown, the footer gets its own deeper token. */
  --maroon:     #A54D4C;   /* secondary / sunrise mid — 4.79 on paper, 4.50 on paper-2 */
  --maroon-deep:#823C3C;   /* the same role on the aqua footer — 4.54 on aqua          */
  --gold-text:  #806735;   /* gold as TEXT (4.62 on paper); --gold stays for decoration */
  --coral-text: #AB4238;   /* coral as small text on light panels                       */

  --line:       #D8C8B2;   /* hairline on paper            */
  --nav-h:      110px;     /* the fixed nav reserves no space in the flow. Measured at
                              74-93px at 375w and 100px at 1280w — it varies with scroll
                              state — so this sits above the highest reading. */
  --line-dark:  rgba(244,237,225,.18);

  --gold:       #C6A052;   /* award accent — used only for the No.1 seal */
  --gold-lt:    #E7C77E;
  --award-bg:   #1B140C;   /* warm charcoal band behind the gold seal    */

  /* type */
  --f-display: "DM Serif Text", Georgia, "Times New Roman", serif;
  --f-body:    "Fira Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --f-accent:  "Recursive", "Fira Sans", monospace;

  /* scale (fluid) */
  --step--1: clamp(.78rem, .74rem + .18vw, .88rem);
  --step-0:  clamp(1rem, .96rem + .2vw, 1.125rem);
  --step-1:  clamp(1.2rem, 1.1rem + .5vw, 1.5rem);
  --step-2:  clamp(1.6rem, 1.3rem + 1.4vw, 2.4rem);
  --step-3:  clamp(2.1rem, 1.5rem + 2.9vw, 3.8rem);
  --step-4:  clamp(2.8rem, 1.7rem + 5.2vw, 6rem);
  --step-5:  clamp(3.4rem, 1.6rem + 8.4vw, 8.5rem);

  --maxw: 1320px;
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --radius: 4px;

  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  font-family: var(--f-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, video, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul { list-style: none; padding: 0; }
::selection { background: var(--coral); color: var(--paper); }

/* ---------- Typography ---------- */
h1, h2, h3, h4 { font-family: var(--f-display); font-weight: 400; line-height: 1.02; letter-spacing: -.01em; }
/* brand rule: headline text is lowercase */
h1, h2, h3 { text-transform: lowercase; }
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
p  { max-width: 62ch; }

.eyebrow {
  font-family: var(--f-accent);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .28em;
  text-transform: uppercase;
  /* --maroon clears 4.5:1 on --paper (4.79) and only just on --paper-2 (4.50), but
     eyebrows sit on tinted sections too — 3.21 on --aqua, 3.99 on the finale tint.
     --maroon-deep passes on all of them (6.78 / 6.37 / 4.54 / 5.5) and fixes every
     instance at once instead of one override per section. */
  color: var(--maroon-deep);
  display: inline-flex;
  align-items: center;
  gap: .8em;
}
.eyebrow::before {
  content: "";
  width: 1.8em; height: 1px;
  background: currentColor;
  display: inline-block;
}
.eyebrow.centered::after {
  content: "";
  width: 1.8em; height: 1px;
  background: currentColor;
  display: inline-block;
}

.serif-italic { font-style: italic; }
.display-xl { font-family: var(--f-display); font-size: var(--step-5); line-height: .98; }

/* the *** censor device */
.stars { letter-spacing: .04em; color: var(--coral); }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap-wide { max-width: 1560px; }
section { position: relative; }
/* VERTICAL RHYTHM — rewritten 22 Aug 2026 after measuring the homepage.
   The old values (9vw / 12vw per side) were fine for one section and wrong for two:
   every section padded 130px top AND bottom, so two adjacent sections stacked
   260px of bare paper between their ink — measured 275px between the flavours and
   the range, 310px between the almond artwork and "What we're about", and 160-176px
   on a 375px phone, a fifth of the screen. The founder read those as broken.

   The fix is to think in GAPS, not paddings: --rhythm is the total blank a reader
   should see between one section's last line and the next section's first, and each
   section contributes half of it. Two stacked sections therefore produce exactly one
   rhythm unit, not two. A tinted band still gets its colour padded on both sides.
   1440px: 64px a side, ~128 between ink. 375px: 40px a side, ~80 between ink.
   Page-specific sections (.story, .name-section, .about-hero, and the gifting bands
   .hgrid/.gfill/.ghow/.gcorp/.gbrief/.gcta) read the same tokens — add new sections the
   same way rather than inventing another clamp(). */
:root {
  --rhythm: clamp(5rem, 8.8vw, 8rem);
  --rhythm-lg: clamp(6rem, 10.5vw, 10rem);
}
.section-pad { padding-block: calc(var(--rhythm) / 2); }
.section-pad-lg { padding-block: calc(var(--rhythm-lg) / 2); }

.grid { display: grid; gap: clamp(1.5rem, 3vw, 3rem); }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
.cols-3 { grid-template-columns: repeat(3, 1fr); }
.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .cols-2, .cols-3, .cols-4 { grid-template-columns: 1fr; } }

/* ---------- Buttons ---------- */
.btn {
  --bg: var(--ink); --fg: var(--paper);
  position: relative;
  display: inline-flex; align-items: center; gap: .7em;
  padding: .95em 1.7em;
  font-family: var(--f-accent);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg);
  background: var(--bg);
  border-radius: 100px;
  overflow: hidden;
  isolation: isolate;
  transition: color .28s var(--ease), transform .28s var(--ease), box-shadow .28s var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--coral);
  border-radius: 100px;
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .3s var(--ease);
}
.btn:hover { color: var(--paper); transform: translateY(-2px); box-shadow: 0 12px 26px -12px rgba(20,14,7,.5); }
.btn:hover::before { transform: scaleY(1); }
.btn:active { transform: translateY(0); }
.btn:hover .btn-arrow { transform: translateX(4px); }
.btn-arrow { transition: transform .28s var(--ease); }
/* Ink label, not paper. --paper on --coral is 2.94:1 and this is the "add to basket" /
   "explore the range" button — the least legible element on the site was also the most
   important one. --ink on --coral is 4.97:1 and keeps the coral itself untouched, which
   matters because --coral is used decoratively in ~40 other places. Hover is unaffected:
   .btn:hover forces --paper while ::before fills with --ink, landing at 14.63:1.        */
.btn--coral { --bg: var(--coral); --fg: var(--ink); }
.btn--coral::before { background: var(--ink); }
.btn--outline { --bg: transparent; --fg: var(--ink); border: 1px solid var(--ink); }
.btn--outline::before { background: var(--ink); }
.btn--on-dark { --bg: var(--paper); --fg: var(--ink); }
.btn--on-dark::before { background: var(--coral); }
.btn--on-dark:hover { color: var(--paper); }

/* text link with animated underline */
.link {
  position: relative;
  font-family: var(--f-accent);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding-bottom: 3px;
}
.link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .45s var(--ease);
}
.link:hover::after { transform: scaleX(1); transform-origin: left; }
/* inline links inside body copy — subtle, editorial, never button-y */
.ilink { color: inherit; border-bottom: 1px solid rgba(33,27,23,.3); transition: color .25s var(--ease), border-color .25s var(--ease); }
.ilink:hover { color: var(--coral); border-color: var(--coral); }

/* =====================================================================
   Sunrise motif — the brand's signature shape
   ===================================================================== */
.sunrise { display: block; }
.sunrise-arc { transform-origin: 50% 100%; }

/* horizon divider: a thin rule with a small rising dome centered */
.horizon {
  display: flex; align-items: center; gap: 1.4rem;
  color: var(--line);
}
.horizon::before, .horizon::after { content: ""; height: 1px; background: currentColor; flex: 1; }

/* half-moon "dome" split backdrop used behind products (Joy Rush blob → BOD dome) */
.dome {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
}

/* =====================================================================
   Navigation
   ===================================================================== */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  display: flex; align-items: center; justify-content: flex-start;
  padding: clamp(1rem, 2vw, 1.6rem) var(--gutter);
  transition: background .5s var(--ease), box-shadow .5s var(--ease);
}
/* twin auto margins centre the links between the logo and the right cluster, and the
   right cluster (wholesale · search · cart) packs tight instead of being spread by
   space-between — which was the "weird spacing" between those three */
.nav-links { margin-inline: auto; }
.nav-cta { margin-left: auto; }
.nav--solid {
  background: rgba(244,237,225,.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--line);
  /* NO padding change: the nav is one fixed height in every state on every page, so the
     cross-document view transition holds it perfectly still instead of morphing it */
}
/* Phones: drop the blur and make the fill opaque. A backdrop-filter on a FIXED element is
   re-rasterised every frame across the full width of the screen, which is the single most
   expensive thing on this page during a scroll, and iOS Safari is the worst at it. At 100%
   paper the bar reads as a clean solid strip instead of a translucent smear over the beige
   catalogue. Desktop keeps the blur — it can afford it and the effect is worth having. */
@media (max-width: 760px) {
  .nav--solid {
    background: var(--paper);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
.nav--on-dark { color: var(--paper); }
/* subtle top scrim: the bar is transparent over the video until it turns solid on scroll,
   so the cream wordmark + links can wash out on a bright frame. Fades out when solid. */
.nav::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 220%;
  background: linear-gradient(to bottom, rgba(20,14,7,.34), rgba(20,14,7,0));
  pointer-events: none; z-index: -1; opacity: 0; transition: opacity .5s var(--ease);
}
.nav--light:not(.nav--solid)::before { opacity: 1; }
/* BAND FIX 2026-08-21. The scrim is 220% of the bar's height, so it hangs ~89px BELOW
   the nav. Over the dark hero that is invisible and doing its job. Over the range page's
   beige catalogue it reads as a murky taupe band that follows the scroll.

   The :not() above should already switch it off once the bar turns solid, but it does so
   through a .5s opacity transition, so there is a window on every state change — and on
   any scroll that hovers near the threshold — where a dark gradient is drawn over cream.
   Stating opacity 0 explicitly for the solid state removes the ambiguity, and killing the
   transition in that direction means the scrim is simply gone the moment the bar is solid
   rather than fading out over half a second. */
.nav--solid::before { opacity: 0 !important; transition: none; }
.nav-logo { display: flex; align-items: center; gap: .55rem; z-index: 2; }
.nav-logo .mark { height: 36px; width: 36px; clip-path: circle(45% at 50% 50%); }
.nav-wordmark {
  font-family: var(--f-display); font-size: 1.28rem; line-height: 1;
  letter-spacing: .005em; padding-top: 2px;
}
/* wordmark pre-coloured to the exact nav-link colour (file://-safe) */
.nav-wordmark-mask {
  display: block; width: 226px; height: 24px;
  max-width: 100%;
  background: url("brand-assets/logos/bod-wordmark-ink.png") left center / contain no-repeat;  /* = nav-link ink */
}
/* keep the wordmark from crowding the nav controls on small phones */
@media (max-width: 560px) { .nav-wordmark-mask { width: 190px; height: 20px; } }
/* MOBILE NAV BAR — even spacing (24 Aug 2026).
   The bar was logo | (auto gap) | search cart toggle, so the wordmark took every
   spare pixel and the three controls bunched hard against the right edge with
   uneven gaps between them. The controls now sit in one evenly-gapped cluster and
   the wordmark yields space instead of claiming it. */
@media (max-width: 860px) {
  /* One evenly-gapped cluster on the right. The previous version nudged each control
     with its own margin, which stacked up and let the cart pill sit on top of the
     hamburger. Now a single gap governs the spacing and nothing carries a margin. */
  .nav { gap: 0; padding-inline: clamp(1rem, 4vw, 1.5rem); align-items: center; }
  .nav-logo { flex: 0 1 auto; min-width: 0; margin-right: auto; }
  .nav-search, .nav-cart, .nav-toggle { flex: none; margin: 0 !important; }
  .nav-search { margin-left: .75rem !important; }
  .nav-cart { margin-left: .55rem !important; }
  .nav-toggle { margin-left: .75rem !important; align-self: center; }
}
@media (max-width: 420px) {
  .nav-wordmark-mask { width: 158px; height: 17px; }
  .nav { gap: .5rem; }
}
.nav--light .nav-wordmark-mask { background-image: url("brand-assets/logos/bod-wordmark-cream.png"); }        /* = nav-link cream over video */
.nav--light.nav--solid .nav-wordmark-mask { background-image: url("brand-assets/logos/bod-wordmark-ink.png"); }

.nav-links { display: flex; align-items: center; gap: clamp(1.5rem, 2.5vw, 2.6rem); }
.nav-links a {
  font-family: var(--f-accent);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: .03em;
  text-transform: lowercase;
  position: relative;
  padding: .3em 0;
}
.nav-links a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .4s var(--ease);
}
.nav-links a:hover::after, .nav-links a[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }
/* Safe-by-default: the base case is a paper background, where --coral is 2.94:1. The
   bright coral is the EXCEPTION, valid only while the bar floats over a dark hero.
   Doing it the other way round is what hid this — .nav--solid is added by JS after
   40px of scroll, so on a paper page at rest neither solid rule had applied yet and
   the active link sat at 2.94:1 until you scrolled. The underline carries the state
   too, so colour was never the only cue.                                            */
.nav-links a[aria-current="page"] { color: var(--coral-text); }
.nav--light:not(.nav--solid) .nav-links a[aria-current="page"] { color: var(--coral); }

.nav-cta { display: inline-flex; }
.nav-toggle { display: none; }

@media (max-width: 860px) {
  .nav-links, .nav-cta.desktop-only { display: none; }
  .nav-search { margin-left: auto !important; }
  .nav-toggle {
    display: flex; flex-direction: column; gap: 5px; z-index: 120;
    width: 30px; padding: 6px 0;
  }
  .nav-toggle span { height: 2px; width: 100%; background: currentColor; transition: transform .4s var(--ease), opacity .3s; }
  .nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
  .nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* mobile fullscreen menu — image-backed brand moment */
.mobile-menu {
  position: fixed; inset: 0; z-index: 110;
  color: var(--paper);
  display: flex; flex-direction: column;
  padding: calc(clamp(1rem, 2vw, 1.6rem) + 64px) clamp(1.4rem, 5vw, 2.4rem) clamp(1.2rem, 4vw, 2rem);
  visibility: hidden; opacity: 0; pointer-events: none;
  transition: opacity .3s var(--ease), visibility 0s linear .3s;
}
.nav-open .mobile-menu { visibility: visible; opacity: 1; pointer-events: auto; transition: opacity .3s var(--ease); }
.mm-bg {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(16,10,6,.8) 0%, rgba(16,10,6,.52) 40%, rgba(16,10,6,.82) 100%),
    url("brand-assets/lifestyle/almond-milk-mobile-nav.jpg") center 40% / cover no-repeat;
  transform: scale(1.04);
  transition: transform .7s var(--ease);
}
.nav-open .mm-bg { transform: scale(1); }
.mm-nav {
  /* justify-content:center centred a SHORT list nicely but had no answer for a long
     one: with "shop" expanded the list outgrew the screen and the tail was simply
     unreachable. It now scrolls, and centres only while it still fits. */
  flex: 1; display: flex; flex-direction: column; justify-content: safe center;
  border-top: 1px solid rgba(244,237,225,.22);
  padding-top: clamp(1.4rem, 4vh, 2.4rem);
  overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none;
}
.mm-nav::-webkit-scrollbar { display: none; }
.mm-list { display: flex; flex-direction: column; gap: clamp(.9rem, 3.2vh, 1.6rem); }
.mm-list a {
  position: relative; display: inline-flex; align-items: center; gap: .5em;
  font-family: var(--f-display); font-size: clamp(2rem, 8.5vw, 3.1rem);
  line-height: 1.05; text-transform: lowercase; color: var(--paper);
  opacity: 0; transform: translateY(14px);
  transition: opacity .28s var(--ease), transform .28s var(--ease), color .3s var(--ease);
}
/* small dot beside each item */
.mm-list a::before {
  content: ""; flex: none; width: .17em; height: .17em; border-radius: 50%;
  background: rgba(244,237,225,.5);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.mm-list a:hover::before, .mm-list a:active::before { background: var(--coral); transform: scale(1.25); }
.mm-list a:active { color: var(--coral); }
/* the "shop" accordion trigger takes the same voice as the links around it */
.mm-shop-btn {
  position: relative; display: inline-flex; align-items: center; gap: .5em;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--f-display); font-size: clamp(2rem, 8.5vw, 3.1rem);
  line-height: 1.05; text-transform: lowercase; color: var(--paper);
  opacity: 0; transform: translateY(14px);
  transition: opacity .28s var(--ease), transform .28s var(--ease), color .3s var(--ease);
}
.mm-shop-btn::before {
  content: ""; flex: none; width: .17em; height: .17em; border-radius: 50%;
  background: rgba(244,237,225,.5); transition: background .3s var(--ease), transform .3s var(--ease);
}
.mm-shop-btn:active { color: var(--coral); }
.mm-shop-mark { font-family: var(--f-accent); font-size: .45em; color: var(--coral);
  transition: transform .3s var(--ease); }
.mm-shop-btn[aria-expanded="true"] .mm-shop-mark { transform: rotate(45deg); }
/* [hidden] first, or display:grid below wins and the submenu can never collapse —
   which is exactly how "shop" got stuck permanently open (reported 24 Aug). */
.mm-sub[hidden] { display: none; }
.mm-sub { list-style: none; margin: .5rem 0 0 1.1em; padding: 0 0 0 .9em;
  border-left: 1px solid rgba(244,237,225,.25);
  display: grid; gap: .55rem; }
.mm-sub a {
  font-family: var(--f-accent); font-size: clamp(1rem, 4.2vw, 1.2rem); font-weight: 500;
  opacity: 1; transform: none; letter-spacing: .02em;
}
.mm-sub a::before { display: none; }
.mm-sub-all { color: var(--coral); }
/* No per-item stagger. The cascade meant the middle links were still arriving while
   home and contact sat ready — on a phone that read as the menu being slow, not
   theatrical (reported 24 Aug). Everything lands together, fast. */
.nav-open .mm-list a, .nav-open .mm-shop-btn { opacity: 1; transform: none; }
/* current page: coral asterisk + leading mark, like a signature */
.mm-list a.is-current::before { background: var(--coral); transform: scale(1.25); }
.mm-cta {
  align-self: flex-start; margin-top: clamp(1.6rem, 5vh, 2.6rem);
  display: inline-flex; align-items: center; gap: .6em;
  font-family: var(--f-accent); font-size: .78rem; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--paper);
  border: 1px solid rgba(235,91,77,.75); border-radius: 100px;
  padding: .9em 1.7em;
  opacity: 0; transform: translateY(12px);
  transition: opacity .28s var(--ease) .08s, transform .28s var(--ease) .08s,
              background .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
}
.nav-open .mm-cta { opacity: 1; transform: none; }
.mm-cta:hover, .mm-cta:active { background: var(--coral); border-color: var(--coral); color: var(--paper); }
.mm-foot {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1.2rem;
  border-top: 1px solid rgba(244,237,225,.22);
  padding-top: clamp(1rem, 3vh, 1.6rem);
  opacity: 0; transform: translateY(10px);
  transition: opacity .28s var(--ease) .08s, transform .28s var(--ease) .08s;
}
.nav-open .mm-foot { opacity: 1; transform: none; }
.mm-mails { display: flex; flex-direction: column; gap: .55rem; }
.mm-mails a {
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: rgba(244,237,225,.85);
  transition: color .3s var(--ease);
}
.mm-mails a:hover, .mm-mails a:active { color: var(--coral); }
.mm-social { display: flex; gap: .7rem; }
.mm-social a {
  width: 46px; height: 46px; border-radius: 50%;
  border: 1px solid rgba(244,237,225,.35);
  display: grid; place-items: center; color: var(--paper);
  transition: border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
.mm-social svg { width: 21px; height: 21px; }
.mm-social a:hover, .mm-social a:active { border-color: var(--coral); background: rgba(235,91,77,.18); transform: translateY(-2px); }
/* the toggle becomes a circled X over the menu */
.nav-open .nav-toggle { border: 1px solid rgba(244,237,225,.5); border-radius: 50%; }

/* =====================================================================
   Reveal animation states (progressive enhancement)
   Only applied once .enhanced is set on <html> by JS.
   ===================================================================== */
.enhanced [data-reveal] { opacity: 0; transform: translateY(20px); }
.enhanced [data-reveal].is-in { opacity: 1; transform: none; transition: opacity .55s var(--ease), transform .55s var(--ease); }
.enhanced [data-reveal-up] { opacity: 0; transform: translateY(26px); }
.enhanced [data-reveal-up].is-in { opacity: 1; transform: none; transition: opacity .6s var(--ease), transform .6s var(--ease); }

/* line-mask text reveal */
.reveal-line { display: block; overflow: hidden; padding-bottom: .16em; margin-bottom: -.16em; }
.reveal-line > span { display: block; }
.enhanced .reveal-line > span { transform: translateY(105%); transition: transform .6s var(--ease); }
.enhanced .reveal-line.is-in > span { transform: none; }

/* headline word-mask reveal — words rise gently from a clip, small stagger.
   Applied by JS to display headlines; opacity handled so no flash. */
.enhanced .rw-split { opacity: 1; transform: none; }
.rw-mask { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .16em; margin-bottom: -.16em; }
.enhanced .rw-word { display: inline-block; transform: translateY(112%); transition: transform .6s var(--ease); will-change: transform; }
.enhanced .rw-split.is-in .rw-word { transform: none; }

/* =====================================================================
   Custom cursor
   ===================================================================== */
/* REMOVED at the user's request (asked twice). The element stays in the
   markup on 13 pages; this makes it inert, and the JS returns early. */
.cursor { display: none !important; }
.cursor--dead { position: fixed; top: 0; left: 0; z-index: 9999; pointer-events: none; }
.cursor.is-on { opacity: 1; }
.cursor-dot { width: 0; height: 0; border-radius: 50%; background: var(--paper); transform: translate(-50%, -50%); transition: width .3s var(--ease), height .3s var(--ease); }
.cursor.is-hover .cursor-dot { width: 54px; height: 54px; }
.cursor-label {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(.6);
  font-family: var(--f-accent); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink); opacity: 0; white-space: nowrap; transition: opacity .3s, transform .3s var(--ease); mix-blend-mode: normal;
}
.cursor.is-view .cursor-dot { width: 76px; height: 76px; background: var(--coral); }
.cursor.is-view .cursor-label { opacity: 1; transform: translate(-50%, -50%) scale(1); color: var(--paper); }
@media (hover: none) { .cursor { display: none; } }

/* =====================================================================
   Footer
   ===================================================================== */
.footer { background: var(--aqua); color: var(--ink); position: relative; overflow: hidden; }
/* --coral on --aqua is 1.97:1. --maroon-deep exists precisely for "the same role on
   the aqua footer" and lands at 4.54:1. */
.footer .stars { color: var(--maroon-deep); }
.footer-top { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 3rem; padding-block: clamp(4rem, 8vw, 7rem) 3rem; }
@media (max-width: 860px) { .footer-top { grid-template-columns: 1fr; gap: 2.5rem; } }
.footer h2 { font-size: var(--step-3); max-width: 14ch; }
.footer-col h3 { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--maroon-deep); margin-bottom: 1.2rem; }
.footer-col ul { display: flex; flex-direction: column; gap: .7rem; }
.footer-col a { opacity: .82; transition: opacity .3s; }
.footer-col a:hover { opacity: 1; }
.footer-bar { display: flex; justify-content: space-between; align-items: center; gap: 1rem 1.4rem; flex-wrap: wrap; padding-block: 1.8rem; border-top: 1px solid rgba(33,27,23,.22); font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .08em; text-transform: uppercase; color: rgba(33,27,23,.82); }

.footer-legal a { color: inherit; text-decoration: underline; text-underline-offset: .25em;
  text-decoration-color: rgba(33,27,23,.34); transition: color .25s var(--ease), text-decoration-color .25s var(--ease); }
.footer-legal a:hover { color: var(--maroon); text-decoration-color: var(--maroon); }

/* newsletter */
/* One cream pill with the button seated inside it, rather than a ruled field with a
   detached button. The wrapper carries the focus ring (:focus-within) because the input
   itself has no visible edge of its own to show one on. */
.subscribe {
  display: flex; align-items: center; gap: .4rem;
  max-width: 420px; margin-top: 1.5rem;
  background: var(--paper); border-radius: 100px; padding: .32rem .32rem .32rem .35rem;
  box-shadow: 0 10px 22px -16px rgba(33,27,23,.55);
}
.subscribe:focus-within { outline: 2px solid var(--coral); outline-offset: 3px; }
.subscribe input {
  flex: 1; min-width: 0; background: transparent; border: none;
  color: var(--ink); font-family: var(--f-body); font-size: var(--step--1);
  padding: .85em .4em .85em 1.1em;
}
.subscribe input::placeholder { color: rgba(33,27,23,.52); }
.subscribe input:focus { outline: none; }
.subscribe-go {
  flex: none; cursor: pointer; border: 0; border-radius: 100px;
  background: var(--ink); color: var(--paper);
  font-family: var(--f-accent); font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  padding: 1.05em 1.9em;
  transition: background .3s var(--ease);
}
.subscribe-go:hover { background: var(--maroon-deep); }
.footer .footer-note { color: rgba(33,27,23,.78); margin-top: .9rem; }  /* .66 gave 3.05:1 on aqua */

/* social row — outline circles, 44px so they clear the touch-target minimum outright
   rather than relying on the (pointer:coarse) padding rule */
.footer-social { display: flex; flex-wrap: wrap; gap: .65rem; margin-top: 1.7rem; list-style: none; }
.footer-social a {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(33,27,23,.32); color: var(--ink);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.footer-social svg { width: 19px; height: 19px; }
.footer-social a:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* the rule that separates the sign-up block from the link columns */
@media (min-width: 861px) {
  .footer-col:nth-child(2) {
    border-left: 1px solid rgba(33,27,23,.16);
    padding-left: clamp(1.6rem, 3.4vw, 3.4rem);
  }
}

/* bottom bar — brand mark on the left, © and licence stacked beside it */
.footer-mark { display: inline-flex; align-items: center; gap: .75rem; flex: none; }
.footer-mark-sun { width: 40px; height: auto; display: block; }
.footer-mark-word { width: 104px; height: auto; display: block; }
.footer-cr { line-height: 1.55; text-transform: none; letter-spacing: .04em; }

/* The bar carries five items (mark, ©, legal, the JS-injected "share a thought", back to
   top). Measured at 1440 they total 1127px inside a 1205px bar — they fit, and it was the
   four 28.8px gaps that tipped it over, wrapping BACK TO TOP alone onto a second row
   flush left, which read as broken. The legal run is the one item that can wrap inside
   itself without looking wrong, so it takes the slack.
   NOTE: .link must stay a DIRECT child of .footer-bar — main.js does
   bar.insertBefore(trigger, bar.querySelector('.link')), which throws if it is nested. */
.footer-legal { flex: 1 1 16rem; min-width: 0; }
@media (max-width: 700px) { .footer-legal { flex-basis: 100%; } }

/* The registered operational address, on every page. Payment providers look for it in
   the footer, and it is the one place a visitor always knows to check. Takes its own
   full-width row above the legal run so neither has to fight for space. */
.footer-addr { flex: 1 1 100%; order: -1; font-style: normal; line-height: 1.6;
  text-transform: none; letter-spacing: .03em; color: inherit; opacity: .82;
  padding-bottom: .55rem; margin-bottom: .35rem;
  border-bottom: 1px solid color-mix(in srgb, currentColor 14%, transparent); }
.footer-addr a { color: inherit; text-decoration: underline; text-underline-offset: .25em;
  text-decoration-color: rgba(33,27,23,.34); transition: color .25s var(--ease); }
.footer-addr a:hover { color: var(--maroon); }

/* =====================================================================
   Utility
   ===================================================================== */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.muted { color: var(--grey); }
.tint-teal { background: var(--teal); color: var(--paper); }
.tint-aqua { background: var(--aqua); color: var(--ink); }
.tint-sand { background: var(--paper-2); }
.lead { font-size: var(--step-1); line-height: 1.5; color: var(--ink-soft); max-width: 40ch; }
.badge-row { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.badge-row img { height: clamp(58px, 8vw, 82px); width: auto; }

/* accessible focus */
:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; border-radius: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .enhanced [data-reveal], .enhanced [data-reveal-up], .enhanced .reveal-line > span, .enhanced .rw-word { opacity: 1 !important; transform: none !important; }
}

/* Safety net for the early .enhanced flag set in <head>: if main.js never runs (blocked,
   errored, offline), the head script adds .reveal-fallback after 2.5s and every hidden
   element is shown. Without this, setting .enhanced before paint could leave a blank page. */
.reveal-fallback [data-reveal], .reveal-fallback [data-reveal-up], .reveal-fallback .reveal-line > span,
.reveal-fallback .rw-word { opacity: 1 !important; transform: none !important; }

/* =====================================================================
   PAGE-TO-PAGE TRANSITIONS (cross-document View Transitions)
   One declaration opts every same-origin navigation into a transition where the
   browser supports it (Chromium 126+, Safari 18.2+); everywhere else navigation is
   exactly what it was. The header carries its own name so it holds still while the
   page body crossfades underneath it — the bar is the one thing that is the same on
   both pages, and watching it fade out and back in is what makes a site feel like
   separate documents. Durations are short on purpose: a page change should feel
   instant with the edge taken off, not like a slideshow. Respects reduced motion.
   ===================================================================== */
@view-transition { navigation: auto; }
.nav { view-transition-name: site-nav; }
::view-transition-old(root) { animation: vt-out .18s cubic-bezier(.4, 0, 1, 1) both; }
::view-transition-new(root) { animation: vt-in .28s cubic-bezier(0, 0, .2, 1) both; }
::view-transition-old(site-nav), ::view-transition-new(site-nav) { animation: none; mix-blend-mode: normal; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* =====================================================================
   CINEMATIC VIDEO HERO (pinned, Lasala × Unseen)
   The hero is fixed full-screen; .site-body scrolls up over it.
   ===================================================================== */
.hero-cine {
  position: fixed; inset: 0; z-index: 0;
  height: 100svh; width: 100%;
  overflow: hidden;
  background: var(--paper);
}
.hero-cine-media {
  position: absolute; inset: 0;
  transform-origin: 50% 45%;
  opacity: 0;
  will-change: transform, opacity;
}
.hero-cine.is-ready .hero-cine-media { opacity: 1; transition: opacity 1.1s var(--ease-soft); }
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 42%;
  /* filmic grade — makes the 720p source read as intentional/cinematic */
  filter: contrast(1.07) saturate(1.06) brightness(1.02);
}
/* The hero copy sits mid-left, but the bottom-up wash only reached 36% of the
   height — so the headline sat on bare video. That was invisible while the hero
   footage was dark there; the moment a video with a BRIGHT middle went in
   (blending, white milk) the cream headline fell to 3.1:1 and the 18px sub-line
   to 3.25:1. Measured, not guessed.
   The fix is a LEFT-side wash rather than a heavier overall one: the copy is
   left-aligned, so darkening that column protects the type while leaving the
   right-hand side of the frame — where the product actually is — clear.
   Re-measure across the loop if the hero video is ever swapped again. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(132% 116% at 50% 42%, transparent 50%, rgba(20,14,10,.5) 100%),
    linear-gradient(to bottom, rgba(20,14,10,.45) 0%, rgba(20,14,10,0) 22%),
    linear-gradient(to top, rgba(20,14,10,.62) 0%, rgba(20,14,10,.3) 44%, rgba(20,14,10,0) 70%),
    linear-gradient(to right, rgba(20,14,10,.62) 0%, rgba(20,14,10,.26) 34%, rgba(20,14,10,0) 60%);
  opacity: .92;
}
/* animated film grain */
.hero-grain {
  position: absolute; inset: -60px; z-index: 2; pointer-events: none;
  opacity: .07; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  animation: grainShift .5s steps(3) infinite;
}
@keyframes grainShift {
  0% { transform: translate(0,0); }
  33% { transform: translate(-18px, 10px); }
  66% { transform: translate(14px, -14px); }
  100% { transform: translate(0,0); }
}

.hero-cine-foot {
  /* bottom anchor raised 25 Aug ("a little more up") — was clamp(1.6rem, 4vh, 3rem) */
  position: absolute; left: 0; right: 0; bottom: clamp(3rem, 9vh, 6rem);
  z-index: 3;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem;
  padding-left: clamp(1rem, 2vw, 2rem);   /* nudged left to clear the bottle */
}
.hero-cine-foot .hero-lead { max-width: 42rem; }
@media (min-width: 861px) {
  /* The block is bottom-anchored and then lifted; the lift is what sets its
     height on screen. It has come down in two steps at the user's request:
     -22vh (centre-float) -> -14vh -> -7vh -> -10vh (25 Aug, "a little more up"). */
  .hero-cine-foot .hero-lead { max-width: 42%; transform: translateY(-10vh); }
}
.hero-lead { display: flex; flex-direction: column; gap: 1.1rem; align-items: flex-start; }
/* Hero actions. The block previously ended at the tagline and left the scroll
   cue as the only thing to do. */
.hero-cta { display: flex; flex-wrap: wrap; gap: .7rem .8rem; margin-top: .5rem; }
/* An outline button on a photograph needs its own ground — a bare 1px border
   over a dark image is nearly invisible and moves with the crop. The tint is
   the minimum that holds the edge without becoming a second solid button. */
.btn--ghost-light {
  --bg: rgba(244, 237, 225, .12); --fg: var(--paper);
  border: 1px solid rgba(244, 237, 225, .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.btn--ghost-light::before { background: var(--paper); }
.btn--ghost-light:hover { color: var(--ink); }
.hero-word {
  font-family: var(--f-display); color: var(--paper); text-transform: lowercase;
  font-size: clamp(2.3rem, 1.5rem + 3vw, 4.4rem); line-height: .98; letter-spacing: -.01em;
  text-shadow: 0 2px 40px rgba(20,14,10,.45);
}
.hero-dot { color: var(--coral); }
.hero-word .stars { color: var(--coral); text-shadow: none; }
.hero-sub-cine {
  color: rgba(244,237,225,.9); font-size: var(--step-0); line-height: 1.55;
  max-width: 46ch; text-shadow: 0 1px 18px rgba(20,14,10,.5);
}
.hero-sub-cine .stars { color: var(--coral); }
/* The orientation line. Deliberately quieter than .hero-sub-cine above it — it is
   information, not voice, and it must not compete with the headline. Sized down and
   dimmed so it reads as a caption to the brand statement rather than a second claim. */
.hero-what {
  color: rgba(244,237,225,.72); font-size: var(--step--1); line-height: 1.5;
  max-width: 44ch; margin-top: .9rem; text-shadow: 0 1px 18px rgba(20,14,10,.5);
}

.hero-right { display: flex; flex-direction: column; align-items: center; gap: 1.1rem; }
.hero-pause {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid rgba(244,237,225,.5); color: var(--paper);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; letter-spacing: .12em;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.hero-pause:hover { border-color: var(--paper); background: rgba(244,237,225,.12); }
.eyebrow--light { color: var(--paper); }
.eyebrow--light::before, .eyebrow--light::after { background: var(--paper); opacity: .7; }

.hero-cue {
  display: inline-flex; flex-direction: column; align-items: center; gap: .8rem;
  color: var(--paper);
  font-family: var(--f-accent); font-size: 11.5px; letter-spacing: .3em; text-transform: uppercase;
}
.hero-cue-track { width: 1px; height: 52px; background: rgba(244,237,225,.4); position: relative; overflow: hidden; }
.hero-cue-track i { position: absolute; inset: 0; background: var(--paper); animation: cueDrop 2.4s var(--ease) infinite; }
@keyframes cueDrop { 0% { transform: translateY(-100%); } 55%, 100% { transform: translateY(100%); } }

/* flavour strip swipe cue — the hero scroll cue turned on its side; touch screens only */
.flavour-cue { display: none; }
@media (hover: none) and (max-width: 899px) {
  .flavour-cue {
    display: inline-flex; align-items: center; gap: .7rem;
    margin: 1.1rem auto 0; width: 100%; justify-content: center;
    font-family: var(--f-accent); font-size: max(.72rem, 11.5px); font-weight: 600;
    letter-spacing: .3em; text-transform: uppercase; color: var(--ink-soft);
  }
  .flavour-cue-track { width: 52px; height: 1px; background: color-mix(in srgb, var(--ink) 28%, transparent);
    position: relative; overflow: hidden; }
  .flavour-cue-track i { position: absolute; inset: 0; background: var(--coral);
    animation: cueSlide 2.4s var(--ease) infinite; }
}
@keyframes cueSlide { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .flavour-cue-track i { animation: none; } }

/* entrance fade */
.hero-fade { opacity: 0; transform: translateY(14px); }
.hero-cine.is-ready .hero-fade { opacity: 1; transform: none; transition: opacity 1s var(--ease) .35s, transform 1s var(--ease) .35s; }
.hero-cine.is-ready .hero-cue.hero-fade { transition-delay: .5s; }

/* hero conversion CTAs — reuse .btn styles, sit inside the foot (above the media) */
.hero-cta-row { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: .35rem; }
/* the hero media itself is a shortcut into the range; foot controls (z-index 3) stay above it */
.hero-shop { position: absolute; inset: 0; z-index: 2; display: block; }

.hero-spacer { height: 100svh; pointer-events: none; }
.site-body { position: relative; z-index: 2; background: var(--paper); }
.footer { z-index: 2; }
@media (max-width: 640px) { .hero-cine-foot .eyebrow { font-size: 11.5px; letter-spacing: .16em; } }

/* ---- Nav: light (over video) vs solid (scrolled) ---- */
.nav--light { color: var(--paper); }
.nav--light .nav-wordmark, .nav--light .nav-links a { color: var(--paper); }
.nav--light .btn.nav-cta { background: transparent; color: var(--paper); border: 1px solid rgba(244,237,225,.55); }
.nav--light .btn.nav-cta::before { background: var(--paper); }
.nav--light .btn.nav-cta:hover { color: var(--ink); }
.nav--light.nav--solid { color: var(--ink); }
.nav--light.nav--solid .nav-wordmark, .nav--light.nav--solid .nav-links a { color: var(--ink); }
.nav--light.nav--solid .nav-links a[aria-current="page"] { color: var(--coral-text); }
.nav--light.nav--solid .btn.nav-cta { background: var(--ink); color: var(--paper); border-color: transparent; }
.nav--light.nav--solid .btn.nav-cta::before { background: var(--coral); }

/* =====================================================================
   HERO (legacy two-column — retained for inner-page use)
   ===================================================================== */
.hero {
  min-height: 100svh;
  display: flex; align-items: center;
  padding: clamp(6rem, 12vh, 9rem) 0 clamp(3rem, 7vh, 5rem);
  position: relative; overflow: hidden;
  background:
    radial-gradient(80% 60% at 78% 42%, rgba(235,91,77,.08), transparent 60%),
    var(--paper);
}
.hero-inner {
  display: grid; grid-template-columns: 1.05fr .95fr;
  align-items: center; gap: clamp(1.5rem, 4vw, 4rem); width: 100%;
}
.hero-sun {
  position: relative; z-index: 0;
  width: 100%; max-width: 560px; margin-inline: auto;
}
.hero-sun .sunrise { width: 100%; overflow: visible; }
@media (max-width: 860px) {
  .hero { align-items: flex-end; }
  .hero-inner { grid-template-columns: 1fr; }
  .hero-sun {
    position: absolute; top: 12%; right: -8%; width: 78vw; max-width: 460px;
    opacity: .5; z-index: 0; margin: 0;
  }
  .hero-content { position: relative; z-index: 2; }
}
.sun-rays path { stroke: var(--maroon); stroke-width: 1; opacity: 0; }
.sun-arc { transform-box: fill-box; transform-origin: 50% 100%; }
/* entrance: the sun rises from the horizon on load */
.enhanced .sun-arc { transform: translateY(28%) scaleY(.05); opacity: 0; }
.enhanced .arc-1 { animation: sunRise 1.3s var(--ease) .15s forwards; }
.enhanced .arc-2 { animation: sunRise 1.3s var(--ease) .32s forwards; }
.enhanced .arc-3 { animation: sunRise 1.3s var(--ease) .49s forwards; }
.enhanced .sun-rays path { animation: rayFade 1.4s var(--ease) .9s forwards; }
@keyframes sunRise { to { transform: none; opacity: 1; } }
@keyframes rayFade { to { opacity: .16; } }

.hero-content { position: relative; z-index: 2; }
.hero-title {
  font-size: clamp(2.7rem, 1.1rem + 5vw, 5.2rem);
  margin: .28em 0 .55em;
}
.hero-sub {
  font-size: var(--step-1);
  max-width: 40ch; color: var(--ink-soft);
  margin-bottom: 2.2rem;
}
.hero-actions { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; }
.hero-scroll {
  position: absolute; right: var(--gutter); bottom: clamp(3rem, 7vh, 6rem); z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: .8rem;
  font-family: var(--f-accent); font-size: 11.5px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink-soft);
  writing-mode: vertical-rl;
}
.hero-scroll i { width: 1px; height: 46px; background: var(--ink); position: relative; overflow: hidden; }
.hero-scroll i::after { content:""; position:absolute; inset:0; background: var(--coral); animation: scrolldot 2.4s var(--ease) infinite; }
@keyframes scrolldot { 0%{transform:translateY(-100%)} 60%,100%{transform:translateY(100%)} }
@media (max-width: 640px) { .hero-scroll { display: none; } }

/* =====================================================================
   MARQUEE
   ===================================================================== */
.marquee { overflow: hidden; padding-block: 1.1rem; border-block: 1px solid var(--line-dark); }
.marquee-track { display: flex; width: max-content; gap: 0; animation: marquee 34s linear infinite; }
.marquee-track span {
  font-family: var(--f-display); font-size: clamp(1.3rem, 3vw, 2.1rem);
  white-space: nowrap; padding-right: 0;
}
.marquee em { color: var(--aqua); font-style: normal; margin: 0 .5em; }
@keyframes marquee { to { transform: translateX(-50%); } }
.marquee:hover .marquee-track { animation-play-state: paused; }

/* =====================================================================
   MANIFESTO
   ===================================================================== */
.manifesto-grid { align-items: start; gap: clamp(2rem, 5vw, 5rem); }
.manifesto-head { font-size: var(--step-3); line-height: 1.05; }
.manifesto-body { display: flex; flex-direction: column; gap: 1.3rem; padding-top: .5rem; align-items: flex-start; }
/* One voice: the lead used to run a step larger than the paragraph under it, which
   on a phone read as two unrelated text sizes (reported 24 Aug). */
.manifesto-body .lead { font-size: inherit; line-height: inherit; }

/* brand claim chips */
.claim-chips { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
.chip {
  display: inline-flex; align-items: center; gap: .55em;
  padding: .55em 1.05em .55em .8em;
  border: 1px solid var(--line); border-radius: 100px;
  background: var(--paper);
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink);
  transition: border-color .4s var(--ease), transform .4s var(--ease), background .4s var(--ease);
}
.chip-mark { width: 20px; height: auto; flex: 0 0 auto; }
.chip:hover { border-color: var(--ink); transform: translateY(-2px); background: var(--paper-2); }
.claim-more { margin-top: 1.2rem; }
.claim-more span { transition: transform .4s var(--ease); display: inline-block; }
.claim-more:hover span { transform: translateX(4px); }

/* =====================================================================
   THE RANGE
   ===================================================================== */
.range-head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .8rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
/* cute lil grid — smaller cards, roomy centred layout */
.range-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.9rem, 1.6vw, 1.4rem);
  max-width: 880px; margin-inline: auto;
}
@media (max-width: 720px) { .range-grid { grid-template-columns: repeat(2, 1fr); max-width: 460px; }
  .range-card:has(.award-pill) .range-meta { padding-right: 4.4rem; } }
@media (max-width: 420px) { .range-grid { grid-template-columns: repeat(2, 1fr); gap: .7rem; } }

.range-card {
  position: relative; overflow: hidden;
  aspect-ratio: 1 / 1.06;
  border-radius: clamp(20px, 2.4vw, 30px);
  background: var(--paper-2);
  background: color-mix(in srgb, var(--c1, var(--aqua)) 24%, var(--paper));
  display: flex; flex-direction: column; justify-content: space-between;
  padding: clamp(.85rem, 1.4vw, 1.15rem);
  transition: transform .32s var(--ease), box-shadow .32s var(--ease);
  will-change: transform;
}
.range-card:hover { transform: translateY(-5px); box-shadow: 0 20px 34px -22px rgba(33,27,23,.42); }
/* soft sunrise: nested suns rising from the base */
.range-dome {
  position: absolute; left: 50%; bottom: -34%; transform: translateX(-50%);
  width: 108%; aspect-ratio: 1; border-radius: 50%; z-index: 0;
  background: var(--c1, var(--aqua));
  transition: transform .4s var(--ease);
}
.range-card::after {
  content: ""; position: absolute; left: 50%; bottom: -34%; transform: translateX(-50%);
  width: 66%; aspect-ratio: 1; border-radius: 50%; z-index: 0;
  background: var(--c2, var(--coral));
  transition: transform .4s var(--ease);
}
.range-card:hover .range-dome, .range-card:hover::after { transform: translateX(-50%) translateY(-6%); }
.range-card--cta .range-dome, .range-card--cta::after { display: none; }
.range-prod {
  position: relative; z-index: 1;
  height: 58%; width: auto; max-width: 82%; margin: 0 auto;
  object-fit: contain; object-position: bottom;
  filter: drop-shadow(0 16px 20px rgba(33,27,23,.3));
  transition: transform .34s var(--ease);
}
.range-card:hover .range-prod { transform: translateY(-4px) scale(1.04); }
.range-prod--round { height: 48%; margin-top: auto; }
.range-meta { position: relative; z-index: 2; order: -1; }
.range-meta h3 { font-size: var(--step-1); line-height: 1; }
.range-meta h3 .stars { color: var(--ink); }
.range-meta p { font-family: var(--f-accent); font-size: clamp(.62rem, 1.1vw, .72rem); letter-spacing: .03em; color: var(--ink-soft); margin-top: .35rem; }

.range-card--cta { background: var(--ink); color: var(--paper); align-items: flex-start; justify-content: center; }
.range-card--cta:hover { background: var(--coral); }
.range-cta-inner { position: relative; z-index: 2; }
.range-cta-arrow { display: block; font-size: 1.6rem; margin-bottom: .7rem; transition: transform .34s var(--ease); }
.range-card--cta:hover .range-cta-arrow { transform: translate(5px, -5px); }
.range-card--cta h3 { font-size: var(--step-1); color: var(--paper); }
.range-card--cta .link { color: var(--aqua); margin-top: .6rem; display: inline-block; font-size: var(--step--1); }

/* =====================================================================
   Range — an annotated photograph. The image is untouched and dominant;
   the interface is five editorial annotations drawn over it: a name on a
   shared baseline, a tiny dot, a hairline down to the product, and a
   faint EXPLORE cue. No pills, boxes, cards, overlays or movement in the
   photograph — the hover changes only opacity and a 1.5px dot radius,
   fast enough (~160ms) to feel like focus rather than animation.

   Type/lines live in the SVG viewBox (the image's own pixel space), so
   at the 1312px content width everything renders at ~0.96x the authored
   size and stays glued to the photo at every viewport.
   ⚠️ .scene-img must keep its intrinsic ratio — width:100%, height:auto,
   no object-fit — or the raster crops while the viewBox does not, and
   every annotation detaches from its product.
   ===================================================================== */
.range-scene-wrap { margin-top: clamp(1.4rem, 3vw, 2.2rem); }
.range-scene {
  position: relative; overflow: hidden;
  border-radius: clamp(14px, 1.6vw, 20px);
  box-shadow: 0 30px 60px -38px rgba(33,27,23,.5);
}
.scene-img { display: block; width: 100%; height: auto; }
.scene-ann { position: absolute; inset: 0; width: 100%; height: 100%; }

.ann { cursor: pointer; outline: none; }
/* Invisible silhouette over the product itself, so pointing at the CHEESE
   lights the cheese annotation — the label, dot and line are hit targets
   too, but nobody should have to aim at a hairline. Purely a hit area:
   it never paints. */
.ann-hit { fill: transparent; stroke: none; pointer-events: fill; }
/* the whole annotation is one hit area; generous line hit via stroke */
.ann-line {
  stroke: #FAF6EC; stroke-width: 1; vector-effect: non-scaling-stroke;
  opacity: .62; transition: opacity .16s ease-out;
}
.ann-dot {
  fill: #FAF6EC; opacity: 1;
  transition: r .16s ease-out, opacity .16s ease-out;
}
.ann-name {
  font-family: var(--f-accent); font-size: 17px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  fill: #FAF6EC; opacity: 1; text-anchor: middle;
  transition: opacity .16s ease-out;
  /* a whisper of ground so the caps hold on the brightest patches of brick */
  paint-order: stroke; stroke: rgba(27,22,19,.42); stroke-width: 3px;
  stroke-linejoin: round;
}
.ann-stars { fill: var(--coral); }
.ann-cta {
  font-family: var(--f-accent); font-size: 11px; font-weight: 600;
  letter-spacing: .26em; text-transform: uppercase;
  fill: #FAF6EC; opacity: .66; text-anchor: middle;
  transition: opacity .16s ease-out;
  paint-order: stroke; stroke: rgba(27,22,19,.28); stroke-width: 2px;
  stroke-linejoin: round;
}

.ann:hover .ann-line,  .ann:focus-visible .ann-line  { opacity: .95; }
.ann:hover .ann-dot,   .ann:focus-visible .ann-dot   { r: 4.5; opacity: 1; }
.ann:hover .ann-name,  .ann:focus-visible .ann-name  { opacity: 1; }
.ann:hover .ann-cta,   .ann:focus-visible .ann-cta   { opacity: 1; }
/* keyboard gets one extra cue the mouse doesn't need */
.ann:focus-visible .ann-name { text-decoration: underline; text-underline-offset: 4px; }

/* chips: guaranteed tap targets on touch + the affordance that the picture
   is navigable. On hover-capable desktops the five product chips hide —
   the annotations do that job — leaving only the whole-range CTA. */
.scene-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: .55rem .6rem;
  /* sat tight against the photograph and far from the section rule below — now
     centred between them (user, 24 Aug) */
  margin-block: clamp(1.6rem, 3.5vw, 2.4rem) clamp(.8rem, 2vw, 1.2rem); }
.scene-chip {
  font-family: var(--f-accent); font-weight: 600; font-size: var(--step--1);
  letter-spacing: .04em; color: var(--ink); text-decoration: none;
  border: 1px solid var(--line); border-radius: 999px; padding: .62rem 1.05rem;
  transition: border-color .25s var(--ease), color .25s var(--ease), background .25s var(--ease);
}
.scene-chip:hover { border-color: var(--ink); }
.scene-chip:active { transform: scale(.97); }
.scene-chip--all { border-color: var(--ink); }
.scene-chip--all:hover { background: var(--ink); color: var(--paper); }
@media (hover: hover) and (min-width: 768px) {
  .scene-chip:not(.scene-chip--all) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ann-line, .ann-dot, .ann-name, .ann-cta { transition: none; }
}

/* benefits strip */
/* "also from the kitchen" — surfaces the categories the six cards don't cover,
   as quiet type rather than four more image cards (they have no photos yet anyway) */
.rng-more { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.1rem;
  margin-top: clamp(1.4rem, 3vw, 2rem); padding-top: clamp(1.1rem, 2.4vw, 1.5rem);
  border-top: 1px solid var(--line); }
.rng-more-k { font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); margin-right: .3rem; }
.rng-more a { font-family: var(--f-display); font-size: var(--step-0); color: var(--ink);
  border-bottom: 1px solid rgba(36,28,23,.25); padding-bottom: 1px; transition: color .25s var(--ease), border-color .25s var(--ease); }
.rng-more a:hover { color: var(--coral); border-color: var(--coral); }

.rng-benefits { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 2.4vw, 2.2rem);
  margin-top: clamp(2.4rem, 4vw, 3.4rem); padding-top: clamp(1.9rem, 3vw, 2.6rem);
  border-top: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); }
@media (max-width: 780px) { .rng-benefits { grid-template-columns: repeat(2, 1fr); gap: 1.6rem 1.4rem; } }
@media (max-width: 400px) { .rng-benefits { grid-template-columns: 1fr; } }
.rng-benefit { display: flex; gap: .85rem; align-items: flex-start;
  padding-left: clamp(1rem, 2vw, 1.8rem); border-left: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.rng-benefit:nth-child(1) { border-left: none; padding-left: 0; }
@media (max-width: 780px) { .rng-benefit:nth-child(odd) { border-left: none; padding-left: 0; } }
@media (max-width: 400px) { .rng-benefit { border-left: none; padding-left: 0; } }
.rng-bicon { width: 26px; height: 26px; flex: none; color: var(--ink); margin-top: 1px; }
.rng-benefit h4 { font-family: var(--f-accent); font-size: .66rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; margin-bottom: .35rem; }
.rng-benefit p { font-size: var(--step--1); color: var(--ink-soft); line-height: 1.45; }

/* =====================================================================
   Quick buy — buy a favourite without leaving the homepage
   ===================================================================== */
/* 404 — a branded dead-end recovery, not a browser error page */
.e404-acts { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.4rem; margin-top: 1.6rem; }
.e404-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.1rem;
  margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.e404-k { font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); margin-right: .3rem; }
.e404-links a { font-family: var(--f-display); font-size: var(--step-0); color: var(--ink);
  border-bottom: 1px solid rgba(36,28,23,.25); padding-bottom: 1px; transition: color .25s var(--ease), border-color .25s var(--ease); }
.e404-links a:hover { color: var(--coral); border-color: var(--coral); }

/* returning customer: their usual, one tap away — quiet, dismissible, never for new visitors */
.welcome-back { background: color-mix(in srgb, var(--aqua) 30%, var(--paper)); }
.wb-inner { max-width: var(--maxw, 1240px); margin: 0 auto; padding: .85rem var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.wb-copy { font-size: var(--step--1); color: var(--ink); }
.wb-copy strong { font-weight: 600; }
.wb-acts { display: flex; align-items: center; gap: .5rem; flex: none; }
.wb-add { padding: .55rem 1rem; font-size: .74rem; }
.wb-close { width: 30px; height: 30px; border: 0; background: none; cursor: pointer; color: var(--ink-soft);
  border-radius: 50%; font-size: .8rem; transition: background .25s var(--ease), color .25s var(--ease); }
.wb-close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }

/* gift mode — one tick, note field only when needed */
.co-gift { margin: 1.1rem 0 .2rem; }
.co-gift-tick { display: inline-flex; align-items: center; gap: .55rem; cursor: pointer;
  font-family: var(--f-accent); font-size: .92rem; color: var(--ink); }
.co-gift-tick input { width: 18px; height: 18px; accent-color: var(--coral); cursor: pointer; flex: none; }
.co-gift-more { margin-top: .8rem; }
.co-gift-more label { display: block; font-family: var(--f-accent); font-size: .76rem; font-weight: 600;
  letter-spacing: .04em; color: var(--ink-soft); margin-bottom: .35rem; }
.co-gift-more textarea { width: 100%; font-family: inherit; font-size: 1.05rem; padding: .7rem .8rem;
  border-radius: 12px; border: 1.5px solid color-mix(in srgb, var(--ink) 16%, transparent);
  background: var(--paper); color: var(--ink); resize: vertical; }
.co-gift-more textarea:focus { outline: none; border-color: var(--ink); }
.co-gift-note { font-size: .8rem; color: var(--ink-soft); margin-top: .4rem; }

/* help where doubt happens */
.cart-help { font-size: .82rem; color: var(--ink-soft); line-height: 1.5; margin-top: .9rem; text-align: center; }
.cart-help a { color: var(--teal-ink); border-bottom: 1px solid currentColor; padding-bottom: 1px; }
.cart-help a:hover { color: var(--coral); }

/* quick-buy now lives INSIDE the range section (one shop moment, not two) */
.qb-inline { margin-top: clamp(1.4rem, 3vw, 2rem); padding-top: clamp(1.1rem, 2.4vw, 1.5rem); border-top: 1px solid var(--line); }
.qb-inline-k { font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); margin-bottom: .9rem; }
.qb-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(.8rem, 2vw, 1.4rem); }
@media (max-width: 760px) { .qb-row { grid-template-columns: 1fr; } }
.qb-item { background: var(--paper-2, color-mix(in srgb, var(--aqua) 16%, var(--paper))); border-radius: 20px;
  padding: clamp(1rem, 2.2vw, 1.4rem); display: flex; flex-direction: column; gap: .5rem; }
@media (max-width: 760px) {
  .qb-item { flex-direction: row; align-items: center; gap: 1rem; flex-wrap: wrap; }
  .qb-body { flex: 1; min-width: 9ch; }
  .qb-add { width: 100%; justify-content: center; }
}
.qb-media { display: block; aspect-ratio: 1 / 1; border-radius: 14px; overflow: hidden;
  background: color-mix(in srgb, var(--aqua) 26%, var(--paper)); display: grid; place-items: center; }
@media (max-width: 760px) { .qb-media { width: 88px; aspect-ratio: 1/1; flex: none; } }
.qb-media img { width: 78%; height: 78%; object-fit: contain; transition: transform .45s var(--ease); }
.qb-media:hover img { transform: scale(1.05); }
.qb-cat { font-family: var(--f-accent); font-size: .62rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); }
.qb-name { font-size: var(--step-1); line-height: 1.05; margin-top: .18rem; }
.qb-price { font-family: var(--f-display); font-size: 1.12rem; margin-top: .3rem; }
.qb-price span { font-family: var(--f-body); font-size: .82rem; color: var(--ink-soft); }
.qb-add { margin-top: auto; align-self: flex-start; }

/* =====================================================================
   Subscribe & save
   ===================================================================== */
.subscribe-band { background: color-mix(in srgb, var(--aqua) 46%, var(--paper)); }
.sub-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
@media (max-width: 820px) { .sub-grid { grid-template-columns: 1fr; gap: 2.4rem; } }
.sub-copy h2 { margin-top: .5rem; }
.sub-copy .lead { margin-top: 1.1rem; max-width: 44ch; }
.sub-actions { display: flex; align-items: center; gap: 1.4rem 1.6rem; flex-wrap: wrap; margin-top: 1.9rem; }
.sub-call { font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .03em; color: var(--ink-soft); border-bottom: 1px solid currentColor; padding-bottom: 2px; transition: color .3s var(--ease); }
.sub-call:hover { color: var(--ink); }
/* how it works — always visible now the cadence cards are gone */
.sub-how { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: .6rem; counter-reset: subhow; }
.sub-how li { counter-increment: subhow; position: relative; padding-left: 2.1rem; font-size: var(--step-0); line-height: 1.45; color: var(--ink); }
.sub-how li::before { content: counter(subhow); position: absolute; left: 0; top: -.05em; width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--coral); color: var(--paper); font-family: var(--f-accent); font-size: .72rem; font-weight: 600; display: grid; place-items: center; }
/* subscribe & save tiers (real offer: 15+/mo = 5%, 25+/mo = 8% off all orders) */
.sub-tiers { margin-top: 1.5rem; }
.sub-tiers-lead { font-size: var(--step-1); line-height: 1.2; margin-bottom: 1rem; }
.sub-tier-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
.sub-tier { background: var(--paper); border-radius: 18px; padding: 1.15rem 1.3rem; display: flex; flex-direction: column; gap: .25rem; }
.sub-tier--top { background: var(--ink); color: var(--paper); }
.sub-tier-q { font-family: var(--f-accent); font-weight: 600; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--maroon); }
.sub-tier--top .sub-tier-q { color: var(--aqua); }
.sub-tier-q span { opacity: .65; font-weight: 500; }
.sub-tier-d { font-family: var(--f-display); font-size: clamp(2.4rem, 6vw, 3.2rem); line-height: 1; color: var(--coral); }
.sub-tier-d span { font-size: .5em; }
.sub-tier-n { font-size: var(--step--1); color: var(--ink-soft); }
.sub-tier--top .sub-tier-n { color: rgba(244,237,225,.75); }
.sub-tiers-note { font-size: .82rem; color: var(--ink-soft); line-height: 1.5; margin-top: .85rem; }
@media (max-width: 480px) { .sub-tier-grid { grid-template-columns: 1fr; } }

/* =====================================================================
   FEATURE (video)
   ===================================================================== */
.feature { display: grid; grid-template-columns: 1.1fr 1fr; align-items: stretch; }
@media (max-width: 860px) { .feature { grid-template-columns: 1fr; } }
.feature-media {
  position: relative; overflow: hidden; min-height: 60vh;
  background: var(--teal-ink);
}
.feature-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.feature-visual { position: relative; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.feature-dome {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(74%, 420px); aspect-ratio: 1; border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, var(--maroon) 0 26%, transparent 26.4%),
    radial-gradient(circle at 50% 50%, var(--aqua) 0 50%, transparent 50.4%);
  opacity: .95;
}
.feature-visual img {
  position: relative; z-index: 1;
  height: clamp(300px, 46vh, 520px); width: auto; object-fit: contain;
  filter: drop-shadow(0 30px 34px rgba(10,30,35,.5));
}
.feature-body {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1.4rem;
  padding: clamp(3rem, 7vw, 7rem) clamp(2rem, 6vw, 6rem);
  justify-content: center;
}
.feature-quote { font-size: var(--step-3); line-height: 1.04; }
.feature-body p { color: rgba(244,237,225,.86); }

/* =====================================================================
   FLAVOURS
   ===================================================================== */
.flavours-head { font-size: var(--step-4); margin-top: .3rem; }
.flavours-all { display: inline-block; margin-top: 1.3rem; }
.flavours-links { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .7rem 2rem; margin-top: 1.3rem; }
.flavours-quiz { color: var(--maroon-deep); }  /* --maroon on --sand was 3.92:1 */
/* colour-world: JS shifts the section background to the active flavour's tint */
/* The colour world is a FLAT fill, edge to edge. A bottom fade-out was tried first
   (to soften the boundary with the range section) and rejected — the dissolve read as
   the colour running out before the section did (user, 24 Aug). The wash still lives
   in a registered @property so the .55s crossfade between flavours keeps working. */
@property --fx-wash { syntax: '<color>'; inherits: false; initial-value: transparent; }
.flavours {
  background-color: var(--fx-wash);
  transition: --fx-wash .55s var(--ease), background-color .55s var(--ease);
}
.flavours .eyebrow { color: var(--fx-deep, var(--maroon)); transition: color .55s var(--ease); }
.flavours .eyebrow::before, .flavours .eyebrow::after { background: var(--fx-deep, var(--maroon)); transition: background-color .55s var(--ease); }
.flavour-scroll {
  /* align-items:flex-start, not the flex default of stretch: with stretch every
     bottle stretched to the tallest item in the line, which inflated each card
     from 421px to 1569px and left ~1200px of dead space under the row. */
  display: flex; align-items: flex-start; gap: clamp(1rem, 2vw, 2rem);
  padding: 3rem var(--gutter) 1rem;
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none;
  cursor: grab;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 4%, #000 96%, transparent);
}
.flavour-scroll.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.flavour-scroll::-webkit-scrollbar { display: none; }
.flavour-item {
  flex: 0 0 auto; width: clamp(180px, 22vw, 260px);
  scroll-snap-align: center; text-align: center; position: relative;
}
.flavour-item > * { pointer-events: none; }
.flavour-item img {
  position: relative;
  height: clamp(240px, 32vw, 360px); width: 100%; object-fit: contain;
  filter: drop-shadow(0 18px 22px rgba(33,27,23,.2));
  transition: transform .45s var(--ease), filter .45s var(--ease);
}
.flavour-item.is-active img {
  transform: translateY(-12px) scale(1.06);
  filter: drop-shadow(0 30px 34px rgba(33,27,23,.28));
}
.flavour-item figcaption {
  font-family: var(--f-display); font-size: var(--step-1); margin-top: 1rem;
  padding-bottom: .4rem; position: relative; display: inline-block; text-transform: lowercase;
  transition: opacity .45s var(--ease); opacity: .5;
}
.flavour-item.is-active figcaption { opacity: 1; }
.flavour-item figcaption::after { content:""; position:absolute; left:50%; bottom:0; width:26px; height:3px; background: var(--tint); transform: translateX(-50%); border-radius: 3px; transition: width .45s var(--ease); }
.flavour-item.is-active figcaption::after { width: 46px; }

/* =====================================================================
   FOUNDER
   ===================================================================== */
.founder { display: grid; grid-template-columns: 1fr 1fr; align-items: center; background: var(--aqua); color: var(--ink); }
.founder-media { position: relative; overflow: hidden; aspect-ratio: 3 / 2; }
.founder-media img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
@media (max-width: 860px) { .founder { grid-template-columns: 1fr; } }
.founder-body { padding: clamp(3rem, 7vw, 7rem) clamp(2rem, 6vw, 6rem); display: flex; flex-direction: column; gap: 1.4rem; align-items: flex-start; }
.founder-body h2 { font-size: var(--step-3); }
.founder-body .eyebrow { color: var(--maroon-deep); }  /* .founder bg is --aqua: 3.21 -> 4.54 */
.founder-body .eyebrow::before, .founder-body .eyebrow::after { background: var(--maroon); opacity: .7; }
.founder-body p { color: rgba(33,27,23,.78); }
.founder .btn--outline { color: var(--ink); border-color: rgba(33,27,23,.55); }
.founder .btn--outline::before { background: var(--ink); }
.founder .btn--outline:hover { color: var(--paper); }

/* =====================================================================
   VALUES
   ===================================================================== */
.values-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(2rem, 4vw, 4rem); }
@media (max-width: 780px) { .values-grid { grid-template-columns: 1fr; gap: 2.5rem; } }
.value { display: flex; flex-direction: column; gap: .8rem; align-items: flex-start; }
.value-mark svg { width: 48px; height: auto; margin-bottom: .4rem; }
.value h3 { font-size: var(--step-2); }
.value p { color: var(--teal-ink); opacity: .82; }

.footer-sun { position: absolute; right: clamp(-70px, -3vw, 0px); top: 0; width: clamp(240px, 34vw, 470px); opacity: .13; z-index: 0; }
.footer .wrap { position: relative; z-index: 1; }
.footer-note { font-size: var(--step--1); color: var(--aqua); margin-top: 1rem; opacity: .8; }

/* =====================================================================
   PAGE HEADER (inner pages)
   ===================================================================== */
.page-head { position: relative; padding: clamp(9rem, 16vh, 13rem) 0 clamp(3rem, 6vw, 5rem); overflow: hidden; }
.page-title { font-size: clamp(2.8rem, 1.2rem + 6vw, 6rem); margin: .2em 0 .4em; }
.page-intro { font-size: var(--step-1); max-width: 46ch; color: var(--ink-soft); }
.page-head-sun { position: absolute; right: clamp(-30px, 2vw, 40px); bottom: 0; width: clamp(160px, 24vw, 300px); z-index: -1; opacity: .9; }
@media (max-width: 700px) { .page-head-sun { opacity: .35; } }

/* contact: the three ways to reach us, as cards you can tap (24 Aug redesign) */
.contact-quick { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem;
  margin-top: clamp(1.6rem, 4vw, 2.4rem); max-width: 46rem; }
@media (max-width: 700px) { .contact-quick { grid-template-columns: 1fr; } }
.cq-card { display: flex; flex-direction: column; gap: .28rem;
  padding: 1.05rem 1.15rem; border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent);
  border-radius: calc(var(--radius) * .75); background: color-mix(in srgb, var(--paper) 88%, var(--sand));
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease); }
.cq-card:hover, .cq-card:active { border-color: var(--coral); transform: translateY(-2px);
  box-shadow: 0 14px 28px -22px rgba(20,14,7,.5); }
.cq-k { font-family: var(--f-accent); font-size: .64rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--coral); }
.cq-card strong { font-family: var(--f-display); font-size: 1.15rem; color: var(--ink); line-height: 1.15; }
.cq-v { font-family: var(--f-accent); font-size: .8rem; color: var(--ink-soft); overflow-wrap: anywhere; }

/* ---- page header carrying a photograph (contact) -------------------------
   COPY LEFT, PHOTOGRAPH RIGHT — the about-hero idiom. Third treatment, 2026-08-14.

   History, so nobody retries the first two: (1) type over the photo, blurred
   14px under a 76% paper scrim — structurally broken, a dusk exterior with
   rgb(28,21,7) behind the copy cannot carry ink type without a scrim heavy
   enough to erase the photograph. (2) title stacked above a full-bleed strip —
   legible, but it letterboxed a tall subject (the doors) into a short sliver
   and the founder rejected how it read. This split gives the gate its height,
   keeps every word on paper (eyebrow --maroon-deep 6.78:1, same as every other
   page head), and repeats .about-hero-inner's shape so contact opens in the
   site's own language.

   Alignment is CENTER, not about-hero's `end` — that page bottom-aligns a
   portrait against three stacked title lines; here the photo is landscape and
   `end` left the copy hanging above its baseline. */
/* CONTACT HERO — the gate photograph is the whole background; the copy sits on
   a cream veil that dissolves into it. On desktop that veil is BAKED INTO THE
   SOURCE (storefront-dusk-v2), not painted here. It used to take two CSS layers
   — a paper->transparent gradient plus a separately masked backdrop-filter,
   because colour alone left a straight edge where the photo kept its contrast.
   The photograph's own optical falloff does both jobs at once and reads softer.
   Its veil colour was retargeted to --paper on export, so the band and the page
   background are the same cream and the section has no seam at its bottom edge.
   The recipe lives beside its master, at
   brand-assets/_originals/lifestyle/storefront-gate-recut.py — re-run it there
   rather than editing the shipped .webp, and bump the -v suffix when you do.
   ⚠️ Do NOT re-add a CSS veil on desktop: it would stack on the baked one,
   doubling the ramp and washing out the planters. The mobile rules below are
   still needed — there the copy sits over the whole frame, not beside it. */
.page-head--photo {
  position: relative; overflow: hidden; background: var(--paper);
  /* Height is derived from the WIDTH so the whole photograph fits with no
     crop: the source is 1672x941, and 100 / (1672/941) = 56.3, so 56.3vw is
     exactly the image's own height at any viewport width.
     ⚠️ Do NOT express this as `aspect-ratio` plus `max-height` — when the
     height is clamped, aspect-ratio shrinks the WIDTH to preserve the ratio,
     so the section stops filling the page and leaves a gap down the side.
     The px cap only bites on very wide screens. */
  min-height: min(56.3vw, 1000px);
  display: flex; align-items: center;
  padding-block: clamp(3rem, 6vh, 5rem);
}
.ph-split { display: grid; gap: clamp(2rem, 5vw, 5rem); align-items: center;
  position: relative; z-index: 2; width: 100%; }
@media (min-width: 880px) { .ph-split { grid-template-columns: 1fr 1fr; } }
.ph-copy { min-width: 0; }
/* The display line can run past the veil's plateau — near-black serif at that
   size stays legible over blurred foliage. The intro cannot: it is 1rem of
   --grey, and its tail was landing on lit leaves. 28rem keeps its right edge
   inside 42% of the viewport at every width from 1280 up, which is where the
   picture's own dissolve is still above 0.8. Measure it before widening this. */
@media (min-width: 880px) { .page-head--photo .page-intro { max-width: 28rem; } }

/* the photograph, full bleed behind everything */
.page-head--photo .ph-photo {
  position: absolute; inset: 0; z-index: 0;
  margin: 0; border-radius: 0; overflow: hidden;
}
.page-head--photo .ph-photo img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
  border-radius: 0;
}
/* No veil layer on desktop — the source carries it. See the block comment above.
   The BOTTOM scrim is still CSS, and has to be: the section is cover-cropped
   vertically once the viewport passes ~1777px wide, so a baked fade would drift
   off its own edge. This one always lands on the section's. The frame ends on
   lawn in shadow, near rgb(40,45,25), and butting that straight against --paper
   drew a hard line across the page.

   There is deliberately NO matching scrim at the top, and the nav being hard to
   read over the roof tiles at rest is a KNOWN, ACCEPTED trade — do not "fix" it.
   A paper scrim was built and rejected: it read as haze over the photograph
   rather than as a photograph. Four alternatives were mocked up and turned down
   too — the site's own solid bar via [data-nav-solid], insetting the photo below
   the bar, a cream halo on the type, and a plate behind the links. The founder
   chose the photograph. It also self-corrects: main.js:273 flips the nav to
   .nav--solid after 40px of scroll, so this only shows at the very top.

   ⚠️ This lives on .ph-photo, not on the section, and that placement is
   load-bearing. .ph-photo is positioned WITH z-index 0, which makes it a
   stacking context, so .ph-cap's z-index 3 only ranks inside the figure. Put
   the scrim on the section instead and it outranks the entire figure — caption
   included — and washes the caption out to an unreadable pale grey. Only
   .ph-split escapes, because it is a sibling of the figure rather than a child.
   Phones are excluded: there the ::after wash below already covers the frame
   top to bottom, and a second pass makes the photo vanish altogether. */
@media (min-width: 880px) {
  .page-head--photo .ph-photo::before {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background:
      linear-gradient(to top,
        var(--paper) 0,
        color-mix(in srgb, var(--paper) 58%, transparent) 40%,
        transparent 100%) bottom / 100% 24% no-repeat;
  }
  /* The section's height is 56.3vw, so it is fractional at most widths, and on
     a 2x screen the image rounds one device row lower than the gradient above
     it — a single dark line of lawn along the bottom edge, which is exactly the
     seam the fade exists to remove. A few px of flat paper closes it. Sits
     above the figure (z-index 0) but clear of .ph-cap, which is ≥16px up. */
  .page-head--photo::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
    background: var(--paper); z-index: 2; pointer-events: none;
  }
}
/* Caption sits bottom-right. The generic .ph-cap below is a full-width scrim
   (left:0 + a dark gradient) meant for a boxed photo; inherit that here and it
   paints a grey bar clean across the cream half, so left, padding and background
   all have to be cancelled. It used to be cream with a shadow, sitting on the
   dark lawn — but the bottom scrim now turns that corner to paper, so it reads
   as ink, the same way it already did on phones. --ink-soft, not the --grey the
   phone rule uses: the corner is paper over lawn rather than clean paper, and
   --grey measures 3.79:1 there against 5.72:1 for --ink-soft. This is 11.8px
   text, so it needs 4.5:1. */
.page-head--photo .ph-cap {
  position: absolute; left: auto; right: clamp(1.25rem, 4vw, 4rem); bottom: clamp(1rem, 3vh, 2rem);
  z-index: 3; margin: 0; padding: 0; background: none;
  color: var(--ink-soft); text-align: right; text-shadow: none;
}
@media (max-width: 879px) {
  /* One column on phones: the veil covers the whole frame rather than a
     left band, because there is no left band to speak of. The source's own
     baked veil is mostly cropped away here — cover on a narrow box keeps the
     middle of a 16:9 frame — so these two layers do all the work, and unlike
     desktop they still have to exist. */
  .page-head--photo { min-height: auto; }
  /* Cover on a phone-width box shows only ~30% of a 16:9 frame, and centred
     that lands wholly inside the veil — the storefront vanishes into cream.
     81% puts the doors in the middle of whatever slice the copy's height
     leaves, and holds them there from roughly 600px to 900px of section. */
  .page-head--photo .ph-photo img { object-position: 81% 50%; }
  .page-head--photo .ph-photo::after {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--paper) 92%, transparent) 0%,
      color-mix(in srgb, var(--paper) 88%, transparent) 55%,
      color-mix(in srgb, var(--paper) 70%, transparent) 100%);
  }
  .ph-veil {
    position: absolute; inset: 0; z-index: 1; pointer-events: none;
    backdrop-filter: blur(22px) saturate(.94);
    -webkit-backdrop-filter: blur(22px) saturate(.94);
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 70%, rgba(0,0,0,.6) 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 70%, rgba(0,0,0,.6) 100%);
  }
  .page-head--photo .ph-cap { position: static; text-align: left; color: var(--grey);
    text-shadow: none; margin-top: 1.5rem; padding: 0; background: none; }
}
/* Same frame as .about-hero-media. aspect-ratio 4/3 crops the 1312x902 frame
   (1.45:1) only slightly; the 50% 58% bias survives from the overlay days —
   it keeps the signboard and doorway rather than the roofline. */
.ph-photo { position: relative; margin: 0; border-radius: var(--radius); overflow: hidden; }
/* height:auto is load-bearing: the img carries height="902" for layout-shift
   protection, and that presentational hint is a definite height — with both
   dimensions definite, aspect-ratio silently does nothing. auto releases it. */
.ph-photo img { display: block; width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; object-position: 50% 58%; }
/* Caption ON the photo, bottom edge, where the frame is darkest — the lawn in
   shadow. Cream on that ground measures well above 4.5:1; it is also the one
   piece of text allowed on the image, because it sits on the photo's darkest
   band by construction, not on an arbitrary crop. */
.ph-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 2.2rem 1.1rem .8rem;
  background: linear-gradient(180deg, transparent, rgba(20, 14, 7, .62) 62%);
  color: var(--paper); font-family: var(--f-accent);
  font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
}
/* Still hidden. The sun anchors bottom-right of the section, which in the
   split layout is exactly where the photo column sits — it would poke out from
   behind the gate like a second sunset. One sundown per hero. */
.page-head--photo .page-head-sun { display: none; }


/* page header with a lifestyle image (range page) */
/* shorter: the range page was spending most of a viewport on its own
   title before anyone saw a product */
.page-head--media { padding-top: clamp(5.6rem, 9vh, 7rem); padding-bottom: clamp(1.2rem, 2.5vw, 2rem); }
.page-head--media .page-title { font-size: clamp(2.2rem, 5.2vw, 3.4rem); }
.page-head--media .ph-media img { max-height: 42vh; width: 100%; object-fit: cover; }
.ph-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.ph-copy .page-title { margin-top: .15em; }
.ph-media { position: relative; border-radius: clamp(16px, 2vw, 24px); overflow: hidden;
  aspect-ratio: 4 / 3.4; box-shadow: 0 34px 70px -34px rgba(33,27,23,.5); }
.ph-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 58%; display: block; }
@media (max-width: 860px) {
  .ph-grid { grid-template-columns: 1fr; gap: 2rem; }
  .ph-media { aspect-ratio: 4 / 3; order: -1; }
  .page-head--media { padding-top: clamp(5rem, 9vh, 6rem); }
}

/* =====================================================================
   FILTER BAR
   ===================================================================== */
.filter-wrap { position: sticky; top: 62px; z-index: 40; background: rgba(244,237,225,.9); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-block: 1px solid var(--line); }

/* =====================================================================
   PRODUCT GRID
   ===================================================================== */
.prod-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(.9rem, 1.4vw, 1.4rem); }
@media (max-width: 1080px) { .prod-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px) { .prod-grid { grid-template-columns: repeat(2, 1fr); gap: .7rem; } }
@media (max-width: 340px) { .prod-grid { grid-template-columns: 1fr; } }

/* Card = a 3:4 visual tile with the flavour name captioned BENEATH it (never over
   the photo, so nothing overlaps the bottle). Applies to every card in the grid. */
.prod-card {
  position: relative; display: flex; flex-direction: column; cursor: pointer;
  transition: transform .45s var(--ease);
}
.prod-card.is-hidden { display: none; }
.prod-card:hover { transform: translateY(-6px); }

.prod-visual {
  position: relative; aspect-ratio: 3 / 4; overflow: hidden; border-radius: var(--radius);
  background: color-mix(in srgb, var(--c-top, var(--aqua)) 26%, var(--paper));
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  transition: box-shadow .45s var(--ease);
}
.prod-card:hover .prod-visual { box-shadow: 0 30px 52px -26px rgba(33,27,23,.5); }

/* bold sunrise arcs rising from the base — grounds the older transparent-PNG renders.
   Cards on studio photography use .prod-card--shot, which hides these. */
.prod-dome {
  position: absolute; left: 50%; bottom: -30%; transform: translateX(-50%);
  width: 118%; aspect-ratio: 1; border-radius: 50%; z-index: 0;
  background: var(--c-top, var(--aqua));
  transition: transform .55s var(--ease);
}
.prod-visual::after {
  content: ""; position: absolute; left: 50%; bottom: -30%; transform: translateX(-50%);
  width: 72%; aspect-ratio: 1; border-radius: 50%; z-index: 0;
  background: var(--c-bot, var(--coral));
  transition: transform .55s var(--ease);
}
.prod-card:hover .prod-dome { transform: translateX(-50%) translateY(-5%) scale(1.05); }
.prod-card:hover .prod-visual::after { transform: translateX(-50%) translateY(-5%) scale(1.05); }
.prod-visual > img {
  position: relative; z-index: 1;
  height: 66%; width: auto; max-width: 88%; margin: 0 auto; object-fit: contain; object-position: bottom;
  filter: drop-shadow(0 22px 24px rgba(33,27,23,.34));
  transition: transform .5s var(--ease);
}
.prod-card:hover .prod-visual > img { transform: translateY(-6px) rotate(-2.5deg) scale(1.05); }
/* Shrinks a wide round product (a wheel, a squat jar) so it sits properly on the arc backdrop.
   Scoped away from .prod-card--shot: on a full-bleed photo its `height: 52% !important` beat
   the fill rule and left the photograph as a band across the middle of the tile. */
.prod-card:not(.prod-card--shot) .prod-img--round { height: 52% !important; align-self: center; margin-top: auto; }

/* Real product photography fills the whole tile — no arcs behind it. Applied to every card
   whose image comes from brand-assets/product-grid/ (the studio board shots). Cards still on
   the older transparent PNG renders stay plain, so they keep their arc backdrop. */
.prod-card--shot .prod-dome,
.prod-card--shot .prod-visual::after { display: none; }
.prod-card--shot .prod-visual { background: var(--paper-2); }
.prod-card--shot .prod-visual > img { position: absolute; inset: 0; width: 100%; height: 100%;
  max-width: none; margin: 0; object-fit: cover; object-position: center; filter: none; }
.prod-card--shot:hover .prod-visual > img { transform: scale(1.04); }
/* Touch screens: tapping a card fired its :hover state and the tile enlarged
   mid-scroll, making the shelf look uneven (user, 24 Aug). Hover flourishes are
   for pointers that can actually hover. The dome keeps its centring transform. */
@media (hover: none) {
  .prod-card:hover { transform: none; }
  .prod-card:hover .prod-visual { box-shadow: none; }
  .prod-card:hover .prod-visual > img { transform: none; }
  .prod-card--shot:hover .prod-visual > img { transform: none; }
  .prod-card:hover .prod-dome { transform: translateX(-50%); }
  .prod-card:hover .prod-visual::after { transform: translateX(-50%); }
}

/* typographic placeholder for products awaiting a photo.
   THE CHIP CARRIES ITS OWN BACKGROUND, and that is a contrast fix rather than a
   style choice. It used to be ink at 50% alpha with no background, sitting straight
   on .prod-visual — whose colour is a PER-CATEGORY TINT read from products.csv, so
   there is no single backdrop to tune against. Measured across all twelve
   awaiting-photo cards it ran 1.65:1 to 3.09:1, every one of them under the 4.5
   required at this size, worst on the deep red tint rgb(153,58,45).
   Darkening could not fix it: ink at FULL opacity still only reaches 2.43 there, and
   light text would then fail on the pale tints at the other end of the range. The
   only way to make the result deterministic is to stop the tint being the backdrop. */
.prod-card--soon .prod-soon {
  position: relative; z-index: 1; margin: auto; text-align: center;
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-soft);
  background: var(--paper);
  border: 1px solid var(--line); border-radius: 100px; padding: .4em .9em;
}

/* 'most loved' badge — the flagship feta */
.pc-fav { position: absolute; top: .7rem; left: .7rem; z-index: 3;
  font-family: var(--f-accent); font-size: .58rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink); background: var(--coral);
  padding: .45em .85em; border-radius: 100px; box-shadow: 0 6px 16px -6px rgba(20,14,7,.5); }
/* On phones the type floor grows this pill until it ran under the "+" quick-add
   circle (user, 24 Aug). Truncating it read worse ("MOST LO…"), so on small
   screens the badge moves to the bottom-left corner instead — full text, and the
   opposite corner from the "+". */
@media (max-width: 640px) {
  .pc-fav { top: auto; bottom: .7rem; letter-spacing: .1em; }
}

/* caption beneath the tile — editorial hierarchy:
   category eyebrow -> oversized flavour name (focal point) -> tagline -> price · size */
.prod-info { padding: 1.1rem .4rem .2rem; text-align: center; flex: 1 1 auto; display: flex; flex-direction: column; }
.prod-cat { display: block; font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase; color: var(--maroon); margin-bottom: .5rem; }
.prod-info h3 { font-size: var(--step-2); line-height: .95; letter-spacing: -.015em; }
/* The product name is a real button — it's the card's keyboard control. Styled to be
   invisible as a control so the card looks exactly as before. */
.pc-open { all: unset; display: inline; cursor: pointer; color: inherit; font: inherit;
  letter-spacing: inherit; text-transform: inherit; }
.pc-open:focus-visible { outline: 2px solid var(--coral); outline-offset: 4px; border-radius: 3px; }
.prod-tag { margin: .5rem auto 0; max-width: 26ch; color: var(--ink-soft); font-size: .88rem; line-height: 1.4; }
.prod-price { margin-top: auto; padding-top: .8rem; font-family: var(--f-display); font-size: var(--step-1); color: var(--ink); line-height: 1; }

/* QUICK ADD, 21 Aug 2026. The shortest path from browsing to basket was three actions
   — card, product page, add — on a 54-card catalogue. This serves the customer who has
   already decided; the card click still opens the PDP for the one who has not.

   No new JS: main.js already delegates [data-quickadd] from the document, and the card
   already carries every data-qa-* attribute the handler reads.

   POINTER-AWARE, not hover-only: on touch there is no hover, so a hover-reveal button
   would be invisible on precisely the devices where the extra tap costs most. It is
   permanently visible on coarse pointers and revealed on hover for fine ones. */
.pc-quickadd {
  /* RETIRED AS UI (24 Aug 2026), KEPT AS DATA. The card already carries the round "+"
     (.pc-add) — this second dark "add" pill duplicated it, and on touch screens it was
     always-visible and sat on top of the price line. display:none rather than removing
     the markup: the category rail's add button copies its data-qa-* attributes from
     this element (main.js railAdd), so the node must stay in the DOM. */
  display: none;
  position: absolute; right: .55rem; bottom: .55rem; z-index: 3;
  border: 0; border-radius: 999px; cursor: pointer;
  padding: .5em 1.1em; font-family: var(--f-accent); font-size: .68rem;
  font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  background: var(--ink); color: var(--paper);
  transition: opacity .22s var(--ease), transform .22s var(--ease), background .22s var(--ease);
}
.pc-quickadd:hover { background: var(--coral); }
.pc-quickadd:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }
/* the card is the positioning context for the button */
.prod-card { position: relative; }

@media (hover: hover) and (pointer: fine) {
  .pc-quickadd { opacity: 0; transform: translateY(6px); }
  .prod-card:hover .pc-quickadd,
  .prod-card:focus-within .pc-quickadd { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .pc-quickadd { transition: none; } }
@media (max-width: 760px) {
  .prod-info { padding-top: .9rem; }
  .prod-tag { font-size: .82rem; }
}

/* =====================================================================
   FETA SPOTLIGHT — the fan-favourite band on the products page
   ===================================================================== */
/* ===== FETA SPOTLIGHT — the award, said once =====================================
   Warm charcoal rather than aqua: a warm beige photograph on a cold aqua field was
   fighting itself, and gold only reads as gold against something dark. This is the one
   dark moment on the homepage, which is what makes it land as an award. */
.feta-feature { padding: clamp(4rem, 8vw, 6.5rem) 0; background: var(--award-bg);
  color: var(--paper); overflow: hidden; }
.feta-grid { display: grid; grid-template-columns: 1fr .92fr; gap: clamp(2.4rem, 6vw, 5rem);
  align-items: center; }
@media (max-width: 820px) { .feta-grid { grid-template-columns: 1fr; gap: 2.2rem; }
  .feta-media { order: -1; max-width: 480px; margin-inline: auto; } }
.feta-media { position: relative; overflow: hidden; border-radius: 3px;
  box-shadow: 0 40px 80px -30px rgba(0,0,0,.7); }
.feta-media img { width: 100%; height: 100%; object-fit: cover; display: block; aspect-ratio: 4 / 5; }

/* the laurel: a hairline rule either side of a single gold star */
/* Rebuilt 21 Aug 2026 with the section. .feta-laurel, .feta-award-line and .feta-quote
   are gone with their markup — the star, the gold award pill and the pull-quote were the
   four blocks of type standing in front of the photograph. */
.feta-k { font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold-lt); margin: 0; }
/* the award is now the LAST and SMALLEST thing in the section: supporting proof,
   sitting under the CTA, not a banner above the headline */
.feta-award-sub { font-family: var(--f-accent); font-size: .68rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: rgba(244,237,225,.55);
  margin: 1.1rem 0 0; }

/* text-transform: none matches the decision taken on the 10x headline: display headings
   are lowercased by house style, and these two are set as written, deliberately. */
.feta-copy h2 { font-size: var(--step-3); line-height: 1.06; margin: 1rem 0 1.3rem;
  color: var(--paper); text-transform: none; }
.feta-copy .serif-italic { color: var(--gold-lt); }

.feta-note { color: rgba(244,237,225,.74); margin-bottom: 1.7rem; max-width: 46ch; line-height: 1.65; }
.feta-feature .btn--on-dark { --bg: var(--paper); --fg: var(--ink); }


/* =====================================================================
   CLAIMS STRIP
   ===================================================================== */
.claims-inner { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); padding-block: clamp(3rem, 6vw, 5rem); }
@media (max-width: 760px) { .claims-inner { grid-template-columns: 1fr; gap: 2rem; } }
.claim { display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; }
.claim img { height: 74px; width: auto; }
.claim p { font-family: var(--f-display); font-size: var(--step-1); line-height: 1.25; color: var(--paper); max-width: 20ch; }
.claim-no { font-family: var(--f-display); font-size: clamp(3rem, 6vw, 4.4rem); line-height: .72; color: var(--paper); }
.prod-note { text-align: center; max-width: 62ch; margin: clamp(2.5rem, 5vw, 4rem) auto 0; color: var(--ink-soft); }
.prod-note .link { text-transform: none; letter-spacing: normal; font-family: var(--f-body); }

/* =====================================================================
   CTA BAND
   ===================================================================== */
.cta-band { background: var(--paper-2); text-align: center; }
.cta-band h2 { font-size: var(--step-4); margin: .3em 0 .5em; }
.cta-band .btn { margin-top: 2rem; }
.cta-band .lead { margin-inline: auto; }

/* =====================================================================
   AWARD — India's No.1 Plant-Based Cheese
   ===================================================================== */
.award { background: var(--paper); overflow: hidden; }
.award-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 6vw, 6rem); align-items: center; }
@media (max-width: 860px) { .award-grid { grid-template-columns: 1fr; gap: clamp(2rem, 6vw, 3rem); } }
.award-text { max-width: 32rem; }
.award-medal { width: clamp(80px, 9vw, 116px); height: auto; border-radius: 50%; display: block;
  box-shadow: 0 12px 34px rgba(20,14,7,.30); margin-bottom: 1.5rem; }
.award-eyebrow { color: var(--gold); }
.award-eyebrow::before, .award-eyebrow::after { background: var(--gold); opacity: .65; }
.award-head { font-size: var(--step-3); line-height: 1.03; }
.award-head .serif-italic { color: var(--maroon); }
.award-body { margin: 1.2rem 0 1.9rem; color: var(--ink-soft); max-width: 36ch; }
.award-figure { position: relative; width: min(100%, 30rem); margin-inline: auto; }
.award-figure::before { content: ""; position: absolute; inset: 0; z-index: 0;
  transform: translate(18px, 18px); border-radius: 999px 999px 18px 18px; background: var(--aqua); opacity: .55; }
.award-portrait { position: relative; z-index: 1; display: block; width: 100%; height: auto;
  border-radius: 999px 999px 18px 18px; box-shadow: 0 30px 60px rgba(20,14,7,.24); }
@media (max-width: 860px) { .award-figure::before { transform: translate(12px, 12px); } }

/* compact award strip */
.award-slim { background: var(--paper); border-block: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.award-slim-inner { display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.2rem);
  padding-block: clamp(1.4rem, 3vw, 2.1rem); }
.award-slim-medal { width: clamp(64px, 8vw, 92px); height: auto; border-radius: 50%; flex: none;
  box-shadow: 0 10px 26px rgba(20,14,7,.28); }
.award-slim-text { flex: 1 1 auto; min-width: 0; }
.award-slim-text .eyebrow { color: var(--gold); }
.award-slim-text .eyebrow::before, .award-slim-text .eyebrow::after { background: var(--gold); opacity: .65; }
.award-slim-head { font-size: clamp(1.3rem, 1rem + 1.9vw, 2rem); line-height: 1.05; margin-top: .5rem; }
.award-slim-head .serif-italic { color: var(--maroon); }
.award-slim-cta { flex: none; }
@media (max-width: 680px) {
  .award-slim-inner { flex-wrap: wrap; gap: 1rem 1.2rem; }
  .award-slim-text { flex-basis: calc(100% - 5rem); }
  .award-slim-cta { flex-basis: 100%; }
}

/* small gold pill (range cheese card) — animated */
.award-pill {
  display: inline-flex; align-items: center; gap: .4em;
  padding: .5em .95em .5em .8em; border-radius: 100px;
  background: linear-gradient(135deg, var(--gold-lt), var(--gold));
  color: #2A1E08; font-family: var(--f-accent); font-size: .66rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
  box-shadow: 0 6px 16px -6px rgba(42,30,8,.6);
  position: relative; overflow: hidden;
}
.award-pill::after {   /* sweeping shine */
  content: ""; position: absolute; top: 0; left: -60%; width: 45%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.7), transparent);
  transform: skewX(-18deg); animation: pillShine 4.5s var(--ease) infinite;
}
@keyframes pillShine { 0%, 62% { left: -60%; } 82%, 100% { left: 130%; } }
.award-pill .pill-star { font-size: .95em; animation: pillStar 4.5s var(--ease) infinite; }
@keyframes pillStar { 0%, 60%, 100% { transform: rotate(0) scale(1); } 70% { transform: rotate(72deg) scale(1.3); } 80% { transform: rotate(144deg) scale(1); } }
.range-card .award-pill { position: absolute; top: .7rem; right: .7rem; left: auto; z-index: 3;
  font-size: .56rem; letter-spacing: .1em; padding: .45em .8em .45em .68em;
  transition: transform .3s var(--ease); }
.range-card:hover .award-pill { transform: translateY(-2px) scale(1.04); }
@media (prefers-reduced-motion: reduce) { .award-pill::after, .award-pill .pill-star { animation: none; } }

/* compact award badge (products page header) */
.award-badge {
  display: inline-flex; align-items: center; gap: .8rem; margin-top: 1.8rem;
  padding: .5rem 1.1rem .5rem .55rem; border: 1px solid var(--line); border-radius: 100px;
  background: var(--paper); transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.award-badge:hover { border-color: var(--gold); transform: translateY(-2px); box-shadow: 0 12px 26px -14px rgba(20,14,7,.45); }
.award-badge img { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: 0 0 auto;
  box-shadow: 0 4px 12px rgba(20,14,7,.3); }
.award-badge span {
  display: flex; flex-direction: column; gap: .15em; line-height: 1.35;
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--grey);
}
.award-badge strong { color: var(--gold-text); font-weight: 600; font-size: .74rem; letter-spacing: .1em; }

/* =====================================================================
   PRESS — as featured in
   ===================================================================== */
.press { background: var(--paper); }
.press-inner { display: flex; flex-direction: column; align-items: center; gap: clamp(1.4rem, 3vw, 2.2rem); text-align: center; }
.press-label { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .28em; text-transform: uppercase; color: var(--grey); }
.press-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: clamp(1.4rem, 4vw, 3.4rem); }
.press-row a {
  font-family: var(--f-display); font-size: clamp(1.05rem, .9rem + .7vw, 1.5rem);
  color: var(--ink-soft); opacity: .72;
  transition: opacity .35s var(--ease), color .35s var(--ease), transform .35s var(--ease);
  white-space: nowrap;
}
.press-row a:hover { opacity: 1; color: var(--coral); transform: translateY(-2px); }
.press-row .press-sep { color: var(--line); opacity: .8; font-family: var(--f-body); }
@media (max-width: 640px) { .press-row .press-sep { display: none; } .press-row { gap: 1rem 1.6rem; } }

/* =====================================================================
   TESTIMONIALS — cinematic quote stage
   ===================================================================== */
.testimonials { position: relative; overflow: hidden; background: var(--teal); color: var(--paper); }
.testimonials .wrap { position: relative; z-index: 1; }
.testi-head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .8rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.testi-head .eyebrow { color: var(--aqua); }
.testi-head .eyebrow::before, .testi-head .eyebrow::after { background: var(--aqua); }
.testi-head h2 { font-size: var(--step-3); }

.testi-mark {
  position: absolute; top: clamp(1rem, 4vw, 3rem); left: 50%; transform: translateX(-50%);
  font-family: var(--f-display); font-size: clamp(12rem, 26vw, 24rem); line-height: 1;
  color: var(--paper); opacity: .06; pointer-events: none; user-select: none; z-index: 0;
}

.testi-stage { display: grid; min-height: clamp(300px, 38vh, 380px); align-items: center; }
.testi-item {
  grid-area: 1 / 1;
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 1.2rem;
  max-width: 780px; margin-inline: auto;
  opacity: 0; visibility: hidden; transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease), visibility 0s .7s;
}
.testi-item.active { opacity: 1; visibility: visible; transform: none; transition: opacity .7s var(--ease) .15s, transform .7s var(--ease) .15s, visibility 0s; }
.testi-stars { display: flex; gap: .35em; color: var(--coral); font-size: 1.05rem; letter-spacing: 0; }
.testi-quote {
  font-family: var(--f-display); font-size: clamp(1.25rem, 1rem + 1.4vw, 1.85rem);
  line-height: 1.4; color: var(--paper); max-width: 48ch;
}
.testi-rule { width: 44px; height: 2px; background: var(--aqua); opacity: .7; }
.testi-name { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--aqua); }

.testi-nav { display: flex; align-items: center; justify-content: center; gap: clamp(1.2rem, 3vw, 2rem); margin-top: clamp(2rem, 4vw, 3rem); }
.testi-arrow {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(244,237,225,.35); color: var(--paper);
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem;
  transition: border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
.testi-arrow:hover { border-color: var(--paper); background: rgba(244,237,225,.1); transform: scale(1.06); }
.testi-dots { display: flex; gap: .55rem; }
.testi-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(244,237,225,.3); padding: 0;
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.testi-dot.active { background: var(--coral); transform: scale(1.35); }
.testi-dot:hover { background: rgba(244,237,225,.65); }
@media (max-width: 640px) { .testi-quote { font-size: 1.15rem; max-width: 100%; } .testi-stage { min-height: 340px; } }

/* =====================================================================
   GATHER
   ===================================================================== */
.gather-tag {
  font-family: var(--f-accent); font-size: clamp(1rem, .9rem + .4vw, 1.3rem);
  letter-spacing: .06em; color: var(--paper); opacity: .92; margin-top: .7rem; text-transform: lowercase;
}
.gather-intro .manifesto-head { font-size: var(--step-3); }
.gather-intro .value-mark svg { width: 54px; margin-top: .5rem; }

/* THREE ACROSS, changed 2026-08-15. These were three stacked rows alternating
   image-left / image-right — the classic zig-zag — at 730px each. That is
   2,191px, a third of the whole page, to deliver three ideas. Side by side the
   same content runs about 700px and nothing is hidden behind an interaction,
   which is why this beat a carousel: ENGAGE / CONNECT / SAVOUR is the brand's
   own positioning and should not need a swipe to be read.

   The row also rhymes with the square rate cards below it, so the page now has
   one three-column rhythm instead of a zig-zag followed by a grid. */
.pillars {
  background: var(--paper);
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  max-width: var(--maxw); margin-inline: auto;
  padding: clamp(2.5rem, 5vw, 4.5rem) var(--gutter);
}
.pillar { display: flex; flex-direction: column; gap: clamp(1rem, 1.6vw, 1.4rem); }
.pillar-media { position: relative; border-radius: var(--radius); overflow: hidden; }
/* SQUARE, not the old 4/4.2 portrait and not 4/3 either. The source files are
   900x1200 portraits, so a 4/3 window throws away 44% of the frame — heads and
   ceilings both go. A square crops 25%, is only 91px taller across the whole
   row, and rhymes with the square rate cards below it. */
.pillar-media img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
/* On the numbers looking crooked: they were, but not because of the type. In
   the old zig-zag the three photos alternated left column / right column, so
   01, 02 and 03 stepped diagonally across the page. Three-across puts all
   three on one row at an identical offset — measured: same top, same 21px
   inset. Nothing here needed changing.
   (I did try font-variant-numeric: tabular-nums first, on the theory that DM
   Serif Text's proportional "1" made 01 narrower than 02. It IS narrower — 32px
   against 39px — but the face ships no tnum feature, so the declaration did
   nothing, and since these are left-positioned the left edges aligned anyway.
   Removed rather than left in as decoration.) */
.pillar-num {
  position: absolute; top: 1.1rem; left: 1.3rem;
  font-family: var(--f-display); font-size: var(--step-2); color: var(--paper);
  mix-blend-mode: difference; opacity: .85;
}
.pillar-body { display: flex; flex-direction: column; gap: .7rem; align-items: flex-start; flex: 1; }
/* step-3 was sized for a half-width column. At a third of the width it wrapped
   to five or six lines and reintroduced the height the layout just saved. */
.pillar-body h2 { font-size: var(--step-1); line-height: 1.15; }
.pillar-body p { color: var(--ink-soft); font-size: var(--step--1); line-height: 1.6; }
/* margin-top:auto lands all three asides on the same baseline even though the
   headings above them wrap to different depths */
.pillar-aside {
  font-family: var(--f-display); font-style: italic; color: var(--maroon);
  font-size: var(--step-0); margin-top: auto;
}
@media (max-width: 900px) { .pillars { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .pillars { grid-template-columns: 1fr; gap: 2.2rem; } }

/* packages */
/* Three across at EVERY width — they used to stack below 760px, which is what
   made them look like a list instead of three cards. Staying side by side is
   the point: the row of squares is the thing.
   The card's contents are sized in `cqi` (percent of the container's inline
   size) rather than rem or vw, so they scale with the CARD rather than with
   the screen — which is what keeps a 103px square on a phone from being a
   normal-sized price inside a tiny box. The container is .wrap and not
   .package-grid because container-type applies layout containment, and the
   grid is what carries the shared 3D perspective for the tilt. */
.packages .wrap { container-type: inline-size; }
/* .section-pad gives this 115px top and bottom — 230px of the section's 1,404,
   and nearly double the 72px the pillars row above it uses. Matching the
   pillars both shortens the section and makes the two three-across rows read
   as one rhythm instead of two differently-spaced blocks. */
.packages { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.packages .range-head { margin-bottom: clamp(1.6rem, 3vw, 2.5rem); }
.package-grid {
  --pk-gap: clamp(.4rem, 1.6cqi, 1.6rem);
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--pk-gap);
  /* Capped and centred rather than filling the wrap. At full width these were
     375px squares and shouted over the CTA above them; at 50rem they were
     254px, which turned out to be too small once they became clickable — a
     card that opens something needs to look worth pressing. 62rem lands near
     315px. */
  max-width: 62rem; margin-inline: auto;
  /* The CTA above used to sit 48px off the top of this grid, so the eye went
     straight past it into the prices. This is the "space above the next
     chapter" — it buys the CTA its own airspace. */
  margin-top: clamp(2.6rem, 6vw, 5rem);
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
/* Was text-align:center with a single button. It now carries two, and inline-flex
   buttons side by side collapse to a single space between them — so it needs a real
   gap, and needs to stack rather than overflow on a phone. */
.package-cta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .7rem clamp(.7rem, 2vw, 1.1rem);
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
/* The hire panes' CTA is the point of the whole section, and at default button
   size it read as one more row of small caps between the use-list and the
   prices. Scaled up and given a shadow so it sits forward of the page rather
   than in it. Only inside .hire-pane — the site's other buttons stay as they
   are, because if every CTA is loud none of them is. */
.hire-pane .package-cta { margin-top: clamp(.6rem, 1.6vw, 1.2rem); }
.hire-pane .package-cta .btn {
  font-size: var(--step-0); padding: 1.05em 2.1em; letter-spacing: .1em;
}
.hire-pane .package-cta .btn--coral {
  box-shadow: 0 10px 26px -12px rgba(235, 91, 77, .85);
}
.hire-pane .package-cta .btn--coral:hover { box-shadow: 0 14px 30px -12px rgba(235, 91, 77, .95); }
/* Square-ish cards with a generous radius, not the site's 4px --radius. These
   are the one place on the site that behaves like a physical card — it tilts,
   it catches light — and a near-square face with soft corners is what sells
   that. --radius stays 4px everywhere else; this is a local override.
   aspect-ratio only applies while the cards sit three-across: stacked on a
   phone a square card is a screenful of empty paper, so it reverts to
   content height there. */
.package-card {
  position: relative; background: var(--paper);
  border-radius: clamp(9px, 1.6cqi, 20px);
  padding: clamp(.6rem, 3.4cqi, 2.6rem);
  aspect-ratio: 1;                      /* square at every width, by request */
  display: flex; flex-direction: column; gap: clamp(.15rem, .6cqi, .5rem);
  box-shadow: 0 1px 0 var(--line);
  overflow: hidden;    /* a square cannot grow, so contents are clipped not spilled */
}
/* The price carries the empty middle instead of the meta being shoved to the
   floor. Pinning only the fine print left a visible dead band between the
   number and the base of the square; centring the price in the space above it
   distributes that air rather than pooling it in one place. */
.package-card .package-price { margin-block: auto; }
.package-card .package-meta { margin-top: 0; }
/* Type scales with the container, not the viewport: at 103px the card needs
   type sized to the CARD. Floors are the smallest still-legible values, not
   the smallest that fit. */
.package-card .package-dur { font-size: clamp(.62rem, 1.5cqi, var(--step--1)); letter-spacing: .04em; }
.package-card .package-price { font-size: clamp(1.05rem, 5.2cqi, var(--step-3)); }
.package-card .package-meta { font-size: clamp(.66rem, 1.4cqi, var(--step--1)); line-height: 1.3; }
.package-card .package-badge {
  top: clamp(.35rem, 1.4cqi, 1.2rem); right: clamp(.35rem, 1.4cqi, 1.2rem);
  font-size: clamp(.42rem, 1.25cqi, .68rem); padding: .35em .7em;
}
/* TWO ACROSS ON PHONES. 360px of container is exactly a 400px viewport: the
   gutter is clamp(1.25rem, 4vw, 4rem), which floors at 20px a side there.
   Expressed as a container query rather than a media query so it also holds if
   this section is ever dropped into a narrower column — and so it is testable
   without a 400px-wide browser.

   Three 92px squares on a phone were technically fine and practically mean:
   the fine print sat at its legible floor and still overflowed, and the whole
   row read as a strip of chips rather than three cards. Two across roughly
   doubles the card and the squeeze on padding and leading is no longer needed.

   The cqi coefficients scale by 3/2 because the card is now ~50% of the
   container instead of ~33% — cqi tracks the CONTAINER, so without this the
   cards grow and the type inside them does not. */
@container (max-width: 360px) {
  .package-grid { grid-template-columns: repeat(2, 1fr); }
  /* Three cards into two columns leaves an orphan. It spans the row but keeps
     one column's width so it stays SQUARE, and centres rather than hanging off
     to the left. */
  .package-card:last-child {
    grid-column: 1 / -1;
    width: calc(50% - var(--pk-gap) / 2);
    justify-self: center;
  }
  .package-card { padding: clamp(.7rem, 4.5cqi, 2.6rem); gap: clamp(.2rem, .9cqi, .5rem); }
  .package-card .package-dur { font-size: clamp(.62rem, 2.25cqi, var(--step--1)); }
  .package-card .package-price { font-size: clamp(1.05rem, 7.8cqi, var(--step-3)); }
  .package-card .package-meta { font-size: clamp(.66rem, 2.1cqi, var(--step--1)); line-height: 1.3; }
  .package-card .package-badge {
    top: clamp(.4rem, 2cqi, 1.2rem); right: clamp(.4rem, 2cqi, 1.2rem);
    font-size: clamp(.46rem, 1.9cqi, .68rem);
  }
}

/* ---- tilt (gather rate cards) ---------------------------------------------
   Cursor-tracked 3D tilt with a radial shine, driven by main.js. The card's
   rotation and the shine's position arrive as custom properties so the whole
   effect is one composited transform plus one gradient — no layout, no paint
   of the card itself.

   Perspective sits on the GRID, not the card: on the card it is resolved per
   element, so each card gets its own vanishing point and the row reads as
   three unrelated objects. One shared perspective on the parent makes the
   outer cards lean away from a common centre, which is the whole effect.

   `--tilt-*` default to zero, so a card with JS disabled is exactly the flat
   card it was before. */
@media (hover: hover) and (pointer: fine) {
  .package-grid, .pillars { perspective: 1000px; }
  /* The pillar photos tilt too, so the page's two three-across rows behave the
     same way. Only the IMAGE tilts, not the whole pillar — the paragraph under
     it is reading matter and text on a rotating plane is just harder to read. */
  .pillar-media {
    --tilt-x: 0deg; --tilt-y: 0deg; --tilt-s: 1;
    transform: perspective(1000px) rotateX(var(--tilt-x)) rotateY(var(--tilt-y)) scale(var(--tilt-s));
    transform-style: preserve-3d;
    transition: box-shadow .4s var(--ease);
  }
  .pillar-media.is-tilting { box-shadow: 0 18px 40px -22px rgba(33, 27, 23, .5); }
  .pillar-media .pc-shine { border-radius: inherit; }
  /* the site preview tilts too — it is the thing on the page most worth
     touching, and a window that leans as you approach it invites the click */
  .gnext { perspective: 1400px; }
  .gnext-frame {
    --tilt-x: 0deg; --tilt-y: 0deg; --tilt-s: 1;
    transform: perspective(1400px) rotateX(var(--tilt-x)) rotateY(var(--tilt-y)) scale(var(--tilt-s));
    transform-style: preserve-3d; position: relative;
    transition: box-shadow .4s var(--ease);
  }
  .gnext-frame.is-tilting { box-shadow: 0 40px 70px -28px rgba(0,0,0,.85); }
  .gnext-frame .pc-shine { border-radius: inherit; }
  .package-card {
    --tilt-x: 0deg; --tilt-y: 0deg; --tilt-s: 1;
    transform: perspective(1000px) rotateX(var(--tilt-x)) rotateY(var(--tilt-y)) scale(var(--tilt-s));
    transform-style: preserve-3d;
    overflow: hidden;                    /* clips the shine to the rounded box */
    transition: box-shadow .4s var(--ease);
  }
  .package-card.is-tilting { box-shadow: 0 18px 40px -22px rgba(33, 27, 23, .45), 0 1px 0 var(--line); }
  /* The shine. A soft radial at the cursor, additive over both card colours:
     white at 12% reads as a sheen on --paper and as a lit edge on --ink,
     where a tinted glare would just look like a stain. */
  .pc-shine {
    position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    opacity: 0; transition: opacity .35s var(--ease);
    background: radial-gradient(
      22rem circle at var(--shine-x, 50%) var(--shine-y, 50%),
      rgba(255, 255, 255, .12), rgba(255, 255, 255, 0) 60%);
  }
  .package-card.is-tilting .pc-shine { opacity: 1; }
  /* Content rides slightly above the card face so the tilt has visible depth
     rather than looking like a flat image being rotated. */
  .package-card > *:not(.pc-shine) { transform: translateZ(28px); }
  /* Child combinator, not a bare `.package-badge`: the rule above is (0,2,0)
     because :not() carries its argument's specificity, so a lone class here
     loses to it and the badge sat at 28px with everything else. */
  .package-card > .package-badge { transform: translateZ(44px); }
}

/* Tilt is a pointer flourish, never a requirement. Reduced motion gets the
   flat card and no shine at all. */
@media (prefers-reduced-motion: reduce) {
  .package-card { transform: none !important; transition: none; }
  .pc-shine { display: none; }
}
.package-card--feature { background: var(--ink); color: var(--paper); }
.package-dur { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--maroon); }
.package-card--feature .package-dur { color: var(--aqua); }
.package-price { font-family: var(--f-display); font-size: var(--step-3); line-height: 1; }
.package-meta { font-size: var(--step--1); color: var(--ink-soft); }
.package-card--feature .package-meta { color: rgba(244,237,225,.72); }
.package-meta s { opacity: .6; }
.package-badge {
  position: absolute; top: 1.2rem; right: 1.2rem;
  background: var(--coral); color: var(--ink);   /* paper on coral is 2.94:1 */
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  padding: .35em .75em; border-radius: 100px;
}
/* The cards are <button> now. Strip the UA styling so they still look like the
   cards they were, and give them the affordances a control needs.
   ⚠️ The colour pair below is order-sensitive and both lines must stay. A
   button does not inherit `color`, so the reset has to set it — but this block
   sits AFTER `.package-card--feature { color: var(--paper) }` and carries the
   same (0,1,0) specificity, so whatever it sets wins. Setting `inherit` here
   made the two dark cards render their price ink-on-ink at 1.0:1 — present in
   the DOM, invisible on screen, because .package-price has no colour of its
   own and had been relying on inheriting --paper from the card. */
.package-card { appearance: none; border: 0; font: inherit; text-align: left; cursor: pointer; color: var(--ink); }
.package-card--feature { color: var(--paper); }
.package-card:focus-visible { outline: 3px solid var(--maroon); outline-offset: 3px; }
.package-card--feature:focus-visible { outline-color: var(--aqua); }
.package-more {
  display: inline-flex; align-items: center; gap: .4em; margin-top: .55rem;
  font-family: var(--f-accent); font-size: clamp(.56rem, 1.15cqi, .72rem);
  font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--maroon); opacity: .9;
}
.package-card--feature .package-more { color: var(--aqua); }
/* the chevron rotates when the card's panel is open */
.package-more i {
  width: .5em; height: .5em; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-.1em); transition: transform .3s var(--ease);
}
.package-card[aria-expanded="true"] .package-more i { transform: rotate(225deg) translateY(-.1em); }

/* ---- rate detail panels ---------------------------------------------------
   Outside the grid, so an open panel spans the full row instead of stretching
   one square. Height is animated from the panel's own scrollHeight in main.js;
   `hidden` is removed first so it can be measured. */
.pkg-details { max-width: 62rem; margin: 0 auto clamp(1.6rem, 3vw, 2.4rem); }
.pkg-detail { overflow: hidden; height: 0; transition: height .42s var(--ease); }
.pkg-detail[hidden] { display: none; }
.pkg-detail-in {
  display: grid; gap: clamp(1rem, 2.5vw, 2.2rem); align-items: start;
  background: var(--paper); border: 1px solid var(--line); border-radius: 14px;
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
}
@media (min-width: 720px) { .pkg-detail-in { grid-template-columns: 1.35fr .65fr; } }
.pkg-detail-in h3 { font-size: var(--step-1); margin: 0 0 .4rem; }
.pkg-detail-in p { color: var(--ink-soft); font-size: var(--step--1); line-height: 1.65; margin: 0; }
.pkg-detail-in ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .45rem; }
.pkg-detail-in li {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: var(--step--1); color: var(--ink-soft);
  padding-bottom: .45rem; border-bottom: 1px solid var(--line);
}
.pkg-detail-in li:last-child { border-bottom: 0; padding-bottom: 0; }
.pkg-detail-in li strong { color: var(--ink); font-weight: 600; }
.pkg-detail-foot {
  margin: clamp(.9rem, 2vw, 1.2rem) auto 0; max-width: 62ch; text-align: center;
  font-size: var(--step--1); color: var(--teal-ink);
}
.pkg-detail-foot strong { color: var(--ink); font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .pkg-detail { transition: none; } }

.package-notes { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; max-width: 920px; }
@media (max-width: 760px) { .package-notes { grid-template-columns: 1fr; } }
.package-notes p { color: var(--teal-ink); font-size: var(--step--1); line-height: 1.65; }
.package-notes strong { color: var(--ink); font-weight: 600; }

/* ---- hire toggle: one room, two audiences (gather page) --------------------
   Two panes, one shared rate card. The COPY forks; the prices cannot, because
   the card sits outside the panes. Thumb is a 50% pill that slides on a
   data-mode flip; panes are stacked in one grid cell and cross-fade with a
   ±18px slide whose direction follows the thumb. The wrapper's height is set
   by main.js from the active pane and transitioned, so the rate card below
   glides rather than jumps when pane heights differ. */
.hire-toggle {
  position: relative; display: grid; grid-template-columns: 1fr 1fr;
  width: min(26rem, 100%); margin: 0 auto clamp(1.8rem, 4vw, 2.6rem);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 999px; padding: .3rem;
}
.ht-btn {
  position: relative; z-index: 1; appearance: none; border: 0; background: transparent;
  cursor: pointer; font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.02rem, 1.6vw, 1.22rem); line-height: 1; color: var(--ink);
  padding: .68em .5em; border-radius: 999px;
  transition: color .35s var(--ease);
}
/* paper on ink — same pairing as .package-card--feature */
.ht-btn[aria-pressed="true"] { color: var(--paper); }
.ht-thumb {
  position: absolute; top: .3rem; bottom: .3rem; left: .3rem;
  width: calc(50% - .3rem); border-radius: 999px; background: var(--ink);
  transition: transform .45s var(--ease); z-index: 0;
}
.hire-toggle[data-mode="work"] .ht-thumb { transform: translateX(100%); }

/* align-items:start is load-bearing: stacked grid items default to stretch, so
   both panes measured as the TALLER one and the height animation had nothing to
   animate — and the shorter pane trailed empty space. start keeps each pane its
   natural height, so offsetHeight is honest per pane. */
.hire-panes { position: relative; display: grid; align-items: start; overflow: hidden; transition: height .5s var(--ease); }
.hire-pane {
  grid-area: 1 / 1; display: flex; flex-direction: column; align-items: center;
  opacity: 1; transform: none;
  transition: opacity .4s var(--ease), transform .5s var(--ease), visibility 0s 0s;
}
/* visibility waits for the fade so the outgoing pane stays paintable while it
   leaves; inert (set in JS) keeps its links out of the tab order meanwhile */
.hire-pane.is-off {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .35s var(--ease), transform .5s var(--ease), visibility 0s .5s;
}
.hire-pane.is-off.off-left  { transform: translateX(-18px); }
.hire-pane.is-off.off-right { transform: translateX(18px); }

.hire-lead {
  text-align: center; max-width: 46ch; margin: 0 auto;
  color: var(--teal-ink); font-size: var(--step-0); line-height: 1.6;
}
.hire-uses {
  list-style: none; padding: 0; display: grid; grid-template-columns: 1fr 1fr;
  gap: .2rem 2.4rem; margin: clamp(1.4rem, 3vw, 2rem) auto clamp(1.6rem, 3vw, 2.2rem);
  width: min(56rem, 100%); text-align: left;
}
@media (max-width: 700px) { .hire-uses { grid-template-columns: 1fr; } }
.hire-uses li { display: flex; align-items: flex-start; gap: .85rem; padding: .8rem 0; }
.hire-uses h3 { font-size: var(--step-0); margin: 0 0 .15rem; }
.hire-uses p { color: var(--teal-ink); font-size: var(--step--1); line-height: 1.55; margin: 0; }
.hire-note {
  text-align: center; max-width: 52ch; margin: 0 auto clamp(1.4rem, 3vw, 2rem);
  color: var(--teal-ink); font-size: var(--step--1); line-height: 1.65;
}
.hire-note strong { color: var(--ink); font-weight: 600; }
.hire-pane .package-cta { margin-bottom: clamp(2.2rem, 4vw, 3rem); }

@media (prefers-reduced-motion: reduce) {
  .ht-thumb, .hire-pane, .hire-panes, .ht-btn { transition: none; }
}

/* ---- next chapter: the doorway to Gather's own site ------------------------
   Dark, because it is the one moment on the page that says "there is another
   place" — the surrounding sections are all --paper, so the tone change does
   the work before a word is read. */
.gnext { background: var(--ink); color: var(--paper); padding-block: clamp(3rem, 6vw, 5.5rem); }
.gnext-grid { display: grid; gap: clamp(2rem, 4vw, 4rem); align-items: center; }
@media (min-width: 900px) { .gnext-grid { grid-template-columns: .92fr 1.08fr; } }
.gnext-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; min-width: 0; }
/* --aqua, not --maroon-deep: the eyebrow's usual colour is tuned for paper and
   drops to 2.4:1 on --ink. Aqua on ink measures 9.8:1. */
.gnext .eyebrow { color: var(--aqua); }
.gnext .eyebrow::before, .gnext .eyebrow::after { background: var(--aqua); }
.gnext-h { font-size: var(--step-3); line-height: 1.04; margin: 0; }
.gnext-lead { font-size: var(--step-0); line-height: 1.62; color: var(--paper); opacity: .92; max-width: 34ch; }
.gnext-sub { font-size: var(--step--1); color: var(--aqua); max-width: 34ch; }
.gnext-actions { margin-top: .5rem; }
.gnext-cta { font-size: var(--step-0); padding: 1.05em 2.1em; }

/* The browser frame. Chrome + the Gather site's own share image, so it reads as
   a window onto a different site rather than another photo of the room. */
.gnext-frame {
  display: block; border-radius: 12px; overflow: hidden;
  background: #2A2420; box-shadow: 0 30px 60px -30px rgba(0,0,0,.75);
  text-decoration: none; color: inherit;
}
.gnext-bar {
  display: flex; align-items: center; gap: .7rem;
  padding: .6rem .85rem; background: #352E29;
}
.gnext-dots { display: inline-flex; gap: .32rem; flex: 0 0 auto; }
.gnext-dots i { width: .55rem; height: .55rem; border-radius: 50%; background: rgba(244,237,225,.28); }
.gnext-url {
  flex: 1; text-align: center; border-radius: 100px;
  background: rgba(244,237,225,.1); color: rgba(244,237,225,.72);
  font-family: var(--f-accent); font-size: .72rem; letter-spacing: .04em;
  padding: .28rem .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gnext-frame img { display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; }
.gnext-frame:focus-visible { outline: 3px solid var(--aqua); outline-offset: 4px; }

/* book band */
.book-band { position: relative; overflow: hidden; background: var(--teal); color: var(--paper); text-align: center; }
/* blurred studio photo behind the form (teal-tinted for brand + legibility) */
.book-band--photo { background: var(--ink); }
/* Neutral warm scrim, not a teal cast. It stays because every bit of type on this
   band is --paper: without it the light text sits unreadable on the photo. */
.book-bg { position: absolute; inset: -26px; z-index: 0;
  background:
    linear-gradient(180deg, rgba(24,19,16,.52) 0%, rgba(24,19,16,.70) 100%),
    url("brand-assets/gather/gather-image-2.jpg") center 38% / cover no-repeat;
  filter: blur(3px); transform: scale(1.05); }
.book-band--photo .book-sun { opacity: .1; z-index: 0; }
.book-sun { position: absolute; left: 50%; top: clamp(-30px, -2vw, 0px); transform: translateX(-50%); width: clamp(170px, 24vw, 310px); opacity: .14; }
.book-band .wrap { position: relative; z-index: 1; }
.book-band h2 { font-size: var(--step-3); margin: .3em 0 .5em; }
.book-band .lead { color: rgba(244,237,225,.85); }
.book-contacts { display: flex; gap: clamp(1rem, 3vw, 2.5rem); justify-content: center; flex-wrap: wrap; margin: 1.4rem 0 .4rem; }
.book-contact { font-size: var(--step-0); }
.book-contact { font-family: var(--f-display); font-size: var(--step-1); color: var(--paper); padding-bottom: 4px; border-bottom: 1px solid rgba(244,237,225,.3); transition: border-color .3s var(--ease); }
.book-contact:hover { border-color: var(--aqua); }

/* =====================================================================
   ABOUT
   ===================================================================== */
.about-hero { padding: clamp(8rem, 15vh, 12rem) 0 calc(var(--rhythm) / 2); }
.about-hero-inner { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: end; }
@media (max-width: 860px) { .about-hero-inner { grid-template-columns: 1fr; gap: 2.5rem; } }
.about-hero-title { font-size: clamp(2.8rem, 1.3rem + 5.5vw, 5.6rem); margin: .25em 0 .5em; }
.about-hero-media { position: relative; border-radius: var(--radius); overflow: hidden; }
/* height:auto or the height ATTRIBUTE wins and the photo renders at its pixel
   height regardless of width — the founder portrait was a blown-up crop for
   exactly that reason (reported 24 Aug). Natural ratio; the file is landscape. */
.about-hero-media img { width: 100%; height: auto; }
.about-hero-media figcaption {
  position: absolute; left: 1rem; bottom: 1rem;
  background: rgba(33,27,23,.7); color: var(--paper); backdrop-filter: blur(4px);
  font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .1em; text-transform: uppercase;
  padding: .5em 1em; border-radius: 100px;
}

.story-grid { align-items: center; gap: clamp(2rem, 5vw, 5rem); }
.story-copy { display: flex; flex-direction: column; gap: 1.3rem; align-items: flex-start; }
.story-copy h2 { font-size: var(--step-3); }
.story-media img { width: 100%; height: auto; border-radius: var(--radius); }
.stat-row { display: flex; gap: clamp(1.5rem, 4vw, 3rem); margin-top: 1rem; flex-wrap: wrap; }
.stat { display: flex; flex-direction: column; }
.stat strong { font-family: var(--f-display); font-size: var(--step-3); line-height: 1; color: var(--coral); }
.stat span { font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .06em; color: var(--ink-soft); margin-top: .3rem; }
@media (max-width: 860px) { .story-media { order: -1; } }

.name-section { position: relative; overflow: hidden; padding-block: calc(var(--rhythm-lg) / 2); }
.name-inner { display: grid; grid-template-columns: .8fr 1.2fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
@media (max-width: 860px) { .name-inner { grid-template-columns: 1fr; } }
.name-sun { display: flex; justify-content: center; }
.name-sun svg { width: min(80%, 340px); }
.name-copy { display: flex; flex-direction: column; gap: 1.3rem; align-items: flex-start; }
.name-copy h2 { font-size: var(--step-3); }
.name-copy p { color: rgba(244,237,225,.86); }
.name-tag { font-family: var(--f-accent); font-weight: 700; font-style: italic; font-size: var(--step-1); color: var(--aqua); margin-top: .4rem; }

.device-grid { align-items: center; gap: clamp(2rem, 5vw, 5rem); }
.device-media img { width: 100%; height: auto; border-radius: var(--radius); }
/* Four bottles as a real grid. The old asset was a 1503x350 strip whose height
   attribute stretched it into funhouse bottles on a phone (reported 24 Aug);
   these are the same transparent packshots the flavour rail uses, each on its
   own flavour tint. */
.device-bottles { display: grid; grid-template-columns: repeat(4, 1fr); gap: .7rem; margin: 0; }
@media (max-width: 620px) { .device-bottles { grid-template-columns: 1fr 1fr; } }
.device-bottles figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.device-bottles .db-well { width: 100%; aspect-ratio: 3 / 4; border-radius: calc(var(--radius) * .75);
  background: color-mix(in srgb, var(--db-tint, var(--aqua)) 38%, var(--paper));
  display: grid; place-items: end center; overflow: hidden; padding-top: 1rem; }
.device-bottles img { width: 62%; height: auto; display: block; }
.device-bottles figcaption { font-family: var(--f-accent); font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.device-copy { display: flex; flex-direction: column; gap: 1.3rem; align-items: flex-start; }
.device-copy h2 { font-size: var(--step-3); }
.device-copy p { color: var(--ink-soft); }

.gather { display: grid; grid-template-columns: 1.15fr .85fr; align-items: stretch; background: var(--teal); color: var(--paper); }
@media (max-width: 860px) { .gather { grid-template-columns: 1fr; } }
.gather-media { overflow: hidden; min-height: 55vh; }
.gather-media img { width: 100%; height: 100%; object-fit: cover; }
.gather-body { display: flex; flex-direction: column; gap: 1.4rem; align-items: flex-start; justify-content: center; padding: clamp(3rem, 6vw, 6rem); }
.gather-body h2 { font-size: var(--step-3); }
.gather-body p { color: rgba(244,237,225,.86); }

/* =====================================================================
   CONTACT
   ===================================================================== */
.contact-grid { display: grid; grid-template-columns: 1.3fr .7fr; gap: clamp(2.5rem, 6vw, 6rem); align-items: start; }
@media (max-width: 860px) { .contact-grid { grid-template-columns: 1fr; gap: 3rem; } }
.contact-form-wrap h2 { font-size: var(--step-3); margin-bottom: 1rem; }
.muted-2 { color: var(--ink-soft); max-width: 44ch; margin-bottom: 2rem; }
.contact-form { display: flex; flex-direction: column; gap: 1.3rem; align-items: flex-start; max-width: 560px; }
.field { display: flex; flex-direction: column; gap: .5rem; width: 100%; }
.field label { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.field input, .field textarea, .field select {
  width: 100%; font-family: var(--f-body); font-size: var(--step-0); color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .85em 1em; transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.field textarea { resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px rgba(22,107,128,.12); }
.field input::placeholder, .field textarea::placeholder { color: var(--grey); }
.form-note { font-family: var(--f-accent); font-size: var(--step--1); color: var(--grey); letter-spacing: .04em; }

/* Skip link — offscreen until focused, then the first thing a keyboard visitor lands on.
   Sits above the fixed nav (which is z-index 50) so it can't be covered. */
.skip-link {
  position: fixed; top: .75rem; left: .75rem; z-index: 200;
  transform: translateY(calc(-100% - 1.5rem));
  background: var(--ink); color: var(--paper);
  font-family: var(--f-accent); font-size: .8rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  padding: .8rem 1.2rem; border-radius: 100px; text-decoration: none;
  transition: transform .18s var(--ease);
}
.skip-link:focus { transform: none; outline: 2px solid var(--coral); outline-offset: 3px; }

/* Form result panel. Sits on paper (contact/wholesale) and on the aqua footer (newsletter),
   so it's built from translucent ink rather than a solid fill, and reads on both. Type is
   kept at the larger accessible sizes agreed for all new UI. */
.form-status { margin-top: 1.1rem; padding: 1rem 1.1rem; border-radius: 10px;
  border-left: 2px solid var(--aqua-deep); background: rgba(33,27,23,.055);
  font-size: .92rem; line-height: 1.6; color: var(--ink); max-width: 46ch; }
.form-status[hidden] { display: none; }
.form-status:focus { outline: none; }
.form-status:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.form-status.is-fail { border-left-color: var(--coral); background: rgba(235,91,77,.09); }
.fs-head { font-family: var(--f-display); font-size: 1.25rem; line-height: 1.1; margin-bottom: .35rem; }
.fs-body { color: var(--ink-soft); margin-bottom: .9rem; }
.fs-acts { display: flex; align-items: center; gap: .6rem 1.1rem; flex-wrap: wrap; }
.fs-alt { font-family: var(--f-accent); font-size: .8rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--maroon); text-decoration: underline;
  text-underline-offset: 3px; }
.fs-alt:hover { color: var(--coral); }
/* the feedback modal's panel is a narrow column — let it use the full width */
.fb-fallback { max-width: none; margin-top: 1rem; }

.contact-details { display: flex; flex-direction: column; gap: 2rem; padding-top: .5rem; }

/* ---- contact details as two cards ----------------------------------------
   Replaced five stacked small-caps headings down a bare column. The facts are
   unchanged; the grouping follows what a reader wants (reach us / come by)
   rather than mirroring the data's own shape. Cards give the column an edge
   so it stops looking like a leftover strip beside the form. */
.detail-card {
  background: var(--paper-2); border: 1px solid var(--line); border-radius: 14px;
  padding: clamp(1.2rem, 2.2vw, 1.6rem);
}
.detail-card h3 {
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--maroon);
  margin: 0 0 1rem;
}
/* label above value, so the address-style rows read top-down rather than as a
   two-column table that would wrap badly in a narrow aside */
.detail-rows { margin: 0; display: flex; flex-direction: column; gap: .9rem; }
.detail-rows > div { display: flex; flex-direction: column; gap: .1rem; }
.detail-rows dt {
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grey);
}
.detail-rows dd { margin: 0; }
.detail-rows a {
  font-family: var(--f-display); font-size: var(--step-0); color: var(--ink);
  transition: color .3s var(--ease); word-break: break-word;
}
.detail-rows a:hover { color: var(--coral); }
.detail-foot { margin: 1rem 0 0; font-size: var(--step--1); color: var(--ink-soft); }
.detail-card--visit { background: var(--sand); }
.detail-addr { margin: 0; color: var(--ink-soft); line-height: 1.62; }
.detail-hours { margin: .9rem 0 0; color: var(--ink-soft); line-height: 1.62; }
.detail-hours strong { color: var(--ink); font-weight: 600; }
.detail-links {
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
  margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line);
}
.detail-block h3 { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--maroon); margin-bottom: .7rem; }
.detail-block p { color: var(--ink-soft); line-height: 1.6; }
.detail-link { display: block; font-size: var(--step-1); font-family: var(--f-display); color: var(--ink); transition: color .3s; }
.detail-link:hover { color: var(--coral); }
.social-row { display: flex; gap: 1.4rem; margin-bottom: .8rem; }
.tag { font-family: var(--f-accent); font-weight: 600; letter-spacing: .08em; color: var(--teal); }

.stockist-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.5rem, 3vw, 2.5rem); }
@media (max-width: 900px) { .stockist-grid { grid-template-columns: repeat(2, 1fr); gap: 2.5rem; } }
@media (max-width: 480px) { .stockist-grid { grid-template-columns: 1fr; } }
.stockist-col { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .55rem;
  text-align: center; padding: clamp(1.6rem, 3vw, 2.2rem) 1rem; border-radius: 14px;
  background: color-mix(in srgb, var(--paper) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  transition: border-color .3s var(--ease), transform .3s var(--ease); }
.stockist-col:hover { border-color: color-mix(in srgb, var(--coral) 45%, transparent); transform: translateY(-3px); }
.stockist-col h3 { font-family: var(--f-display); font-size: var(--step-1); font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--ink); }
.stockist-count { font-family: var(--f-accent); font-size: .78rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--maroon-deep); }
.stockist-note { text-align: center; max-width: 62ch; margin: clamp(2rem, 4vw, 3rem) auto 0; color: var(--ink-soft); font-family: var(--f-display); font-style: italic; font-size: var(--step-0); }

/* =====================================================================
   LEGAL — privacy / terms prose pages
   ===================================================================== */
.legal-wrap { max-width: 68ch; }
.legal-block { margin-bottom: clamp(2.4rem, 5vw, 3.4rem); }
.legal-block h2 { font-family: var(--f-display); font-size: var(--step-2); margin-bottom: .8rem; }
.legal-block p { color: var(--ink-soft); margin-bottom: .9rem; }
.legal-block p:last-child { margin-bottom: 0; }
.legal-list { display: flex; flex-direction: column; gap: .7rem; margin: 0 0 1rem; padding-left: 1.1rem; }
.legal-list li { color: var(--ink-soft); list-style: disc; }
.legal-list strong { color: var(--ink); font-weight: 600; }
.legal-updated { padding-top: clamp(1.6rem, 3vw, 2.2rem); border-top: 1px solid var(--line);
  font-family: var(--f-accent); font-size: .82rem; color: var(--grey); }

/* =====================================================================
   FAQ — native <details> accordion, styled to the brand
   ===================================================================== */
.faq-wrap { max-width: 74ch; }
.faq-group { margin-bottom: clamp(2.4rem, 5vw, 3.6rem); }
.faq-group > h2 { font-family: var(--f-display); font-size: var(--step-2); margin-bottom: .4rem; }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item summary { list-style: none; cursor: pointer; position: relative;
  padding: 1.1rem 2.6rem 1.1rem 0; font-family: var(--f-display); font-size: var(--step-1);
  line-height: 1.18; color: var(--ink); transition: color .25s var(--ease); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; position: absolute; right: .3rem; top: 1.05rem;
  font-family: var(--f-body); font-weight: 300; font-size: 1.6rem; line-height: 1; color: var(--coral);
  transition: transform .3s var(--ease); }
.faq-item[open] summary::after { content: "\2013"; }
.faq-item summary:hover { color: var(--coral); }
.faq-item summary:focus-visible { outline: 2px solid var(--coral); outline-offset: 4px; border-radius: 2px; }
.faq-answer { padding: 0 2.6rem 1.4rem 0; }
.faq-answer p { color: var(--ink-soft); line-height: 1.6; margin: 0; }
.faq-answer a { color: var(--maroon); }
@media (prefers-reduced-motion: no-preference) {
  .faq-item[open] .faq-answer { animation: faqReveal .35s var(--ease); }
  @keyframes faqReveal { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
}

/* =====================================================================
   WHOLESALE — B2B page (why stock us / what we supply / how it works)
   ===================================================================== */
.ws-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.5rem, 3vw, 2.6rem); }
@media (max-width: 760px) { .ws-grid { grid-template-columns: 1fr; } }
.ws-reason { padding: clamp(1.6rem, 3vw, 2.2rem); border-radius: 16px;
  background: color-mix(in srgb, var(--paper-2) 60%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink) 9%, transparent); }
.ws-reason h3 { font-family: var(--f-display); font-size: var(--step-1); margin: .8rem 0 .5rem; }
.ws-reason p { color: var(--ink-soft); max-width: none; }
.ws-num { font-family: var(--f-display); font-size: clamp(2rem, 3.6vw, 2.8rem); line-height: 1; color: var(--coral); display: block; }
.ws-badge { display: inline-block; font-family: var(--f-accent); font-size: .72rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: #6b4f14; padding: .42em .9em; border-radius: 999px;
  background: linear-gradient(100deg, #f4dc9a, #e8c25f 45%, #f4dc9a); }

.ws-cats { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 2vw, 1.6rem); }
@media (max-width: 900px) { .ws-cats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .ws-cats { grid-template-columns: 1fr; } }
.ws-cat { position: relative; display: block; padding: clamp(1.3rem, 2.4vw, 1.8rem); padding-bottom: 3rem; border-radius: 14px;
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  transition: transform .3s var(--ease), border-color .3s var(--ease); }
.ws-cat:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--maroon) 45%, transparent); }
.ws-cat h3 { font-family: var(--f-display); font-size: var(--step-1); margin-bottom: .35rem; }
.ws-cat p { color: var(--ink-soft); font-size: var(--step--1); max-width: none; padding-right: 1.6rem; }
.ws-cat-go { position: absolute; right: 1.2rem; bottom: 1.1rem; color: var(--maroon); transition: transform .3s var(--ease); }
.ws-cat:hover .ws-cat-go { transform: translateX(4px); }
.ws-cat--all { background: var(--ink); border-color: var(--ink); }
.ws-cat--all h4, .ws-cat--all .ws-cat-go { color: var(--paper); }
.ws-cat--all p { color: color-mix(in srgb, var(--paper) 72%, transparent); }
.ws-terms { text-align: center; max-width: 62ch; margin: clamp(2rem, 4vw, 3rem) auto 0;
  font-family: var(--f-display); font-style: italic; font-size: var(--step-0); color: var(--ink-soft); }

.ws-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 3vw, 2.8rem); list-style: none; }
@media (max-width: 760px) { .ws-steps { grid-template-columns: 1fr; gap: 2rem; } }
.ws-step { padding-top: 1.2rem; border-top: 2px solid color-mix(in srgb, var(--coral) 35%, transparent); }
.ws-step-n { font-family: var(--f-accent); font-size: .78rem; font-weight: 700; letter-spacing: .16em; color: var(--maroon); }
.ws-step h3 { font-family: var(--f-display); font-size: var(--step-1); margin: .5rem 0 .5rem; }
.ws-step p { color: var(--ink-soft); max-width: none; }

/* =====================================================================
   REVIEWS — warm editorial, horizontal rail of all reviews
   ===================================================================== */
.reviews { background: #E9DFCB; overflow: hidden; }
/* --- centred header --- */
.rv-head { text-align: center; display: flex; flex-direction: column; align-items: center; gap: .9rem;
  margin-bottom: clamp(2.2rem, 5vw, 3.4rem); }
.rv-hstars { color: var(--maroon-deep); letter-spacing: .3em; font-size: .95rem; }
.rv-head h2 { font-size: var(--step-3); line-height: 1.06; max-width: 18ch; }
.rv-sub { color: var(--ink-soft); max-width: 46ch; margin-inline: auto; }
.rv-badge { display: inline-flex; align-items: center; gap: clamp(.8rem, 2vw, 1.4rem); margin-top: .5rem;
  padding: .6em 1.3em; border-radius: 999px; background: color-mix(in srgb, var(--paper) 72%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); flex-wrap: wrap; justify-content: center; }
.rv-badge-l { display: inline-flex; align-items: center; gap: .55rem; }
.rv-g { width: 20px; height: 20px; flex: none; }
.rv-badge b { font-family: var(--f-display); font-size: 1.15rem; color: var(--ink); }
/* was a raw #E8A33D — outside the palette entirely, and 1.85:1 on paper. Matches
   .rv-hstars, the other star row, which moved to the same token. */
.rv-badge-stars { color: var(--maroon-deep); letter-spacing: .08em; font-size: .9rem; }
.rv-badge-div { width: 1px; align-self: stretch; background: color-mix(in srgb, var(--ink) 16%, transparent); }
.rv-badge-link { font-family: var(--f-accent); font-size: .76rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--maroon-deep); white-space: nowrap; }
.rv-badge-link:hover { color: var(--coral); }
@media (max-width: 520px) { .rv-badge-div { display: none; } }

/* --- coverflow: one featured card, the rest fanned out beside it.
   JS (main.js) positions each card from its distance to the active index. --- */
/* text-only cards: narrower than the old photo layout so the serif keeps a
   readable measure and short reviews don't leave a hole above the name */
.tcar { --aw: min(540px, 90vw); --iw: 232px; --gap: 18px; --stage: 360px; position: relative; }
@media (max-width: 900px) { .tcar { --iw: 180px; --stage: 400px; } }
.tcar-stage { position: relative; height: var(--stage); }
.tcar-card { position: absolute; top: 50%; left: 50%; width: var(--iw); height: 86%;
  display: flex; gap: 1.2rem; padding: clamp(1.2rem, 2.2vw, 1.7rem);
  background: #F4EDDE; border: 1px solid rgba(33,27,23,.09); border-radius: 16px;
  box-shadow: 0 18px 40px -30px rgba(20,14,7,.55);
  transform: translate(-50%, -50%); transform-origin: center;
  transition: transform .55s var(--ease), width .55s var(--ease), height .55s var(--ease), opacity .45s var(--ease);
  overflow: hidden; cursor: pointer; }
.tcar-card.is-active { width: var(--aw); height: 100%; z-index: 5; cursor: default;
  box-shadow: 0 34px 70px -34px rgba(20,14,7,.55); }
.tcar-card.is-far { opacity: 0; pointer-events: none; }
/* Top-RIGHT, not top-left: the stars sit at the top-left of the body, and the mark
   was rendering straight underneath them (reported 24 Aug). Opposite corners now. */
.tc-mark { position: absolute; top: .1rem; right: .9rem; left: auto; font-family: var(--f-display); font-size: 3.4rem;
  line-height: 1; color: color-mix(in srgb, var(--ink) 13%, transparent); pointer-events: none; }
.tc-body { position: relative; z-index: 1; display: flex; flex-direction: column; min-width: 0; flex: 1; }
.tc-stars { color: var(--maroon); letter-spacing: .14em; font-size: .8rem; margin-bottom: .7rem; }
.tcar-card blockquote { font-family: var(--f-display); font-size: .95rem; line-height: 1.42; color: var(--ink-soft);
  max-height: 11.4em; overflow: hidden; }
.tcar-card blockquote p + p { margin-top: .6em; }
.tc-lead { color: var(--ink); }
.tcar-card.is-active blockquote { font-size: clamp(.98rem, .9rem + .3vw, 1.06rem); max-height: 10em; }
.tcar-card.is-active .tc-lead { font-size: clamp(1.24rem, 1.05rem + .7vw, 1.6rem); line-height: 1.24;
  color: var(--ink); margin-bottom: .55em; }
.tcar-card.is-clamped blockquote {
  -webkit-mask-image: linear-gradient(#000 66%, transparent 98%);
          mask-image: linear-gradient(#000 66%, transparent 98%); }
.tcar-card.is-open blockquote { max-height: 200em; -webkit-mask-image: none; mask-image: none; }
.tcar-card figcaption { margin-top: auto; padding-top: 1rem; display: flex; flex-direction: column; gap: .2rem; }
.tcar-card figcaption b { font-family: var(--f-display); font-size: 1.02rem; color: var(--ink); }
.tcar-card figcaption span { font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--maroon); }
.tcar-card .rev-more { display: none; align-self: flex-start; margin-top: .6rem; background: none; border: none;
  cursor: pointer; padding: .3rem 0; font-family: var(--f-accent); font-size: .72rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--maroon);
  border-bottom: 1px solid color-mix(in srgb, var(--maroon) 40%, transparent); }
.tcar-card.is-active.is-clamped .rev-more { display: inline-block; }
.tcar-card--excerpt .rev-context { display: none; }
.tcar-card--excerpt.is-open .rev-context { display: inline; }
.tcar-card--excerpt:not(.is-open) .rev-praise::before { content: "\2026"; }

/* --- arrows + dots --- */
.tcar-nav { display: flex; align-items: center; justify-content: center; gap: clamp(1rem, 3vw, 2rem);
  margin-top: clamp(1.6rem, 3vw, 2.4rem); }
.tcar-arrow { width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--line); background: transparent;
  color: var(--ink); font-size: 1.05rem; display: grid; place-items: center; cursor: pointer; flex: none;
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease); }
.tcar-arrow:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.tcar-arrow:disabled { opacity: .32; cursor: default; background: transparent; color: var(--ink); }
.tcar-dots { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: center; max-width: 62%; }
.tcar-dot { width: 7px; height: 7px; padding: 0; border: none; border-radius: 50%; cursor: pointer;
  background: color-mix(in srgb, var(--ink) 22%, transparent);
  transition: background .3s var(--ease), transform .3s var(--ease); }
.tcar-dot.is-on { background: var(--coral); transform: scale(1.5); }
/* 25 dots wrap to two rows on a phone and aren't tappable at that size anyway;
   swipe + arrows cover it */
@media (max-width: 620px) { .tcar-dots { display: none; } }

/* ── phones: a real scroll rail ────────────────────────────────────────────────
   The JS fan was wrong on touch (reported 24 Aug): swipes missed, the active
   card's text re-sized mid-swipe, and nothing suggested there were more cards.
   Below 620px the stage is a plain scroll-snap rail — every card the same size,
   the same type, the next one peeking in from the right. main.js detects the
   same breakpoint and stands down. */
@media (max-width: 620px) {
  .tcar { --aw: 84vw; --iw: 60vw; --gap: 12px; }
  .tcar-stage { height: auto; display: flex; gap: 12px;
    overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    padding: .4rem var(--gutter) 1rem; scroll-padding-inline: var(--gutter);
    scrollbar-width: none; }
  .tcar-stage::-webkit-scrollbar { display: none; }
  .tcar-card, .tcar-card.is-active {
    position: relative; inset: auto; flex: 0 0 84vw; width: 84vw; height: 340px;
    transform: none !important; opacity: 1 !important; cursor: default;
    scroll-snap-align: center; transition: none; }
  .tcar-card.is-open { height: auto; }
  /* one type size whatever the card's state — no growing on activation */
  .tcar-card blockquote, .tcar-card.is-active blockquote { font-size: .98rem; max-height: 9.5em; }
  .tc-lead, .tcar-card.is-active .tc-lead { font-size: 1.18rem; line-height: 1.28; }
  /* the fade + read-more works per card here, not only on the active one */
  .tcar-card.is-clamped .rev-more { display: inline-block; }
}

.reviews-press { display: flex; flex-direction: column; align-items: center; gap: 1.3rem; text-align: center;
  margin-top: clamp(3rem, 7vw, 5rem); padding-top: clamp(2.4rem, 5vw, 3.4rem); border-top: 1px solid var(--line); }
.reviews-press .press-label { font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .28em; text-transform: uppercase; color: var(--grey); }
.reviews-press .press-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: clamp(1.2rem, 4vw, 3rem); }
.reviews-press .press-row a { font-family: var(--f-display); font-size: clamp(1.05rem, .9rem + .6vw, 1.5rem);
  color: var(--ink); opacity: .8; transition: opacity .3s var(--ease), color .3s var(--ease), transform .3s var(--ease); }
.reviews-press .press-row a:hover { color: var(--coral); transform: translateY(-2px); }

/* =====================================================================
   DAYBREAK — the close (full-bleed morning, copy in the negative space)
   ===================================================================== */
/* Full image is always shown (never cropped); copy overlays on the left on desktop. */
.daybreak { position: relative; overflow: hidden; background: #140E07; }
.daybreak-media { position: relative; width: 100%; line-height: 0; }
.daybreak-photo { display: block; width: 100%; height: auto; }
.daybreak-scrim { position: absolute; inset: 0; background:
  linear-gradient(90deg, rgba(18,12,6,.9) 0%, rgba(18,12,6,.62) 28%, rgba(18,12,6,.12) 54%, transparent 72%),
  linear-gradient(0deg, rgba(18,12,6,.4) 0%, transparent 30%); }
.daybreak-copy { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; justify-content: center;
  color: var(--paper); box-sizing: border-box;
  padding-left: max(var(--gutter), calc(50vw - var(--maxw) / 2 + var(--gutter))); padding-right: var(--gutter); }
.daybreak-copy > * { max-width: 34rem; }
.daybreak-copy .daybreak-eyebrow { color: var(--gold-lt); }
.daybreak-copy .daybreak-eyebrow::before, .daybreak-copy .daybreak-eyebrow::after { background: var(--gold-lt); opacity: .8; }
.daybreak-payoff { font-family: var(--f-display); text-transform: lowercase; margin-top: 1rem;
  font-size: clamp(2.2rem, 1rem + 3.4vw, 4.6rem); line-height: .98; letter-spacing: -.015em; color: var(--paper); }
.daybreak-payoff .serif-italic { color: var(--gold-lt); }
.daybreak-sub { margin-top: 1.3rem; font-size: var(--step-1); line-height: 1.5; color: rgba(244,237,225,.92); }
.daybreak-cta { margin-top: 2rem; }
.daybreak-cta::before { background: var(--coral); }
.daybreak-tags { list-style: none; display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 2rem; }
.daybreak-tags li { font-family: var(--f-accent); font-size: .74rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--paper); padding: .55em 1em; border: 1px solid rgba(244,237,225,.42); border-radius: 999px; }
/* Below the desktop breakpoint the copy stacks under the (fully visible) image. */
@media (max-width: 860px) {
  .daybreak-scrim { display: none; }
  .daybreak-copy { position: static; inset: auto; padding: clamp(2rem, 7vw, 3rem) var(--gutter) clamp(2.6rem, 9vw, 3.6rem); }
  .daybreak-copy > * { max-width: none; }
  .daybreak-payoff { font-size: clamp(2rem, 1.2rem + 4vw, 2.9rem); }
  .daybreak-sub { font-size: var(--step-0); max-width: 34ch; }
}

/* =====================================================================
   Finale — the close woven with subscribe (one section)
   ===================================================================== */
.finale { display: grid; grid-template-columns: 1.02fr 1fr; align-items: stretch;
  background: color-mix(in srgb, var(--aqua) 46%, var(--paper)); overflow: hidden; }
.finale-media { position: relative; min-height: 100%; }
.finale-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
.finale-body { padding: clamp(2.6rem, 5vw, 4.8rem) clamp(1.5rem, 4vw, 3.8rem); }
.finale-body > * { max-width: 46ch; }
.finale-head { font-family: var(--f-display); text-transform: lowercase; margin-top: .7rem;
  font-size: clamp(2.1rem, 1.4rem + 3vw, 3.2rem); line-height: 1.02; }
.finale-head .serif-italic { color: var(--maroon); }
.finale-sub { margin-top: 1.05rem; font-size: var(--step-0); line-height: 1.55; color: var(--ink-soft); }
.finale .sub-actions { margin-top: 1.5rem; max-width: none; }
.finale-nod { margin-top: 1.6rem; font-family: var(--f-accent); font-size: var(--step--1);
  letter-spacing: .03em; color: var(--ink-soft); }
@media (max-width: 900px) {
  .finale { grid-template-columns: 1fr; }
  .finale-media { min-height: 0; aspect-ratio: 16 / 10; }
  .finale-photo { position: static; }
  .finale-body > * { max-width: none; }
}

/* =====================================================================
   Journal / recipes
   ===================================================================== */
.journal-hero { background: var(--paper-2); text-align: center; }
.journal-title { font-family: var(--f-display); text-transform: lowercase; line-height: .95;
  font-size: clamp(3rem, 1.8rem + 7vw, 6rem); margin-top: .4rem; }
.journal-intro { max-width: 48ch; margin: 1.2rem auto 0; color: var(--ink-soft); font-size: var(--step-1); line-height: 1.5; }
.journal-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.3rem, 2.4vw, 2.1rem); }
@media (max-width: 900px) { .journal-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .journal-grid { grid-template-columns: 1fr; } }
.journal-card { display: flex; flex-direction: column; background: var(--paper-2);
  border-radius: clamp(16px, 2vw, 24px); overflow: hidden;
  transition: transform .32s var(--ease), box-shadow .32s var(--ease); }
.journal-card:hover { transform: translateY(-5px); box-shadow: 0 24px 42px -28px rgba(33,27,23,.5); }
.journal-card--feature { grid-column: span 2; flex-direction: row; }
@media (max-width: 600px) { .journal-card--feature { grid-column: auto; flex-direction: column; } }
.journal-media { position: relative; aspect-ratio: 3 / 2; overflow: hidden;
  background: color-mix(in srgb, var(--jc, var(--aqua)) 32%, var(--paper)); }
.journal-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.journal-media--soon { display: grid; place-items: center; }
.journal-soon { font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-soft);
  background: color-mix(in srgb, var(--paper) 72%, transparent); padding: .5em 1.1em; border-radius: 100px; }
.journal-card--feature .journal-media { aspect-ratio: auto; flex: 1 1 54%; min-height: 300px; }
.journal-body { display: flex; flex-direction: column; gap: .5rem; flex: 1;
  padding: clamp(1.2rem, 2vw, 1.6rem); }
.journal-card--feature .journal-body { flex-basis: 46%; justify-content: center; padding: clamp(1.6rem, 3vw, 2.8rem); }
.journal-tag { align-self: flex-start; font-family: var(--f-accent); font-size: .58rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--maroon); }
.journal-h { font-size: var(--step-1); line-height: 1.05; }
.journal-card--feature .journal-h { font-size: var(--step-3); }
.journal-ex { color: var(--ink-soft); font-size: var(--step--1); line-height: 1.55; }
.journal-more { margin-top: auto; padding-top: .5rem; font-family: var(--f-accent); font-size: var(--step--1);
  font-weight: 600; letter-spacing: .04em; color: var(--teal); transition: color .3s var(--ease); }
.journal-card:hover .journal-more { color: var(--coral); }
.journal-note { text-align: center; margin-top: clamp(2rem, 4vw, 3rem); color: var(--ink-soft); }
.journal-note a { border-bottom: 1px solid currentColor; }

/* home teaser strip */
.home-journal { background: var(--paper); }
.home-journal .journal-teaser-head { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: clamp(1.6rem, 3vw, 2.4rem); }
.home-journal .journal-teaser-head h2 { font-size: var(--step-3); }
.jt-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.1rem, 2vw, 1.8rem); }
@media (max-width: 760px) { .jt-grid { grid-template-columns: 1fr; } }

/* gift hampers (reuses .journal-card layout) */
.hamper-grid { margin-top: 0; }
.hamper-cta { align-self: flex-start; margin-top: .7rem; display: inline-flex; align-items: center; gap: .4em;
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .04em; color: var(--teal);
  transition: gap .3s var(--ease), color .3s var(--ease); }
.hamper-card:hover .hamper-cta { color: var(--coral); gap: .75em; }

/* =====================================================================
   TEAL ACCENTS — quiet brand-colour presence through the warm sections
   ===================================================================== */
.chip { border-color: rgba(127,184,178,.55); }
.reviews-progress span { background: var(--aqua-deep); }
.rev-arrow:hover { background: var(--aqua); border-color: var(--aqua); color: var(--ink); }
.reviews-press { border-top-color: rgba(127,184,178,.45); }
.reviews-press .press-row a:hover { color: var(--maroon); opacity: 1; }
.review-card figcaption span { color: var(--teal); }
.review-card figcaption { border-top-color: rgba(127,184,178,.4); }
.reviews-head-r .link { color: var(--teal); }
.claim-more:hover { color: var(--teal); }
.award-figure::before { background: var(--aqua); opacity: .6; }
.chip:hover { border-color: var(--aqua-deep); background: rgba(161,205,200,.16); }

/* ── first-add suggestions ─────────────────────────────────────────────────────
   Shown once, right after the first item lands in the basket: the same
   goes-well-with picks the cart footer uses, offered while the decision is hot. */
.xpop { position: fixed; inset: 0; z-index: 118; display: grid; place-items: end center;
  padding: 1rem; background: rgba(20,14,7,.4); opacity: 0; pointer-events: none;
  transition: opacity .3s var(--ease); }
.xpop.is-open { opacity: 1; pointer-events: auto; }
@media (min-width: 720px) { .xpop { place-items: center; } }
.xpop-panel { width: min(430px, 100%); background: var(--paper); border-radius: 18px;
  padding: 1.2rem 1.3rem 1.3rem; box-shadow: 0 30px 70px -30px rgba(20,14,7,.6);
  transform: translateY(14px); transition: transform .3s var(--ease); }
.xpop.is-open .xpop-panel { transform: none; }
.xpop-added { display: flex; align-items: center; gap: .55rem; font-family: var(--f-accent);
  font-size: .8rem; color: var(--ink-soft); }
.xpop-added b { color: var(--ink); }
.xpop-tick { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--teal);
  color: var(--paper); display: grid; place-items: center; font-size: .7rem; }
.xpop-h { font-family: var(--f-display); font-size: 1.25rem; margin: .8rem 0 .6rem; }
.xpop-row { display: flex; flex-direction: column; gap: .55rem; }
.xpop-item { display: flex; align-items: center; gap: .75rem; }
.xpop-item img { width: 52px; height: 52px; border-radius: 12px; object-fit: cover; flex: none; }
.xpop-name { min-width: 0; font-family: var(--f-display); font-size: 1rem; }
.xpop-price { font-family: var(--f-accent); font-size: .74rem; color: var(--ink-soft); }
.xpop-add { margin-left: auto; flex: none; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--paper); font-size: 1.05rem; cursor: pointer;
  transition: background .3s var(--ease), color .3s var(--ease); }
.xpop-add:hover, .xpop-add:active { background: var(--ink); color: var(--paper); }
.xpop-foot { display: flex; align-items: center; justify-content: space-between; gap: .8rem;
  margin-top: 1.1rem; }
.xpop-skip { background: none; border: 0; cursor: pointer; font-family: var(--f-accent);
  font-size: .78rem; color: var(--ink-soft); text-decoration: underline; text-underline-offset: 3px; }
.xpop-view { flex: none; }

/* contact detail hint */
.detail-hint { font-family: var(--f-accent); font-size: .7rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--grey); margin-top: .55rem; }
@media (prefers-reduced-motion: reduce) {
  .mm-bg, .mm-list a, .mm-cta, .mm-foot { transition: none; transform: none; }
  .flavour-item img { transition: none; }
}

/* nav sits above the open menu: cream wordmark + circled close */
.nav-open .nav { z-index: 130; background: transparent; box-shadow: none; color: var(--paper); }
.nav-open .nav .nav-wordmark-mask { background-image: url("brand-assets/logos/bod-wordmark-cream.png"); }
@media (max-width: 860px) {
  .nav-open .nav-toggle {
    width: 44px; height: 44px; padding: 0; gap: 5px;
    align-items: center; justify-content: center;
    border: 1px solid rgba(244,237,225,.5); border-radius: 50%; color: var(--paper);
  }
  .nav-open .nav-toggle span { width: 16px; }
}

/* =====================================================================
   PRODUCT OVERLAY — quick view + whatsapp ordering
   ===================================================================== */
.prod-card { cursor: pointer; }
/* the card is no longer focusable itself; the ring follows its .pc-open button instead */
.prod-card:focus-within { outline: none; }
.prod-overlay { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: clamp(1rem, 3vw, 2rem); }
.prod-overlay[hidden] { display: none; }
.ov-backdrop { position: absolute; inset: 0; background: rgba(20,14,7,.58); backdrop-filter: blur(3px);
  opacity: 0; transition: opacity .4s var(--ease); }
.prod-overlay.is-open .ov-backdrop { opacity: 1; }
.ov-panel {
  position: relative; width: min(100%, 880px); max-height: 90vh;
  display: grid; grid-template-columns: 1fr 1.1fr; grid-template-rows: minmax(0, 1fr); overflow: hidden;
  background: var(--paper); border-radius: 18px; box-shadow: 0 40px 90px rgba(20,14,7,.4);
  opacity: 0; transform: translateY(26px) scale(.97);
  transition: opacity .45s var(--ease), transform .45s var(--ease);
}
.prod-overlay.is-open .ov-panel { opacity: 1; transform: none; }
.ov-close {
  position: absolute; top: .9rem; right: .9rem; z-index: 3;
  width: 42px; height: 42px; border-radius: 50%; border: 1px solid rgba(33,27,23,.25);
  background: var(--paper); color: var(--ink); font-size: .95rem; cursor: pointer;
  display: grid; place-items: center;
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.ov-close:hover { background: var(--ink); color: var(--paper); transform: rotate(90deg); }
/* THE LANTERN — the stage is a dark warm room and the PRODUCT is the light source, not a
   lamp pointed at it. Warmth glows out of the product, spills onto whatever it's standing
   on, and falls off into the dark. Warm browns deliberately, never a dark teal. */
.ov-media { position: relative; min-height: 0; display: grid; place-items: center;
  padding: clamp(1.6rem, 4vw, 2.6rem); overflow: hidden;
  background: radial-gradient(120% 90% at 50% 56%, #3A2A1E 0%, #241A13 44%, #120C09 100%); }
/* the light the product throws into the room */
.ov-glow { position: absolute; left: 50%; top: 52%; width: 88%; aspect-ratio: 1;
  transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none; z-index: 0;
  background: radial-gradient(circle at center, rgba(255,204,138,.34) 0%, rgba(255,180,104,.13) 38%, rgba(255,170,90,0) 68%);
  transition: transform .5s var(--ease), opacity .5s var(--ease); }
.ov-media.is-live .ov-glow { transform: translate(-50%, -50%) scale(1.06); }
/* that light landing on the surface underneath, so the product reads as standing on
   something rather than floating in a void (a dark shadow would be invisible here) */
.ov-pool { position: absolute; left: 50%; bottom: 15%; width: 54%; height: 20px;
  transform: translateX(-50%); border-radius: 50%; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(255,214,158,.30), rgba(255,214,158,0) 72%);
  filter: blur(2px); transition: opacity .35s var(--ease), transform .35s var(--ease); }
.ov-media.is-live .ov-pool { opacity: .95; transform: translateX(-50%) scale(1.06); }
.ov-media.is-empty .ov-glow { opacity: .3; }
.ov-media.is-empty .ov-pool { opacity: 0; }
.ov-nophoto { position: relative; z-index: 1; font-family: var(--f-accent); font-size: .68rem;
  font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: rgba(244,237,225,.42); }
/* A fixed box, with the product CONTAINed inside it — a tall bottle ends up height-capped and
   a wide wheel width-capped, exactly as before. The box being fixed is the point: the masked
   layers below use `contain` against the same box, so they land on the product's silhouette
   pixel-for-pixel whatever its shape. (An aspect-ratio box that hugs the product overflows
   the column for wide products; don't reintroduce it.) */
.ov-obj { position: relative; z-index: 1; width: 88%; height: 78%; will-change: transform;
  transition: filter .35s var(--ease);
  filter: drop-shadow(0 26px 30px rgba(0,0,0,.55)); }
.ov-media.is-live .ov-obj { filter: drop-shadow(0 34px 38px rgba(0,0,0,.6)); }
.ov-media.is-held .ov-obj { filter: drop-shadow(0 16px 22px rgba(0,0,0,.68)); }
.ov-obj[hidden] { display: none; }
.ov-obj img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* --ovmask is the product's own image, used as a mask, so both lit layers are clipped to its
   exact silhouette. This is what stops them reading as gradients floating over a sticker. */
.ov-inner, .ov-spec { position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: var(--ovmask) center / contain no-repeat; mask: var(--ovmask) center / contain no-repeat;
  mix-blend-mode: screen; }
/* the product lit from within */
.ov-inner { background: radial-gradient(52% 34% at 50% 60%, rgba(255,198,126,.50) 0%, rgba(255,186,112,.18) 52%, rgba(255,186,112,0) 78%); }
/* specular: a band of light that slides across the surface as the cursor moves, so glass
   reads as glass. --sx is driven from JS. */
.ov-spec { opacity: 0; transition: opacity .4s var(--ease);
  background: linear-gradient(105deg,
    rgba(255,255,255,0)   calc(var(--sx, 50%) - 26%),
    rgba(255,255,255,.28) calc(var(--sx, 50%) - 5%),
    rgba(255,255,255,.44) var(--sx, 50%),
    rgba(255,255,255,.28) calc(var(--sx, 50%) + 5%),
    rgba(255,255,255,0)   calc(var(--sx, 50%) + 26%)); }
.ov-media.is-live .ov-spec { opacity: 1; }
/* the product answers the cursor: soft tilt on move, lift on hover, pick it up and turn it.
   The tilt transform is driven from JS onto .ov-obj; the entrance + idle float below live on
   the img inside it, so the two never overwrite each other. */
.ov-media { perspective: 900px; cursor: grab; touch-action: pan-y; }
.ov-media.is-held { cursor: grabbing; }
/* it arrives: rises into the light, then breathes. gentle + fast, per the motion brief. */
@keyframes ov-arrive { from { opacity: 0; transform: translateY(18px) scale(.965); }
                       to   { opacity: 1; transform: none; } }
@keyframes ov-float  { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
.ov-obj img { animation: ov-arrive .55s var(--ease) both, ov-float 6s ease-in-out 1.1s infinite; }
@media (prefers-reduced-motion: reduce) {
  .ov-media { cursor: default; perspective: none; }
  .ov-obj { transform: none !important; }
  .ov-obj img { animation: none; }
  .ov-spec { display: none; }
}
.ov-body { padding: clamp(1.8rem, 4vw, 3rem); display: flex; flex-direction: column; align-items: flex-start; gap: .9rem; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.ov-line { font-family: var(--f-accent); font-size: .72rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--maroon); }
.ov-body h3 { font-size: var(--step-3); line-height: 1; }
.ov-desc { color: var(--ink-soft); line-height: 1.6; max-width: 34ch; }
.ov-price { font-family: var(--f-display); font-size: var(--step-1); color: var(--ink); }
.ov-wa { margin-top: .4rem; }
.ov-note { font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--grey); margin-top: auto; padding-top: 1rem; }
.ov-sub { display: inline-flex; align-items: center; gap: .4rem; margin-top: .7rem; font-family: var(--f-accent); font-weight: 600; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--maroon); }
.ov-sub:hover { color: var(--coral); }
@media (max-width: 720px) {
  .ov-panel { grid-template-columns: 1fr; grid-template-rows: auto; max-height: 90vh; overflow-y: auto; }
  .ov-media { padding: 2rem 1.4rem 1.2rem; }
  .ov-obj { width: 60%; height: 240px; }
  .ov-body { padding: 1.4rem 1.4rem 1.8rem; overflow: visible; }
}
body.ov-lock { overflow: hidden; }

/* =====================================================================
   PINCODE CHECKER (contact)
   ===================================================================== */
.pin-check { display: flex; flex-direction: column; align-items: center; gap: 1rem; text-align: center;
  margin: 0 auto clamp(2.4rem, 5vw, 3.6rem); max-width: 34rem; }
.pin-label { font-family: var(--f-accent); font-size: .78rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--maroon); }
.pin-form { display: flex; gap: .7rem; width: 100%; max-width: 26rem; }
.pin-form input {
  flex: 1; min-width: 0; background: var(--paper); border: 1px solid var(--line); border-radius: 100px;
  font-family: var(--f-accent); font-size: 1rem; letter-spacing: .14em; text-align: center;
  color: var(--ink); padding: .8em 1.2em;
}
.pin-form input:focus { outline: none; border-color: var(--aqua-deep); box-shadow: 0 0 0 3px rgba(161,205,200,.35); }
.pin-result { min-height: 1.4em; font-size: var(--step-0); color: var(--ink-soft); max-width: 36ch; }
.pin-result.is-yes { color: var(--teal); }
.pin-result.is-no { color: var(--maroon); }

/* =====================================================================
   GATHER BOOKING FORM (on the dark book band)
   ===================================================================== */
.book-form { width: min(100%, 34rem); margin: 2.2rem auto 0; text-align: left;
  display: flex; flex-direction: column; gap: 1.1rem; }
.bf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
@media (max-width: 560px) { .bf-row { grid-template-columns: 1fr; } }
.book-form .field label { color: var(--aqua); }
.book-form .field input, .book-form .field select, .book-form .field textarea {
  background: rgba(244,237,225,.06); border: 1px solid rgba(244,237,225,.3);
  color: var(--paper); border-radius: 10px; width: 100%;
  font-family: var(--f-body); font-size: var(--step-0); padding: .75em .95em;
}
.book-form .field input::placeholder, .book-form .field textarea::placeholder { color: rgba(244,237,225,.45); }
.book-form .field input:focus, .book-form .field select:focus, .book-form .field textarea:focus {
  outline: none; border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(161,205,200,.2); }
.book-form .field select option { color: var(--ink); background: var(--paper); }
.book-form .field input[type="date"] { color-scheme: dark; }
.book-form .btn { align-self: flex-start; }
.bf-note { font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: rgba(244,237,225,.55); }

/* =====================================================================
   STICKY WHATSAPP ORDER BUTTON
   ===================================================================== */
.wa-fab {
  position: fixed; right: clamp(1rem, 3vw, 2rem); bottom: clamp(1rem, 3vw, 2rem); z-index: 95;
  display: inline-flex; align-items: center; gap: 0;
  height: 58px; padding: 0; width: 58px; border-radius: 100px;
  background: var(--ink); color: var(--paper); overflow: hidden;
  box-shadow: 0 14px 30px -10px rgba(20,14,7,.55);
  transform: translateY(150%); opacity: 0;
  transition: transform .5s var(--ease), opacity .5s var(--ease), width .4s var(--ease), background .3s var(--ease);
}
.wa-fab.is-in { transform: none; opacity: 1; }
/* sticky mobile checkout bar — fastest path to checkout when the basket has items */
.checkout-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 92; width: 100%;
  display: none; align-items: center; gap: .7rem; text-align: left; cursor: pointer; border: 0;
  padding: .8rem clamp(1rem, 4vw, 1.3rem); padding-bottom: calc(.8rem + env(safe-area-inset-bottom));
  background: var(--ink); color: var(--paper); font-family: var(--f-accent);
  box-shadow: 0 -8px 26px -14px rgba(20,14,7,.6); }
.cob-l { font-size: .9rem; }
.cob-count { display: inline-grid; place-items: center; min-width: 1.45rem; height: 1.45rem; padding: 0 .4rem;
  border-radius: 100px; background: var(--coral); color: var(--paper); font-weight: 700; font-size: .82rem; }
.cob-mid { font-family: var(--f-display); font-size: 1.2rem; margin-left: auto; }
.cob-cta { display: inline-flex; align-items: center; gap: .4rem; background: var(--coral); color: var(--paper);
  padding: .5rem .95rem; border-radius: 100px; font-weight: 600; font-size: .78rem; letter-spacing: .05em; text-transform: uppercase; }
@media (max-width: 720px) {
  .checkout-bar:not([hidden]) { display: flex; }
  body.has-cob .wa-fab { bottom: calc(76px + env(safe-area-inset-bottom)); }
  /* a returning basket's sticky bar was sitting on top of the hero's
     "explore the range" button (user, 24 Aug) — the hero foot makes room */
  body.has-cob .hero-cine-foot { padding-bottom: calc(66px + env(safe-area-inset-bottom)); }
}
.wa-fab svg { width: 26px; height: 26px; flex: 0 0 58px; }
.wa-fab-label {
  font-family: var(--f-accent); font-size: .72rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; white-space: nowrap; opacity: 0; padding-right: 0;
  transition: opacity .3s var(--ease), padding .4s var(--ease);
}
@media (hover: hover) {
  .wa-fab:hover { width: 250px; background: #128C4B; }
  .wa-fab:hover .wa-fab-label { opacity: 1; padding-right: 1.4rem; }
}
.wa-fab:focus-visible { outline: 2px solid var(--coral); outline-offset: 3px; }
body.ov-lock .wa-fab, body.nav-open .wa-fab { opacity: 0; pointer-events: none; transform: translateY(150%); }
@media (prefers-reduced-motion: reduce) { .wa-fab { transition: opacity .3s; } }

/* The "start with our favourites" shortcut card lived here. An earlier sweep removed
   its selectors but left two declarations and their closing braces behind — orphans
   with no rule to belong to, i.e. two stray `}` that made the stylesheet invalid.
   Browsers recovered by discarding to the next valid selector, so nothing visibly
   broke and it survived unnoticed. Removed 2026-08-01. */
.quiz-modal { position: fixed; inset: 0; z-index: 207; display: grid; place-items: center; padding: 1.5rem; visibility: hidden; }
.quiz-modal.is-open { visibility: visible; }
.quiz-backdrop { position: absolute; inset: 0; background: rgba(16,10,6,.58); opacity: 0; transition: opacity .3s var(--ease); }
.quiz-modal.is-open .quiz-backdrop { opacity: 1; }
.quiz-panel { position: relative; z-index: 1; width: min(520px, 100%); max-height: 88vh; overflow-y: auto;
  background: var(--paper); color: var(--ink); border-radius: 22px; padding: 2.2rem clamp(1.4rem, 3vw, 2.4rem);
  box-shadow: 0 34px 80px -34px rgba(16,10,6,.65);
  transform: translateY(14px) scale(.98); opacity: 0; transition: transform .32s var(--ease), opacity .32s var(--ease); }
.quiz-modal.is-open .quiz-panel { transform: none; opacity: 1; }
.quiz-close { position: absolute; top: 1rem; right: 1rem; width: 34px; height: 34px; border-radius: 50%; border: none;
  background: none; cursor: pointer; color: var(--ink); font-size: .95rem; transition: background .3s var(--ease); }
.quiz-close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.quiz-prog { display: flex; gap: .35rem; margin-bottom: 1.2rem; }
.quiz-prog span { flex: 1; height: 3px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 12%, transparent); transition: background .3s var(--ease); }
.quiz-prog span.is-on { background: var(--coral); }
.quiz-step { font-family: var(--f-accent); font-size: .7rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--maroon); }
.quiz-q { font-size: var(--step-2); line-height: 1.1; margin: .4rem 0 1.3rem; }
.quiz-opts { display: flex; flex-direction: column; gap: .6rem; }
.quiz-opt { width: 100%; text-align: left; cursor: pointer; padding: .95rem 1.2rem; border-radius: 14px;
  background: var(--paper-2); border: 1.5px solid color-mix(in srgb, var(--ink) 12%, transparent);
  font-family: var(--f-display); font-size: 1.15rem; color: var(--ink);
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .18s var(--ease); }
.quiz-opt:hover { border-color: var(--ink); transform: translateX(4px); }
.quiz-back { margin-top: 1.2rem; border: none; background: none; cursor: pointer; color: var(--ink-soft);
  font-family: var(--f-accent); font-size: .82rem; padding: 0; transition: color .3s var(--ease); }
.quiz-back:hover { color: var(--ink); }
.quiz-box { display: flex; flex-direction: column; gap: .5rem; margin-bottom: 1.4rem; }
.quiz-item { display: grid; grid-template-columns: 46px 1fr auto; gap: .9rem; align-items: center;
  padding: .7rem .8rem; border-radius: 12px; background: var(--paper-2); animation: quizIn .3s var(--ease) backwards; }
.quiz-item:nth-child(2) { animation-delay: .05s; } .quiz-item:nth-child(3) { animation-delay: .1s; } .quiz-item:nth-child(4) { animation-delay: .15s; }
@keyframes quizIn { from { opacity: 0; transform: translateY(8px); } }
.quiz-item-media { width: 46px; height: 46px; border-radius: 9px; overflow: hidden; background: var(--paper); display: grid; place-items: center; }
.quiz-item-media img { width: 82%; height: 82%; object-fit: contain; }
.quiz-item-name { font-family: var(--f-display); font-size: 1.05rem; }
.quiz-item-cat { font-family: var(--f-accent); font-size: .66rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--maroon); }
.quiz-item-price { font-family: var(--f-accent); font-size: .9rem; font-weight: 600; color: var(--ink-soft); }
.quiz-add { width: 100%; justify-content: center; }
@media (prefers-reduced-motion: reduce) { .quiz-panel, .quiz-backdrop, .quiz-opt, .quiz-item { transition: none; animation: none; } }

/* feedback modal */
.feedback-link { background: none; border: none; cursor: pointer; font: inherit; color: inherit;
  letter-spacing: .08em; text-transform: uppercase; opacity: 1; transition: color .3s var(--ease); }
.feedback-link:hover { opacity: 1; text-decoration: underline; }
.fb-modal { position: fixed; inset: 0; z-index: 205; display: grid; place-items: center; padding: 1.5rem; visibility: hidden; }
.fb-modal.is-open { visibility: visible; }
.fb-backdrop { position: absolute; inset: 0; background: rgba(16,10,6,.55); opacity: 0; transition: opacity .35s var(--ease); }
.fb-modal.is-open .fb-backdrop { opacity: 1; }
.fb-panel { position: relative; z-index: 1; width: min(440px, 100%); background: var(--paper); color: var(--ink);
  border-radius: 20px; padding: 2rem clamp(1.4rem, 3vw, 2.2rem); box-shadow: 0 30px 70px -30px rgba(16,10,6,.6);
  transform: translateY(16px) scale(.98); opacity: 0; transition: transform .4s var(--ease), opacity .4s var(--ease); }
.fb-modal.is-open .fb-panel { transform: none; opacity: 1; }
.fb-close { position: absolute; top: 1rem; right: 1rem; width: 34px; height: 34px; border-radius: 50%; border: none;
  background: none; cursor: pointer; color: var(--ink); font-size: .95rem; transition: background .3s var(--ease); }
.fb-close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.fb-panel .eyebrow { color: var(--maroon); }
.fb-panel h3 { font-size: var(--step-2); margin: .35rem 0 .6rem; }
.fb-sub { color: var(--ink-soft); font-size: var(--step--1); line-height: 1.55; margin-bottom: 1.3rem; }
.fb-field { margin-bottom: 1rem; }
.fb-field label { display: block; font-family: var(--f-accent); font-size: .64rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }
.fb-opt { text-transform: none; letter-spacing: 0; font-weight: 400; }
.fb-field textarea, .fb-field input { width: 100%; font-family: var(--f-body); font-size: .95rem; color: var(--ink);
  background: var(--paper-2); border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); border-radius: 10px; padding: .7em .8em; resize: vertical; }
.fb-field textarea:focus, .fb-field input:focus { outline: none; border-color: var(--ink); }
.fb-send { width: 100%; justify-content: center; margin-top: .3rem; }
.fb-done { text-align: center; padding: 1.6rem .5rem; font-family: var(--f-display); font-size: 1.35rem; line-height: 1.4; }
@media (prefers-reduced-motion: reduce) { .fb-panel, .fb-backdrop { transition: none; } }

/* subscription CTA band (range page) */
.sub-cta { background: color-mix(in srgb, var(--aqua) 46%, var(--paper)); }
.sub-cta-inner { display: flex; align-items: center; justify-content: space-between; gap: clamp(1.6rem, 4vw, 3.5rem); flex-wrap: wrap; }
.sub-cta-copy { max-width: 46ch; }
.sub-cta-copy h2 { margin-top: .4rem; }
.sub-cta-copy .lead { margin-top: .9rem; }
.sub-cta-btn { flex: none; }

/* =====================================================================
   Cart, checkout drawer, hover add-to-basket, size picker
   ===================================================================== */
.nav-cart, .nav-search, .nav-acct { position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%; flex: none; margin-left: .6rem; cursor: pointer;
  background: transparent; color: inherit; border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease); }
.nav-cart:hover, .nav-search:hover, .nav-acct:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.nav-acct { text-decoration: none; }
/* On phones the bar holds wordmark + search + cart + hamburger and nothing else —
   a fourth pill pushed the hamburger clean off a 375px screen (found live, 24 Aug).
   Account moves into the mobile menu instead. */
@media (max-width: 700px) { .nav-acct { display: none; } }
.nav-cart svg, .nav-search svg { width: 19px; height: 19px; }
.nav-search { margin-left: .8rem; }
/* Opted in per page with .nav--filled-icons (contact). Carries the wholesale
   pill's own colours — --ink under --paper, wiping to --coral on hover — so the
   three controls read as one group instead of two hairlines beside a solid pill.
   Dropped once the bar turns solid on scroll, because by then the default
   outline has paper behind it and three filled shapes in a row is heavy.
   861px is where .nav-cta.desktop-only appears; below it there is no pill to
   match and the icons sit on the hero's cream anyway, where the hairline reads
   fine — filling them there is weight for nothing, next to a bare hamburger. */
@media (min-width: 861px) {
  .nav--filled-icons:not(.nav--solid) :is(.nav-cart, .nav-search) {
    background: var(--ink); color: var(--paper); border-color: var(--ink);
  }
  .nav--filled-icons:not(.nav--solid) :is(.nav-cart, .nav-search):hover {
    background: var(--coral); border-color: var(--coral);
  }
}

/* search overlay */
.search-modal { position: fixed; inset: 0; z-index: 206; visibility: hidden; }
.search-modal.is-open { visibility: visible; }
.search-backdrop { position: absolute; inset: 0; background: rgba(16,10,6,.5); opacity: 0; transition: opacity .3s var(--ease); }
.search-modal.is-open .search-backdrop { opacity: 1; }
.search-panel { position: absolute; top: 0; left: 0; right: 0; background: var(--paper); overflow-y: auto; max-height: 82vh;
  padding: clamp(1.2rem, 3vw, 2rem) clamp(1.2rem, 5vw, 3rem) 1.6rem; box-shadow: 0 24px 55px -24px rgba(16,10,6,.5);
  transform: translateY(-100%); transition: transform .4s var(--ease); }
.search-modal.is-open .search-panel { transform: none; }
.search-inputwrap { display: flex; align-items: center; gap: .8rem; max-width: var(--maxw); margin-inline: auto;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 15%, transparent); padding-bottom: .8rem; }
.search-inputwrap svg { width: 22px; height: 22px; color: var(--ink-soft); flex: none; }
.search-inputwrap input { flex: 1; border: none; background: none; color: var(--ink);
  font-family: var(--f-display); font-size: clamp(1.3rem, 3vw, 2rem); }
/* Reset only the mouse-focus ring. The bare :focus form outranks the global
   :focus-visible rule on specificity, so it was stripping the keyboard ring too and
   this input has no border or background of its own to fall back on. */
.search-inputwrap input:focus:not(:focus-visible) { outline: none; }
.search-esc { flex: none; border: 1px solid color-mix(in srgb, var(--ink) 20%, transparent); border-radius: 8px;
  padding: .35em .6em; cursor: pointer; background: none; color: var(--ink-soft);
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.search-esc:hover { color: var(--ink); border-color: var(--ink); }
.search-results { max-width: var(--maxw); margin: .9rem auto 0; display: flex; flex-direction: column; }
.search-hint, .search-empty { max-width: var(--maxw); margin: 1rem auto; color: var(--ink-soft); font-size: var(--step--1); }
.search-result { display: flex; align-items: baseline; gap: .9rem; width: 100%; text-align: left; cursor: pointer;
  padding: .75rem .5rem; border: none; background: none; border-radius: 10px; transition: background .2s var(--ease); }
.search-result:hover, .search-result.is-active { background: color-mix(in srgb, var(--ink) 5%, transparent); }
.search-result .sr-name { font-family: var(--f-display); font-size: 1.15rem; color: var(--ink); }
.search-result .sr-cat { font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--maroon); }
@media (prefers-reduced-motion: reduce) { .search-panel, .search-backdrop { transition: none; } }
.nav-cart-count { position: absolute; top: -5px; right: -5px; min-width: 18px; height: 18px; padding: 0 4px;
  display: grid; place-items: center; border-radius: 999px; background: var(--coral); color: var(--paper);
  font-family: var(--f-accent); font-size: .6rem; font-weight: 700; line-height: 1;
  opacity: 0; transform: scale(.4); transition: opacity .25s var(--ease), transform .25s var(--ease); }
.nav-cart-count.is-on { opacity: 1; transform: scale(1); }
.nav-cart.bump { animation: cartBump .45s var(--ease); }
/* signature add-to-cart moment: a dawn rises behind the basket, then sets */
.cart-sunrise { position: absolute; left: 50%; bottom: -13px; width: 32px; height: 19px;
  transform: translate(-50%, 8px); opacity: 0; pointer-events: none; }
.cart-sunrise svg { width: 100%; height: 100%; display: block; }
.cart-sunrise.is-rising { animation: cartSunrise .9s var(--ease); }
@keyframes cartSunrise {
  0%   { opacity: 0; transform: translate(-50%, 9px) scale(.8); }
  35%  { opacity: 1; transform: translate(-50%, 0) scale(1); }
  70%  { opacity: 1; transform: translate(-50%, 0) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -5px) scale(1.03); }
}
@media (prefers-reduced-motion: reduce) { .cart-sunrise { display: none; } }
@keyframes cartBump { 0%,100% { transform: scale(1); } 40% { transform: scale(1.2); } }

.pc-add { position: absolute; top: .7rem; right: .7rem; z-index: 4; width: 38px; height: 38px; border-radius: 50%;
  border: none; cursor: pointer; display: grid; place-items: center; background: var(--paper); color: var(--ink);
  box-shadow: 0 8px 18px -8px rgba(33,27,23,.55); opacity: 0; transform: translateY(-4px) scale(.9);
  transition: opacity .28s var(--ease), transform .28s var(--ease), background .28s var(--ease), color .28s var(--ease); }
.pc-add svg { width: 16px; height: 16px; }
.pc-add:hover { background: var(--ink); color: var(--paper); }
.prod-card:hover .pc-add, .prod-card:focus-within .pc-add { opacity: 1; transform: none; }
@media (hover: none) { .pc-add { opacity: 1; transform: none; } }

.ov-sizes { display: flex; flex-wrap: wrap; gap: .5rem; margin: .3rem 0 .2rem; }
.ov-sizes:empty { display: none; }
.ov-size { font-family: var(--f-accent); font-size: .72rem; font-weight: 600; letter-spacing: .02em; cursor: pointer;
  padding: .5em .95em; border-radius: 999px; color: var(--ink-soft); background: transparent;
  border: 1px solid color-mix(in srgb, var(--ink) 22%, transparent); transition: all .25s var(--ease); }
.ov-size:hover { border-color: var(--ink); color: var(--ink); }
.ov-size.is-sel { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.ov-add { align-self: flex-start; margin-top: .4rem; }
/* buy-now express: a real secondary button, not a faint text link.
   Skips the basket entirely for people who want just this one thing. */
.ov-wa-link { align-self: stretch; display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  font-family: var(--f-accent); font-size: .78rem; font-weight: 600; letter-spacing: .05em;
  color: var(--ink); background: transparent; border: 1.5px solid color-mix(in srgb, var(--ink) 22%, transparent);
  border-radius: 100px; padding: .72rem 1.1rem; margin-top: .55rem; text-align: center;
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease); }
.ov-wa-link:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* Enriched overlay detail — facts, review pull, related products */
.ov-details { align-self: stretch; border-top: 1px solid var(--line); margin-top: 1.1rem; padding-top: 1.2rem;
  display: flex; flex-direction: column; gap: 1.1rem; }
.ov-details[hidden] { display: none; }
.ov-facts { display: flex; flex-direction: column; gap: .9rem; margin: 0; }
.ov-fact { display: grid; grid-template-columns: 7rem 1fr; gap: .5rem 1rem; align-items: baseline; }
.ov-fact dt { font-family: var(--f-accent); font-size: .62rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); }
.ov-fact dd { margin: 0; color: var(--ink-soft); font-size: .92rem; line-height: 1.5; }
.ov-pairs { display: flex; flex-wrap: wrap; gap: .4rem; }
.ov-pairs span { font-family: var(--f-accent); font-size: .7rem; font-weight: 600; letter-spacing: .02em;
  color: var(--ink); background: var(--sand); border-radius: 100px; padding: .32em .8em; }
.ov-review { align-self: stretch; border-left: 2px solid var(--coral); padding-left: 1rem; margin: 0; }
.ov-review[hidden] { display: none; }
.ov-review p { font-family: var(--f-display); font-style: italic; font-size: 1.05rem; line-height: 1.4; color: var(--ink); max-width: none; }
.ov-review cite { display: block; margin-top: .5rem; font-family: var(--f-accent); font-style: normal;
  font-size: .64rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--maroon); }
.ov-related { align-self: stretch; border-top: 1px solid var(--line); margin-top: 1.1rem; padding-top: 1.2rem; }
.ov-related[hidden] { display: none; }
.ov-related-h { font-family: var(--f-accent); font-size: .62rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); margin-bottom: .75rem; }
.ov-related-h span { color: var(--maroon); }
.ov-related-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; }
.ov-goeswith .ov-related-row { grid-template-columns: repeat(2, 1fr); }
.ov-rel { display: flex; flex-direction: column; gap: .45rem; cursor: pointer; background: none; border: 0; padding: 0; text-align: left; }
.ov-rel-img { position: relative; aspect-ratio: 1; border-radius: 12px; overflow: hidden; display: grid; place-items: center;
  background: color-mix(in srgb, var(--rc, var(--aqua)) 26%, var(--paper)); transition: transform .3s var(--ease); }
.ov-rel:hover .ov-rel-img { transform: translateY(-3px); }
.ov-rel-img img { width: 76%; height: 76%; object-fit: contain; filter: drop-shadow(0 8px 10px rgba(33,27,23,.22)); }
.ov-rel-soon { font-family: var(--f-accent); font-size: .54rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: rgba(33,27,23,.5); }
.ov-rel-name { font-family: var(--f-body); font-size: .82rem; color: var(--ink); line-height: 1.15; }
@media (max-width: 400px) {
  .ov-fact { grid-template-columns: 1fr; gap: .2rem; }
}

body.cart-lock { overflow: hidden; }
.cart-drawer { position: fixed; inset: 0; z-index: 200; visibility: hidden; }
.cart-drawer.is-open { visibility: visible; }
.cart-backdrop { position: absolute; inset: 0; background: rgba(16,10,6,.5); opacity: 0; transition: opacity .4s var(--ease); }
.cart-drawer.is-open .cart-backdrop { opacity: 1; }
.cart-panel { position: absolute; top: 0; right: 0; height: 100%; width: min(420px, 92vw);
  background: var(--paper); color: var(--ink); display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .45s var(--ease); box-shadow: -24px 0 60px -30px rgba(16,10,6,.6); }
.cart-drawer.is-open .cart-panel { transform: none; }
.cart-head { display: flex; align-items: center; justify-content: space-between; padding: 1.3rem 1.5rem;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.cart-head h2 { font-size: var(--step-1); }
.cart-close { width: 36px; height: 36px; border-radius: 50%; border: none; background: none; cursor: pointer;
  color: var(--ink); font-size: 1rem; transition: background .3s var(--ease); }
.cart-close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.cart-items { flex: 1; overflow-y: auto; padding: .4rem 1.5rem; }
.cart-empty { padding: 3.5rem 1rem; text-align: center; color: var(--ink-soft); line-height: 1.7; font-size: 1rem; }
.cart-reorder { margin-top: 1.5rem; }
.cart-item { display: grid; grid-template-columns: 58px 1fr auto; gap: .9rem; align-items: start;
  padding: 1.1rem 0; border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.cart-item-media { width: 58px; height: 58px; border-radius: 12px; overflow: hidden; background: var(--paper-2); display: grid; place-items: center; }
.cart-item-media img { width: 82%; height: 82%; object-fit: contain; }
.cart-item-name { font-family: var(--f-display); font-size: 1.18rem; line-height: 1.08; }
.cart-item-cat { font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--maroon); margin-top: .25rem; }
.cart-item-size { margin-top: .35rem; }
.cart-size-sel { font-family: var(--f-accent); font-size: .82rem; color: var(--ink-soft); background: var(--paper);
  border: 1px solid color-mix(in srgb, var(--ink) 18%, transparent); border-radius: 8px; padding: .3em .5em; }
.cart-item-sizetxt { font-family: var(--f-accent); font-size: .82rem; letter-spacing: .04em; color: var(--ink-soft); }
.cart-qty { display: inline-flex; align-items: center; margin-top: .55rem;
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent); border-radius: 999px; }
.cart-qty button { width: 27px; height: 27px; border: none; background: none; cursor: pointer; color: var(--ink);
  font-size: .95rem; border-radius: 50%; transition: background .25s var(--ease); }
.cart-qty button:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.cart-qty span { min-width: 26px; text-align: center; font-family: var(--f-accent); font-size: .9rem; }
.cart-item-right { text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: .55rem; }
.cart-item-price { font-family: var(--f-accent); font-weight: 600; font-size: .98rem; }
.cart-remove { border: none; background: none; cursor: pointer; color: var(--ink-soft); font-family: var(--f-accent);
  font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; text-decoration: underline; transition: color .3s var(--ease); }
.cart-remove:hover { color: var(--coral); }
.cart-foot { border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); padding: 1.2rem 1.5rem 1.5rem; }
/* On a phone the footer (goes-well-with + totals + extras + button) grew taller than
   the screen and squeezed .cart-items to nothing — the customer could not see their
   own basket under the "goes well with" block (user, 24 Aug). The items keep a
   guaranteed slice and the footer scrolls internally instead. */
@media (max-width: 720px) {
  .cart-items { min-height: 30vh; }
  .cart-foot { overflow-y: auto; overscroll-behavior: contain; }
  .cart-xsell-row img { width: 40px; height: 40px; }
}
.cart-subtotal { display: flex; justify-content: space-between; align-items: baseline; }
.cart-subtotal .st-label { font-family: var(--f-accent); font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.cart-subtotal .st-val { font-family: var(--f-display); font-size: 1.5rem; }
.cart-foot-note { font-size: .82rem; color: var(--ink-soft); margin: .35rem 0 1rem; line-height: 1.5; }
/* "complete your basket" cross-sell (top of the cart footer; collapses when empty) */
.cart-xsell:empty { display: none; }
.cart-xsell { margin-bottom: 1.1rem; padding-bottom: 1.1rem; border-bottom: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); }
.cart-xsell-h { font-family: var(--f-accent); font-size: .64rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--maroon); margin-bottom: .6rem; }
.cart-xsell-row { display: grid; gap: .55rem; }
.cart-xsell-item { display: flex; align-items: center; gap: .7rem; }
.cxs-img { width: 44px; height: 44px; border-radius: 10px; background: color-mix(in srgb, var(--aqua) 30%, var(--paper)); display: grid; place-items: center; flex: none; overflow: hidden; }
.cxs-img img { width: 84%; height: 84%; object-fit: contain; }
.cxs-txt { display: flex; flex-direction: column; gap: .08rem; flex: 1; min-width: 0; }
.cxs-name { font-size: .92rem; color: var(--ink); }
.cxs-price { font-size: .8rem; color: var(--ink-soft); }
.cxs-add { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line); background: var(--paper); color: var(--ink); font-size: 1.15rem; line-height: 1; display: grid; place-items: center; flex: none; cursor: pointer; transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease); }
.cxs-add:hover { background: var(--coral); color: var(--paper); border-color: var(--coral); }
.cart-checkout-btn { width: 100%; justify-content: center; }
.cart-checkout { display: none; flex: 1; overflow-y: auto; padding: 1.1rem 1.5rem 1.6rem; }
.cart-drawer.is-checkout .cart-items, .cart-drawer.is-checkout .cart-foot { display: none; }
.cart-drawer.is-checkout .cart-checkout { display: block; }
.cart-back { border: none; background: none; cursor: pointer; color: var(--ink-soft); font-family: var(--f-accent);
  font-size: .85rem; letter-spacing: .04em; padding: 0; margin-bottom: 1rem; transition: color .3s var(--ease); }
.cart-back:hover { color: var(--ink); }
.co-title { font-size: var(--step-2); margin-bottom: 1.1rem; }
.co-field { margin-bottom: 1rem; }
.co-field label { display: block; font-family: var(--f-accent); font-size: .76rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }
.co-field input, .co-field textarea { width: 100%; font-family: var(--f-body); font-size: 1.05rem; color: var(--ink);
  background: var(--paper-2); border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); border-radius: 10px; padding: .7em .8em; }
.co-field textarea { resize: vertical; }
.co-field input:focus, .co-field textarea:focus { outline: none; border-color: var(--ink); }
.co-field input.is-error, .co-field textarea.is-error { border-color: var(--coral); background: color-mix(in srgb, var(--coral) 8%, var(--paper)); }
.co-row { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }

/* ── pincode gate ──────────────────────────────────────────────────────────────
   One question in front of the basket (24 Aug 2026). It is the only thing the
   Shopify checkout will not ask for later, so it is the only thing we ask first.
   [hidden]-style rules first: .cart-gate is display:none by default and only the
   .is-gate state turns it on, so it can never strand a customer behind it. */
.cart-gate { display: none; padding: 1.5rem 1.5rem 1.7rem; }
.cart-drawer.is-gate .cart-gate { display: block; }
.cart-drawer.is-gate .cart-items,
.cart-drawer.is-gate .cart-foot,
.cart-drawer.is-gate .cart-checkout,
.cart-drawer.is-gate .dv-strip--cart { display: none; }
.cg-h { font-size: var(--step-2); line-height: 1.15; margin: 0 0 .45rem; }
.cg-say { font-size: .9rem; color: var(--ink-soft); line-height: 1.55; margin: 0 0 1.3rem; max-width: 34ch; }
.cg-go { width: 100%; justify-content: center; margin-top: .3rem; }
#gatePin { font-size: 1.25rem; letter-spacing: .12em; font-variant-numeric: tabular-nums; }

/* footer line: which pincode is in force, and the way back to change it */
.cart-pin { display: flex; align-items: baseline; flex-wrap: wrap; gap: .45rem;
  font-size: .82rem; color: var(--ink-soft); margin-bottom: .7rem; }
.cart-pin:empty { display: none; }
.cart-pin strong { color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: .06em; }
.cp-ok, .cp-no { font-family: var(--f-accent); font-size: .7rem; letter-spacing: .06em;
  text-transform: uppercase; padding: .18rem .5rem; border-radius: 999px; line-height: 1.35; }
.cp-ok { color: var(--aqua-deep, var(--ink)); background: color-mix(in srgb, var(--aqua, var(--ink)) 16%, transparent); }
.cp-no { color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 8%, transparent); }
.cp-change { margin-left: auto; background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--f-accent); font-size: .76rem; color: var(--ink-soft);
  text-decoration: underline; text-underline-offset: 3px; }
.cp-change:hover { color: var(--ink); }

/* gift + preferred date, collapsed. The fast path must stay one tap. */
.cart-extra { border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  margin: 0 0 1rem; padding-top: .55rem; }
.cx-toggle { width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; background: none; border: 0; padding: .45rem 0; cursor: pointer;
  font-family: var(--f-accent); font-size: .8rem; color: var(--ink-soft); text-align: left; }
.cx-toggle:hover { color: var(--ink); }
.cx-chev { font-size: 1rem; line-height: 1; transition: transform .25s var(--ease); }
.cx-toggle[aria-expanded="true"] .cx-chev { transform: rotate(45deg); }
.cx-body[hidden] { display: none; }
.cx-body { padding-top: .5rem; }
.cx-body .co-field { margin-bottom: .8rem; }
.cx-body .co-gift { margin-bottom: .2rem; }
.co-pin-msg { font-family: var(--f-accent); font-size: .78rem; margin-top: .4rem; line-height: 1.4; min-height: 1em; }
.co-pin-msg.is-yes { color: #2f7d4f; }
.co-pin-msg.is-no { color: var(--maroon); }
.co-send { width: 100%; justify-content: center; margin-top: .3rem; }

/* delivery choice */
.cart-item-when { font-family: var(--f-accent); font-size: .72rem; letter-spacing: .03em; color: var(--teal); margin-top: .3rem; }
.co-delivery { margin-bottom: 1.7rem; }
.dv-single { font-family: var(--f-display); font-size: 1.3rem; color: var(--ink); }
.dv-intro { font-size: .92rem; color: var(--ink-soft); margin-bottom: .9rem; line-height: 1.5; }
.dv-opts { display: flex; flex-direction: column; gap: .7rem; }
.dv-opt { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: .2rem; width: 100%; text-align: left;
  cursor: pointer; padding: 1rem 3.2rem 1rem 1.1rem; border-radius: 14px; background: var(--paper-2);
  border: 1.5px solid color-mix(in srgb, var(--ink) 12%, transparent);
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .2s var(--ease); }
.dv-opt:hover { border-color: color-mix(in srgb, var(--ink) 35%, transparent); }
.dv-opt.is-sel { border-color: var(--ink); background: var(--paper); transform: translateY(-2px); }
/* tick indicator: quick, springy pop */
.dv-opt::before { content: ""; position: absolute; top: 1.05rem; right: 1.1rem; width: 22px; height: 22px; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  transition: background .18s var(--ease), border-color .18s var(--ease); }
.dv-opt.is-sel::before { background: var(--ink); border-color: var(--ink); }
.dv-opt.is-sel::after { content: "✓"; position: absolute; top: 1.05rem; right: 1.1rem; width: 22px; height: 22px;
  display: grid; place-items: center; color: var(--paper); font-size: .72rem; font-weight: 700;
  animation: dvPop .26s cubic-bezier(.34,1.56,.64,1); }
@keyframes dvPop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
.dv-title { font-family: var(--f-display); font-size: 1.2rem; color: var(--ink); display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.dv-title em { font-family: var(--f-accent); font-style: normal; font-size: .6rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--paper); background: var(--coral); padding: .35em .7em; border-radius: 999px; }
.dv-desc { font-family: var(--f-accent); font-size: .86rem; font-weight: 600; color: var(--teal); }
.dv-meta { font-size: .84rem; color: var(--ink-soft); line-height: 1.45; }
.dv-cut { font-family: var(--f-accent); font-size: .78rem; letter-spacing: .01em; color: var(--ink-soft); margin-top: 1rem; line-height: 1.6; }
.dv-cut strong { color: var(--ink); }
.dv-emergency { display: inline-flex; align-items: center; gap: .5em; margin-top: .8rem; padding: .7em 1.1em; border-radius: 999px;
  background: color-mix(in srgb, var(--coral) 12%, var(--paper)); border: 1.5px solid color-mix(in srgb, var(--coral) 50%, transparent);
  color: var(--maroon); font-family: var(--f-accent); font-size: .84rem; font-weight: 600;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease); }
.dv-emergency:hover { background: var(--coral); color: var(--paper); border-color: var(--coral); }
.dv-emergency--cart { display: flex; width: 100%; justify-content: center; margin-top: .7rem; }
.co-totals { margin: 1.3rem 0 1rem; padding-top: 1rem; border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); }
.co-line { display: flex; justify-content: space-between; align-items: baseline; font-family: var(--f-accent); font-size: .92rem; color: var(--ink-soft); margin-bottom: .45rem; }
.co-freehint { font-family: var(--f-accent); font-size: .78rem; color: var(--coral); margin: -.15rem 0 .5rem; letter-spacing: .01em; }
/* checkout "how this works" — sets the send + prepaid expectation before the handoff */
.co-how { background: color-mix(in srgb, var(--aqua) 22%, var(--paper)); border-radius: 14px;
  padding: 1rem 1.1rem; margin: 1.1rem 0 1.2rem; }
.co-how-h { font-family: var(--f-accent); font-size: .68rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); margin-bottom: .6rem; }
.co-how-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; counter-reset: cohow; }
.co-how-steps li { counter-increment: cohow; position: relative; padding-left: 1.9rem;
  font-size: .88rem; line-height: 1.5; color: var(--ink); }
.co-how-steps li::before { content: counter(cohow); position: absolute; left: 0; top: 0;
  width: 1.35rem; height: 1.35rem; border-radius: 50%; background: var(--ink); color: var(--paper);
  font-family: var(--f-accent); font-size: .7rem; font-weight: 700; display: grid; place-items: center; }
.co-how-safe { font-size: .8rem; color: var(--ink-soft); margin-top: .75rem; padding-top: .6rem;
  border-top: 1px solid rgba(36,28,23,.12); }
.sent-fine { font-size: .86rem; }
/* order reference — a shared handle both sides can quote */
.sent-ref { display: flex; flex-direction: column; align-items: center; gap: .3rem;
  background: color-mix(in srgb, var(--aqua) 24%, var(--paper)); border-radius: 14px;
  padding: .9rem 1.2rem; margin: .2rem 0 1.2rem; }
.sent-ref-k { font-family: var(--f-accent); font-size: .62rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); }
.sent-ref-v { font-family: var(--f-mono, var(--f-accent)); font-size: 1.15rem; letter-spacing: .06em; color: var(--ink); }
.sent-ref-help { font-family: var(--f-accent); font-size: .74rem; font-weight: 600; color: var(--teal-ink);
  border-bottom: 1px solid currentColor; padding-bottom: 1px; margin-top: .25rem; }
.sent-ref-help:hover { color: var(--coral); }
.co-line--total { font-family: var(--f-display); font-size: 1.35rem; color: var(--ink); margin-top: .7rem; padding-top: .7rem;
  border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); }
/* delivery countdown strip */
.dv-strip { display: flex; align-items: center; justify-content: center; gap: .7rem 1.1rem; flex-wrap: wrap;
  font-family: var(--f-accent); font-size: .84rem; color: var(--ink-soft); }
.dv-strip--page { background: color-mix(in srgb, var(--aqua) 26%, var(--paper)); padding: .85rem clamp(1rem, 4vw, 2rem);
  border-block: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
/* The cart drawer is far narrower than the page banner, so the inherited
   flex-wrap:wrap broke BETWEEN the clock and the sentence — stranding the icon
   alone on line one and pushing the text to line two, which cost the drawer a
   whole row of vertical space for nothing.

   nowrap keeps the icon and the sentence on the same line. min-width:0 is the
   load-bearing half: without it the text is a flex item at its min-content
   width and refuses to wrap inside itself, so it would overflow the drawer
   instead. align-items:flex-start keeps the clock level with the first line of
   text rather than floating to the vertical centre of a two-line block. */
.dv-strip--cart { justify-content: flex-start; padding: .8rem 1.5rem; font-size: .78rem;
  flex-wrap: nowrap; align-items: flex-start; gap: .5rem;
  background: color-mix(in srgb, var(--aqua) 22%, var(--paper));
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
.dv-strip--cart .dvs-clock { margin-top: .1em; }
.dv-strip--cart .dvs-now { min-width: 0; }
.dvs-clock { display: inline-flex; flex: none; color: var(--teal); }
.dvs-clock svg { width: 17px; height: 17px; }
.dvs-now { color: var(--ink); }
.dvs-now strong { color: var(--ink); font-weight: 700; }
.dvs-now.is-urgent strong { color: var(--coral-text); }
.dvs-rules { color: var(--ink-soft); opacity: .85; }
.dvs-rules strong { color: var(--ink); font-weight: 600; }
.dv-strip--cart .dvs-rules { display: none; }
/* .dvs-track exists only so the mobile ticker can loop. Everywhere else it and
   its two copies dissolve with display:contents, so .dvs-clock / .dvs-now /
   .dvs-rules stay DIRECT flex children of .dv-strip and keep its gap — and the
   duplicate copy is removed outright. Without this, wrapping the content for
   the ticker printed the whole line twice on desktop. */
.dvs-track, .dvs-track > span { display: contents; }
.dvs-track > span[aria-hidden="true"] { display: none; }
/* On mobile the strip stacked into a three-line block ~110px tall for what is
   one sentence of information. It becomes a single-line ticker instead: the
   content is duplicated once and the track translates -50%, so the loop is
   seamless with no JS. Height is fixed to one line, so it can never grow.
   Paused under prefers-reduced-motion (a permanently moving marquee is a
   vestibular problem, and the text must stay readable when it stops). */
@media (max-width: 640px) {
  /* BOTH strips take the one-line treatment. The ticker rules below (.dvs-track etc.)
     were never scoped to --page, so the cart strip animated its track too — but without
     this clamp it kept flex-wrap and normal white-space, rendering BOTH copies of the
     sentence as a thick wrapped block sliding sideways. One line, thin, or nothing. */
  .dv-strip--page, .dv-strip--cart {
    display: block; padding: .6rem 0; overflow: hidden;
    white-space: nowrap; font-size: .78rem; text-align: left;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  }
  .dv-strip--cart { padding: .5rem 0; font-size: .74rem; }
  /* the ticker: one copy scrolls out as the other scrolls in, so the loop has
     no seam and needs no JS. */
  .dvs-track {
    display: inline-block; padding-left: 100%;
    animation: dvTicker 30s linear infinite;
  }
  .dvs-track > span,
  .dvs-track > span[aria-hidden="true"] { display: inline; padding-right: 3rem; }
  /* the clock stays — the mobile line should read exactly like the desktop one.
     inline-flex would break the single line, so it is aligned as inline art. */
  .dvs-clock { display: inline-block; vertical-align: -3px; margin-right: .35rem; }
  .dvs-now, .dvs-rules { display: inline; }
  .dvs-now { margin-right: .55rem; }
}
@keyframes dvTicker { from { transform: translateX(0); } to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  /* No scrolling — and critically, drop the duplicate copy, or the sentence
     renders twice. The visible copy wraps normally as it did before. */
  .dvs-track { animation: none; padding-left: 0; display: block; }
  .dvs-track > span[aria-hidden] { display: none; }
  .dvs-track > span { padding-right: 0; }
  @media (max-width: 640px) {
    .dv-strip--page, .dv-strip--cart { white-space: normal; text-align: center; padding-inline: 1rem; }
  }
}

/* order sent confirmation */
/* explains the WhatsApp route when an unmapped item forces it */
.co-send-note { margin-top: .6rem; font-size: max(.74rem, 12px); line-height: 1.45;
  color: var(--ink-soft); text-align: center; }
.co-send-note[hidden] { display: none; }

.cart-sent { display: none; flex: 1; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 2rem 1.6rem; gap: .2rem; }
.cart-drawer.is-sent .cart-items, .cart-drawer.is-sent .cart-foot,
.cart-drawer.is-sent .cart-checkout, .cart-drawer.is-sent .dv-strip--cart { display: none; }
.cart-drawer.is-sent .cart-sent { display: flex; }
.sent-tick { width: 58px; height: 58px; border-radius: 50%; background: var(--ink); color: var(--paper);
  display: grid; place-items: center; font-size: 1.5rem; margin-bottom: 1rem; animation: dvPop .4s cubic-bezier(.34,1.56,.64,1); }
.cart-sent h3 { font-size: var(--step-2); }
.cart-sent p { color: var(--ink-soft); font-size: .92rem; line-height: 1.6; margin: .6rem 0 1.6rem; max-width: 30ch; }
/* "how did you find us" — the post-order attribution ask. Sits below the subscription
   block and is deliberately the quietest thing on the panel: it is our bookkeeping, not
   the customer's business, and it must never compete with "did you press send?". */
.sent-src { margin-top: .5rem; margin-bottom: 1.4rem; padding-top: 1.2rem;
            border-top: 1px solid rgba(33,27,23,.12);
            display: flex; flex-direction: column; align-items: center; gap: .7rem; max-width: 36ch; }
/* Sentence case, body face. The panel's uppercase label idiom (.sent-ref-k) is for
   two- and three-word tags; a seven-word question set that way wrapped to two lines
   and shouted — which is the opposite of what this block is supposed to be. */
.sent-src-q { font-size: .88rem; color: var(--grey); text-align: center; line-height: 1.45; }
.sent-src-done { color: var(--teal-ink); }
.sent-src-opts { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem; }
.sent-src-b {
  font-family: var(--f-body); font-size: .82rem; color: var(--ink-soft);
  padding: .45em .9em; border: 1px solid var(--line); border-radius: 100px;
  background: transparent; cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.sent-src-b:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.sent-src-b:focus-visible { outline: 2px solid var(--teal-ink); outline-offset: 2px; }
/* the tap target grows on touch without moving the pill visually */
@media (pointer: coarse) { .sent-src-b { padding-block: .62em; } }

.sent-sub { margin-top: .4rem; padding-top: 1.3rem; border-top: 1px solid rgba(33,27,23,.12); display: flex; flex-direction: column; align-items: center; gap: .25rem; max-width: 34ch; }
.sent-sub-lead { font-size: var(--step-0); color: var(--ink); }
.sent-sub-note { font-size: .82rem; color: var(--ink-soft); line-height: 1.5; margin-bottom: .7rem; }
.sent-sub-link { display: inline-flex; align-items: center; gap: .4rem; font-family: var(--f-accent); font-weight: 600; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--maroon); }
.sent-sub-link:hover { color: var(--coral); }

/* returning customer */
.co-welcome { display: flex; align-items: center; justify-content: space-between; gap: .8rem; flex-wrap: wrap;
  margin-bottom: 1rem; padding: .75rem 1rem; border-radius: 12px;
  background: color-mix(in srgb, var(--aqua) 34%, var(--paper)); font-size: .88rem; color: var(--ink); }
.co-welcome button { border: none; background: none; cursor: pointer; font-family: var(--f-accent); font-size: .76rem;
  font-weight: 600; color: var(--ink-soft); text-decoration: underline; }
.co-welcome button:hover { color: var(--coral); }

.cart-toast { position: fixed; left: 50%; bottom: 26px; z-index: 210; transform: translateX(-50%) translateY(18px);
  background: var(--ink); color: var(--paper); padding: .8em 1.35em; border-radius: 999px;
  font-family: var(--f-accent); font-size: .8rem; font-weight: 500; letter-spacing: .01em;
  box-shadow: 0 14px 34px -14px rgba(16,10,6,.65); opacity: 0; pointer-events: none;
  transition: opacity .3s var(--ease), transform .3s var(--ease); }
.cart-toast.is-on { opacity: 1; transform: translateX(-50%); }
body.cart-lock .wa-fab { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .cart-panel, .cart-backdrop, .cart-toast, .nav-cart.bump { transition: none; animation: none; } }

/* ===== HIGH PROTEIN — badge + goal chip =========================================
   The badge is a fact, not a promotion: it states the number rather than shouting a
   claim, and it only ever appears on cards whose own lab figures clear the threshold. */
.pc-protein {
  position: absolute; left: .7rem; bottom: .7rem; z-index: 3;
  display: inline-flex; align-items: baseline; gap: .3em;
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink); background: rgba(244,237,225,.92);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: .42em .75em; border-radius: 100px;
  box-shadow: 0 4px 14px -6px rgba(20,14,7,.4);
}
.pc-protein b { font-family: var(--f-display); font-weight: 400; font-size: 1.28em; letter-spacing: 0; }
.pc-protein i { font-style: normal; opacity: .6; letter-spacing: .06em; }
/* a card carrying both the award pill and the protein badge keeps them apart */
.prod-card--soon .pc-protein { display: none; }

/* the goal chip sits in the same bar as the categories but reads as a different question */
/* Goal chips used to be gold-starred so they stood out among the category chips. Now that
   goals have their own mode, every chip in the bar is a goal — so the marker is redundant,
   and six starred chips in a row read as busy. They use the standard chip style. */

/* the high-protein shelf on the homepage — same module as the old quick-buy row */
.qb-inline-sub { color: var(--ink-soft); max-width: 52ch; margin: .5rem 0 1.6rem; line-height: 1.6; }
.qb-media { position: relative; }
.qb-protein {
  position: absolute; left: .55rem; bottom: .55rem; z-index: 2;
  display: inline-flex; align-items: baseline; gap: .3em;
  font-family: var(--f-accent); font-size: .58rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink);
  background: rgba(244,237,225,.92); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: .4em .7em; border-radius: 100px; box-shadow: 0 4px 14px -6px rgba(20,14,7,.4);
}
.qb-protein b { font-family: var(--f-display); font-weight: 400; font-size: 1.28em; letter-spacing: 0; }
.qb-protein i { font-style: normal; opacity: .6; }
.qb-inline-more {
  display: inline-flex; align-items: center; gap: .45em; margin-top: 1.4rem;
  font-family: var(--f-accent); font-size: .72rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--maroon); text-decoration: underline;
  text-underline-offset: 4px;
}
.qb-inline-more:hover { color: var(--coral); }

/* The high-protein shelf uses the same board photography as the range cards, so its tiles
   fill edge-to-edge rather than floating a cutout on a tinted square. */
/* portrait, not square: the board shots are 3:4, and a 1:1 crop cut the jars off */



/* .footer-note also matches a generic rule carrying opacity:.8, which compounded with the
   alpha colour and pushed it back under contrast on the aqua footer */
.footer .footer-note { opacity: 1; }

/* ===== THE COMPARISON — evidence instead of claims ==============================
   Deliberately quiet: no "VS", no red crosses, no green ticks. Two lists, one hairline
   between them. The length difference is the argument; shouting would weaken it. */

/* ===== INGREDIENT LIST IN THE OVERLAY ========================================= */
.ov-ing { margin-top: 1.3rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.ov-ing[hidden] { display: none; }
.ov-ing-h { font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--maroon); margin-bottom: .5rem; }
.ov-ing-list { font-family: var(--f-display); font-size: 1.06rem; line-height: 1.5; color: var(--ink); }
.ov-ing-meta { margin-top: .6rem; font-size: .85rem; line-height: 1.55; color: var(--ink-soft); }
.ov-ing-meta b { font-weight: 600; color: var(--ink); }

/* ===== FILTER — one row, no modes ==============================================
   A mode toggle made people choose how to choose. Goals and categories now sit in the
   same scrollable row, separated by a hairline: guidance first, then the map. */
.fb-div { flex: none; width: 1px; align-self: stretch; margin: .35rem .85rem;
  background: var(--line); }
@media (max-width: 760px) { .fb-div { margin: .35rem .55rem; } }

/* Products the kitchen has taken off the menu. Hidden rather than deleted so bringing one
   back is a single attribute; they must never be orderable while marked. */
.prod-card[data-offmenu] { display: none !important; }

/* ===== THE PROTEIN SHELF ========================================================
   Redesigned 24 Aug 2026 ("the morning plate"). Three full-bleed photo cards, the
   protein figure overlaid at display scale on the image — the previous layout set
   transparent cut-outs beside the numbers and read as a spec sheet. Desktop: a
   three-across grid. Phone: a CSS-only scroll-snap strip, one card ~76vw with the
   next card peeking, because the section should feel like flipping through three
   small posters rather than scrolling past a table. */
.pshelf { margin-top: clamp(2.4rem, 5vw, 3.6rem); padding-top: clamp(1.8rem, 3.4vw, 2.4rem);
  border-top: 1px solid var(--line); }

.pshelf-head { max-width: 52ch; }
.pshelf-k { font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: var(--maroon); margin-bottom: .55rem; }
.pshelf-h { font-family: var(--f-display); font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  line-height: 1.04; letter-spacing: -.01em; margin-bottom: 0; }
.pshelf-h em { font-style: italic; color: var(--maroon); }
.pshelf-sub { margin-top: .6rem; color: var(--ink-soft); line-height: 1.6; max-width: 52ch;
  font-size: var(--step--1); }
.pshelf-sub .stars { color: var(--coral); }

.pcard-row { list-style: none; margin: clamp(1.1rem, 2.2vw, 1.8rem) 0 0; padding: 0;
  display: grid; gap: clamp(.9rem, 1.8vw, 1.3rem); }
.pcard-item { position: relative; }

.pcard { position: relative; display: block; border-radius: .65rem; overflow: hidden;
  aspect-ratio: 4 / 5; background: var(--sand); color: var(--paper); text-decoration: none;
  transform: translateZ(0); }
.pcard-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform .6s var(--ease); }
@media (hover: hover) { .pcard:hover .pcard-img { transform: scale(1.04); } }
/* legibility scrim — the number sits on photography, so it earns its own gradient
   top and bottom rather than trusting whatever the shot happens to be */
.pcard::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20,14,7,.38) 0%, transparent 32%, transparent 55%, rgba(20,14,7,.74) 100%); }

.pcard-num { position: absolute; top: .9rem; left: 1rem; z-index: 2; line-height: .9;
  font-family: var(--f-accent); color: var(--paper);
  text-shadow: 0 2px 16px rgba(20,14,7,.55); }
.pcard-num b { font-weight: 620; font-size: clamp(1.9rem, 4vw, 3.2rem); letter-spacing: -.02em; }
.pcard-num span { font-size: max(.72rem, 11.5px); font-weight: 500; letter-spacing: .08em;
  margin-left: .3em; opacity: .92; }

.pcard-meta { position: absolute; left: 1rem; right: 1rem; bottom: .95rem; z-index: 2; }
.pcard-name { font-family: var(--f-accent); font-weight: 600;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem); letter-spacing: .01em; }
.pcard-name .stars { color: var(--coral); }
.pcard-price { font-size: max(.78rem, 12.5px); opacity: .88; margin-top: .15em; }

/* add-to-basket floats on the card's bottom-right, OUTSIDE the <a> (a button inside a
   link is invalid and double-announces). 44px minimum met by padding. */
.pcard-add { position: absolute; right: .7rem; bottom: .7rem; z-index: 3;
  width: 44px; height: 44px; border-radius: 50%; border: none; cursor: pointer;
  display: grid; place-items: center; background: var(--paper); color: var(--ink);
  box-shadow: 0 8px 18px -8px rgba(33,27,23,.55);
  transition: background .28s var(--ease), color .28s var(--ease); }
.pcard-add svg { width: 17px; height: 17px; }
.pcard-add:hover { background: var(--ink); color: var(--paper); }

.pcard-hint { display: none; }

/* phone: swipeable snap strip */
@media (max-width: 719px) {
  .pcard-row { display: flex; gap: .8rem; margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter); overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter);
    scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .pcard-row::-webkit-scrollbar { display: none; }
  .pcard-item { flex: 0 0 min(62vw, 270px); scroll-snap-align: start; }
  .pcard-hint { display: block; margin-top: .9rem; text-align: right;
    font-family: var(--f-accent); font-size: max(.72rem, 11.5px); font-weight: 600;
    letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); }
  /* the hint is a touch affordance — pointless under a mouse */
  @media (hover: hover) and (pointer: fine) { .pcard-hint { display: none; } }
}
@media (min-width: 720px) { .pcard-row { grid-template-columns: repeat(3, 1fr); } }

.pshelf-foot { margin-top: clamp(1.2rem, 2.2vw, 1.7rem); font-size: .92rem; color: var(--ink-soft); }
.pshelf-foot a { font-family: var(--f-accent); font-size: .72rem; font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--maroon);
  text-decoration: underline; text-underline-offset: 4px; margin-left: .5rem; white-space: nowrap; }
.pshelf-foot a:hover { color: var(--coral); }

/* ===== COMPARISON — the conclusion moved to the top ==============================
   The payoff line ("eight times the almond") was set below the evidence in body-sized
   type, so the most persuasive sentence on the homepage was also the least visible.
   It now leads at display scale and the two ingredient lists become the proof beneath it. */

/* ===== THE 10x SECTION, 2026-08-21 ==============================================
   Full-bleed artwork with the copy layered on top as REAL TEXT. What this replaced
   was a two-column ingredient comparison that read like a spec sheet; the evidence
   it carried now lives on the almond milk product pages and the FAQ.

   The overlay sits in the ONE part of the artwork that is flat enough to hold type.
   I sampled local contrast across an 8x6 grid of the image: the lower-right quadrant
   measures 4.0-6.4 std-dev against 34-85 everywhere else, because it is empty cream
   to the right of the carton. Every other candidate area already carries the baked-in
   "10X", the script line, or the three roundels. If the artwork is ever re-cropped,
   re-measure before trusting this position.
   =============================================================================== */
/* The bleed below uses 100vw, which counts the desktop scrollbar, so the section
   ancestor must clip. `clip` (not `hidden`) does not create a scroll container, so
   it cannot break sticky or anchor behaviour elsewhere in the section. */
#range { overflow-x: clip; }
/* THE SECTION carries the bleed, not the figure. That matters: .tenx-copy is positioned
   with percentages, and it must resolve them against the SAME box the artwork occupies.
   When only the figure was full-bleed, the copy was still positioned against the narrow
   content column, so "right: 4%" landed ~4% of a 1100px column instead of 4% of the
   viewport — pushing the text left, onto the carton. */
.tenx { position: relative; margin-top: clamp(3rem, 6vw, 4.5rem);
  margin-inline: calc(50% - 50vw); width: 100vw; }
.tenx-shot { margin: 0; }
.tenx-shot img { display: block; width: 100%; height: auto; }

/* THE HIERARCHY IS THE ARGUMENT (see renderCompare in build/build.mjs).
   Percentage, then grams, then the comparison — sized so they are read in that order
   whether or not anyone chooses to read them. The number is set several steps larger
   than any other heading in the section because it is doing the work of a poster.

   text-transform on .tenx-h-w and .tenx-g is CSS, not baked into the markup, so the
   underlying text stays natural case: selectable, translatable, and read normally by
   screen readers rather than spelled out letter by letter. */
.tenx-h { font-family: var(--f-display); font-weight: 400; color: var(--ink);
  text-transform: none; display: flex; flex-direction: column; align-items: start;
  font-size: clamp(3.1rem, 6.6vw, 4.9rem); line-height: .9; letter-spacing: -.035em;
  margin: 0; }
/* The big number is the grams (the percentage is painted on the wall, in the artwork).
   The word-line under it wraps to two lines at the copy width; line-height covers that. */
.tenx-h-w { font-family: var(--f-accent); font-weight: 600; font-size: .2em;
  letter-spacing: .16em; text-transform: uppercase; line-height: 1.35;
  margin-top: .5em; color: var(--maroon); max-width: 16ch; }
.tenx-vs { font-size: .82rem; color: var(--ink-soft); margin: .9rem 0 1.25rem;
  line-height: 1.35; text-wrap: balance; }
.tenx-cta { align-self: start; }

/* MOBILE FIRST: the copy sits on paper under the artwork, and only gets lifted onto the
   image where the image is big enough to hold it. See the breakpoint note below — that
   threshold moved from 900px to 1200px on 22 Aug 2026 and the reason is measured. */
.tenx-copy { display: flex; flex-direction: column;
  padding: clamp(1.5rem, 5vw, 2rem) var(--gutter) 0; }
@media (max-width: 899px) { .tenx-copy { padding-inline: clamp(1rem, 5vw, 2rem); } }

/* DESKTOP: lift the same markup onto the artwork's clean quadrant. Percentages, not
   pixels, so it tracks the image as it scales.

   THE 1200px THRESHOLD IS MEASURED, NOT PICKED. Sampling tenx-hero.webp per 5% band,
   the quadrant that is genuinely clean enough to set --ink type on runs x 75-100% and
   y 40-85% — minimum luminance >= 180 throughout, which is 8:1 against --ink. Outside
   that window it falls to 56 (bottle edge, left) and 62 (dark base, bottom), where the
   same type sits at 1.5:1 and is simply unreadable.

   So the usable height is 45% of the image, and the image is 0.5578 x viewport wide:
   the copy may be no taller than ~0.251 x viewport. The three-element block runs ~250px,
   which needs ~1000px of viewport, and 1200 leaves honest headroom for a longer grams
   line or a translated string. Below it the copy goes back on paper under the image,
   where the type can stay poster-sized instead of being shrunk to fit.

   IF THE ARTWORK IS EVER REPLACED, RE-MEASURE. Both numbers here are properties of
   this file, not of the layout. */
@media (min-width: 1200px) {
  .tenx-copy {
    position: absolute; z-index: 2; padding: 0;
    /* top 44%, not 50%: the block hangs DOWN from its anchor, so it is aligned to the
       top of the clean band (40%) plus a little air, not to the middle of the image. */
    right: 5%; top: 44%; width: min(20%, 19rem);
  }
}

/* Honeypot. Hidden from people and from assistive tech, visible to naive bots.
   Not display:none — some bots skip those; this is off-screen but focusable-by-nothing. */
.hp-field { position: absolute !important; left: -9999px !important; width: 1px; height: 1px;
  opacity: 0; pointer-events: none; }

/* =====================================================================
   THE STORY — one composition, three stages (2026-07-28)
   Replaces the old .range grid + .pshelf + .cmp + .manifesto stack.

   The fault those four shared was rhythm, not decoration: each opened with
   an identical eyebrow -> serif headline -> grey sub on its own tinted band,
   so the page reset the reader's attention three times over. Here ONE
   background runs the whole height, and stages one and two share one grid
   (rail + flow) so the interface persists while only its contents change.
   Stage three releases to full width as the resolution.

   Old .pshelf / .cmp / .rng-* / .manifesto rules above are now dead; they are
   left in place for a separate CSS sweep. Nothing below depends on them.
   ===================================================================== */

.story {
  /* one continuous ground for all three stages — the single biggest reason
     the area stops reading as three separate pages */
  background: linear-gradient(180deg, var(--paper) 0%, var(--paper-2) 46%, var(--paper) 100%);
  padding-block: calc(var(--rhythm-lg) / 2);
  --rail: clamp(15rem, 25vw, 21rem);
}

.stage {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* Stages 1 and 2 are the SAME grid. That identity is the continuity device. */
.stage--shelf, .stage--proof {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.4rem);
}
@media (min-width: 900px) {
  .stage--shelf, .stage--proof { grid-template-columns: var(--rail) 1fr; }
}
/* Grid items default to min-width:auto, so .stage-flow refused to shrink below
   the intrinsic width of the mobile swipe row (6 x 63vw) and blew the whole
   page out to 1610px. This is the fix — without it, overflow-x:auto on .shelf
   cannot contain anything, because its parent has already grown. */
.stage--shelf > *, .stage--proof > *, .rail > * { min-width: 0; }
.stage--proof { margin-top: clamp(3.5rem, 7vw, 6rem); }
.stage--trust { margin-top: clamp(3.5rem, 7vw, 6rem); }

.story-k {
  font-family: var(--f-accent); font-size: .66rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: var(--maroon); margin: 0;
}
.stage-head { max-width: 34rem; }   /* rem, not ch: ch here resolves at body size, not headline size */
.stage-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.9rem, 4.2vw, 3.1rem); line-height: 1.03; letter-spacing: -.01em;
  margin: .75rem 0 0; text-wrap: balance;
}
.stage-h em { font-style: italic; color: var(--maroon); }
.stage-sub { color: var(--ink-soft); line-height: 1.62; margin: 1rem 0 0; max-width: 40ch; }

.stage-cta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.6rem;
  margin: clamp(1.8rem, 3.5vw, 2.6rem) 0 0;
}
.stage-alt {
  font-family: var(--f-accent); font-size: .72rem; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--maroon); text-decoration: underline;
  text-underline-offset: 4px;
}
.stage-alt:hover { color: var(--coral); }

/* ---------------------------------------------------------- THE RAIL */
/* Sticky for the height of its stage, so whichever product you point at, its
   detail is already on screen. No click, no modal, no navigation. */
.rail { position: relative; }
@media (min-width: 900px) {
  .rail { position: sticky; top: clamp(5rem, 12vh, 8rem); align-self: start; }
}
.rail-media {
  aspect-ratio: 4 / 5; border-radius: 6px; overflow: hidden; background: var(--sand);
  box-shadow: 0 18px 40px -24px rgba(33, 27, 23, .5);
}
.rail-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: opacity .34s var(--ease);
}
.rail.is-swapping .rail-media img { opacity: 0; }

.rail-cat {
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); margin: 1.1rem 0 0;
}
.rail-name { font-family: var(--f-display); font-size: var(--step-1); text-transform: lowercase;
  margin: .3rem 0 0; line-height: 1.05; font-weight: 400; }
.rail-name a { color: inherit; text-decoration: none; }
.rail-name a:hover { text-decoration: underline; text-underline-offset: 4px; }
.rail-desc { color: var(--ink-soft); font-size: .92rem; line-height: 1.55; margin: .55rem 0 0; }

.rail-facts { margin: 1rem 0 0; display: grid; gap: .35rem; }
.rf { display: flex; align-items: baseline; gap: .6rem; }
.rf dt {
  font-family: var(--f-accent); font-size: .58rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--grey); min-width: 4.6em;
}
.rf dd { margin: 0; font-size: .95rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.rf dd b { font-family: var(--f-display); font-weight: 400; font-size: 1.25rem; }
.rf dd span { font-size: .8rem; color: var(--ink-soft); margin-left: .3em; }

.rail-ing { margin: .9rem 0 0; font-size: .84rem; line-height: 1.5; color: var(--ink-soft); }
.rail-ing > span:first-child {
  font-family: var(--f-accent); font-size: .58rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--grey); display: block; margin-bottom: .2rem;
}
/* the copy block crossfades as a unit when the active product changes */
.rail-copy { transition: opacity .26s var(--ease); }
.rail.is-swapping .rail-copy { opacity: 0; }

.rail-cta { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.2rem; margin: 1.3rem 0 0; }
.rail-view {
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--maroon); text-decoration: underline; text-underline-offset: 4px;
}
.rail-view:hover { color: var(--coral); }

/* stage two reuses the rail column for a still photograph */
.rail--still { margin: 0; }
.rail--still img {
  width: 100%; height: auto; display: block; border-radius: 6px;
  box-shadow: 0 18px 40px -24px rgba(33, 27, 23, .5);
}
.rail--still figcaption {
  margin-top: .8rem; font-size: .84rem; line-height: 1.5; color: var(--ink-soft);
  font-family: var(--f-display); font-style: italic;
}

/* ---------------------------------------------------------- THE SHELF */
.shelf {
  list-style: none; margin: clamp(1.8rem, 3.5vw, 2.6rem) 0 0; padding: 0;
  display: grid; gap: clamp(1.2rem, 2.4vw, 1.8rem);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 620px) { .shelf { grid-template-columns: repeat(3, 1fr); } }

.pod {
  position: relative; display: flex; flex-direction: column; height: 100%;
  background: var(--paper); border-radius: 6px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(33,27,23,.05), 0 10px 26px -20px rgba(33,27,23,.5);
  transition: transform .42s var(--ease), box-shadow .42s var(--ease);
}
@media (hover: hover) {
  .pod:hover, .pod:focus-within {
    transform: translateY(-5px);
    box-shadow: 0 2px 4px rgba(33,27,23,.06), 0 26px 46px -24px rgba(33,27,23,.62);
  }
}
.pod-media { display: block; aspect-ratio: 3 / 4; overflow: hidden; background: var(--sand); }
.pod-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .6s var(--ease);
}
@media (hover: hover) { .pod:hover .pod-media img { transform: scale(1.04); } }

.pod-body { padding: .85rem .9rem 1rem; display: flex; flex-direction: column; gap: .18rem; flex: 1; }
.pod-name { font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: var(--step-0); line-height: 1.1; margin: 0; }
.pod-name a { color: inherit; text-decoration: none; }
/* the whole pod is the hit area for the name link, so the card feels clickable
   without nesting one interactive element inside another */
.pod-name a::after { content: ""; position: absolute; inset: 0; }
.pod-name a:focus-visible { outline: none; }
.pod-name a:focus-visible::after { outline: 2px solid var(--coral); outline-offset: -3px; border-radius: 6px; }
.pod-cat {
  font-family: var(--f-accent); font-size: .55rem; font-weight: 600; letter-spacing: .15em;
  text-transform: uppercase; color: var(--grey); margin: 0;
}
.pod-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .7rem; margin: .45rem 0 0; }
.pod-protein { font-size: .8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.pod-protein b { font-family: var(--f-display); font-weight: 400; font-size: 1.15rem; color: var(--ink); }
.pod-protein i { font-style: normal; color: var(--grey); }
.pod-pack { font-size: .76rem; color: var(--grey); }
.pod-price { margin: .5rem 0 0; font-size: .9rem; color: var(--ink); }

/* Quick add sits above the card link and slides up on hover. It is always in the
   tab order and always visible on touch — the slide is a desktop nicety, never
   the only way to reach it. */
.pod-add {
  position: relative; z-index: 2; appearance: none; border: 0; cursor: pointer;
  width: 100%; padding: .72rem .9rem; background: var(--ink); color: var(--paper);
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; text-align: center;
  transition: background .3s var(--ease);
}
.pod-add:hover { background: var(--coral); }
@media (hover: hover) and (min-width: 620px) {
  .pod-add { position: absolute; left: 0; right: 0; bottom: 0;
    transform: translateY(101%); transition: transform .38s var(--ease), background .3s var(--ease); }
  .pod:hover .pod-add, .pod:focus-within .pod-add { transform: none; }
}

/* ---------------------------------------------------------- STAGE TWO */
.proof-figures {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem clamp(1.4rem, 4vw, 3rem);
  margin: clamp(1.8rem, 3.5vw, 2.6rem) 0 0;
}
.fig-n {
  font-family: var(--f-display); line-height: .84; margin: 0;
  display: flex; align-items: baseline; font-variant-numeric: tabular-nums;
}
.fig-n b { font-weight: 400; font-size: clamp(3.2rem, 9vw, 6rem); letter-spacing: -.03em; }
.fig-n span { font-size: clamp(1.2rem, 2.6vw, 2rem); color: var(--maroon); }
.fig-w {
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600; letter-spacing: .15em;
  text-transform: uppercase; color: var(--grey); margin: .6rem 0 0;
}
.fig--them .fig-n b, .fig--them .fig-n span { color: var(--grey); }
.fig-vs {
  font-family: var(--f-display); font-style: italic; font-size: 1.1rem;
  color: var(--ink-soft); margin: 0; align-self: center;
}
.proof-read {
  font-family: var(--f-display); font-size: clamp(1.15rem, 2.1vw, 1.6rem); line-height: 1.32;
  margin: clamp(1.4rem, 2.6vw, 2rem) 0 0; max-width: 30ch;
}

.proof-lists {
  display: grid; gap: clamp(1.6rem, 3vw, 2.6rem);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
}
@media (min-width: 700px) { .proof-lists { grid-template-columns: 1fr 1fr; } }
.plist-h {
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); margin: 0 0 .9rem;
}
.pills { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .45rem; }
.pill {
  font-family: var(--f-body); font-size: .86rem; padding: .42em .85em;
  border-radius: 999px; background: var(--paper); border: 1px solid var(--line);
  color: var(--ink); white-space: nowrap;
}
.pill--them { background: transparent; border-style: dashed; color: var(--ink-soft); }
/* staggered entrance, gated on .enhanced so a no-JS visitor sees them immediately */
.enhanced .pill { opacity: 0; transform: translateY(6px); }
.enhanced .is-in .pill {
  opacity: 1; transform: none;
  transition: opacity .42s var(--ease) calc(var(--i) * 55ms),
              transform .42s var(--ease) calc(var(--i) * 55ms);
}
.pills--rest { margin-top: .45rem; }

.pmore { margin-top: .55rem; }
.pmore summary {
  cursor: pointer; list-style: none; display: inline-block;
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--maroon);
  text-decoration: underline; text-underline-offset: 4px;
}
.pmore summary::-webkit-details-marker { display: none; }
.pmore summary:hover { color: var(--coral); }
.pmore .pmore-shut { display: none; }
.pmore[open] .pmore-open { display: none; }
.pmore[open] .pmore-shut { display: inline; }

.plist-c {
  margin: 1.1rem 0 0; font-family: var(--f-accent); font-size: .62rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--grey);
}
.plist-c b {
  font-family: var(--f-display); font-weight: 400; font-size: 1.5rem; color: var(--ink);
  letter-spacing: 0; margin-right: .3em; font-variant-numeric: tabular-nums;
}
.plist--theirs .plist-c b { color: var(--grey); }

/* ---------------------------------------------------------- STAGE THREE */
.trust-grid { display: grid; gap: clamp(2rem, 4vw, 3.4rem); align-items: center; }
@media (min-width: 860px) { .trust-grid { grid-template-columns: 1.05fr .95fr; } }
.trust-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(2.1rem, 5.4vw, 3.9rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .8rem 0 0; text-wrap: balance;
}
.trust-h em { font-style: italic; color: var(--maroon); }
.trust-p { color: var(--ink-soft); line-height: 1.62; margin: 1.2rem 0 0; max-width: 42ch; }

/* REMOVED 2026-08-03: a `.values` / `.value` tag-pill component that lived here —
   uppercase .62rem accent type, border-radius:999px, cream background.
   NOTHING USED IT. No HTML carried `class="values"`, and neither main.js nor the
   build generates it. But it sat 2,000 lines BELOW `.value` at line 1116, which is
   the about page's three value cards, so it won the cascade on every one of them:
   the cards rendered as giant pills with their body copy in uppercase letterspaced
   accent type, and the text spilled past the curved edge because the rounding
   assumed a one-line tag.
   A dead component was overriding a live one. If a tag pill is ever wanted back,
   name it for its block (`.trust-tag`) — `.value` is taken.
   `.trust-h`, `.trust-p` and `.trust-media` below/above are dead too, on the same
   check; left in place because they collide with nothing. */
.trust-media { margin: 0; }
.trust-media img {
  width: 100%; height: auto; display: block; border-radius: 6px;
  box-shadow: 0 20px 44px -26px rgba(33,27,23,.55);
}

/* ---------------------------------------------------------- MOBILE */
@media (max-width: 899px) {
  /* Designed, not stacked. The heading and shelf come FIRST and the rail
     follows as a detail panel for whatever card you last landed on — a product
     panel above the section title reads as an orphan. */
  .stage--shelf .stage-flow { order: -1; }
  .stage--shelf .rail { display: grid; grid-template-columns: 6.5rem 1fr; gap: 1rem; align-items: start; }
  .stage--shelf .rail-media { aspect-ratio: 3 / 4; }
  .stage--shelf .rail-cta { grid-column: 1 / -1; margin-top: .4rem; }
  .rail-ing { display: none; }
  .stage--shelf .rail-cat { margin-top: 0; }
}
@media (max-width: 619px) {
  /* the shelf swipes rather than stacking into a long column */
  .shelf {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 63vw;
    overflow-x: auto; scroll-snap-type: x mandatory;
    margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter);
    padding-bottom: .6rem; scrollbar-width: none;
  }
  .shelf::-webkit-scrollbar { display: none; }
  .shelf-item { scroll-snap-align: start; }
}

@media (prefers-reduced-motion: reduce) {
  .pod, .pod-media img, .rail-media img, .rail-copy { transition: none !important; }
  .pod-add { position: relative !important; transform: none !important; }
  .enhanced .pill { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* =====================================================================
   THE CATALOGUE — sections, lenses, wayfinding (2026-07-28)
   Replaces the 16-chip .filter-bar + single flat .prod-grid.

   Controls (temporary lenses + persistent dietary) sit above; the section
   nav below them is wayfinding ONLY and never filters. The catalogue is
   nine permanent sections. A lens thins each section in place rather than
   flattening everything into one list, so the cross-category spread of a
   collection stays visible.

   The old .filter-bar / .fb-goal / .cat-lede / .quiz-band rules this replaced
   were removed in the 2026-08-01 sweep. .filter-wrap is NOT dead — main.js
   still queries it for the goal chips. .feta-feature is NOT dead either; it is
   live markup in index.html, despite an earlier note claiming otherwise.
   ===================================================================== */

/* PLAIN PAPER. This block carried the hero photograph blurred 26px under a 62%
   paper scrim until 2026-08-14, when it was removed on the founder's call.

   It was never really a picture by the end: behind a dense panel of small
   interactive text the image had to be beaten back so far that it read as beige
   noise, and it still cost a 248 KB download. The photo itself is not deleted —
   wholesale.html uses it properly, sharp and unscrimmed.

   Three rules existed ONLY to compensate for that backdrop and went with it:
   `.goal sup` forced to --ink-soft, non-centre `.cc-name` forced to --ink, and
   the ::before/::after layers themselves. Both tokens are back to their designed
   values, which are calibrated against --paper.

   overflow:hidden stays. It no longer has a blur to contain, but the carousel
   still relies on it to clip slides travelling past the block's edges. */
/* Bottom padding was 0, which pinned the dots to the block's edge: 10px below the
   carousel and 0px above the catalogue, so they touched the Range section and read
   as spilling out of the photo rather than belonging to the carousel. Now symmetric
   with the top, which gives the dots room before the cut. */
.cat-controls-wrap {
  padding-block: clamp(1.4rem, 3vw, 2.2rem);
  background: var(--paper);
  /* overflow was hidden for the category carousel's edge bleed; the carousel left
     with the filter-bar redesign, and hidden now CLIPPED the open dropdown menus
     into invisibility (caught on the live mobile audit, 24 Aug). */
  position: relative; overflow: visible; z-index: 30;
}
.cat-controls-wrap > .wrap { position: relative; z-index: 1; }
/* The backdrop is gone, so both of these are back to their designed tokens:
   .goal sup returns to --grey and the non-centre .cc-name to --ink-soft, which
   lets the coverflow's opacity fade read as depth again instead of being
   darkened to fight a photograph.
   Re-measured on plain --paper after the removal, 0 failures: goal label 14.63,
   count on an inactive pill 5.75, count on the active pill 8.67 (that one is
   --ink-soft by design, via `.goal.is-active sup`, not a backdrop compensation),
   browse eyebrow 8.67, off-centre carousel name 8.67. The old note here claimed
   --grey lands at "exactly 4.5:1" on paper; it measures 5.75. */

.controls {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem clamp(1rem, 3vw, 2.5rem);
  padding-bottom: 1rem; border-bottom: 1px solid var(--line);
}
.lenses { display: flex; flex-wrap: wrap; gap: .45rem; }

.lens {
  appearance: none; cursor: pointer; background: transparent;
  border: 1px solid var(--line); border-radius: 999px; color: var(--ink-soft);
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .11em;
  text-transform: lowercase; padding: .62em 1.05em; white-space: nowrap;
  transition: background .28s var(--ease), color .28s var(--ease), border-color .28s var(--ease);
}
.lens sup { font-size: .8em; color: var(--grey); margin-left: .25em; font-variant-numeric: tabular-nums; }
.lens:hover:not(:disabled) { border-color: var(--ink); color: var(--ink); }
.lens.is-active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.lens.is-active sup { color: var(--sand); }
/* Disabled, never hidden: removing a control the customer used last time is its
   own kind of broken. It stays, greyed, with an honest 0. */
.lens:disabled { cursor: not-allowed; opacity: .38; border-style: dashed; }

/* Dietary is a labelled GROUP, not a disclosure menu — a menu that opens to one
   checkbox promises contents it does not have. It becomes a menu when there is
   more than one real tag. */
/* REMOVED 2026-08-03: an inline dashed-pill dietary filter — `.diet`, `.diet-label`,
   and a FIRST `.diet-opt` (999px radius, accent type, lowercase, with a <sup> count
   and an .is-active state).
   NOTHING USED IT. No markup carries `class="diet"` or `.diet-label`; `.diet-opt` in
   products.html is the DROPDOWN row styled ~290 lines below, which uses aria-checked
   and a `.diet-tick`, never `.is-active` (the only is-active toggles in main.js are on
   `.lens` buttons and `.pod`s). The <sup> count rule was dead too.

   IT WAS NOT INERT. Its `.diet-opt:hover` set `color: var(--maroon)`, and the live
   rule's hover only sets `background` — so hovering a dietary row in the real menu
   turned the text maroon (#A54D4C) instead of staying ink (#211B17). Measured in the
   browser before removal. A dead component was tinting a live one through a partial
   property overlap, which is the quietest way this class of bug shows up.

   Same shape as the `.value` collision on the about page, opposite luck: there the
   dead block sat LATER and won outright; here it sat EARLIER and leaked only the
   properties the live block did not redeclare.
   `.diet-opt` belongs to the dropdown. Name any future filter pill `.diet-pill`. */

/* An active constraint is ANNOUNCED. Three jain products reduce the catalogue to
   one section, so a subtle marker could not explain what happened. */
.cat-state {
  margin: .9rem 0 0; font-size: .92rem; color: var(--ink);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem;
}
/* display:flex overrides the UA stylesheet's [hidden]{display:none} — without
   these two rules both panels render as empty boxes when they are "hidden". */
.cat-state[hidden], .cat-empty[hidden] { display: none; }
.cat-clear {
  appearance: none; background: none; border: 0; cursor: pointer; padding: 0;
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--maroon);
  text-decoration: underline; text-underline-offset: 4px;
}
.cat-clear:hover { color: var(--coral); }

/* ----------------------------------------------------- section nav (sticky) */
.secnav {
  position: sticky; top: 0; z-index: 40;
  display: flex; gap: .1rem; overflow-x: auto; scrollbar-width: none;
  margin-top: 0; padding: .7rem 0;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.secnav::-webkit-scrollbar { display: none; }
.secnav a {
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .1em;
  text-transform: lowercase; color: var(--ink-soft); text-decoration: none;
  padding: .5em .8em; border-radius: 999px; white-space: nowrap;
  transition: background .25s var(--ease), color .25s var(--ease);
}
.secnav a sup { font-size: .8em; color: var(--grey); margin-left: .2em; font-variant-numeric: tabular-nums; }
.secnav a:hover { color: var(--ink); }
.secnav a.is-here { background: var(--ink); color: var(--paper); }
.secnav a.is-here sup { color: var(--sand); }
/* A collapsed section stays on the map but is not a destination — otherwise the
   nav (and any inbound #anchor) scrolls to nothing. */
.secnav a.is-dead { opacity: .34; cursor: default; pointer-events: none; }

/* --------------------------------------------------------------- catalogue */
.catalogue { padding-top: clamp(1.6rem, 3vw, 2.4rem); }
.sec { padding-block: clamp(2.2rem, 5vw, 3.6rem); scroll-margin-top: 4.5rem; }
.sec + .sec { border-top: 1px solid var(--line); }
.sec[hidden] { display: none; }

.sec-head { max-width: 42rem; }
.sec-k {
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--maroon); margin: 0;
}
.sec-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.7rem, 3.6vw, 2.7rem); line-height: 1.04; letter-spacing: -.01em;
  margin: .6rem 0 0; text-wrap: balance;
}
.sec-desc { color: var(--ink-soft); line-height: 1.62; margin: .8rem 0 0; max-width: 52ch; }
/* PHONES ONLY: the range page carries three tiers of copy per category —
   .sec-k (the label), .sec-h (the tagline) and .sec-desc (the sub-copy). Nine
   categories x a 2-3 line paragraph is a lot of thumb travel before the reader
   reaches any actual product, so the third tier is dropped below 760px.

   display:none, NOT removal from the markup: the text still ships in the HTML,
   so it remains available to crawlers and to the desktop layout. Google indexes
   mobile-first and does discount visually hidden copy, which is the accepted
   cost here — the paragraphs are brand voice, not the terms anyone searches. */
@media (max-width: 760px) { .sec-desc { display: none; } }
.sec-count {
  margin: .9rem 0 0; font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .15em; text-transform: uppercase; color: var(--grey);
  font-variant-numeric: tabular-nums;
}

/* editorial header — only the two leading sections carry one */
.sec-ed {
  display: grid; gap: clamp(1.4rem, 3vw, 2.6rem); align-items: center;
  margin: clamp(1.6rem, 3vw, 2.4rem) 0 0;
  padding: clamp(1.4rem, 3vw, 2.2rem);
  background: var(--paper-2); border-radius: 6px;
}
@media (min-width: 820px) { .sec-ed { grid-template-columns: 1fr 1fr; } }
.sec-ed-media { margin: 0; }
/* The two editorial photos are different shapes (one 3:2, one near-square), so a
   fixed ratio is what keeps the two leading sections looking like a pair rather
   than two accidents. It also stops a tall source image dominating the section. */
.sec-ed-media img {
  /* height:auto is REQUIRED: without it the img's height="" attribute acts as a
     presentational hint and silently defeats aspect-ratio. */
  width: 100%; height: auto; display: block; border-radius: 4px;
  aspect-ratio: 4 / 3; object-fit: cover;
  box-shadow: 0 16px 36px -24px rgba(33,27,23,.55);
}
.sec-ed-claim {
  font-family: var(--f-display); font-size: clamp(1.8rem, 4vw, 2.8rem); line-height: 1;
  margin: 0; letter-spacing: -.02em;
}
.sec-ed-line { color: var(--ink-soft); line-height: 1.6; margin: .8rem 0 0; max-width: 40ch; }
.sec-ed-quote { margin: .9rem 0 0; }
.sec-ed-quote p {
  font-family: var(--f-display); font-size: clamp(1.05rem, 1.9vw, 1.35rem); line-height: 1.4;
  margin: 0; color: var(--ink);
}
.sec-ed-quote footer {
  margin-top: .55rem; font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-soft);
}

.sec .prod-grid { margin-top: clamp(1.4rem, 3vw, 2.2rem); }
.prod-card.is-hidden { display: none; }

.cat-empty {
  margin: 0 0 1.6rem; padding: 1.1rem 1.2rem; border: 1px dashed var(--line);
  border-radius: 5px; color: var(--ink-soft); font-size: .95rem;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem;
}

@media (max-width: 640px) {
  .controls { gap: .8rem; }
  .lenses { gap: .35rem; width: 100%; overflow-x: auto; flex-wrap: nowrap;
    scrollbar-width: none; padding-bottom: .2rem; }
  .lenses::-webkit-scrollbar { display: none; }
  .diet { width: 100%; }
  .sec-ed { padding: 1.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .lens, .diet-opt, .secnav a { transition: none !important; }
}

/* =====================================================================
   BROWSE BY GOALS + CATEGORY CAROUSEL (2026-07-28)
   Built to the supplied reference layout, in Break of Dawn's own type,
   colour and motion language. Replaces .controls / .lenses / .secnav.

   Motion brief still governs: soft, fast, never overburdened. Everything
   below animates transform/opacity only, so the carousel stays on the
   compositor at 60fps while dragging.
   ===================================================================== */

/* ------------------------------------------------------------- goals row */
.browse { padding-block: clamp(1.6rem, 4vw, 2.8rem) 0; }
/* width:100% / max-width:none because an inherited paragraph measure was
   shrinking this to 393px, so text-align:center centred it inside its own
   narrow box rather than across the row. */
.browse-k {
  font-family: var(--f-accent); font-size: .66rem; font-weight: 600; letter-spacing: .26em;
  text-transform: uppercase; color: var(--ink-soft); text-align: center;
  margin: 0; width: 100%; max-width: none;
}
/* z-index 200: the carousel track carries will-change/transform during a drag,
   which creates a stacking context that painted OVER the open dropdown. Lifting
   the whole control bar keeps the menu a true floating panel. */
/* Above the carousel (z-index 1), BELOW the fixed nav (z-index 100). It was
   200, which painted the goals bar over the navigation and ate its taps. */
.browse { position: relative; z-index: 20; }
.browse-row {
  position: relative; display: flex; align-items: center; justify-content: center;
  gap: 0; margin-top: clamp(1rem, 2.4vw, 1.5rem);
}
.goals { display: flex; align-items: center; justify-content: center; gap: clamp(.15rem, 1.4vw, 1rem); }

/* Only the ACTIVE goal carries a filled pill; the rest are bare type, exactly
   as in the reference. The pill is --sand rather than ink so it reads as a
   quiet resting place, not a button. */
.goal {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1rem, 1.55vw, 1.28rem); line-height: 1; color: var(--ink);
  padding: .72em 1.35em; border-radius: 999px; white-space: nowrap;
  display: inline-flex; align-items: baseline; gap: .32em;
  transition: background .42s var(--ease), color .3s var(--ease), opacity .3s var(--ease);
}
.goal sup {
  font-family: var(--f-accent); font-size: .5em; font-weight: 600; color: var(--grey);
  font-variant-numeric: tabular-nums; transition: color .3s var(--ease);
}
.goal:hover:not(.is-active):not(:disabled) { background: color-mix(in srgb, var(--sand) 46%, transparent); }
.goal.is-active { background: var(--sand); }
.goal.is-active sup { color: var(--ink-soft); }
.goal:disabled { cursor: not-allowed; opacity: .3; }

/* ------------------------------------------------------- dietary dropdown */
/* In flow, not absolutely positioned: the goals and the dietary control are ONE
   bar, and pinning dietary to the right edge left a gulf between it and
   "essentials". A hairline divider separates the two jobs instead. */
.diet-wrap { position: relative; flex: 0 0 auto; }
.diet-name { font-family: var(--f-display); font-size: 1.02rem; font-weight: 400; text-transform: lowercase; }

/* ===== FILTER BAR (24 Aug 2026) ==================================================
   SHOP ALL · CATEGORY ▾ · GOALS ▾ · DIETARY ▾ · find your morning — one quiet row,
   replacing the goal pill parade and the category carousel. Dropdown panels reuse
   the dietary menu's skin (.diet-btn / .diet-menu); only layout is new. */
.fbar { display: flex; align-items: center; flex-wrap: wrap; gap: .55rem;
  padding-block: .35rem; }
.fdd { position: relative; }
.fdd-menu { min-width: 15rem; }
/* phones: a button-anchored panel overflows the viewport edge, so the menu anchors
   to the full bar instead and opens as a sheet beneath it */
@media (max-width: 560px) {
  .fbar { position: relative; }
  .fdd { position: static; }
  .fdd .fdd-menu { left: 0; right: 0; width: 100%; min-width: 0; }
}
/* menu rows speak the same voice as the goal pills — display serif, lowercase —
   instead of the utility font they had (user, 24 Aug: "aren't using the site font") */
.fdd-opt { display: flex; align-items: baseline; justify-content: space-between; gap: 1.2rem;
  width: 100%; padding: .62rem .85rem; border-radius: .5rem; text-decoration: none;
  font-family: var(--f-display); font-size: 1.05rem; font-weight: 400;
  text-transform: lowercase; color: var(--ink); }
.fdd-menu ul { display: grid; gap: .15rem; }
.fdd-opt:hover { background: color-mix(in srgb, var(--sand) 45%, transparent); }
/* goals inside the menu stack vertically and drop the pill look */
.goals--menu { display: grid; gap: .15rem; }
.goals--menu .goal { width: 100%; justify-content: space-between; border: none;
  background: none; border-radius: .5rem; padding: .6rem .85rem; }
.goals--menu .goal:hover { background: color-mix(in srgb, var(--sand) 45%, transparent); }
.goals--menu .goal.is-active { background: var(--ink); color: var(--paper); }
.fb-all { flex: none; }
.fbar-gap { flex: 1 1 auto; }
@media (max-width: 700px) {
  .fbar-gap { flex-basis: 100%; height: 0; }
  .quiz-start { margin-left: 0; }
}

.ctrl-div {
  width: 1px; align-self: stretch; margin-inline: clamp(.5rem, 1.4vw, 1.1rem);
  background: var(--line); flex: 0 0 auto;
}

/* .quiz-start rides the .diet-btn rules rather than cloning them: it sits in the
   same control row and must read as the same class of secondary control. A
   parallel component here is exactly how the .value and .diet-opt collisions
   started, so it shares the selector instead of duplicating the paint. */
.diet-btn,
.quiz-start {
  appearance: none; cursor: pointer;
  /* a soft off-white against the cream page, so it reads as the secondary
     control next to the goals rather than a sixth goal */
  position: relative; isolation: isolate;
  background: rgba(255, 252, 246, .55);
  border: 1px solid rgba(33, 27, 23, .09);
  border-top-color: rgba(255, 255, 255, .9);
  border-radius: 999px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    inset 0 -1px 0 rgba(33, 27, 23, .05),
    0 10px 24px -16px rgba(33, 27, 23, .4);
  -webkit-backdrop-filter: blur(16px) saturate(165%);
  backdrop-filter: blur(16px) saturate(165%);
  display: inline-flex; align-items: center; gap: .55em;
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(.95rem, 1.3vw, 1.1rem); color: var(--ink);
  padding: .6em 1.05em;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
/* the sheen: one diagonal highlight, no extra element, no layout cost */
.diet-btn::after,
.quiz-start::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  pointer-events: none;
  background: linear-gradient(118deg,
    rgba(255,255,255,.85) 0%, rgba(255,255,255,.22) 26%,
    transparent 52%, rgba(255,255,255,.4) 100%);
  opacity: .55; transition: opacity .4s var(--ease);
}
.diet-btn:hover, .diet-btn[aria-expanded="true"], .quiz-start:hover {
  background: rgba(255, 253, 249, .72);
  border-color: rgba(33, 27, 23, .14);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 14px 30px -16px rgba(33, 27, 23, .5);
}
.diet-btn:hover::after, .diet-btn[aria-expanded="true"]::after, .quiz-start:hover::after { opacity: .8; }
/* Unlike .diet-btn — which sits inside .diet-wrap — this is a DIRECT child of the
   flex .browse-row, so it is a flex item and shrinks below its content width.
   Without these it squeezed to 127px and wrapped "find your morning" onto three
   lines, making a 102px-tall button next to a 49px one. */
.quiz-start { flex: 0 0 auto; white-space: nowrap; }
/* the sun mark carries the accent, the way .diet-leaf does on its sibling */
.quiz-start svg {
  width: 1.05em; height: 1.05em; color: var(--maroon); flex: 0 0 auto;
  transition: transform .4s var(--ease);
}
.quiz-start:hover svg { transform: rotate(22deg); }
.diet-leaf { width: 1.05em; height: 1.05em; color: var(--maroon); flex: 0 0 auto; }
.diet-chev { width: .7em; height: .7em; color: var(--ink-soft); transition: transform .34s var(--ease); }
.diet-btn[aria-expanded="true"] .diet-chev { transform: rotate(180deg); }
.diet-btn.has-diet { border-color: var(--maroon); color: var(--maroon); }

/* LIQUID GLASS. Warm-tinted, not the usual cold white — a neutral frost on this
   paper reads as a foreign UI kit. The saturate() is what stops the blur going
   muddy over the cream. Falls back to a solid panel where backdrop-filter is
   unsupported, so it can never render as unreadable transparent text. */
.diet-menu {
  position: absolute; right: 0; top: calc(100% + .6rem); z-index: 60;
  min-width: 18.5rem; padding: .95rem 1rem 1rem;
  border-radius: 16px;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--paper) 70%, var(--line));
  border-top-color: rgba(255, 255, 255, .95);
  box-shadow: 0 1px 0 rgba(255,255,255,.9) inset,
              inset 0 -1px 0 rgba(33,27,23,.05),
              0 28px 60px -24px rgba(33,27,23,.5),
              0 2px 8px -4px rgba(33,27,23,.18);
  transform-origin: top right;
  isolation: isolate;
  opacity: 0; transform: translateY(-6px) scale(.97);
  transition: opacity .26s var(--ease), transform .3s var(--ease);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  /* The tint carries legibility on its own, and the blur is a bonus on top.
     backdrop-filter silently does nothing wherever compositing is unavailable
     (software rendering, some Android webviews) — and at a lower tint the
     carousel headings behind stayed READABLE through the menu. Glass may show
     shape and colour; it must never show words. */
  .diet-menu {
    background: color-mix(in srgb, var(--paper) 93%, transparent);
    -webkit-backdrop-filter: blur(26px) saturate(1.6);
    backdrop-filter: blur(26px) saturate(1.6);
  }
}
/* Panel sheen + a lit top edge. This is the part that was missing: glass is
   recognised by how it catches light along its edges, not by how much shows
   through it, which is why the tint can stay high AND still read as glass. */
.diet-menu::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  pointer-events: none;
  background: linear-gradient(126deg,
    rgba(255,255,255,.7) 0%, rgba(255,255,255,.14) 30%,
    transparent 58%, rgba(255,255,255,.28) 100%);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
}
.diet-menu[hidden] { display: none; }
.diet-menu.is-open { opacity: 1; transform: none; }
.diet-menu-k {
  font-family: var(--f-accent); font-size: .58rem; font-weight: 600; letter-spacing: .17em;
  text-transform: uppercase; color: var(--grey); margin: 0 0 .55rem;
}
.diet-menu ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.diet-opt {
  appearance: none; border: 0; cursor: pointer; background: transparent;
  width: 100%; display: flex; align-items: center; gap: .65rem;
  padding: .5rem .55rem; border-radius: 9px; text-align: left;
  font-family: var(--f-body); font-size: .95rem; color: var(--ink);
  transition: background .24s var(--ease);
}
.diet-opt:hover { background: color-mix(in srgb, var(--sand) 52%, transparent); }
.diet-tick {
  width: 1.05rem; height: 1.05rem; border-radius: 5px; flex: 0 0 auto;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--paper) 70%, transparent);
  position: relative; transition: background .26s var(--ease), border-color .26s var(--ease);
}
.diet-tick::after {
  content: ""; position: absolute; left: 50%; top: 46%;
  width: .3rem; height: .55rem; border: 2px solid var(--paper);
  border-top: 0; border-left: 0; border-radius: 1px;
  transform: translate(-50%, -50%) rotate(45deg) scale(.4); opacity: 0;
  transition: opacity .2s var(--ease), transform .26s var(--ease);
}
.diet-opt[aria-checked="true"] .diet-tick { background: var(--maroon); border-color: var(--maroon); }
.diet-opt[aria-checked="true"] .diet-tick::after { opacity: 1; transform: translate(-50%, -50%) rotate(45deg) scale(1); }
.diet-name { flex: 1; white-space: nowrap; }
.diet-n {
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600; color: var(--grey);
  font-variant-numeric: tabular-nums;
}
.diet-opt:disabled { cursor: not-allowed; }
.diet-opt:disabled .diet-name, .diet-opt:disabled .diet-tick { opacity: .42; }
.diet-n--soon {
  font-family: var(--f-accent); font-size: .55rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--grey); white-space: nowrap;
}
.diet-note {
  margin: .7rem 0 0; padding-top: .6rem; border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  font-size: .74rem; color: var(--grey);
}

/* --------------------------------------------------------- the carousel */
.cc { position: relative; z-index: 1; margin-top: clamp(1.4rem, 3vw, 2.2rem); }
/* A REAL SCROLLER since 2026-08-07, matching .flavour-scroll on the homepage.
   It was overflow:hidden with a JS-driven transform, which could only move a whole
   card per gesture. Native overflow-x hands momentum, rubber-band and snap to the
   browser's compositor. overflow-y is explicitly hidden so vertical intent still
   belongs to the page — `overflow-x:auto` alone would make BOTH axes scrollable. */
.cc-stage {
  position: relative;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;      /* a flick to the end must not page-navigate back */
  scrollbar-width: none;
  padding-block: clamp(1rem, 2.4vw, 1.8rem);
  /* the neighbours fade rather than being clipped by a hard edge */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.cc-stage::-webkit-scrollbar { display: none; }
.cc-track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center;
  cursor: grab;
}
.cc-track.is-dragging { cursor: grabbing; }
.cc-slide {
  flex: 0 0 auto; width: var(--cc-w, 15.5rem); padding-inline: clamp(.3rem, .7vw, .6rem);
  scroll-snap-align: center;
}

/* NO CARD. The product itself is the card — it floats on the page with its name
   above it and nothing drawn behind it. The tinted panel, its 20px radius and its
   shadow are all gone on purpose; the coverflow scale/elevation still does the
   depth work, so the effect survives without the box.
   The padding STAYS: with no panel to sit in, it is the only thing keeping the
   name, product and count from touching their neighbours. */
.cc-card {
  appearance: none; border: 0; cursor: pointer; width: 100%; display: block;
  background: none; border-radius: 0; box-shadow: none;
  padding: clamp(1.1rem, 2vw, 1.6rem) clamp(1rem, 1.8vw, 1.4rem) clamp(1.2rem, 2vw, 1.6rem);
  text-align: center;
}
.cc-name {
  display: block; font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.15rem, 1.9vw, 1.62rem); line-height: 1.05; color: var(--maroon);
  letter-spacing: -.01em;
}
.cc-art {
  display: grid; place-items: center; margin-top: clamp(.7rem, 1.6vw, 1.1rem);
  aspect-ratio: 1 / 1;
  /* NOT overflow:hidden — --art-scale may push a product a little past the box,
     and with the card panel gone there is no edge for it to break out of. The
     square box is still what keeps every card the same height. */
}
/* The art box MUST stay square whatever the product's proportions, because the card
   height is what keeps the carousel even. A tall bottle (303x1000) stretched the
   grid track to 668px and took its card to 833px against 264px for its neighbours,
   which pushed the card title up under the fixed nav.
   width/height:100% + object-fit:contain does NOT prevent that — the image's
   INTRINSIC size still sets the grid item's automatic minimum, so aspect-ratio
   loses. Capping with max-* while width/height stay auto is what actually holds
   the box. Art is always larger than the box, so nothing is ever upscaled. */
.cc-art img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  min-width: 0; min-height: 0; object-fit: contain; display: block;
  /* --art-scale evens out apparent product size (see renderCarousel). A transform
     deliberately, not a size change: it leaves the layout box untouched, so no
     value of it can make the cards uneven again. */
  transform: scale(var(--art-scale, 1));
}
/* PLACEHOLDER until the transparent art lands. Deliberately quiet — a dashed box
   with a label would shout "unfinished" on a premium page. Drop the file in and
   this rule stops applying. */
/* Deliberately empty. The transparent product art drops straight in here and
   nothing else moves — the box is already the right size. */
/* .cc-n (the visible product count) was removed 2026-07-30 — the card is the
   product and its name. The count survives in the button's aria-label. */

/* The click cue. Swiping used to navigate, so nothing had to advertise that a
   card was a destination; now it does. It occupies its space at all times
   (height is not animated) so revealing it cannot shift the card's layout. */
.cc-go {
  display: block; margin-top: .5rem;
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--maroon);
  opacity: 0; transition: opacity .35s var(--ease);
}
.cc-slide.is-centre .cc-go { opacity: 1; }
.cc-go-a { display: inline-block; transition: transform .35s var(--ease); }
@media (hover: hover) {
  .cc-slide.is-centre .cc-card:hover .cc-go-a { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .cc-go, .cc-go-a { transition: none !important; }
}

/* the centre card is larger and elevated; neighbours recede.
   JS sets --d (distance from centre) per slide; CSS owns every visual value,
   so the look is tunable without touching the script. */
.cc-slide .cc-card {
  transform: scale(calc(1 - .07 * var(--d, 0)));
  opacity: calc(1 - .22 * var(--d, 0));
  transition: transform .55s var(--ease), opacity .45s var(--ease);
}
/* No box-shadow on the centre card. With the panel removed the shadow has no
   object to sit under — it draws a soft dark ring around an empty rectangle,
   which reads as exactly the card we just took away. Scale and opacity carry
   the depth on their own. */
.cc-slide.is-centre .cc-card { transform: scale(1.1) translateZ(0); }
@media (hover: hover) {
  .cc-slide.is-centre .cc-card:hover { transform: scale(1.13) translateY(-4px); }
}
.cc-slide.is-centre .cc-name { color: var(--maroon); }
.cc-slide:not(.is-centre) .cc-name { color: var(--ink-soft); }
.cc-slide.is-far .cc-card { opacity: 0; pointer-events: none; }
@media (hover: hover) {
  .cc-slide:not(.is-centre) .cc-card:hover { opacity: 1; transform: scale(calc(1 - .07 * var(--d, 0) + .03)); }
}

.cc-arrow {
  position: absolute; top: 50%; z-index: 5; transform: translateY(-50%);
  appearance: none; cursor: pointer; width: 2.9rem; height: 2.9rem; border-radius: 50%;
  background: var(--paper); border: 1px solid var(--line); color: var(--ink);
  display: grid; place-items: center;
  box-shadow: 0 10px 24px -16px rgba(33,27,23,.5);
  transition: transform .3s var(--ease), border-color .3s var(--ease), opacity .3s var(--ease);
}
.cc-arrow svg { width: 1rem; height: 1rem; }
.cc-arrow:hover { border-color: var(--ink-soft); transform: translateY(-50%) scale(1.07); }
.cc-arrow:disabled { opacity: .28; cursor: default; }
.cc-arrow--prev { left: clamp(.25rem, 2vw, 1.5rem); }
.cc-arrow--next { right: clamp(.25rem, 2vw, 1.5rem); }

.cc-dots { display: flex; justify-content: center; gap: .5rem; margin-top: clamp(.6rem, 1.5vw, 1rem); }
.cc-dot {
  appearance: none; border: 0; cursor: pointer; padding: 0;
  width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 22%, transparent);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.cc-dot:hover { background: color-mix(in srgb, var(--ink) 40%, transparent); }
.cc-dot.is-on { background: var(--maroon); transform: scale(1.35); }

@media (max-width: 900px) { .cc-slide { width: var(--cc-w, 14rem); } .cc-arrow { display: none; } }
@media (max-width: 560px) { .cc-slide { width: var(--cc-w, 12.5rem); } }
@media (max-width: 1079px) {
  /* left-aligned and on its own line under the goals row. Centred beneath a
     left-aligned scroller read as an orphan. */
  /* Stacked, these sat flush at 0px — the goals row and the dietary pill already
     touched before the quiz trigger joined them. The dividers that did the
     separating on desktop are display:none here, so the gap has to come back. */
  /* Was flex-direction:column, which put the goals row, the dietary pill and
     the quiz trigger on three separate lines and cost ~110px of vertical space
     before any product was visible. The goals row still gets its own line (it
     scrolls horizontally); dietary and the quiz trigger now sit together. */
  .browse-row { flex-wrap: wrap; align-items: center; row-gap: .55rem; column-gap: .5rem; }
  .browse-row > .goals { flex: 1 0 100%; }
  .ctrl-div { display: none; }
  /* Stacked, .diet-wrap sits at the LEFT edge, but the menu is anchored right:0
     and is wider than its trigger — so it opened 166px off the left of a 375px
     screen with two of its rows unreachable. Pre-existing; it only had one live
     option to lose before. Anchor left here, and never let it exceed the
     viewport on the narrowest phones. */
  .diet-menu {
    right: auto; left: 0; transform-origin: top left;
    min-width: min(18.5rem, calc(100vw - 2rem));
  }
  .diet-wrap { align-self: flex-start; }
  .goals { width: 100%; overflow-x: auto; justify-content: flex-start;
    scrollbar-width: none; padding-inline: .2rem; }
  .goals::-webkit-scrollbar { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cc-slide .cc-card, .cc-track, .diet-menu, .goal, .cc-arrow, .cc-dot { transition: none !important; }
  .cc-stage { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------- perf */
/* The catalogue is 55 cards across nine sections. content-visibility lets the
   browser skip layout and paint for sections that are off screen, which is the
   single biggest win available here; contain-intrinsic-size keeps the scrollbar
   honest so nothing jumps as they come into view. */
/* ⚠️ THE PLACEHOLDER HEIGHT WAS 900px AND THE SECTIONS ARE NOWHERE NEAR IT.
   Measured 2026-08-07: a shelf is ~527px on desktop and ~636px on a phone, but
   every unrendered section was reserving 1042px. So each one COLLAPSED by ~515px
   the moment it rendered, yanking everything below it upward — nine times on the
   way down, shortening the document from 9,377px to 4,763px as you scrolled.
   That is what made this page feel glitchy: the content kept jumping out from
   under the cursor. contain-intrinsic-size was doing the exact opposite of the
   job the comment above claims for it.
   A shelf's height barely varies with card count (it is one horizontal row), so a
   per-breakpoint constant is accurate. `auto` still means the real size is
   remembered once measured; these numbers only have to carry the FIRST pass —
   which is the pass every new visitor gets.
   RE-MEASURE THESE if the card or shelf height ever changes.

   NOTE these are CONTENT heights. contain-intrinsic-size sizes the content box and
   the section's own padding is added on top (141px desktop, 83px phone), so the
   reserved total lands at ~537px and ~642px respectively — matching the real thing
   to the pixel. Measuring the TOTAL and using that is the easy mistake. */
.sec { content-visibility: auto; contain-intrinsic-size: auto 525px; } /* re-measured 24 Aug: real 608 total - 83 padding */
@media (min-width: 900px) { .sec { contain-intrinsic-size: auto 396px; } }
/* will-change is applied only WHILE dragging (see main.js). Leaving it on
   permanently keeps a compositor layer alive for the whole page life and was
   part of why scrolling felt heavy. */
/* The track no longer carries a transform — the stage scrolls — so there is
   nothing here to promote. Left as an explicit auto so no stale layer survives. */
.cc-track { will-change: auto; }

/* =====================================================================
   PRODUCT SHELVES (2026-07-28)
   Each category is a merchandised shelf: editorial column left, a row you
   browse sideways right. Replaces the full-width .prod-grid per section and
   the two .sec-ed editorial blocks, which are gone.

   THE SCROLLING IS NATIVE. .shelf-row is a real overflow container with
   scroll-snap, so momentum, trackpad, touch and keyboard all come from the
   browser. There is no custom scroll code in it, which is precisely why it
   cannot stutter, freeze or fight the page.
   ===================================================================== */

.sec {
  display: grid; gap: clamp(1.4rem, 3vw, 2.6rem);
  /* Tightened 2026-08-17. Was clamp(2.6rem, 5.5vw, 4.4rem) — 70px top AND bottom
     at desktop, which with .shelf-row's own 1.4rem bottom padding left ~163px of
     dead space between one shelf and the next section's heading. The 1px rule at
     .sec + .sec is what separates the sections; it does not need a void as well. */
  padding-block: clamp(1.7rem, 3.2vw, 2.6rem);
  scroll-margin-top: 4.5rem;
}
@media (min-width: 900px) {
  /* align-items:center vertically centres the editorial column against its
     shelf. It was `start`, which pinned the copy to the top of the row. */
  .sec { grid-template-columns: minmax(15rem, 22rem) minmax(0, 1fr); align-items: center; }
  /* The head used to be position:sticky with a top offset, so it tracked the
     scroll and drifted downward through its own section as you moved. Static:
     it stays exactly where it is laid out. */
  .sec-head { position: static; }
}
.sec + .sec { border-top: 1px solid color-mix(in srgb, var(--line) 62%, transparent); }

.sec-head { max-width: 34rem; text-align: left; }
.sec-desc { max-width: 34ch; }
.sec-count { margin-top: 1rem; }
.sec-count-w { color: var(--grey); }

/* ------------------------------------------------------------- the shelf */
.shelf-wrap { position: relative; min-width: 0; }
.shelf-row {
  list-style: none; margin: 0; padding: .35rem clamp(1rem, 4vw, 2.5rem) 1.4rem 0;
  display: flex; gap: clamp(.9rem, 1.8vw, 1.5rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.shelf-row::-webkit-scrollbar { display: none; }
.shelf-row > li { flex: 0 0 auto; width: clamp(9.5rem, 15vw, 12.5rem); scroll-snap-align: start; }
.shelf-row:focus-visible { outline: 2px solid var(--coral); outline-offset: 4px; border-radius: 6px; }
/* Mouse-only shelf controls. They exist because the wheel no longer moves a
   shelf: a vertical wheel belongs to the page, always. Quiet until you are over
   the row, and never rendered at all on touch, where the row already scrolls. */
.shelf-nav {
  position: absolute; top: 32%; z-index: 2;
  width: 38px; height: 38px; border-radius: 50%;
  display: none; place-items: center; cursor: pointer;
  border: 1px solid var(--line); color: var(--ink);
  background: color-mix(in srgb, var(--paper) 88%, #fff);
  box-shadow: 0 2px 5px rgba(33,27,23,.07), 0 14px 28px -18px rgba(33,27,23,.5);
  opacity: 0; transition: opacity .28s var(--ease), background .28s var(--ease);
}
.shelf-wrap.has-nav .shelf-nav { display: grid; }
.shelf-wrap:hover .shelf-nav, .shelf-wrap:focus-within .shelf-nav { opacity: 1; }
.shelf-nav:hover { background: var(--paper); border-color: var(--ink); }
.shelf-nav:disabled { opacity: 0 !important; pointer-events: none; }
.shelf-nav svg { width: 15px; height: 15px; display: block; }
.shelf-nav--prev { left: -8px; }
.shelf-nav--next { right: 2px; }
@media (prefers-reduced-motion: reduce) { .shelf-nav { transition: none !important; } }

/* the row fades out at the right edge so it reads as continuing, not clipped */
.shelf-wrap::after {
  content: ""; position: absolute; right: 0; top: 0; bottom: 1.4rem; width: clamp(1.5rem, 4vw, 3rem);
  background: linear-gradient(90deg, transparent, var(--paper));
  pointer-events: none;
}

/* ------------------------------------------------- cards, quieter + smaller */
.sec .prod-card {
  background: transparent; border-radius: 0; box-shadow: none;
  transition: transform .45s var(--ease);
}
.sec .prod-visual {
  border-radius: 10px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(33,27,23,.04), 0 10px 22px -18px rgba(33,27,23,.45);
  transition: box-shadow .45s var(--ease), transform .45s var(--ease);
}
@media (hover: hover) {
  .sec .prod-card:hover { transform: translateY(-4px); }
  .sec .prod-card:hover .prod-visual {
    box-shadow: 0 2px 4px rgba(33,27,23,.05), 0 22px 38px -22px rgba(33,27,23,.55);
  }
}
.sec .prod-info { padding: .8rem .1rem 0; gap: .15rem; }
/* Sized up across the board. The card art is small on purpose, but the
   name, category and price are the things a customer actually has to read,
   and at .5-.98rem they were failing anyone over about forty. */
.sec .prod-cat {
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--maroon);
}
.sec .prod-card h3 { font-size: 1.18rem; line-height: 1.14; margin-top: .18rem; }
.sec .prod-tag { display: none; }          /* the shelf is scanned, not read */
.sec .prod-price { margin-top: .35rem; font-size: 1rem; color: var(--ink); }

/* --------------------------------------------------------- atmosphere */
/* Warmth without ornament: the page breathes from paper into a slightly
   deeper tone and back, so the shelves sit in light rather than on a flat
   field. One gradient, no textures, no decorative marks. */
/* Flat --paper, matching .cat-controls-wrap above it and the body behind it.
   This carried a sand radial plus a paper -> paper-2 -> paper vertical fade,
   which put a visible seam directly under the carousel: the carousel sits on
   flat rgb(244,237,225) and the gradient started at rgb(242,233,220). Measured,
   not eyeballed. One flat ground reads as one page. */
.catalogue { background: var(--paper); }

@media (max-width: 899px) {
  .sec-head { position: static; }
  .shelf-row { padding-right: var(--gutter); }
}
@media (prefers-reduced-motion: reduce) {
  .sec .prod-card, .sec .prod-visual { transition: none !important; }
  .shelf-row { scroll-behavior: auto; }
}

/* =====================================================================
   RESULTS SHELF (2026-07-29)
   The answering view. Sections are for browsing sideways; a filter asks a
   question about the whole catalogue, so its answer is one labelled grid.
   Full width and gridded on purpose — the sideways shelf is the signature of
   "keep looking", and a result set is something you want to see all of.
   ===================================================================== */
.results { display: block; padding-block: clamp(1.8rem, 4vw, 3rem); scroll-margin-top: 4.5rem; }
.results[hidden] { display: none; }

.results-head {
  max-width: 46rem; margin-bottom: clamp(1.3rem, 2.8vw, 2rem);
}
.results-k {
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--maroon); margin: 0;
}
.results-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.9rem, 4.2vw, 3rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .5rem 0 0; text-wrap: balance;
}
.results-sub {
  margin: .55rem 0 0; color: var(--ink-soft); font-size: .98rem;
  font-family: var(--f-display); font-style: italic;
}
.results-sub[hidden] { display: none; }
.results-meta {
  margin: 1rem 0 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: .8rem;
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600; letter-spacing: .15em;
  text-transform: uppercase; color: var(--grey); font-variant-numeric: tabular-nums;
}
.results-grid { list-style: none; margin: 0; padding: 0; }

/* =====================================================================
   GIFTING (2026-07-29, rebuilt)
   Paper and aqua, like every other page. The first pass ran the whole thing
   on --award-bg charcoal on the theory that gold reads best against dark —
   true in isolation, wrong here: a full page of brown is not this brand, and
   the photographs are warm enough to carry the festivity by themselves.
   ===================================================================== */

/* ------------------------------------------------------------- the hero */
/* 100vh, filled, camera all the way back. svh as well as vh so mobile browser
   chrome cannot make it taller than the screen and push the copy off. */
.ghero {
  position: relative; height: 100vh; height: 100svh; min-height: 34rem;
  overflow: hidden; isolation: isolate; background: var(--award-bg);
  display: flex; align-items: flex-end;
}

.ghero-media { position: absolute; inset: 0; z-index: 0; }
/* cover at natural scale: fills the frame, nothing magnified. object-position
   sits low so the crop takes sky off the top rather than cutting the baskets. */
.ghero-img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%;
  display: block; transform-origin: 50% 62%;
  animation: gheroDrift 28s var(--ease) infinite alternate;
  will-change: transform;
}
/* A slow continuous drift, not a scroll-scrubbed zoom. It reads as a room you
   are standing in rather than a picture being operated, it keeps moving while
   the copy is read, and it never touches the scroll position. 4% of travel is
   the whole range — any more and it becomes the zoom that was rejected. */
@keyframes gheroDrift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.04) translate3d(-1.1%, -0.6%, 0); }
}

/* Legibility only where the words are: a corner wash on the lower left, and a
   thin top gradient so the transparent nav has something to sit on. The middle
   and right of the frame — where the baskets are — stay untouched. */
.ghero::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to top right, rgba(8,5,2,.82) 0%, rgba(8,5,2,.55) 26%, transparent 58%),
    linear-gradient(180deg, rgba(8,5,2,.5), transparent 22%);
}

.ghero-inner {
  position: relative; z-index: 2; width: 100%;
  max-width: var(--maxw); margin-inline: auto;
  padding: 0 var(--gutter) clamp(3.5rem, 11vh, 7rem);
}
/* bottom-left, off the subject */
.ghero-copy { max-width: 30rem; color: var(--paper); }
.ghero-k {
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .3em; text-transform: uppercase; color: var(--gold-lt);
  margin: 0 0 .9rem;
}
.ghero-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(2.2rem, 5.6vw, 4rem); line-height: 1; letter-spacing: -.02em;
  margin: 0; color: var(--paper); text-wrap: balance;
}
.ghero-sub {
  margin: .9rem 0 0; max-width: 26ch; line-height: 1.55; font-size: 1rem;
  color: color-mix(in srgb, var(--paper) 86%, transparent);
}
.ghero-cta { margin-top: 1.5rem; }

/* the copy arrives once, on load — it is an entrance, not a scroll effect */
.ghero-copy > * { animation: gheroRise .9s var(--ease) both; }
.ghero-copy > :nth-child(2) { animation-delay: .08s; }
.ghero-copy > :nth-child(3) { animation-delay: .16s; }
.ghero-copy > :nth-child(4) { animation-delay: .24s; }
@keyframes gheroRise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

.ghero-hint {
  position: absolute; z-index: 2; bottom: clamp(1.1rem, 3vh, 1.8rem);
  left: 50%; transform: translateX(-50%); margin: 0;
  font-family: var(--f-accent); font-size: .55rem; font-weight: 600;
  letter-spacing: .3em; text-transform: uppercase;
  color: color-mix(in srgb, var(--paper) 58%, transparent);
}
.ghero-hint span { display: inline-block; animation: gheroNudge 2.4s var(--ease) infinite; }
@keyframes gheroNudge {
  0%, 100% { transform: translateY(0); opacity: .7; }
  50%      { transform: translateY(5px); opacity: 1; }
}

@media (max-width: 720px) {
  .ghero-inner { padding-bottom: clamp(3rem, 9vh, 5rem); }
  .ghero-copy { max-width: none; }
  /* a portrait crop of a landscape room needs to hold the baskets, not the
     ceiling, so the framing shifts rather than the whole picture shrinking */
  .ghero-img { object-position: 56% 58%; }
  .ghero::before {
    background:
      linear-gradient(to top, rgba(8,5,2,.86) 0%, rgba(8,5,2,.5) 34%, transparent 66%),
      linear-gradient(180deg, rgba(8,5,2,.5), transparent 20%);
  }
  .ghero-hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ghero-img { animation: none; }
  .ghero-copy > * { animation: none; }
  .ghero-hint span { animation: none; }
}

/* --------------------------------------------------- the line it lands on */
.gline { background: var(--paper); padding-block: clamp(3rem, 7vw, 5.5rem); }
.gline-k {
  font-family: var(--f-accent); font-size: .62rem; font-weight: 600;
  letter-spacing: .26em; text-transform: uppercase; color: var(--maroon); margin: 0;
}
.gline-lead {
  font-family: var(--f-display); font-weight: 400;
  font-size: clamp(1.25rem, 2.6vw, 1.9rem); line-height: 1.3; letter-spacing: -.01em;
  margin: 1rem 0 0; max-width: 30ch; color: var(--ink);
}

/* =====================================================================
   LIQUID GLASS  (.lg)
   One primitive, reused. Built from the reference by taking it apart rather
   than copying it: what makes glass read as glass is not the blur, it is the
   stack of four cheap cues below. Only `backdrop-filter` is expensive, and it
   is the one thing that can silently fail.

     1  TINT      carries legibility on its own. This is the rule that matters:
                  backdrop-filter does nothing under software rendering, in
                  some Android webviews, or in headless — so if readability
                  depended on the blur, the text would be unreadable exactly
                  where you cannot see it happening.
     2  BLUR      + saturate, so colour bleeds through rather than grey mud.
     3  EDGE      a hairline that is brighter at the top than the bottom — glass
                  catches light on its top edge. This is the refraction cue.
     4  SHEEN     one soft diagonal highlight, and an inset top line for
                  thickness. Depth, without a second element.

   Deliberately NOT applied to the mobile menu: it sits on its own photographic
   wallpaper and the user explicitly ruled it out.
   ===================================================================== */
.lg {
  position: relative; isolation: isolate;
  background: rgba(24, 17, 10, .52);
  border: 1px solid rgba(255, 250, 242, .16);
  border-top-color: rgba(255, 250, 242, .30);
  border-radius: 999px;
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 242, .22),
    inset 0 -1px 0 rgba(0, 0, 0, .18),
    0 18px 40px -24px rgba(0, 0, 0, .7);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
/* the sheen. pointer-events none, no layout, one gradient. */
.lg::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  pointer-events: none;
  background: linear-gradient(115deg,
    rgba(255, 250, 242, .16) 0%, rgba(255, 250, 242, .04) 32%,
    transparent 55%, rgba(255, 250, 242, .07) 100%);
}
/* Where the glass sits on paper rather than on a photograph, the tint has to
   invert or light text on light glass is unreadable. */
.lg--light {
  background: rgba(255, 252, 246, .62);
  border-color: rgba(33, 27, 23, .10);
  border-top-color: rgba(255, 255, 255, .8);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .85),
    0 14px 34px -22px rgba(33, 27, 23, .45);
}
@media (prefers-reduced-motion: reduce) { .lg { transition: none !important; } }

/* ----------------------------------------------------------- the hampers */
/* Composition from product-grid-reference: dark full-bleed backdrop, editorial
   column left, glass markers right on the CTA's baseline, four light cards
   floating beneath. */
.hgrid { position: relative; overflow: hidden; isolation: isolate;
  padding-block: calc(var(--rhythm) / 2);
  background: var(--award-bg); }
.hgrid-bg { position: absolute; inset: 0; z-index: 0; }
.hgrid-bg img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: .5; }
/* the backdrop is a room, not a texture: it needs holding back so the cards
   read as the subject and the type stays legible over it */
.hgrid-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(16,11,6,.82), rgba(16,11,6,.9));
}
.hgrid-in { position: relative; z-index: 1; }

.hgrid-head {
  display: grid; gap: clamp(1.6rem, 4vw, 3rem); align-items: end;
  margin-bottom: clamp(2rem, 4.5vw, 3.2rem);
}
@media (min-width: 980px) { .hgrid-head { grid-template-columns: minmax(0, 1fr) auto; } }
.hgrid-intro { max-width: 30rem; }
.hgrid-k {
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .3em; text-transform: uppercase; color: var(--gold-lt); margin: 0 0 .8rem;
}
.hgrid-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(2rem, 4.6vw, 3.2rem); line-height: 1; letter-spacing: -.02em;
  margin: 0; color: var(--paper); text-wrap: balance;
}
.hgrid-sub {
  margin: .9rem 0 0; max-width: 30ch; line-height: 1.6; font-size: .98rem;
  color: color-mix(in srgb, var(--paper) 78%, transparent);
}
.hgrid-cta { margin-top: 1.4rem; }

/* glass marker bar */
.lg-markers { padding: .55rem .35rem; }
.lg-markers ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center;
}
.lg-markers li {
  display: flex; align-items: center; gap: .5em;
  padding: .35rem clamp(.7rem, 1.4vw, 1.1rem);
  font-family: var(--f-accent); font-size: .68rem; font-weight: 500;
  letter-spacing: .04em; color: color-mix(in srgb, var(--paper) 90%, transparent);
  white-space: nowrap;
}
.lg-markers li + li { border-left: 1px solid rgba(255, 250, 242, .14); }
.lg-markers svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--gold-lt); }
@media (max-width: 620px) {
  .lg-markers { border-radius: 14px; }
  .lg-markers ul { flex-direction: column; align-items: flex-start; }
  .lg-markers li + li { border-left: 0; border-top: 1px solid rgba(255, 250, 242, .14); width: 100%; }
}

/* ------------------------------------------------------------ the cards */
/* Four across, matching the reference's gutters and proportions. Fixed tracks
   rather than auto-fit so the cards never stretch when there are fewer. */
.hcards {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: clamp(.9rem, 1.7vw, 1.4rem);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1080px) { .hcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .hcards { grid-template-columns: minmax(0, 1fr); } }

.hcard > article {
  height: 100%; display: flex; flex-direction: column; overflow: hidden;
  background: var(--paper); border-radius: 10px;
  box-shadow: 0 2px 4px rgba(0,0,0,.16), 0 26px 50px -30px rgba(0,0,0,.7);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
@media (hover: hover) {
  .hcard:hover > article {
    transform: translateY(-5px);
    box-shadow: 0 3px 6px rgba(0,0,0,.18), 0 38px 68px -32px rgba(0,0,0,.78);
  }
}
.hcard-media { position: relative; overflow: hidden; }
.hcard-media img {
  width: 100%; height: auto; display: block;
  /* 4/3 -> 3/2: ~11% off the card height, and the hamper shots are wide
     arrangements that lose nothing from the shallower crop. */
  aspect-ratio: 3 / 2; object-fit: cover;
  transition: transform .7s var(--ease);
}
@media (hover: hover) { .hcard:hover .hcard-media img { transform: scale(1.05); } }

.hcard-body {
  flex: 1; display: flex; flex-direction: column;
  padding: clamp(.9rem, 1.6vw, 1.2rem);
}
.hcard-top { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; }
.hcard-name {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: 1.16rem; line-height: 1.1; margin: 0; color: var(--ink);
}
.hcard-price {
  margin: 0; flex: 0 0 auto;
  font-family: var(--f-accent); font-size: .66rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--maroon);
}
.hcard-desc {
  margin: .5rem 0 0; font-size: .89rem; line-height: 1.5; color: var(--ink-soft);
}
/* the metadata row. Confirmed facts, never counts: the reference's "7 Items /
   Serves 2-3" numbers do not exist for these hampers. */
/* Icon ABOVE the label, three equal columns — the reference's own arrangement,
   and the reason three labels fit a card this narrow. Inline they wrapped to
   two ragged lines. */
.hcard-meta {
  list-style: none; margin: .9rem 0 0; padding: .85rem 0 0;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem;
}
.hcard-meta li {
  display: flex; flex-direction: column; align-items: center; gap: .35em;
  text-align: center;
  font-family: var(--f-accent); font-size: .54rem; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--grey);
  line-height: 1.25;
}
.hcard-meta svg { width: 13px; height: 13px; flex: 0 0 auto; color: var(--maroon); }

.hcard-cta {
  margin-top: auto; align-self: flex-start;
  display: inline-flex; align-items: center; gap: .5em;
  margin-block-start: 1rem; padding: .7em 1.2em; border-radius: 999px;
  background: var(--ink); color: var(--paper);
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase;
  transition: background .35s var(--ease), transform .35s var(--ease);
}
.hcard-cta span { transition: transform .35s var(--ease); }
@media (hover: hover) {
  .hcard-cta:hover { background: var(--maroon); }
  .hcard-cta:hover span { transform: translateX(3px); }
}
.hgrid-note {
  margin: clamp(1.6rem, 3.5vw, 2.4rem) 0 0; max-width: 54ch;
  font-size: .86rem; line-height: 1.6;
  color: color-mix(in srgb, var(--paper) 52%, transparent);
}
/* The cards all read "on enquiry", so this is the shortest route from a price
   question to the answer. Near-full paper rather than the note's 52%: it has to
   read as a link against the photograph, not as more of the sentence. */
.hgrid-note-link {
  color: color-mix(in srgb, var(--paper) 92%, transparent);
  text-decoration: underline; text-underline-offset: .22em;
  text-decoration-color: color-mix(in srgb, var(--paper) 45%, transparent);
  white-space: nowrap;
}
.hgrid-note-link:hover { text-decoration-color: currentColor; }
@media (prefers-reduced-motion: reduce) {
  .hcard > article, .hcard-media img, .hcard-cta, .hcard-cta span { transition: none !important; }
}

/* --------------------------------------------------------- what goes in */
.gfill { background: var(--paper); padding-block: calc(var(--rhythm) / 2); }
.gfill-head { max-width: 40rem; }
.gfill-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.8rem, 4.2vw, 2.7rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .6rem 0 0;
}
.gfill-list {
  list-style: none; margin: clamp(1.5rem, 3.2vw, 2.2rem) 0 0; padding: 0;
  border-top: 1px solid var(--line);
}
.gfill-list a {
  display: grid; gap: .15rem .8rem; align-items: baseline;
  padding: clamp(.8rem, 1.7vw, 1.1rem) 0;
  border-bottom: 1px solid var(--line);
  transition: padding-left .35s var(--ease), color .35s var(--ease);
}
@media (min-width: 660px) { .gfill-list a { grid-template-columns: 13rem 1fr; } }
@media (hover: hover) { .gfill-list a:hover { padding-left: .7rem; color: var(--maroon); } }
.gfill-n {
  font-family: var(--f-display); font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  text-transform: lowercase; line-height: 1.1;
}
.gfill-d { color: var(--ink-soft); font-size: .92rem; line-height: 1.5; }

/* ---------------------------------------------------------- how it works */
.ghow { background: var(--aqua); padding-block: calc(var(--rhythm) / 2); }
.ghow .eyebrow { color: var(--maroon-deep); }
.ghow-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.8rem, 4.2vw, 2.7rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .6rem 0 0; color: var(--ink);
}
.ghow-steps {
  list-style: none; margin: clamp(1.6rem, 3.5vw, 2.4rem) 0 0; padding: 0;
  display: grid; gap: clamp(1.2rem, 2.5vw, 2rem);
}
@media (min-width: 780px) { .ghow-steps { grid-template-columns: repeat(3, 1fr); } }
.ghow-steps li { display: flex; gap: .9rem; align-items: flex-start; }
.ghow-steps p { margin: 0; line-height: 1.55; color: var(--ink); font-size: .95rem; max-width: 34ch; }
.ghow-n {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--maroon-deep); color: var(--maroon-deep);
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ghow-note {
  margin: clamp(1.5rem, 3.2vw, 2.2rem) 0 0; font-size: .88rem;
  color: var(--maroon-deep); max-width: 52ch;
}

/* ------------------------------------------------------------------- CTA */
.gcta { background: var(--paper); padding-block: calc(var(--rhythm) / 2); }
.gcta-in { text-align: center; }
.gcta-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.9rem, 4.6vw, 3rem); line-height: 1.02; margin: 0; color: var(--ink);
}
.gcta-sub { margin: .8rem auto 0; max-width: 34ch; color: var(--ink-soft); font-size: .98rem; }
.gcta-btns {
  margin-top: 1.5rem; display: flex; flex-wrap: wrap; gap: .9rem 1.5rem;
  align-items: center; justify-content: center;
}
.gcta-mail { color: var(--maroon); }

/* =====================================================================
   THE FIRECRACKER AND ITS SPARK
   Used in the top nav, the mobile menu and this page's own CTA. A burst
   rather than a literal cracker: at 14px a body-and-fuse drawing is mush,
   while a burst reads instantly beside lowercase type. Deliberately NOT the
   brand's own asterisk — that is the censorship motif ("the good s***"), and
   borrowing it as decoration muddles what it means everywhere else.
   ===================================================================== */
/* THERE IS NO ICON. A permanent mark under the nav item read as decoration
   rather than as an event; the burst is the whole idea, and it belongs to the
   moment of the click. The particles now originate from the centre of the
   word itself, which is why the link needs to be a positioning context. */
[data-spark] { position: relative; }

.spark-burst {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  pointer-events: none; z-index: 5;
}
.spark-burst i {
  position: absolute; left: 0; top: 0; width: 3px; height: 3px; margin: -1.5px;
  border-radius: 50%; background: var(--gold);
  animation: sparkOut var(--t, 320ms) cubic-bezier(.19,.68,.33,1) forwards;
}
.spark-burst i:nth-child(3n) { background: var(--coral); }
.spark-burst i:nth-child(4n) { width: 2px; height: 2px; margin: -1px; }
@keyframes sparkOut {
  from { transform: rotate(var(--a)) translateX(2px) scale(1);        opacity: 1; }
  to   { transform: rotate(var(--a)) translateX(var(--d)) scale(.25); opacity: 0; }
}
/* the mobile menu is large serif type, so the burst has to scale with it or it
   looks like dust next to a 2rem word */
.mm-list .spark-burst i { width: 5px; height: 5px; margin: -2.5px; }
@media (prefers-reduced-motion: reduce) {
  .spark-burst { display: none; }
  .hamper-fig img, .gfill-list a { transition: none !important; }
}

/* =====================================================================
   RANGE HEADER — full-bleed editorial (2026-07-30)
   Replaces the split copy-left / image-right header. The background belongs to
   the header alone; the catalogue below is untouched paper.
   ===================================================================== */
.rh {
  position: relative; display: flex; align-items: flex-end;
  overflow: hidden; isolation: isolate; background: var(--award-bg);
  /* The source is now LANDSCAPE (2752x1536, ratio 1.79) — replaced 2026-08-07.
     The previous shot was portrait (1086x1448), and everything here was
     compensation for that: `cover` had to scale a tall image ~1.33x just to fill
     the width, so only 38% of its height survived and the band had to grow to
     92vh to claw framing back. A landscape source in a landscape band crops
     barely at all, so the compensation is removed rather than left to stack on
     top of an image that does not need it. 72/78vh is still a generous editorial
     header — it is simply no longer paying for the wrong aspect ratio. */
  min-height: 72vh; min-height: 72svh;
}
@media (min-width: 900px) {
  .rh { min-height: 78vh; min-height: 78svh; }
}
.rh-media { position: absolute; inset: 0; z-index: 0; }
.rh-media img {
  width: 100%; height: 100%; display: block;
  /* 50% 50% now the source matches the band. The old 44%/34% values existed to
     drag a portrait crop down onto the products; centring a landscape shot keeps
     the room, the table and the spread all in frame. */
  object-fit: cover; object-position: 50% 50%;
}
/* A corner wash rather than a flat veil: the copy sits bottom-left, so the
   right of the frame stays bright and reads as photography. */
.rh::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to top right, rgba(10,7,3,.86) 0%, rgba(10,7,3,.5) 34%, transparent 66%),
    linear-gradient(180deg, rgba(10,7,3,.52), transparent 24%);
}
.rh-in {
  position: relative; z-index: 2;
  padding-top: clamp(7rem, 15vh, 10rem);
  padding-bottom: clamp(2.6rem, 6vh, 4rem);
  color: var(--paper);
}
.rh-k {
  font-family: var(--f-accent); font-size: .6rem; font-weight: 600;
  letter-spacing: .28em; text-transform: uppercase; color: var(--gold-lt);
  margin: 0 0 .9rem;
}
.rh-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(2.1rem, 5.2vw, 3.6rem); line-height: 1; letter-spacing: -.02em;
  margin: 0; color: var(--paper); text-wrap: balance;
}
.rh-h em { font-style: italic; color: var(--gold-lt); }
.rh-sub {
  margin: 1rem 0 0; max-width: 40ch; line-height: 1.6; font-size: 1rem;
  color: color-mix(in srgb, var(--paper) 84%, transparent);
}
/* the award, restated once, as type on glass */
.rh-award {
  display: inline-flex; align-items: center; gap: .7rem; margin: 1.5rem 0 0;
  padding: .5rem .95rem .5rem .55rem; border-radius: 999px;
  background: rgba(24,17,10,.5);
  border: 1px solid rgba(255,250,242,.18); border-top-color: rgba(255,250,242,.3);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  font-family: var(--f-accent); font-size: .58rem; letter-spacing: .1em;
  text-transform: uppercase; line-height: 1.5;
  color: color-mix(in srgb, var(--paper) 78%, transparent);
}
.rh-award b { color: var(--gold-lt); font-weight: 600; }
.rh-award-seal {
  width: 30px; height: 30px; border-radius: 50%; flex: 0 0 auto;
  background: radial-gradient(circle at 34% 30%, var(--gold-lt), var(--gold) 62%, #7d6229);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5);
}

@media (max-width: 720px) {
  /* a portrait viewport crops a landscape room hard, so the band gets taller
     again in proportion and the framing shifts onto the products */
  /* 72vh put the hero at ~610px on a 844px phone and past 900px on a tall one,
     which pushed "browse by goals" well below the fold. 60svh lands ~505-560px
     across current handsets — still an editorial header, but the controls are
     reachable without a long scroll. svh (small viewport) is the one that
     matters here: vh on mobile Safari measures the chrome-less viewport, so it
     over-reports by the height of the URL bar. */
  .rh { min-height: 60vh; min-height: 60svh; }
  .rh-media img { object-position: 54% 42%; }
  .rh-sub { max-width: none; }
  .rh::before {
    background:
      linear-gradient(to top, rgba(10,7,3,.88) 0%, rgba(10,7,3,.5) 38%, transparent 70%),
      linear-gradient(180deg, rgba(10,7,3,.5), transparent 20%);
  }
}

/* ---------------------------------------------- overlay quantity picker */
.ov-qty { display: flex; align-items: center; gap: .7rem; margin: 0 0 .9rem; }
.ov-qty label {
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase; color: var(--grey);
}
/* sized at the accessibility floor this project settled on for checkout
   controls (1.05rem / 44px), not the browser default */
.ov-qty select {
  appearance: none; cursor: pointer;
  font-family: var(--f-accent); font-size: 1.05rem; color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line); border-radius: 8px;
  padding: .5rem 2.2rem .5rem .8rem; min-height: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%234A4038' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .8rem center; background-size: 11px;
  transition: border-color .3s var(--ease);
}
.ov-qty select:hover { border-color: var(--ink-soft); }
.ov-qty select:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }

/* =====================================================================
   CORPORATE GIFTING (2026-07-30)
   A different reader from the rest of the page — someone buying forty, not
   one — so it gets its own quieter register: photograph left, a scannable
   list right, and no price anywhere, because there isn't one to state.
   ===================================================================== */
.gcorp { background: var(--paper-2); padding-block: calc(var(--rhythm) / 2); }
.gcorp-grid { display: grid; gap: clamp(1.8rem, 4vw, 3.4rem); align-items: center; }
@media (min-width: 940px) { .gcorp-grid { grid-template-columns: .92fr 1.08fr; } }
.gcorp-media { margin: 0; }
.gcorp-media img {
  width: 100%; height: auto; display: block;
  aspect-ratio: 4 / 3; object-fit: cover; border-radius: 8px;
  box-shadow: 0 2px 5px rgba(33,27,23,.06), 0 30px 56px -34px rgba(33,27,23,.55);
}
.gcorp-copy { min-width: 0; }
.gcorp-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.9rem, 4.2vw, 2.8rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .6rem 0 0;
}
.gcorp-sub {
  margin: .9rem 0 0; max-width: 46ch; line-height: 1.6; font-size: .98rem;
  color: var(--ink-soft);
}
.gcorp-list {
  list-style: none; margin: clamp(1.4rem, 3vw, 2rem) 0 0; padding: 0;
  display: grid; gap: 0;
}
.gcorp-list li {
  display: flex; align-items: flex-start; gap: .85rem;
  padding: .85rem 0; border-top: 1px solid var(--line);
}
.gcorp-list li:last-child { border-bottom: 1px solid var(--line); }
.gcorp-ico {
  flex: 0 0 auto; width: 2rem; height: 2rem; border-radius: 50%;
  display: grid; place-items: center; margin-top: .05rem;
  background: var(--paper); border: 1px solid var(--line); color: var(--maroon);
}
.gcorp-ico svg { width: 15px; height: 15px; display: block; }
.gcorp-list h3 {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: 1.12rem; line-height: 1.15; margin: 0; color: var(--ink);
}
.gcorp-list p { margin: .2rem 0 0; font-size: .9rem; line-height: 1.5; color: var(--ink-soft); }
.gcorp-note {
  margin: clamp(1.2rem, 2.6vw, 1.8rem) 0 0; max-width: 52ch;
  font-size: .88rem; line-height: 1.6; color: var(--grey);
}
.gcorp-actions {
  margin-top: 1.4rem; display: flex; flex-wrap: wrap; align-items: center; gap: .9rem 1.5rem;
}
.gcorp-mail { color: var(--maroon); }
@media (max-width: 939px) {
  /* the photograph leads on a phone: it is the proof that these get made in
     numbers, and it should not be buried under five list items */
  .gcorp-media { order: -1; }
}

/* ------------------------------------------------------ diwali date band
   The warm charcoal + gold pairing is the one the award band already uses,
   so the site has a single "this is the occasion" register rather than a
   second festive palette invented for one section. Revealed by main.js only
   while the date is still ahead. */
.gdiwali {
  background: var(--award-bg); color: var(--paper);
  padding-block: clamp(2.4rem, 5vw, 3.6rem);
  border-block: 1px solid rgba(198,160,82,.28);
}
.gdiwali[hidden] { display: none; }
.gdiwali-in {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: 1.6rem 2.6rem;
}
.gdiwali-copy { min-width: 0; flex: 1 1 26rem; }
.gdiwali-k { color: var(--gold-lt); margin: 0; }
.gdiwali-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.8rem, 4vw, 2.6rem); line-height: 1.04; letter-spacing: -.015em;
  margin: .5rem 0 0; color: var(--paper);
}
.gdiwali-sub {
  margin: .7rem 0 0; max-width: 46ch; line-height: 1.6;
  font-size: .96rem; color: rgba(244,237,225,.78);
}
.gdiwali-side {
  flex: 0 1 auto; display: flex; flex-direction: column;
  align-items: flex-start; gap: .9rem;
}
.gdiwali-count {
  margin: 0; font-family: var(--f-accent); font-weight: 600;
  font-size: var(--step--1); letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold-lt);
}
.gdiwali-count:empty { display: none; }

/* ------------------------------------------------- corporate brief (form) */
.gbrief { background: var(--paper-2); padding-block: calc(var(--rhythm) / 2); }
.gbrief-in { display: grid; gap: clamp(1.8rem, 4vw, 3.4rem); align-items: start; }
@media (min-width: 940px) { .gbrief-in { grid-template-columns: .85fr 1.15fr; } }
.gbrief-copy { min-width: 0; }
.gbrief-h {
  font-family: var(--f-display); font-weight: 400; text-transform: lowercase;
  font-size: clamp(1.9rem, 4.2vw, 2.8rem); line-height: 1.02; letter-spacing: -.015em;
  margin: .6rem 0 0;
}
.gbrief-sub { margin: .8rem 0 0; color: var(--ink-soft); font-size: .98rem; line-height: 1.6; max-width: 38ch; }
.gbrief-pts { list-style: none; margin: 1.4rem 0 0; padding: 0; }
.gbrief-pts li {
  position: relative; padding: .42rem 0 .42rem 1.1rem;
  font-size: .92rem; line-height: 1.5; color: var(--ink);
}
.gbrief-pts li::before {
  content: ""; position: absolute; left: 0; top: .92em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--maroon);
}
.gbrief-alt { margin: 1.3rem 0 0; font-size: .9rem; color: var(--ink-soft); }
.gbrief-alt .link { color: var(--maroon); }
.gbrief-form { min-width: 0; }
/* two selects side by side were touching at 375px (user, 24 Aug) */
@media (max-width: 640px) { .gbrief-form .co-row { grid-template-columns: 1fr; } }

/* ------------------------------------------ hamper card: two ways to act */
.hcard-actions {
  margin-top: auto; padding-top: .85rem;
  /* nowrap keeps "enquire" beside "build this hamper" instead of dropping it
     to its own line, which is what made the cards tall. Both are allowed to
     shrink, and neither breaks its own label. */
  display: flex; flex-wrap: nowrap; align-items: center; gap: .5rem;
}
.hcard-actions > * { min-width: 0; white-space: nowrap; }
.hcard-actions .hcard-cta { margin-top: 0; margin-block-start: 0; }
.hcard-add {
  appearance: none; cursor: pointer;
  display: inline-flex; align-items: center;
  padding: .7em 1.05em; border-radius: 999px;
  background: var(--coral); color: var(--ink); border: 0;   /* paper on coral is 2.94:1 */
  font-family: var(--f-accent); font-size: .64rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase;
  transition: background .35s var(--ease);
}
.hcard-add:hover { background: var(--maroon); }

/* an unpriced line in the totals, and the sentence that explains it */
.co-line--open span:last-child {
  font-family: var(--f-accent); font-size: .68rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--maroon);
}
.co-open-note {
  margin: .7rem 0 0; font-size: .82rem; line-height: 1.5; color: var(--grey);
}

/* ------------------------------------------------------- hamper picker
   A hamper has no price because the customer chooses its contents, so
   "add to basket" opens this first. Blurred backdrop + a light glass panel;
   per the glass rule the TINT carries legibility, the blur is atmosphere only. */
.hp { position: fixed; inset: 0; z-index: 140; display: grid; place-items: center;
  padding: clamp(.8rem, 3vw, 2rem); }
.hp[hidden] { display: none; }
.hp-back { position: absolute; inset: 0; background: rgba(20, 14, 10, .52);
  -webkit-backdrop-filter: blur(9px); backdrop-filter: blur(9px); }
.hp-panel {
  position: relative; width: min(880px, 100%); max-height: min(86vh, 900px);
  display: flex; flex-direction: column; border-radius: 22px; overflow: hidden;
  box-shadow: 0 30px 70px -30px rgba(20, 14, 10, .6);
  /* High paper tint, same 93% the dietary menu settled on. Over a dark blurred
     backdrop a thinner glass reads grey rather than warm paper, and per the glass
     rule the tint — not the blur — is what has to carry legibility. */
  background: color-mix(in srgb, var(--paper) 93%, #fff);
}
.hp-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem) clamp(1.1rem, 2.4vw, 1.7rem) .5rem; }
.hp-k { font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--maroon); }
.hp-h { font-family: var(--f-display); font-size: clamp(1.4rem, 3vw, 1.9rem); line-height: 1.05;
  text-transform: lowercase; margin-top: .25rem; }
.hp-x { appearance: none; border: 0; background: none; cursor: pointer; font-size: 1.7rem;
  line-height: 1; color: var(--ink-soft); padding: .1em .3em; border-radius: 50%; }
.hp-x:hover { color: var(--ink); }
.hp-note { margin: 0 clamp(1.1rem, 2.4vw, 1.7rem) .9rem; color: var(--ink-soft); font-size: .92rem; }
.hp-body { overflow-y: auto; padding: 0 clamp(1.1rem, 2.4vw, 1.7rem) 1rem; }
.hp-group + .hp-group { margin-top: 1.4rem; }
.hp-group-h { font-family: var(--f-accent); font-size: .6rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); margin-bottom: .6rem; }
.hp-opts { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(122px, 1fr)); gap: .6rem; }
.hp-opt { appearance: none; cursor: pointer; width: 100%; text-align: left;
  display: flex; flex-direction: column; gap: .28rem; padding: .5rem .55rem .6rem;
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-radius: 14px;
  background: color-mix(in srgb, var(--paper) 62%, #fff); position: relative;
  transition: border-color .25s var(--ease), background .25s var(--ease); }
.hp-opt:hover { border-color: color-mix(in srgb, var(--ink) 26%, transparent); }
.hp-opt.is-on { border-color: var(--maroon); background: color-mix(in srgb, var(--maroon) 7%, #fff); }
.hp-opt-img { display: block; aspect-ratio: 1; border-radius: 9px; overflow: hidden;
  background: color-mix(in srgb, var(--paper) 70%, #fff); }
.hp-opt-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hp-opt-n { font-family: var(--f-display); font-size: .95rem; line-height: 1.12;
  text-transform: lowercase; color: var(--ink); }
.hp-opt-p { font-family: var(--f-accent); font-size: .58rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--grey); }
/* the running count sits on the tile so the choice is legible at a glance */
.hp-opt-q { position: absolute; top: .45rem; right: .45rem; min-width: 1.5em; height: 1.5em;
  display: grid; place-items: center; border-radius: 100px; font-family: var(--f-accent);
  font-size: .66rem; font-weight: 700; background: var(--maroon); color: var(--paper);
  opacity: 0; transform: scale(.6); transition: opacity .2s var(--ease), transform .2s var(--ease); }
.hp-opt.is-on .hp-opt-q { opacity: 1; transform: none; }
.hp-foot { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  flex-wrap: wrap; padding: .9rem clamp(1.1rem, 2.4vw, 1.7rem) clamp(1rem, 2.4vw, 1.4rem);
  border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); }
.hp-count { margin: 0; font-family: var(--f-accent); font-size: .74rem; letter-spacing: .05em;
  color: var(--ink-soft); }
.hp-done:disabled { opacity: .45; cursor: not-allowed; }
@media (max-width: 600px) {
  .hp-panel { max-height: 92vh; }
  .hp-opts { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
  .hp-foot .hp-done { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .hp-opt, .hp-opt-q { transition: none !important; }
}

/* =====================================================================
   Journal post pages (.jp-*)
   Generated by build/journal.mjs from data/journal.json.

   A recipe is read while doing something else — one hand on a whisk, phone
   propped against a jar. So the measure is narrow, the steps are numbered and
   generously spaced, and nothing here relies on hover to reveal itself.
   ===================================================================== */
.jp-narrow { max-width: 46rem; }
.jp-head { padding-bottom: clamp(1.4rem, 3vw, 2.2rem); background: var(--paper-2); }

.jp-back, .page-back { display: inline-flex; align-items: center; gap: .45em; margin-bottom: clamp(1.2rem, 3vw, 2rem);
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 600; letter-spacing: .04em;
  color: var(--teal); transition: gap .3s var(--ease), color .3s var(--ease); }
.jp-back:hover, .page-back:hover { gap: .8em; color: var(--coral-text); }
.page-back { text-decoration: none; }

.jp-title { font-family: var(--f-display); text-transform: lowercase; line-height: 1;
  font-size: clamp(2.4rem, 1.5rem + 4.4vw, 4.4rem); margin-top: .3rem; }
.jp-standfirst { margin-top: 1.1rem; max-width: 40ch; color: var(--ink-soft);
  font-size: var(--step-1); line-height: 1.5; }

/* meta strip — a <dl>, because "makes / 6 small kulfi" is genuinely a term and
   its definition, and screen readers then announce the pairing. */
.jp-meta { display: flex; flex-wrap: wrap; gap: clamp(1.4rem, 4vw, 3rem); margin-top: clamp(1.6rem, 3vw, 2.4rem);
  padding-top: 1.4rem; border-top: 1px solid var(--line); }
.jp-meta-item dt { font-family: var(--f-accent); font-size: .58rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); }
.jp-meta-item dd { margin-top: .3rem; font-size: var(--step-0); color: var(--ink); }

.jp-hero-wrap { margin-top: clamp(1.6rem, 4vw, 3rem); }
.jp-hero { border-radius: clamp(16px, 2vw, 24px); overflow: hidden; aspect-ratio: 3 / 2;
  background: color-mix(in srgb, var(--jc, var(--aqua)) 32%, var(--paper)); }
.jp-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }

.jp-bodywrap { padding-top: clamp(2rem, 5vw, 3.4rem); }
.jp-block { margin-bottom: clamp(2.2rem, 5vw, 3.4rem); }
.jp-h2 { font-family: var(--f-display); text-transform: lowercase; font-size: var(--step-2); line-height: 1.05;
  margin-bottom: 1rem; }
.jp-h2--small { font-size: var(--step-1); }
.jp-h3 { font-family: var(--f-accent); font-size: .62rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--maroon); margin: 1.5rem 0 .6rem; }
.jp-p { color: var(--ink-soft); font-size: var(--step-0); line-height: 1.7; max-width: 40ch; }
.jp-p + .jp-p { margin-top: .9rem; }

.jp-ing { list-style: none; display: grid; gap: .1rem; max-width: 36ch; }
.jp-ing li { position: relative; padding: .62em 0 .62em 1.5em; border-bottom: 1px solid var(--line);
  font-size: var(--step-0); line-height: 1.45; }
.jp-ing li::before { content: ""; position: absolute; left: .15em; top: 1.15em;
  width: .42em; height: .42em; border-radius: 50%; background: var(--aqua-deep); }
.jp-ing a { color: var(--teal); text-decoration: underline; text-underline-offset: .18em;
  text-decoration-thickness: 1px; text-decoration-color: var(--aqua-deep); }
.jp-ing a:hover { color: var(--coral-text); text-decoration-color: currentColor; }

/* Counter rather than a plain <ol> marker so the number can sit in its own
   column and the step text keeps a straight left edge over several lines. */
.jp-steps { list-style: none; counter-reset: jpstep; display: grid; gap: clamp(1.1rem, 2.4vw, 1.6rem); }
.jp-steps li { counter-increment: jpstep; position: relative; padding-left: 3.1rem;
  color: var(--ink-soft); font-size: var(--step-0); line-height: 1.7; max-width: 42ch; }
.jp-steps li::before { content: counter(jpstep); position: absolute; left: 0; top: -.1em;
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center; border-radius: 50%;
  background: var(--sand); color: var(--ink);
  font-family: var(--f-accent); font-size: .82rem; font-weight: 600; }
.jp-steps strong { color: var(--ink); font-weight: 600; }

.jp-notes { margin-bottom: clamp(2.2rem, 5vw, 3.4rem); padding: clamp(1.3rem, 3vw, 1.9rem);
  border-radius: clamp(12px, 1.6vw, 18px); background: var(--paper-2); border-left: 3px solid var(--aqua-deep); }
.jp-notes .jp-h2 { margin-bottom: .7rem; }
.jp-notes a { color: var(--teal); text-decoration: underline; text-underline-offset: .18em; }

.jp-uses { margin-bottom: clamp(2.2rem, 5vw, 3.4rem); }
.jp-uses-row { display: flex; flex-wrap: wrap; gap: .7rem; }
.jp-use { display: inline-flex; align-items: center; gap: .6em; padding: .7em 1.1em;
  border: 1px solid var(--line); border-radius: 100px; background: var(--paper-2);
  transition: border-color .3s var(--ease), transform .3s var(--ease); }
.jp-use:hover { border-color: var(--aqua-deep); transform: translateY(-2px); }
.jp-use-name { font-size: var(--step--1); color: var(--ink); }
.jp-use-go { color: var(--teal); }

.jp-next { display: flex; flex-wrap: wrap; align-items: baseline; gap: .8rem;
  padding-top: clamp(1.6rem, 3vw, 2.2rem); border-top: 1px solid var(--line); }
.jp-next-label { font-family: var(--f-accent); font-size: .58rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--grey); }
.jp-next-link { font-family: var(--f-display); text-transform: lowercase; font-size: var(--step-1);
  color: var(--ink); transition: color .3s var(--ease); }
.jp-next-link:hover { color: var(--coral-text); }

/* A post with no page yet is NOT an <a> — see build/journal.mjs. It still sits
   in the grid so the shape of the journal is honest, but it does not lift on
   hover and it does not pretend to be a link. */
.journal-card--soon { cursor: default; }
.journal-card--soon:hover { transform: none; box-shadow: none; }
.journal-more--soon { color: var(--grey); }

@media (prefers-reduced-motion: reduce) {
  .jp-back, .jp-use, .jp-next-link { transition: none; }
}

/* =====================================================================
   Touch targets — WCAG 2.2 AA (2.5.8)
   Measured at 320/375/430/768: standalone text links rendered 14–23px tall.
   Buttons were all fine; this is only the link-styled CTAs.

   Vertical padding, not min-height. On an inline element padding does not
   change the line box, so nothing reflows — but it IS part of the hit
   region, so the tap target grows. min-height would have needed
   display:inline-flex and that DOES move things.

   Scoped to (pointer: coarse) so mouse layouts are untouched.
   ===================================================================== */
@media (pointer: coarse) {
  .link, .sub-call, .rv-badge-link, .stockist-count,
  .pshelf-foot a, .footer-col a, .mm-mails a, .journal-note a,
  .jp-back, .cmp-head a, .footer-legal a, .feedback-link,
  .nav-logo { padding-block: 6px; }
  /* the footer list already has a .7rem gap, so the added padding sits inside it */
  .footer-col ul { gap: .45rem; }

  /* The carousel dots were the worst offenders on the whole site: ten 7px buttons in
     a row, 58 sub-24px targets on products.html alone. Padding cannot fix these —
     background-clip: content-box would keep the hit area but render the dot as a
     square, because border-radius follows the border box, not the clipped content
     box. So on touch the button grows to 25px and the visible 7px dot moves to a
     pseudo-element. The gap collapses to compensate, keeping the row the same width. */
  .cc-dots { gap: 0; }
  .cc-dot {
    width: 25px; height: 25px; background: none; position: relative; transform: none;
  }
  .cc-dot::before {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%;
    background: color-mix(in srgb, var(--ink) 22%, transparent);
    transition: background .3s var(--ease), transform .3s var(--ease);
  }
  .cc-dot:hover { background: none; }
  .cc-dot:hover::before { background: color-mix(in srgb, var(--ink) 40%, transparent); }
  .cc-dot.is-on { background: none; }
  .cc-dot.is-on::before { background: var(--maroon-deep); transform: scale(1.35); }
}

/* ==========================================================================
   PRODUCT PAGES  /products/<handle>
   The document half of the catalogue. products.html keeps its overlay; these
   are the same product as a real page with a real URL, and they reuse the
   catalogue's own visual language rather than inventing a second one — the
   tinted panel and the dome behind the bottle are lifted straight off
   .prod-visual / .prod-dome, driven by the same --c-top / --c-bot the card
   sets from products.csv.
   ========================================================================== */

/* The nav is `position: fixed`, so it is out of flow and reserves no space. The product
   page starts with these breadcrumbs, which therefore began at y=0 and sat squarely
   underneath it — measured at exactly 74px of overlap. Every other page opens with a hero
   that carries its own top offset, which is why only the product pages showed it.

   --nav-h is the nav at its tallest, measured rather than guessed: 74px at 375w and 100px
   at 1280w, because its padding is a clamp. Offsetting by the maximum clears it at every
   width, and the smaller clamp on top of it is the breathing room, not the clearance. */
.pdp-crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5em;
  font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .04em;
  color: var(--grey);
  padding-block: calc(var(--nav-h, 110px) + clamp(.5rem, 2vw, 1.5rem)) 0;
}
/* the back arrow takes the crumbs' first line to itself; the trail reads below it */
.pdp-back { flex-basis: 100%; margin-bottom: .15rem; }
.pdp-crumbs a { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.pdp-crumbs a.page-back { color: var(--teal); border-bottom: none; }
.pdp-crumbs a:hover { color: var(--ink); border-bottom-color: currentColor; }
.pdp-crumbs span { opacity: .5; }

.pdp {
  display: grid; gap: clamp(2rem, 5vw, 4.5rem);
  padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3.5rem, 8vw, 6rem);
  align-items: start;
}
/* THE PHOTOGRAPH IS THE PAGE. The catalogue card needs a tinted dome behind it, because a
   card is a small tile in a grid and the dome is what separates one from the next. A product
   page is not a tile: there is one photograph, it is the reason the visitor came, and the
   packshots already carry their own studio background.

   Stacking a second, differently-coloured backdrop underneath meant the photo rendered at
   just 28% of its natural width (261px from a 900px original) inside a 4:5 box it did not
   share an aspect ratio with. The tint, the dome and the glow are gone, and the image is
   simply shown at the width it is given.

   The catalogue cards are untouched — they keep the dome. */
.pdp-media {
  position: relative; overflow: hidden; border-radius: var(--radius);
  /* flex-START, not center. Once the image is capped by height it no longer fills the
     column, and centring left it floating mid-column with the page gutter on one side and
     a gap on the other — out of line with the breadcrumb, the heading and everything else
     on the page. Aligning to the start puts its left edge on the same gutter as the rest. */
  display: flex; align-items: flex-start; justify-content: flex-start;
  background: transparent;
}
.pdp-glow { display: none; }
/* The image fills its column; the COLUMN is what is capped (see the grid below). Capping
   the image by height instead was worse in two ways: `vh` means something different on every
   screen, and a height-capped image stopped filling its grid column, which left ~200px of
   dead space between the photograph and the text it belongs to. */
.pdp-media img {
  position: relative; z-index: 2;
  width: 100%; height: auto; max-width: 100%;
  object-fit: contain;
}
/* .pdp-img--round used to be border-radius:50% — on a 3:4 photograph that is an
   ELLIPSE, which is why truffle & chives looked "oval for some reason" (user, 24 Aug).
   The class stays in the markup; it just no longer distorts anything. */
.pdp-nophoto {
  position: relative; z-index: 2; margin-bottom: 18%;
  font-family: var(--f-accent); font-size: var(--step--1); color: var(--ink-soft); opacity: .7;
}

/* AFTER the base .pdp-media block on purpose: `position: relative` above is declared at the
   same specificity, so a sticky set earlier in the file would simply lose on source order. */
@media (min-width: 861px) {
  /* Not two equal halves. The packshots are 3:4 portraits, so an equal split made the image
     column taller than everything beside it. 380px sizes the photograph to sit level with
     the name, price and buttons, and it closes the gap between the columns: the image now
     ends where the grid gutter begins instead of 200px short of it.

     The pair is then capped and centred INSIDE the page container. `.wrap` is 1320px, but
     the product copy is short — a name, a line, a price, two buttons — so stretching the
     text column across whatever was left of 1320 left the whole block hugging the left edge
     with a river of empty paper to its right. Capping at 1040 keeps the text to a readable
     measure and puts the image and copy either side of the page's centre line. */
  .pdp { grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
         max-width: 1040px; margin-inline: auto; }
  .pdp-crumbs { max-width: 1040px; margin-inline: auto; }
  /* The photograph holds while the facts scroll past. The offset clears the fixed nav. */
  .pdp-media { position: sticky; top: 6.5rem; }
}

.pdp-body > * + * { margin-top: 1.15rem; }
.pdp-cat {
  font-family: var(--f-accent); font-size: var(--step--1);
  letter-spacing: .12em; text-transform: lowercase; color: var(--maroon);
}
.pdp-body h1 { font-size: var(--step-3); line-height: 1.02; margin-top: .3rem; }
.pdp-note { font-size: var(--step-1); line-height: 1.35; color: var(--ink-soft); }
.pdp-desc { font-size: var(--step-0); line-height: 1.6; color: var(--ink-soft); max-width: 38ch; }
.pdp-price { font-family: var(--f-accent); font-size: var(--step-1); color: var(--ink); }
/* The proof strip: the facts that decide the purchase, sat between the price and the
   button. Deliberately NOT a paragraph — a reader at this point is scanning, and three
   short facts separated by rules read faster than a sentence containing the same three.
   Contents are derived per product in pdp.mjs; this only styles them. */
/* the at-a-glance strip: an enclosed card of icon + headline + subline slots
   (founder's mock, 24 Aug 2026) */
.pdp-proof { list-style: none; display: flex; margin: 1.1rem 0 0; padding: .8rem .3rem;
  border: 1px solid var(--line); border-radius: .9rem;
  background: color-mix(in srgb, var(--sand) 26%, var(--paper)); }
.pdp-proof li { flex: 1 1 0; min-width: 0; display: flex; align-items: center;
  gap: .55rem; padding-inline: .7rem; }
.pdp-proof li + li { border-left: 1px solid var(--line); }
.pp-ico { flex: none; width: 2.1rem; height: 2.1rem; border-radius: 50%; display: grid;
  place-items: center; color: var(--maroon);
  background: color-mix(in srgb, var(--coral) 14%, var(--paper)); }
.pp-ico svg { width: 17px; height: 17px; }
.pp-txt { min-width: 0; }
.pp-txt b { display: block; font-family: var(--f-accent); font-size: max(.7rem, 11.5px);
  font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  line-height: 1.25; }
.pp-txt i { display: block; font-style: normal; font-size: max(.68rem, 11px);
  color: var(--ink-soft); line-height: 1.3; }
/* very small phones: icons alone start to crowd - stack each slot */
@media (max-width: 420px) {
  .pdp-proof { padding: .7rem .2rem; }
  .pdp-proof li { flex-direction: column; text-align: center; gap: .4rem; padding-inline: .45rem; }
}

.pdp-buy { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.6rem; }
/* phones: the buttons stack full-width instead of ragging to the left */
@media (max-width: 640px) {
  .pdp-buy { flex-direction: column; align-items: stretch; }
  .pdp-buy .btn { width: 100%; justify-content: center; }
}
.pdp-buynow { display: inline-flex; align-items: center; gap: .4rem; font-size: var(--step--1); }
.pdp-buynow:hover { border-color: var(--coral); color: var(--coral); }
.pdp-add { font-size: var(--step--1); }
.pdp-wa {
  display: inline-block; font-family: var(--f-accent); font-size: var(--step--1);
  color: var(--maroon); text-decoration: none; border-bottom: 1px solid currentColor;
}
.pdp-wa:hover { color: var(--ink); }
/* Subscribe is now a BUTTON sitting beside add-to-basket, not a quiet link underneath it.
   Almond milk is the one category people buy again every week, and the discount is real
   (5% at 15 bottles a month, 8% at 25), so it deserves to be seen at the moment of the
   decision rather than found afterwards. It is an outline button, not a second coral one:
   two primary buttons compete, and adding to the basket is still the main action. */
.pdp-sub {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: var(--step--1); text-decoration: none;
}
.pdp-sub:hover { border-color: var(--coral); color: var(--coral); }

.pdp-ing, .pdp-nutri {
  margin-top: 1rem; padding: 1.05rem 1.15rem;
  border: 1px solid var(--line); border-radius: .9rem;
}
.pdp-ing { margin-top: 1.8rem; }
.pdp-ing h2, .pdp-nutri h2, .pdp-facts h2 {
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 400;
  letter-spacing: .12em; text-transform: lowercase; color: var(--grey); margin-bottom: .6rem;
}
.pdp-ing p { font-size: var(--step-0); line-height: 1.6; max-width: 44ch; }

/* collapsible facts (24 Aug) — native <details>, summary is the section heading with a
   +/x mark. Content stays in the DOM (crawlers read it), the reader opens what they need. */
.pdp-fold summary { list-style: none; cursor: pointer; display: flex; align-items: center;
  justify-content: space-between; gap: 1rem; }
.pdp-fold summary::-webkit-details-marker { display: none; }
.pdp-fold summary h2 { margin-bottom: 0; }
.fold-mark { font-family: var(--f-accent); font-size: 1.15rem; font-weight: 500; line-height: 1;
  color: var(--maroon); transition: transform .3s var(--ease); }
.pdp-fold[open] .fold-mark { transform: rotate(45deg); }
.pdp-fold[open] summary { margin-bottom: .8rem; }
.pdp-fold summary:hover .fold-mark { color: var(--coral); }
@media (prefers-reduced-motion: reduce) { .fold-mark { transition: none; } }

/* Now a fold like its two neighbours; inside, each fact is one label/value line,
   which cannot go asymmetric no matter how many facts a product has (user, 24 Aug). */
.pdp-facts {
  margin: 1rem 0 0; padding: 1.05rem 1.15rem;
  border: 1px solid var(--line); border-radius: .9rem;
}
.pdp-facts-rows { margin: 0; display: flex; flex-direction: column; }
.pdp-facts-rows div { display: flex; align-items: baseline; justify-content: space-between;
  gap: 1.2rem; padding: .5rem 0; border-bottom: 1px solid var(--line); }
.pdp-facts-rows div:last-child { border-bottom: 0; padding-bottom: 0; }
.pdp-facts dt {
  font-family: var(--f-accent); font-size: max(.72rem, 11.5px); font-weight: 500;
  letter-spacing: .14em; text-transform: lowercase; color: var(--ink-soft);
}
.pdp-facts dd { font-size: var(--step-0); margin: 0; text-align: right; }

.pdp-tags { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.5rem; }
.pdp-tags span {
  font-family: var(--f-accent); font-size: var(--step--1); letter-spacing: .04em;
  padding: .3em .85em; border: 1px solid var(--line); border-radius: 100px; color: var(--ink-soft);
}

.pdp-nutri table { width: 100%; max-width: 26rem; border-collapse: collapse; }
.pdp-nutri caption {
  text-align: left; font-family: var(--f-accent); font-size: var(--step--1);
  color: var(--grey); padding-bottom: .5rem;
}
.pdp-nutri th, .pdp-nutri td {
  text-align: left; padding: .55rem 0; border-bottom: 1px solid var(--line);
  font-size: var(--step-0); font-weight: 400;
}
.pdp-nutri td { text-align: right; font-family: var(--f-accent); }
/* A figure the lab is re-checking reads as a sentence, never as a number and never as zero. */
.pdp-nutri .is-hold { color: var(--grey); font-size: var(--step--1); }
.pdp-nutri .is-hold span { opacity: .75; }

.pdp-pairs { margin-top: 2rem; font-size: var(--step-0); color: var(--ink-soft); }
.pdp-pairs span {
  font-family: var(--f-accent); font-size: var(--step--1);
  letter-spacing: .1em; color: var(--grey); margin-right: .4em;
}
.pdp-review {
  margin-top: 2rem; padding-left: 1.25rem; border-left: 2px solid var(--aqua);
  font-family: var(--f-display); font-size: var(--step-1); line-height: 1.35; color: var(--ink);
}
.pdp-review cite {
  display: block; margin-top: .6rem; font: 400 var(--step--1)/1.4 var(--f-accent);
  letter-spacing: .08em; color: var(--grey); font-style: normal;
}

/* ---- more from this range ---------------------------------------------- */
.pdp-more { padding-block: clamp(3rem, 7vw, 5.5rem); border-top: 1px solid var(--line); }
.pdp-more h2 {
  font-family: var(--f-accent); font-size: var(--step--1); font-weight: 400;
  letter-spacing: .12em; text-transform: lowercase; color: var(--grey); margin-bottom: 1.5rem;
}
.pdp-more-row {
  display: grid; gap: clamp(.75rem, 2vw, 1.5rem);
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
}
.pdp-more-card { text-decoration: none; color: inherit; display: block; }
.pdp-more-card img, .pdp-more-nophoto {
  /* height:auto is load-bearing: the img carries a height="" attribute (CLS), and with
     no CSS height the attribute wins over aspect-ratio — every thumb rendered 1200px
     tall, showing only a bottle neck. */
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: var(--radius); background: var(--paper-2);
  transition: transform .45s var(--ease);
}
.pdp-more-card:hover img { transform: translateY(-4px); }
.pdp-more-name { display: block; margin-top: .6rem; font-size: var(--step-0); }
.pdp-more-price {
  display: block; font-family: var(--f-accent); font-size: var(--step--1); color: var(--grey);
}

@media (prefers-reduced-motion: reduce) {
  .pdp-more-card img { transition: none; }
  .pdp-more-card:hover img { transform: none; }
}

/* phones: "more from" becomes a swipeable snap strip, and the buy row pairs
   ADD with SUBSCRIBE side by side instead of stacking three full-width buttons */
@media (max-width: 719px) {
  .pdp-more-row {
    display: flex; gap: .8rem; margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter); overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter);
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .pdp-more-row::-webkit-scrollbar { display: none; }
  .pdp-more-card { flex: 0 0 min(42vw, 200px); scroll-snap-align: start; }
}
@media (max-width: 640px) {
  .pdp-buy { display: flex; flex-wrap: wrap; gap: .6rem; }
  /* two buttons share a 375px row: the type steps down and tracking tightens so
     "add ₹310 · 300 ml" and "subscribe & save" both clear their pill borders */
  .pdp-buy .btn { flex: 1 1 calc(50% - .3rem); justify-content: center;
    padding-inline: .5rem; white-space: nowrap;
    font-size: max(.68rem, 11.5px); letter-spacing: .06em; }
}

/* ---- FULL-BLEED FETA VARIANT (evaluation only) ---------------------------- */
.feta-feature--bleed { position: relative; padding: 0; }
.feta-bleed-media { margin: 0; }
.feta-bleed-media img { display: block; width: 100%; height: auto; }
.feta-bleed-copy { padding: clamp(1.6rem, 5vw, 2rem) var(--gutter) clamp(2rem, 6vw, 3rem); }
@media (min-width: 900px) {
  .feta-bleed-copy { position: absolute; right: 6%; top: 50%; transform: translateY(-50%);
    width: min(30%, 27rem); padding: 0; }
}
.feta-feature--bleed .feta-note { margin-bottom: 1.4rem; max-width: none; }
/* the bleed variant does not sit inside .feta-copy, so it inherits none of its type
   rules — restate them here, including the capitalisation decision */
.feta-bleed-copy h2 { font-size: clamp(1.5rem, 2.4vw, 2.2rem); line-height: 1.08;
  margin: .8rem 0 1.1rem; color: var(--paper); text-transform: none; }
.feta-bleed-copy .serif-italic { color: var(--gold-lt); }
.feta-bleed-copy .feta-note { color: rgba(244,237,225,.78); font-size: .95rem; line-height: 1.6; }
/* No scrim. The chosen image (feta-bleed-D) was composed with its left third as clean
   dark table — measured luminance ~10 behind the copy, no bright peaks — so the copy
   needs no overlay. If this image is ever swapped, RE-MEASURE before assuming that. */
.feta-bleed-media { position: relative; }
.feta-bleed-copy { z-index: 2; }

/* Per-image copy placement for the bleed variant: the rule is that copy sits in the
   image's own empty dark zone, never on the food. Default is right; --left mirrors it. */
@media (min-width: 900px) {
  .feta-bleed-copy--left { right: auto; left: 6%; }
}


/* =====================================================================
   MOBILE POLISH — 22 Aug 2026, from a measured audit at 375px
   Two findings, both fixed here rather than scattered through the file so the
   next audit can re-run against one block.

   1. TAP TARGETS. 45 interactive elements measured under 40px on a phone: every
      inline text link (26-33px tall), the menu toggle (30x28), the hero pause
      (38px), the footer link lists (31px) and the email field (36px). Apple's
      floor is 44pt; Android's is 48dp. Inline links get their hit area from
      padding that is cancelled by an equal negative margin, so the layout does
      not move a pixel and only the tappable box grows. Scoped to coarse pointers
      so a mouse user's hover states are unaffected.

   2. TYPE FLOOR. Accent labels are set at .66rem, which is 10.2-10.9px on a phone,
      and the grams word-line under the big 72 landed at 9.9px. Nothing that has
      to be read should go below 11.5px on a phone. The labels are uppercase and
      tracked, so a small bump reads as intended, not as a different design.
   ===================================================================== */
@media (pointer: coarse) {
  /* Every text link in the page body and footer: pad each side by exactly what is missing
     from a 44px hit box, and cancel it with an equal negative margin so layout is
     untouched. Sized from the font (1.15em ≈ the glyph box), not from line-height: an
     inline anchor's hit box is its font box plus padding, and line-height does not count.
     A 16px link gets ~13px a side, a 12.5px link ~15px; both land at 44-45px. Anchors
     wrapping images, cards or figures are excluded — those are already large. Buttons
     with their own geometry (.btn) are excluded. */
  :is(main, footer) a:not(.btn):not([class*="card"]):not(:has(img, figure, picture, div, ul)),
  .nav-logo, .footer-mark, .feedback-link {
    --hit: max(0px, calc((44px - 1.15em) / 2));
    padding-block: var(--hit); margin-block: calc(-1 * var(--hit)); }
  /* has its own margins that position it under the quote; pad only, accept the shift */
  .tc-body .rev-more { padding-block: .7rem; }
  .footer-col ul { gap: .95rem; }
  .nav-toggle { width: 44px; height: 44px; padding: 0; justify-content: center; margin: -7px -7px -7px 0; }
  .nav-toggle span { width: 30px; }
  .hero-pause { width: 44px; height: 44px; }
  .subscribe { padding: .3rem; }
  .subscribe input { min-height: 44px; }
  .subscribe-go { min-height: 44px; }
}
@media (max-width: 899px) {
  .pshelf-k, .rng-more-k, .feta-k, .feta-award-sub, .eyebrow, .tenx-k,
  .tc-body figcaption span, .rev-more,
  /* user-facing micro-labels that carry real words (badges, tags, quiz chips) join the
     floor; purely decorative marks stay as designed */
  .award-pill, .journal-tag, .pc-award, .pc-fav, .qb-cat { font-size: max(.72rem, 11.5px); }
  .tenx-h-w { font-size: max(.2em, .74rem); letter-spacing: .14em; }
  /* the grams line on a phone sits on paper under the artwork, where there is room to
     let it breathe instead of wrapping to three lines */
  .tenx-h-w { max-width: 24ch; }
}

/* =====================================================================
   MOBILE COMPOSITIONS (4:5) — 22 Aug 2026
   Three full-width artworks (25% comparison, feta, the range) get a separately
   composed 1080x1350 asset on phones, served through <picture>. The desktop frame is
   16:9 and designed around horizontal negative space; on a 375px screen that frame is
   209px tall and the subject is a thumbnail. The 4:5 versions are composed for the
   phone — bigger subject, no baked-in small text — not cropped from the desktop file.

   The range scene's SVG annotations are pinned to product coordinates in the 16:9
   image, so they are switched off whenever the mobile source is in play; the chips
   under the scene carry navigation on a phone anyway (and were already there).
   ===================================================================== */
.scene-ann--m { display: none; }
@media (max-width: 899px) {
  /* the 4:5 art brings its own annotation layer; the 16:9 one detaches from it */
  .range-scene.has-mobile-art .scene-ann--d { display: none; }
  .range-scene.has-mobile-art .scene-ann--m { display: block; }
  /* labels are re-anchored per-product on the phone frame; type is sized in viewBox
     units so it renders ~12px at 375px wide (1080-unit frame at ~0.32 scale) */
  .scene-ann--m .ann-name { font-size: 38px; }
  /* the annotations ARE the product links now - the chip row keeps only the
     whole-range CTA, mirroring what hover-capable desktops already do */
  .range-scene.has-mobile-art ~ .scene-chips .scene-chip:not(.scene-chip--all) { display: none; }
  .tenx-shot picture, .feta-bleed-media picture, .range-scene picture { display: block; }
}

/* =====================================================================
   SUBSCRIPTION BUILDER (subscribe.html) — 24 Aug 2026
   A guided four-step flow: products -> rhythm -> pincode -> preview, with a
   quiet add-on row. Steps are visually one page (no wizard gating) because on
   a phone a stepper that hides state costs more taps than it saves. */
/* two-step flow (v5): step 1 is products only, step 2 is "when & where" + preview.
   One page, two views — main.js swaps them and mirrors the step in the URL hash. */
.sub-h { font-size: clamp(2rem, 4.6vw, 2.8rem); margin: .4rem 0 0; line-height: 1.02; }

.sub-builder { max-width: 1460px;
  padding-top: clamp(6.2rem, 13vw, 8rem);   /* clears the fixed nav */
  padding-bottom: clamp(3rem, 6vw, 4.5rem); }
.sb-trust { max-width: 1460px; }

.sb-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 1rem 2rem; margin-bottom: clamp(1.6rem, 3.5vw, 2.4rem); }

/* ① products → ② delivery → ③ checkout */
.sb-prog { list-style: none; margin: 0 0 .35rem; padding: 0; display: flex; align-items: center;
  gap: clamp(.7rem, 2vw, 1.4rem); }
.sb-prog li { display: flex; align-items: center; gap: .45rem;
  font-family: var(--f-accent); font-weight: 600; font-size: max(.72rem, 11.5px);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.sb-prog li + li::before { content: ""; width: clamp(.9rem, 2.5vw, 1.6rem); height: 1px;
  background: var(--line); margin-right: .45rem; }
.sb-prog b { width: 1.55rem; height: 1.55rem; border-radius: 50%; display: grid; place-items: center;
  font-size: .78rem; border: 1.5px solid var(--line); color: var(--ink-soft);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease); }
.sb-prog li.is-active { color: var(--ink); }
/* a 375px screen can't fit three labels — numbers carry the row, the active step
   keeps its word */
@media (max-width: 560px) {
  .sb-prog { gap: .55rem; }
  .sb-prog li { font-size: 0; gap: 0; }
  .sb-prog li b { font-size: .78rem; }
  .sb-prog li.is-active { font-size: max(.72rem, 11.5px); gap: .45rem; }
  .sb-prog li + li::before { width: .7rem; margin-right: 0; }
  .sb-prog li.is-active + li::before, .sb-prog li + li.is-active::before { margin-right: .1rem; }
}
.sb-prog li.is-active b { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.sb-prog li.is-done b { background: var(--coral); border-color: var(--coral); color: var(--ink); }

/* step 1: the sticky continue bar */
.sb-continue { position: sticky; bottom: .8rem; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
  background: var(--ink); color: var(--paper); border-radius: 999px;
  padding: .5rem .5rem .5rem 1.4rem;
  font-family: var(--f-accent); font-weight: 600; font-size: .9rem; letter-spacing: .04em;
  box-shadow: 0 16px 34px -12px rgba(20,14,7,.55); }
.sb-continue-go { white-space: nowrap; }
.sb-continue-go[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }
@media (min-width: 720px) { .sb-continue { max-width: 30rem; margin-inline: auto; } }

/* step 2: back link, then days + pincode side by side where there is room */
.sb-back { display: inline-flex; align-items: center; gap: .4em; margin-bottom: 1.2rem;
  background: none; border: none; cursor: pointer; padding: .4em 0;
  font-family: var(--f-accent); font-weight: 600; font-size: max(.78rem, 12.5px);
  letter-spacing: .08em; color: var(--ink-soft); }
.sb-back:hover { color: var(--ink); }
.sb-step2-grid { display: grid; gap: clamp(1rem, 2.5vw, 1.4rem); }
@media (min-width: 860px) {
  .sb-step2-grid { grid-template-columns: 1fr 1fr; align-items: start; }
}
#sbView2 { max-width: 900px; margin-inline: auto; }
#sbView2 .sb-side { margin-top: clamp(1rem, 2.5vw, 1.4rem); }

/* step cards (days / pincode) */
.sb-card { border: 1px solid var(--line); border-radius: 1rem; background: var(--paper);
  padding: clamp(1rem, 2vw, 1.3rem); }
.sb-card .sb-step-head { margin-bottom: .9rem; }
.sb-card .sb-step-head h2 { font-size: clamp(1.25rem, 2vw, 1.45rem); }
.sb-side-card { border: 1px solid var(--line); border-radius: 1rem; background: var(--paper-2);
  padding: clamp(.95rem, 2vw, 1.2rem); }
.sb-side-h { font-family: var(--f-display); font-size: clamp(1.25rem, 2.2vw, 1.45rem); margin-bottom: .55rem; }
.sb-side-days { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .7rem; min-height: 1.4rem; }
.sb-daychip { font-family: var(--f-accent); font-size: max(.68rem, 11px); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; padding: .3em .65em; border-radius: 99px;
  border: 1px solid var(--line); color: var(--ink-soft); }
.sb-daychip.is-on { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.sb-step-head { margin-bottom: 1.1rem; }
.sb-step-head h2 { font-family: var(--f-display); font-size: clamp(1.5rem, 3vw, 2.1rem); }
.sb-step-sub { color: var(--ink-soft); font-size: var(--step--1); margin-top: .2rem; }

/* category pill tabs + one filtered grid */
.sbp-tabs { display: flex; gap: .5rem; overflow-x: auto; padding-bottom: .35rem;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.sbp-tabs::-webkit-scrollbar { display: none; }
.sbp-tab { flex: none; font-family: var(--f-accent); font-weight: 600; font-size: .88rem;
  cursor: pointer; border: 1.5px solid var(--line); background: var(--paper); color: var(--ink);
  border-radius: 999px; padding: .68rem 1.2rem; min-height: 44px;
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease); }
.sbp-tab.is-on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.sbp-row { list-style: none; margin: .9rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(8.6rem, 1fr)); gap: .7rem; }
.sbp-item { position: relative; }
.sbp {
  width: 100%; display: grid; gap: .35rem; text-align: left; cursor: pointer;
  background: var(--paper); border: 1.5px solid var(--line); border-radius: .7rem; padding: .6rem;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease);
}
/* 3/4 = the studio photographs' own ratio, so nothing is cropped — a square here
   was slicing the lids off every bottle */
.sbp-img { display: block; border-radius: .45rem; overflow: hidden; aspect-ratio: 3 / 4; background: var(--sand); }
.sbp-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sbp-n { font-family: var(--f-accent); font-weight: 600; font-size: .88rem; line-height: 1.2; }
.sbp-p { font-size: max(.72rem, 11.5px); color: var(--ink-soft); }
.sbp-item.is-on .sbp { border-color: var(--coral); box-shadow: 0 10px 24px -14px rgba(235,91,77,.6); }
.sbp-check { position: absolute; top: .95rem; left: .95rem; z-index: 2; width: 1.5rem; height: 1.5rem;
  border-radius: 50%; display: grid; place-items: center; background: var(--coral); color: var(--ink);
  opacity: 0; transform: scale(.6); transition: opacity .25s var(--ease), transform .25s var(--ease); }
.sbp-check svg { width: .85rem; height: .85rem; }
.sbp-item.is-on .sbp-check { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .sbp-check { transition: none; } }
.sbp-q[hidden] { display: none; } /* [hidden] must beat the display rule below */
.sbp-q {
  position: absolute; top: .95rem; right: .95rem; z-index: 2;
  display: inline-flex; align-items: center; gap: .1rem;
  background: var(--paper); border: 1px solid var(--line); border-radius: 99px; padding: .1rem;
  box-shadow: 0 6px 16px -8px rgba(33,27,23,.4);
}
.sbp-q b { min-width: 1.4em; text-align: center; font-family: var(--f-accent); font-size: .9rem; }
.sbp-q button {
  width: 30px; height: 30px; border: none; border-radius: 50%; cursor: pointer;
  background: transparent; font-size: 1rem; line-height: 1; color: var(--ink);
}
.sbp-q button:hover { background: var(--sand); }

/* rhythm */
.sb-freq { display: flex; gap: .6rem; }
.sb-freq-opt {
  font-family: var(--f-accent); font-weight: 600; font-size: .9rem; cursor: pointer;
  border: 1.5px solid var(--line); background: var(--paper); color: var(--ink);
  border-radius: 999px; padding: .8rem 1.4rem; min-height: 44px;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
.sb-freq-opt.is-on { border-color: var(--ink); background: var(--ink); color: var(--paper); }
.sb-days { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; align-items: center; }
.sb-day {
  font-family: var(--f-accent); font-weight: 600; font-size: .85rem; text-transform: uppercase;
  letter-spacing: .06em; cursor: pointer; border: 1.5px solid var(--line); background: var(--paper);
  color: var(--ink); border-radius: .6rem; padding: .7rem .85rem; min-height: 44px; min-width: 52px;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.sb-day.is-on { border-color: var(--coral); background: var(--coral); color: var(--ink); }
.sb-day--off { opacity: .4; cursor: not-allowed; text-decoration: line-through; }
.sb-days-note { flex-basis: 100%; font-size: max(.72rem, 11.5px); color: var(--ink-soft); font-family: var(--f-accent); }

/* pincode + name */
.sb-pin, .sb-name { max-width: 22rem; }
.sb-pin input, .sb-name input {
  width: 100%; font: inherit; font-family: var(--f-accent); letter-spacing: .06em;
  padding: .85rem 1.05rem; min-height: 48px; border: 1.5px solid var(--line); border-radius: .7rem;
  background: var(--paper); color: var(--ink);
}
.sb-pin input:focus-visible, .sb-name input:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }
.sb-name { margin-top: .8rem; }
.sb-pin-msg { margin-top: .45rem; font-family: var(--f-accent); font-size: max(.72rem, 11.5px); min-height: 1.2em; }
.sb-pin-msg.is-ok { color: var(--teal); }
.sb-pin-msg.is-no { color: var(--maroon); }

/* add-ons */
.sb-addons { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.sb-addon {
  display: grid; grid-template-columns: 3.2rem 1fr auto; align-items: center; gap: .8rem;
  text-align: left; cursor: pointer; background: var(--paper-2); border: 1px solid var(--line);
  border-radius: .8rem; padding: .55rem .8rem .55rem .55rem; min-height: 44px;
  transition: border-color .25s var(--ease);
}
.sb-addon:hover { border-color: var(--coral); }
.sb-addon img { width: 3.2rem; height: 3.2rem; object-fit: cover; border-radius: .5rem; display: block; }
.sb-addon b { display: block; font-family: var(--f-accent); font-weight: 600; font-size: .92rem; }
.sb-addon i { font-style: normal; font-size: max(.72rem, 11.5px); color: var(--ink-soft); }
.sb-addon em { font-style: normal; font-family: var(--f-accent); font-size: 1.2rem; color: var(--maroon); }

/* preview */
.sb-preview { border-top: 1px solid var(--line); padding-top: .8rem; }
.sb-preview-empty { color: var(--ink-soft); font-family: var(--f-accent); font-size: .92rem; }
.sb-sum-lines { list-style: none; margin: 0 0 .8rem; padding: 0 0 .7rem; border-bottom: 1px solid var(--line); display: grid; gap: .45rem; font-size: .95rem; }
.sb-sum-lines li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "img n p" "img c c";
  column-gap: .7rem; row-gap: .25rem; font-size: var(--step-0); align-items: center; }
.sbl-img { grid-area: img; width: 2.6rem; height: 2.6rem; object-fit: cover;
  border-radius: .45rem; background: var(--sand); display: block; }
.sbl-n { grid-area: n; min-width: 0; align-self: baseline; }
.sb-sum-lines b { grid-area: p; font-family: var(--f-accent); font-weight: 600; white-space: nowrap; }
.sbl-ctl { grid-area: c; display: inline-flex; gap: .3rem; }
.sbl-ctl button { width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--paper); color: var(--ink); cursor: pointer; font-size: .9rem; line-height: 1;
  display: grid; place-items: center; transition: border-color .2s var(--ease), background .2s var(--ease); }
.sbl-ctl button:hover { border-color: var(--ink); }
.sbl-ctl [data-l-remove] { color: var(--maroon); margin-left: .3rem; }
.sbl-ctl [data-l-remove]:hover { background: var(--maroon); border-color: var(--maroon); color: var(--paper); }
.sb-sum-meta { display: grid; gap: .4rem; margin: 0; font-size: .92rem; }
.sb-sum-meta div { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
.sb-sum-meta dt {
  font-family: var(--f-accent); font-size: max(.72rem, 11.5px); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
}
.sb-sum-meta dd { text-align: right; }
.sb-sum-month dd { font-family: var(--f-display); font-size: clamp(1.2rem, 2.2vw, 1.45rem); }
.sb-sum-month s { font-size: .62em; color: var(--ink-soft); text-decoration-color: var(--maroon); margin-right: .3em; }
.sb-miss { color: var(--maroon); font-style: normal; font-family: var(--f-accent); font-size: .85em; }
.sb-sum-note { margin-top: .7rem; font-size: max(.7rem, 11px); color: var(--ink-soft); line-height: 1.4; }

/* the quiet promises row */
.sb-trust { padding-bottom: clamp(3.5rem, 7vw, 5.5rem); }
.sb-trust ul { list-style: none; margin: 0; padding: clamp(1.2rem, 2.5vw, 1.8rem) 0 0;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 1.1rem 2rem; }
.sb-trust b { display: block; font-family: var(--f-accent); font-weight: 700;
  font-size: max(.72rem, 11.5px); letter-spacing: .14em; text-transform: uppercase; color: var(--ink); }
.sb-trust i { display: block; font-style: normal; font-size: max(.78rem, 12.5px);
  color: var(--ink-soft); margin-top: .25rem; line-height: 1.45; }

/* confirm */
.sb-confirm { display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1rem; }
.sb-confirm .btn { padding-block: .8em; font-size: max(.74rem, 12px); }
.sb-confirm .btn[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }
.sb-shopify.is-busy { opacity: .6; pointer-events: none; }
.sb-shopify-note {
  margin-top: .9rem; max-width: 52ch; font-size: var(--step--1); line-height: 1.55;
  color: var(--ink); background: color-mix(in srgb, var(--gold) 18%, var(--paper));
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
  border-radius: .7rem; padding: .85rem 1.05rem;
}
.sb-fine { margin-top: .8rem; font-size: max(.68rem, 10.5px); color: var(--ink-soft); max-width: 56ch; line-height: 1.45; }
.sb-fine .stars { color: var(--coral); }
.sb-confirm { flex-direction: column; }
.sb-confirm .btn { width: 100%; justify-content: center; }
