/* ============================================================================
   NURIVA — the approved design system

   BUILT FILE. Edit the parts in resources/css-src/ and run:
       python scripts/build_css.py

   Loaded after shop.css so the approved rules win at equal specificity, and
   so no commerce rule has to be edited to adopt the palette.

   Every url() below is relative to this file, never rooted at "/". The shop
   deploys into a subfolder, where an absolute asset path resolves against the
   domain root and silently 404s.
   ========================================================================= */

/* ---- 01-tokens-base.css -------------------------------------------- */
/* ============================================================================
   NURIVA — the approved design system

   Ported from the approved ORGANICA build into plain CSS. Loaded *after*
   shop.css so the approved rules win at equal specificity, and so not one
   commerce rule has to be edited to adopt the palette.

   Every url() below is relative to this file, never rooted at "/". The shop
   deploys into a subfolder (…/organic), where an absolute asset path resolves
   against the domain root and silently 404s.
   ========================================================================= */

/* ------------------------------------------------------------------ fonts */
/* Self-hosted. The first render must not wait on a third-party host, and the
   documented hosting has no build step to inline them. */

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-400-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-500-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-600-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-700-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-400-italic-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/manrope-400-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/manrope-500-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/manrope-600-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/manrope-700-latin.woff2") format("woff2");
}

/* ----------------------------------------------------------------- tokens */

:root {
  /* ---- the approved palette ---- */
  --ivory: #f8f4ea;
  --ivory-warm: #f2ebdd;
  --forest: #173d2b;
  --forest-deep: #0f2e20;
  --sage: #dce8d4;
  --sage-muted: #a8b99a;
  --terracotta: #c96f45;
  --honey: #c9953c;
  --soil: #3b291d;
  --ink: #1c261f;
  --white: #fff;

  /* Text companions. Terracotta (3.27:1) and honey (2.44:1) both fail AA as
     text on ivory, so decorative fills keep the brand hue and anything that
     has to be read uses these darker partners. */
  --terracotta-text: #a0542f;   /* 5.03:1 on ivory */
  --honey-text: #8c5a1f;        /* 5.31:1 on ivory */
  --ink-muted: #4a5750;         /* 7.4:1  on ivory */

  --rule: rgba(23, 61, 43, 0.18);
  --rule-strong: rgba(23, 61, 43, 0.34);
  --shadow-soft: 0 18px 40px -28px rgba(28, 38, 31, 0.55);
  --shadow-lift: 0 22px 46px -26px rgba(28, 38, 31, 0.62);

  /* ---- type ---- */
  --font-display: "Cormorant Garamond", Cormorant, Georgia, "Times New Roman", serif;
  --font-body: "Manrope", Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --h1-desktop: clamp(4.5rem, 6vw, 7rem);
  --h1-mobile: clamp(3rem, 13vw, 4.4rem);
  --section-title: clamp(3rem, 5vw, 5.6rem);
  --body-size: clamp(1rem, 1.1vw, 1.125rem);
  --eyebrow-tracking: 0.18em;

  /* ---- layout ---- */
  --max-width: 1440px;
  --content-width: 1320px;
  --gutter: clamp(32px, 5vw, 80px);
  --section-space: clamp(104px, 10vw, 180px);

  --radius-button: 12px;
  --radius-small: 10px;

  --fast: 180ms;
  --normal: 320ms;
  --slow: 700ms;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Row (116) + root drop (74) + ribbon (40). */
  --nav-height: 230px;
  --nav-stuck-height: 76px;

  /*
   * The commerce stylesheet's vocabulary, remapped onto the approved palette.
   *
   * shop.css keeps every one of its rules; only what its names resolve to
   * changes. That is what lets the basket, checkout, account and admin-adjacent
   * pages adopt the approved colours without a single commerce rule being
   * rewritten — which is exactly the blind rewrite the brief rules out.
   */
  --cream: var(--ivory);
  --cream-deep: var(--ivory-warm);
  --paper: var(--white);
  --green: var(--forest);
  --green-deep: var(--forest-deep);
  --green-soft: var(--sage);
  --green-mid: #3d7256;
  --gold: var(--honey-text);
  --gold-soft: var(--honey);
  --ink-soft: var(--ink-muted);
  --ink-faint: #6d7a72;
  --line: var(--rule);
  --line-soft: rgba(23, 61, 43, 0.1);
  --serif: var(--font-display);
  --sans: var(--font-body);
  --wrap: var(--content-width);
}

@media (max-width: 1023px) {
  :root {
    --gutter: clamp(24px, 4vw, 40px);
    --nav-height: 76px;
  }
}

@media (max-width: 767px) {
  :root {
    --gutter: 20px;
    --section-space: 72px;
  }
}

@media (max-width: 359px) {
  :root {
    --gutter: 16px;
  }
}

/* ------------------------------------------------------------------- base */

html {
  scroll-behavior: smooth;
  /* The fixed header must not sit on top of whatever an anchor jumps to. */
  scroll-padding-top: calc(var(--nav-stuck-height) + 20px);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  min-height: 100vh;
  background-color: var(--ivory);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body-size);
  line-height: 1.62;
  overflow-x: hidden;
}

/* Paper grain — the stock the page is printed on, so it stays put rather than
   scrolling with the content. Plain alpha, not mix-blend-mode: a blended
   full-viewport fixed layer forces every transformed section through an
   expensive compositing path. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("../media/design/svg/paper-grain.svg");
  background-size: 320px 320px;
  opacity: 0.34;
}

/*
 * The approved base reset, ported.
 *
 * Without `background: none` a <button> keeps the UA's grey button face, and
 * the footer's "Back to the roots" control rendered ivory text on light grey —
 * unreadable, and invisible in a desktop screenshot because it only shows
 * where the button sits on the dark footer. Element specificity (0,0,1) loses
 * to every `.btn` rule, so the styled buttons are untouched.
 */
button {
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--forest);
  line-height: 1.02;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: 3px;
  border-radius: 3px;
}

/* [hidden] is a UA rule at the lowest specificity, so any class that sets
   `display` quietly beats it. Everything script-toggled depends on this. */
[hidden] { display: none !important; }

/* --------------------------------------------------------------- layout */

.container {
  width: 100%;
  max-width: calc(var(--content-width) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { position: relative; z-index: 1; }

/* ----------------------------------------------------------- primitives */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: clamp(0.68rem, 0.75vw, 0.78rem);
  font-weight: 600;
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--forest);
  opacity: 0.86;
  margin: 0;
}

.eyebrow::after {
  content: "";
  flex: 0 0 auto;
  width: 44px;
  height: 1px;
  background: linear-gradient(90deg, var(--rule-strong), transparent);
}

.section-title {
  font-size: var(--section-title);
  margin-block: 18px 0;
}

.lede {
  max-width: 46ch;
  color: var(--ink-muted);
  font-size: clamp(0.98rem, 1vw, 1.06rem);
  line-height: 1.72;
}

.arrow { flex: 0 0 auto; }

.quiet-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-block: 8px;
  min-height: 44px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--forest);
  text-decoration: none;
}

.quiet-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 6px;
  height: 1px;
  background: var(--rule-strong);
  transform-origin: left;
  transition: transform var(--normal) var(--ease), background-color var(--normal) var(--ease);
}

.quiet-link:hover::after,
.quiet-link:focus-visible::after {
  background: var(--forest);
  transform: scaleY(2);
}

.quiet-link .arrow { transition: transform var(--normal) var(--ease); }
.quiet-link:hover .arrow,
.quiet-link:focus-visible .arrow { transform: translateX(5px); }

.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 200;
  padding: 12px 20px;
  border-radius: var(--radius-button);
  background: var(--forest);
  color: var(--ivory);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--fast) var(--ease);
}

.skip-link:focus,
.skip-link:focus-visible { transform: none; color: var(--ivory); }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- reveals */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-visible { opacity: 1; transform: none; }

/*
 * Nothing may depend on JavaScript to become readable.
 *
 * The reveal only hides content once the script has confirmed it is running,
 * by putting `js-reveal` on <html>. Without that, a failed or blocked script
 * leaves the whole page at opacity 0 — which is the worst possible failure for
 * a progressive enhancement, because it looks like the site is simply broken.
 */
html:not(.js-reveal) [data-reveal] {
  opacity: 1;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---- 02-navbar.css ------------------------------------------------- */

/* ============================================================================
   Root System navbar

   The header is fixed and paired with a spacer, so compressing it on scroll
   cannot change document flow height — a sticky header that shrinks in flow
   makes the whole page shudder.

   Everything vertical derives from --nav-row-h and --link-h, which keeps the
   horizontal root line and the per-link sprouts locked to the same baseline in
   both the tall and the compressed state.
   ========================================================================= */

.root-nav {
  --nav-row-h: 116px;
  --link-h: 46px;
  --ribbon-h: 40px;
  --root-gap: 32px;
  --root-drop: 74px;
  --root-baseline: calc((var(--nav-row-h) - var(--link-h)) / 2 + var(--link-h) + var(--root-gap));
  --sprout-w: 170px;
  --sprout-h: 131px;
  --sprout-base: 46px;
  --root-ink: #5e513b;

  position: fixed;
  inset: 0 0 auto;
  z-index: 60;
  color: var(--forest);
  background: var(--ivory);
  transition: box-shadow var(--normal) var(--ease), background-color var(--normal) var(--ease);
  /* Lets the roots hang into the hero while still clipping at the viewport edge. */
  clip-path: inset(0 0 -340px 0);
}

.root-nav.is-stuck {
  --nav-row-h: 76px;
  --ribbon-h: 0px;
  --root-gap: 10px;
  --root-drop: 0px;
  background: rgba(248, 244, 234, 0.94);
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 30px -26px rgba(28, 38, 31, 0.8);
}

.root-nav__spacer { height: var(--nav-height); }

.root-nav__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  height: var(--nav-row-h);
  transition: height var(--normal) var(--ease);
}

/* ------------------------------------------------------------------ brand */

.root-nav__brand {
  display: block;
  width: clamp(96px, 8vw, 118px);
  color: var(--forest);
  text-decoration: none;
  transition: width var(--normal) var(--ease);
}

.root-nav.is-stuck .root-nav__brand { width: clamp(76px, 6vw, 92px); }
.root-nav__brand svg { width: 100%; height: auto; }

/* An uploaded logo (Settings → Logo) sizes by HEIGHT, not the seal's square
   width, so a wide logo keeps its proportions instead of being crushed into the
   seal's box. The extra `.root-nav` on the width reset outranks the mobile
   brand-width rule below. */
.root-nav .root-nav__brand--logo { width: auto; }
.root-nav__logo {
  display: block;
  height: clamp(40px, 4.4vw, 52px);
  width: auto;
  max-width: min(210px, 46vw);
  object-fit: contain;
  transition: height var(--normal) var(--ease);
}
.root-nav.is-stuck .root-nav__logo { height: clamp(34px, 3.6vw, 44px); }

.seal-word {
  font-family: var(--font-display);
  /* Six letters where the approved seal had eight: sized to fill the same arc
     rather than sitting small in the middle of it. */
  font-size: 27px;
  font-weight: 600;
  letter-spacing: 5px;
}

.seal-sub {
  font-family: var(--font-body);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 1.15px;
}

/* ------------------------------------------------------------------ links */

.root-nav__links ul {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 2.2vw, 40px);
  list-style: none;
  margin: 0;
  padding: 0;
}

.root-nav__links li { position: relative; }

.nav-link {
  position: relative;
  display: flex;
  align-items: center;
  height: var(--link-h);
  min-width: 44px;
  justify-content: center;
  padding-inline: 4px;
  font-size: clamp(0.86rem, 0.95vw, 1.02rem);
  font-weight: 500;
  color: var(--forest);
  text-decoration: none;
  white-space: nowrap;
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--fast) var(--ease);
}

.nav-link--active { font-weight: 700; color: var(--forest-deep); }

.root-sprout {
  position: absolute;
  left: 50%;
  top: calc(100% + var(--root-gap) - var(--sprout-base));
  width: var(--sprout-w);
  /* The global img/svg reset caps width at 100% of the parent, which for a
     short link would shrink the cluster and throw the centring out. */
  max-width: none;
  height: var(--sprout-h);
  margin-left: calc(var(--sprout-w) / -2);
  color: var(--root-ink);
  pointer-events: none;
  overflow: visible;
  transform-origin: 50% var(--sprout-base);
  transition: transform var(--normal) var(--ease), opacity var(--normal) var(--ease);
}

.root-sprout__roots {
  stroke: var(--root-ink);
  opacity: 0.9;
  transition: stroke var(--normal) var(--ease), opacity var(--normal) var(--ease);
}

.root-sprout__leaves { stroke: var(--forest); fill: none; }
.root-sprout__leaves path:not(:first-child) { fill: #6f8a55; }

/* The current page's branch keeps a visibly larger, deeper sprout. */
.root-sprout--active { transform: scale(1.12); }
.root-sprout--active .root-sprout__leaves path:not(:first-child) { fill: #4f7040; }
.root-sprout--active .root-sprout__roots { opacity: 1; }

.nav-link:hover .root-sprout,
.nav-link:focus-visible .root-sprout { transform: scale(1.05); }

.nav-link--active:hover .root-sprout,
.nav-link--active:focus-visible .root-sprout { transform: scale(1.17); }

.nav-link:hover .root-sprout__roots,
.nav-link:focus-visible .root-sprout__roots { stroke: var(--forest); opacity: 1; }

.root-nav.is-stuck .root-sprout { transform: scale(0.4); opacity: 0; }

/* --------------------------------------------------------------- rootline */

.root-nav__line {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--root-baseline) - 12px);
  z-index: 1;
  width: 100%;
  height: 24px;
  color: var(--root-ink);
  pointer-events: none;
  transition: top var(--normal) var(--ease);
}

.root-nav__line path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  /* pathLength is normalised in the markup so one keyframe works at any width. */
  animation: draw-root 1100ms var(--ease) 180ms forwards;
}

@keyframes draw-root { to { stroke-dashoffset: 0; } }

/* ---------------------------------------------------------------- ribbon */

.root-nav__ribbon {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: calc(var(--ribbon-h) + var(--root-drop));
  padding-top: var(--root-drop);
  overflow: hidden;
  font-family: var(--font-display);
  font-size: 0.94rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--forest);
  transition: height var(--normal) var(--ease), opacity var(--fast) var(--ease);
}

.root-nav.is-stuck .root-nav__ribbon { opacity: 0; }
.root-nav__ribbon i { margin-inline: 10px; color: var(--honey-text); font-style: normal; }

/* ---------------------------------------------------------------- tools */

.root-nav__tools { display: flex; align-items: center; gap: 6px; justify-self: end; }

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: 50%;
  color: var(--forest);
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
  transition: background-color var(--fast) var(--ease);
}

.icon-button:hover,
.icon-button:focus-visible { background: rgba(23, 61, 43, 0.08); color: var(--forest); }

.basket { position: relative; }

.basket__count {
  position: absolute;
  right: 0;
  bottom: 2px;
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding-inline: 5px;
  border-radius: 11px;
  background: var(--forest);
  color: var(--ivory);
  font-size: 0.68rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.root-nav__burger { display: none; }

/* ------------------------------------------------------------ mega menu */

.megamenu {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 3;
  padding-block: clamp(24px, 3vw, 40px);
  background: var(--ivory);
  border-top: 1px solid var(--rule);
  box-shadow: 0 30px 50px -40px rgba(28, 38, 31, 0.7);
}

.megamenu__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(18px, 2.4vw, 36px);
}

.megamenu__col > a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  font-family: var(--font-display);
  font-size: 1.18rem;
  font-weight: 600;
  color: var(--forest);
  text-decoration: none;
}

.megamenu__col > a:hover { text-decoration: underline; text-underline-offset: 4px; }
.megamenu__soon { margin-left: 8px; font-family: var(--font-body); font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); }

.megamenu__col ul { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 1px; }

.megamenu__col li a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  font-size: 0.9rem;
  color: var(--ink-muted);
  text-decoration: none;
}

.megamenu__col li a:hover,
.megamenu__col li a:focus-visible { color: var(--forest); text-decoration: underline; text-underline-offset: 3px; }

.megamenu__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 10px clamp(18px, 3vw, 34px);
  margin-top: clamp(18px, 2.4vw, 30px);
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 1023px) {
  .root-nav {
    --nav-row-h: 76px;
    --link-h: 44px;
    --ribbon-h: 0px;
    clip-path: inset(0 0 -140px 0);
  }

  .root-nav.is-stuck { --nav-row-h: 68px; }

  /* 1fr auto 1fr keeps the seal optically centred even though the burger and
     the tool cluster are different widths. */
  .root-nav__inner { grid-template-columns: 1fr auto 1fr; }

  .root-nav__burger { display: inline-flex; justify-self: start; }
  .root-nav__links, .root-nav__ribbon, .megamenu { display: none; }

  .root-nav__brand { grid-column: 2; width: 56px; }
  .root-nav.is-stuck .root-nav__brand { width: 50px; }

  .root-nav__tools { grid-column: 3; gap: 0; }

  /* A single fine root line sits directly under the mobile header. */
  .root-nav__line { top: auto; bottom: -12px; opacity: 0.75; }
}

@media (max-width: 400px) {
  .root-nav__tools { margin-right: -6px; }
}

@media (prefers-reduced-motion: reduce) {
  .root-nav__line path { animation: none; stroke-dashoffset: 0; }
  .root-nav__inner,
  .root-nav__brand,
  .root-sprout,
  .root-nav__ribbon,
  .root-nav__line { transition-duration: 1ms; }
}

/* ---- 03-overlays.css ----------------------------------------------- */

/* ============================================================================
   Drawer and search overlay

   Both are real dialogs: focus is trapped while open, Escape and an outside
   click close them, focus returns to whatever opened them, and the body cannot
   scroll behind. All of that lives in organica-ui.js; this file only describes
   what they look like.
   ========================================================================= */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  background: rgba(15, 46, 32, 0.42);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--normal) var(--ease);
}

.overlay.is-open { opacity: 1; }

/* ---------------------------------------------------------------- drawer */

.drawer-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(420px, 88vw);
  height: 100%;
  background: var(--ivory);
  box-shadow: 20px 0 60px -40px rgba(15, 46, 32, 0.9);
  transform: translateX(-100%);
  transition: transform var(--normal) var(--ease);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.overlay.is-open .drawer-panel { transform: none; }

.drawer-panel__head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 14px var(--gutter);
  background: var(--ivory);
  border-bottom: 1px solid var(--rule);
}

.drawer-panel__title {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--forest);
}

.drawer-panel__body { padding: 8px var(--gutter) 40px; }

.drawer-group + .drawer-group { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rule); }

.drawer-group__title {
  margin: 0 0 6px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.drawer-link {
  display: flex;
  align-items: center;
  min-height: 46px;
  font-size: 1rem;
  font-weight: 600;
  color: var(--forest);
  text-decoration: none;
}

.drawer-link--sub {
  min-height: 42px;
  padding-left: 16px;
  font-size: 0.92rem;
  font-weight: 400;
  color: var(--ink-muted);
}

.drawer-link:hover,
.drawer-link:focus-visible { text-decoration: underline; text-underline-offset: 4px; }

.drawer-soon {
  margin-left: 8px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ---------------------------------------------------------------- search */

.overlay--search { align-items: flex-start; justify-content: center; }

.search-panel {
  width: min(720px, 100%);
  margin-top: clamp(60px, 12vh, 160px);
  padding: clamp(20px, 4vw, 36px);
  background: var(--ivory);
  border-radius: var(--radius-small);
  box-shadow: 0 40px 80px -50px rgba(15, 46, 32, 0.9);
  transform: translateY(-14px);
  transition: transform var(--normal) var(--ease);
}

.overlay.is-open .search-panel { transform: none; }

.search-panel__form { display: flex; gap: 10px; }

.search-panel__input {
  flex: 1;
  min-width: 0;
  min-height: 56px;
  padding: 12px 18px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-button);
  background: var(--white);
  color: var(--ink);
  font-size: 1.05rem;
}

.search-panel__input:focus-visible {
  outline: none;
  border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(23, 61, 43, 0.16);
}

.search-panel__hint { margin: 14px 0 0; font-size: 0.86rem; color: var(--ink-muted); }

@media (prefers-reduced-motion: reduce) {
  .overlay,
  .drawer-panel,
  .search-panel { transition: none; }
}

/* ---- 04-hero.css --------------------------------------------------- */

/* ============================================================================
   Hero — "Goodness Begins Below the Surface."

   Desktop composes three layers in one frame: the field dissolving out of the
   paper, the harvest cluster in front of it, and the soil cross-section that
   carries the whole scene down into the next section.
   ========================================================================= */

.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-start;
  min-height: clamp(700px, 65vw, 950px);
  padding-block: clamp(56px, 9vw, 140px) 0;
  /* Scene layers deliberately bleed past the gutters; clipping the section
     itself keeps that from turning into page-level horizontal scroll, while
     overflow-y stays visible so the roots can hang into the next section. */
  overflow-x: clip;
  overflow-y: visible;
  /* The generic hero rules in shop.css set a gradient background and a grid;
     both are overridden here rather than deleted there. */
  background: none;
  display: flex;
}

.hero__scene {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.hero__farm {
  position: absolute;
  top: 0;
  right: 0;
  width: 70%;
  height: 78%;
  object-fit: cover;
  object-position: 64% 46%;
  /* Three ramps intersected: the photo dissolves into paper on its left, along
     the top and along the bottom, so it never reads as a rectangle dropped on
     the page. */
  -webkit-mask-image: linear-gradient(96deg, transparent 5%, rgba(0, 0, 0, 0.36) 22%, #000 50%),
    linear-gradient(to bottom, transparent 0%, #000 15%),
    linear-gradient(to top, transparent 0%, #000 24%);
  mask-image: linear-gradient(96deg, transparent 5%, rgba(0, 0, 0, 0.36) 22%, #000 50%),
    linear-gradient(to bottom, transparent 0%, #000 15%),
    linear-gradient(to top, transparent 0%, #000 24%);
  -webkit-mask-composite: source-in, source-in;
  mask-composite: intersect, intersect;
}

/* Soil first, harvest on top of it: the products sit on the ground the
   cross-section exposes, exactly as in the approved reference. */
.hero__soil {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 71%;
  width: 110%;
  max-width: none;
  height: auto;
  transform: translateX(-50%) rotate(-8deg);
  transform-origin: 50% 50%;
}

.hero__cluster {
  position: absolute;
  z-index: 2;
  right: clamp(-56px, -2vw, 0px);
  top: 30%;
  width: clamp(500px, 47vw, 760px);
  height: auto;
  filter: drop-shadow(0 26px 34px rgba(28, 38, 31, 0.22));
}

/* ------------------------------------------------------------------ copy */

.hero__content { position: relative; z-index: 1; width: 100%; }
.hero__copy { max-width: min(52%, 760px); }

/* Entrance is pure CSS so the hero reads immediately from the server-rendered
   HTML — nothing here waits on the reveal observer. */
.hero__copy > * { animation: hero-rise 700ms var(--ease) both; }
.hero__copy > *:nth-child(2) { animation-delay: 70ms; }
.hero__copy > *:nth-child(3) { animation-delay: 140ms; }
.hero__copy > *:nth-child(4) { animation-delay: 210ms; }
.hero__copy > *:nth-child(5) { animation-delay: 280ms; }

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(18px); }
}

@media (prefers-reduced-motion: reduce) {
  .hero__copy > * { animation: none; }
}

.hero__eyebrow { margin-bottom: clamp(14px, 2vw, 26px); }

.hero__title {
  font-size: var(--h1-desktop);
  line-height: 0.98;
  letter-spacing: -0.018em;
  /* The line break is authored; balancing would re-flow it. */
  text-wrap: initial;
  margin: 0;
  color: var(--forest);
}

.hero__body {
  max-width: 34ch;
  margin-top: clamp(18px, 2vw, 28px);
  color: var(--ink);
  font-size: clamp(1rem, 1.05vw, 1.1rem);
  line-height: 1.66;
}

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(16px, 2.4vw, 40px);
  margin-top: clamp(26px, 3vw, 42px);
}

.hero__trust {
  --sep-gap: clamp(12px, 1.6vw, 24px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px var(--sep-gap);
  margin-top: clamp(30px, 3.6vw, 52px);
  font-size: 0.92rem;
  color: var(--forest);
  list-style: none;
  padding: 0;
}

.hero__trust li { display: flex; align-items: center; gap: 10px; }
.hero__trust svg { flex: 0 0 auto; color: var(--forest); opacity: 0.9; }

/* Separator dots between trust items, matching the reference rhythm. */
.hero__trust li + li::before {
  content: "";
  width: 4px;
  height: 4px;
  margin-right: var(--sep-gap);
  border-radius: 50%;
  background: var(--sage-muted);
}

/* ------------------------------------------------------------- 1024-1279 */

@media (max-width: 1279px) {
  .hero__copy { max-width: min(50%, 560px); }
  .hero__cluster { width: clamp(460px, 58vw, 640px); bottom: clamp(48px, 8vw, 96px); }
}

/* -------------------------------------------------- tablet portrait, 768+ */

@media (max-width: 1023px) {
  .hero { min-height: 0; padding-block: 40px clamp(96px, 14vw, 160px); }
  .hero__copy { max-width: 62%; }
  .hero__title { font-size: clamp(3.4rem, 7.4vw, 5rem); }
  .hero__farm { width: 84%; object-position: 66% 46%; }
  .hero__cluster { width: 74vw; right: -6vw; bottom: 6vw; }
}

/* ---------------------------------------------------------------- mobile */

@media (max-width: 767px) {
  /* Copy first, media second — the desktop two-column frame is never squeezed
     into a narrow column. */
  .hero {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding-block: 28px 0;
  }

  .hero__content { order: 1; }
  .hero__copy { max-width: none; }

  .hero__scene {
    position: relative;
    inset: auto;
    order: 2;
    z-index: 0;
    margin-top: 34px;
    /* Reserves the composed scene's box before the images decode. */
    aspect-ratio: 100 / 104;
  }

  .hero__farm {
    top: 0;
    right: 0;
    left: 0;
    width: 100%;
    height: 68%;
    object-position: 62% 44%;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 13%, #000 74%, transparent 96%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 13%, #000 74%, transparent 96%);
    -webkit-mask-composite: source-over;
    mask-composite: add;
  }

  .hero__cluster {
    left: 50%;
    right: auto;
    bottom: 14%;
    top: auto;
    width: 104%;
    transform: translateX(-50%);
  }

  .hero__soil {
    top: auto;
    bottom: -12%;
    width: 150%;
    transform: translateX(-50%) rotate(-4deg);
  }

  .hero__title { font-size: var(--h1-mobile); line-height: 1.02; }
  .hero__body { max-width: 40ch; }

  .hero__ctas { flex-direction: column; align-items: stretch; gap: 14px; }
  .hero__cta { width: 100%; min-height: 54px; }
  .hero__ctas .quiet-link { align-self: flex-start; }

  .hero__trust { gap: 12px 18px; font-size: 0.86rem; }
  .hero__trust li + li::before { display: none; }
}

@media (max-width: 359px) {
  .hero__trust { font-size: 0.8rem; }
}

/* ---- 05-vine.css --------------------------------------------------- */

/* ============================================================================
   Follow the Root That Calls You

   Category cut-outs alternate around one central vine. How many there are is
   decided by the database, not by this file: the vine is built from three
   slices — tip, a repeating middle, root ball — so it runs to any height, and
   the branch rows are a grid, so a ninth or twelfth shelf just extends it.
   The stem is masked to --vine-progress and draws itself as the reader moves.
   ========================================================================= */

.categories {
  --vine-progress: 0;
  /* Sized so the painted leaves stay inside the vine zone; the slice is
     508 units wide, so a narrower box also thins the stem and the leaves. */
  --vine-width: clamp(104px, 10vw, 150px);
  --vine-zone: clamp(90px, 9%, 150px);
  --first-lift: clamp(140px, 16vw, 240px);
  --branch-overlap: clamp(24px, 5vw, 78px);

  position: relative;
  padding-block: clamp(56px, 7vw, 120px) clamp(70px, 8vw, 140px);
  overflow-x: clip;
  overflow-y: visible;
}

/* This section is wider than the page's text column on purpose. Each row
   carries artwork on one side of the vine and copy on the other, and inside
   --content-width the copy is squeezed to about 11 characters a line. */
.categories .container { max-width: calc(1560px + var(--gutter) * 2); }

.categories__field { position: relative; }

.categories__vine {
  position: absolute;
  left: 50%;
  top: clamp(-190px, -14vw, -70px);
  bottom: clamp(-40px, -2vw, 0px);
  z-index: 0;
  width: var(--vine-width);
  margin-left: calc(var(--vine-width) / -2);
  pointer-events: none;
}

/* Clusters and copy always sit in front of the stem. */
.categories__branches { position: relative; z-index: 1; }

.categories__vine-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  /* Soft growing tip rather than a hard cut across the stem. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 calc(var(--vine-progress) * 100%),
    rgba(0, 0, 0, 0.35) calc(var(--vine-progress) * 100% + 26px),
    transparent calc(var(--vine-progress) * 100% + 64px)
  );
  mask-image: linear-gradient(
    to bottom,
    #000 calc(var(--vine-progress) * 100%),
    rgba(0, 0, 0, 0.35) calc(var(--vine-progress) * 100% + 26px),
    transparent calc(var(--vine-progress) * 100% + 64px)
  );
}

.categories__vine-cap { flex: 0 0 auto; width: 100%; height: auto; }

.categories__vine-stem {
  flex: 1 1 auto;
  min-height: 0;
  background-image: url("../media/design/vine/vine-mid-508.webp");
  background-repeat: repeat-y;
  background-size: 100% auto;
  background-position: top center;
}

/* ------------------------------------------------------------------ intro */

.categories__intro { max-width: min(44%, 520px); }
.categories__lede { margin-top: clamp(16px, 1.8vw, 24px); max-width: 36ch; }

/* ---------------------------------------------------------------- branches */

/* The first branch rides up beside the intro; the second drops back to a plain
   flow position so it clears the intro copy instead of landing on it. */
.categories__branches > .branch:first-child { margin-top: calc(var(--first-lift) * -1); }
.categories__branches > .branch:nth-child(2) { margin-top: 0; }

.branch {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--vine-zone) minmax(0, 1fr);
  align-items: center;
}

.branch + .branch { margin-top: calc(var(--branch-overlap) * -1); }

.branch--left .branch__link { grid-column: 1; }
.branch--right .branch__link { grid-column: 3; }

.branch__node {
  position: relative;
  grid-column: 2;
  grid-row: 1;
  justify-self: center;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--sage-muted);
  box-shadow: 0 0 0 4px var(--ivory);
  transition: background-color var(--normal) var(--ease), transform var(--normal) var(--ease);
}

.branch.is-visible .branch__node { background: var(--forest); transform: scale(1.18); }

/* Sits beside the stem rather than inside the node, so it keeps the page's
   paper as its background. On a left-hand branch the artwork occupies that
   space, so the marker moves to the other side rather than printing on it. */
.branch__marker {
  position: absolute;
  left: 50%;
  top: 50%;
  /* Clears the stem rather than printing on it. A fixed 64px sat inside the
     vine box at desktop widths, so the offset is derived from the vine's own
     width plus half the marker — it stays clear at every breakpoint. */
  transform: translate(calc(-50% - (var(--vine-width) / 2 + 34px)), -50%);
  font-style: normal;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  line-height: 1.35;
  text-align: center;
  color: var(--ink-muted);
  white-space: nowrap;
}

.branch--left .branch__marker { transform: translate(calc(-50% + (var(--vine-width) / 2 + 34px)), -50%); }

/* ------------------------------------------------------------------ link */

.branch__link {
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 34px);
  padding: 10px;
  border-radius: var(--radius-small);
  text-decoration: none;
  transform: translateY(14px);
  transition: transform var(--slow) var(--ease);
}

.branch.is-visible .branch__link { transform: none; }

/* Upcoming branches sit back through their artwork only. Dimming the whole
   branch would drop the description and CTA below AA if the reveal never ran. */
.branch__art {
  flex: 0 0 auto;
  /* The cut-outs are square and sit loose on the cream — never in a card,
     never cropped. Capped where the copy beside it still reads properly. */
  width: clamp(200px, 21vw, 348px);
  opacity: 0.74;
  transition: opacity var(--slow) var(--ease), transform var(--normal) var(--ease);
}

.branch.is-visible .branch__art { opacity: 1; }

/* The cluster always sits on the vine side of the copy. */
.branch--left .branch__link { flex-direction: row-reverse; text-align: right; }

.branch__art img {
  width: 100%;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 18px 18px rgba(32, 51, 36, 0.14));
}

/* Holds the row open for a shelf whose artwork has not been uploaded yet, so
   nothing collapses and no broken-image icon is ever shown. */
.branch__art-placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  color: var(--sage-muted);
}

.branch__art-placeholder svg { width: 46%; height: auto; }

.branch__link:hover .branch__art,
.branch__link:focus-visible .branch__art { transform: scale(1.02) translateY(-4px); }

.branch__copy { display: grid; gap: 8px; min-width: 0; }
.branch--left .branch__copy { justify-items: end; }

.branch__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.8vw, 1.72rem);
  font-weight: 500;
  line-height: 1.14;
  color: var(--forest);
  margin: 0;
}

.branch__description {
  /* ch resolves against this element's own font, which is the one being
     measured, so 32ch means what it says here. */
  max-width: 32ch;
  font-size: clamp(0.84rem, 0.9vw, 0.95rem);
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0;
}

.branch__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  position: relative;
  margin-top: 6px;
  padding-bottom: 6px;
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--forest);
}

.branch__cta::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--rule-strong);
  transition: background-color var(--normal) var(--ease), transform var(--normal) var(--ease);
  transform-origin: left;
}

.branch--left .branch__cta::after { transform-origin: right; }

.branch__link:hover .branch__cta::after,
.branch__link:focus-visible .branch__cta::after { background: var(--forest); transform: scaleY(2); }

.branch__link:hover .arrow,
.branch__link:focus-visible .arrow { transform: translateX(5px); }

.branch .arrow { transition: transform var(--normal) var(--ease); }

/* A shelf that is not open yet keeps its place on the vine but is not a link,
   so nobody is sent to a page that does not exist. */
.branch__link--inert { cursor: default; }
.branch__cta--soon { color: var(--ink-muted); font-weight: 500; }
.branch__cta--soon::after { background: var(--rule); }

/* Shelves the vine artwork does not cover are listed under it, so a new
   category is reachable without disturbing the composition. */
.categories__extras {
  margin-top: clamp(28px, 4vw, 52px);
  padding-top: clamp(20px, 3vw, 30px);
  border-top: 1px solid var(--rule);
  text-align: center;
}

.categories__extras-label {
  margin: 0 0 12px;
  font-size: 0.76rem;
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.categories__extras ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px 28px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 1023px) {
  .categories { --vine-zone: 14%; --vine-width: clamp(84px, 11vw, 118px); }
  .categories__intro { max-width: 70%; }
  .categories__branches > .branch:first-child { margin-top: clamp(24px, 4vw, 48px); }

  .branch__title { font-size: clamp(1.4rem, 2.6vw, 1.9rem); }
  .branch__link { flex-direction: column; align-items: flex-start; text-align: left; gap: 12px; }
  .branch--left .branch__link { flex-direction: column; align-items: flex-end; text-align: right; }
  .branch__art { width: 100%; }
}

@media (max-width: 767px) {
  /* A single left-rail timeline rather than branches alternating either side.
     Centred alternation leaves each shelf about 40% of the viewport — roughly
     128px of text at 320px — which is not enough for a name like
     "Wellness & Nutrition" plus a description. Pinning the vine left gives
     every block the full remaining width. */
  .categories { --vine-width: 84px; --branch-overlap: 0px; --first-lift: 0px; }

  .categories__vine {
    left: 34px;
    margin-left: calc(var(--vine-width) / -2);
    top: -8px;
    bottom: -16px;
  }

  .categories__intro { max-width: none; }

  .branch,
  .branch--left,
  .branch--right {
    grid-template-columns: 68px minmax(0, 1fr);
    align-items: start;
    column-gap: clamp(10px, 3vw, 18px);
  }

  .branch + .branch { margin-top: clamp(30px, 7vw, 52px); }

  .branch__node { grid-column: 1; justify-self: start; margin-top: 30px; margin-left: 27px; }

  /* Both sides read the same way down the rail: art above, then the words. */
  .branch--left .branch__link,
  .branch--right .branch__link {
    grid-column: 2;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding-inline: 0;
  }

  .branch--left .branch__copy,
  .branch--right .branch__copy { justify-items: start; }

  .branch__art { width: clamp(190px, 72vw, 300px); }
  .branch__marker { left: 0; top: 0; transform: none; font-size: 0.66rem; }

  .branch__title {
    font-size: clamp(1.55rem, 6.4vw, 2rem);
    /* "Wellness & Nutrition" has to break cleanly at 320px. */
    overflow-wrap: anywhere;
  }

  .branch__description { font-size: 0.94rem; }
  .branch__cta { font-size: 0.95rem; min-height: 44px; align-items: flex-end; }
}

@media (max-width: 359px) {
  .categories { --vine-width: 70px; }
  .categories__vine { left: 26px; }
  .branch, .branch--left, .branch--right { grid-template-columns: 56px minmax(0, 1fr); }
  .branch__node { margin-left: 21px; }
}

@media (prefers-reduced-motion: reduce) {
  .branch__link,
  .branch__art { opacity: 1; transform: none; transition: none; }
}

/* ---- 06-harvest-journey.css ---------------------------------------- */

/* ============================================================================
   What Nature Made Today — the editorial product shelf

   The approved design stands five harvest cut-outs on a soil ledge. Here the
   same ledge carries the shop's real products, rendered through the existing
   card partial: composition and styling change, the data and its states do not.
   ========================================================================= */

.harvest {
  position: relative;
  /*
   * Clears the hero's soil cross-section, which is *meant* to hang into this
   * section — that bleed is the whole "below the surface" idea.
   *
   * The number has to track the artwork, not a guess. The soil is 110% of the
   * viewport wide and rotated, so its rendered height grows with the viewport:
   * at 1440px it reaches 363px past the hero's own bottom edge. 26vw covers
   * that at every width, and the clamp keeps it sane on a phone and on a
   * 1920px monitor. Any less and the heading is set on top of the roots.
   */
  padding-top: clamp(120px, 26vw, 400px);
  padding-bottom: clamp(56px, 7vw, 110px);
  overflow-x: clip;
  overflow-y: visible;
}

.harvest__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px clamp(24px, 4vw, 64px);
}

.harvest__intro { max-width: 46ch; }
.harvest__lede { margin-top: clamp(16px, 1.8vw, 24px); }
.harvest__link { margin-bottom: 6px; }

/* ------------------------------------------------------------------ ledge */

.harvest__rail { position: relative; margin-top: clamp(28px, 3.4vw, 52px); }

/*
 * The ledge is gone, deliberately.
 *
 * In the approved reference the five items are transparent cut-outs standing
 * on soil. The shop's products are photographs with their own pale
 * backgrounds, and replacing the client's product images is out of scope — so
 * the ledge could never do its job here. Worse, sitting low enough to read as
 * ground put it directly behind the product names and prices, where dark green
 * text on dark soil is simply unreadable.
 *
 * A decorative layer that costs legibility is not a decoration. The markup
 * still carries it so it can be reinstated the day the catalogue has cut-outs;
 * until then it renders nothing.
 */
.harvest__ledge { display: none; }

.harvest__ledge img {
  position: absolute;
  left: 0;
  top: -16%;
  width: 100%;
  max-width: none;
  height: auto;
  /* Flipped so this ledge does not read as a repeat of the hero cross-section,
     and dissolved on all four edges so it never ends on a straight cut. */
  transform: scaleX(-1);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 11%, #000 89%, transparent 100%),
    linear-gradient(to top, transparent 0%, #000 34%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 11%, #000 89%, transparent 100%),
    linear-gradient(to top, transparent 0%, #000 34%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* The product grid sits in front of the ledge. It keeps the existing card
   partial and every one of its states — price, enquiry, stock, badges,
   ratings, wishlist — and only loses the white card behind it. */
.harvest__products { position: relative; z-index: 1; }

.harvest__products .pgrid { background: none; }

/* Cards float on the paper here rather than sitting in boxes. */
.harvest .card {
  background: none;
  border: 0;
  box-shadow: none;
}

.harvest .card__media {
  background: none;
  border-radius: 0;
}

.harvest .card__media img {
  object-fit: contain;
  filter: drop-shadow(0 18px 20px rgba(32, 51, 36, 0.16));
}

.harvest .card__body { text-align: center; }
.harvest .card__foot { justify-content: center; }

/* ============================================================================
   Nothing Reaches You Without a Story — Seed to Shelf

   Desktop pins the section and translates one continuous landscape sideways.
   Tablet portrait and below drop the pin entirely for a vertical sequence —
   the DOM order never changes, only the composition.
   ========================================================================= */

.journey {
  --journey-progress: 0;
  --band-height: clamp(270px, 45vh, 470px);
  /* Strip of paper under the band that carries the stage captions. */
  --label-strip: clamp(52px, 7vh, 68px);

  position: relative;
  padding-block: clamp(56px, 7vw, 110px) clamp(40px, 5vw, 80px);
  overflow-x: clip;
  overflow-y: visible;
}

.journey--pinned { padding-bottom: 0; }

.journey__pin { position: relative; }

.journey--pinned .journey__viewport {
  display: flex;
  flex-direction: column;
  height: 100vh;
  min-height: 640px;
  /* Clears the compressed header, which floats over the pinned viewport. */
  padding-top: calc(var(--nav-stuck-height) + clamp(12px, 2vh, 30px));
  overflow: clip;
}

.journey__head { flex: 0 0 auto; }
.journey__intro { max-width: min(50%, 640px); }
.journey__title { font-size: clamp(2.2rem, 3.2vw, 3.4rem); }
.journey__lede { margin-top: clamp(14px, 1.6vw, 22px); margin-bottom: clamp(6px, 0.8vw, 12px); max-width: 54ch; }

/* --------------------------------------------------------- pinned track */

.journey__track {
  flex: 0 0 auto;
  margin-top: auto;
  /* A margin of paper before the landscape enters, so the track starts on the
     page's own stock rather than on a hard edge of soil. */
  padding-left: 10vw;
}

.journey__scene {
  position: relative;
  height: var(--band-height);
  /* Panorama aspect ratio (1586 x 376) drives the track width. */
  width: calc(var(--band-height) * 4.218);
}

.journey__band {
  display: block;
  width: 100%;
  max-width: none;
  height: var(--band-height);
  object-fit: fill;
  /* Softens the top cut so the panorama's paper meets the page's paper
     without a visible seam. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 5%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 5%);
}

/* ------------------------------------------------------------- captions */

/*
 * The caption row sits in the viewport, not in the travelling scene.
 *
 * Positioned inside the scene the labels moved with the panorama, so at either
 * end of the scrub the first or last one was half off the screen. They belong
 * to the reader, not to the artwork: all five stay put and readable, and the
 * one being scrubbed past is picked out.
 */
.journey__captions {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  padding-top: 10px;
}

.journey__curve {
  display: block;
  width: 100%;
  height: 34px;
  margin-bottom: 4px;
  color: var(--rule-strong);
  pointer-events: none;
}

.journey__labels {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: clamp(8px, 1.6vw, 28px);
  padding-inline: var(--gutter);
}

.journey-label {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  opacity: 0.62;
  transition: opacity var(--normal) var(--ease), transform var(--normal) var(--ease);
}

.journey-label.is-active { opacity: 1; transform: translateY(-3px); }
.journey-label.is-active .journey-label__name { color: var(--forest-deep); }
.journey-label.is-active .journey-label__headline { color: var(--forest); font-weight: 700; }

.journey-label__name {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.5vw, 1.6rem);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--forest-deep);
  margin: 0;
}

.journey-label__headline { margin-top: 4px; font-size: 0.86rem; font-weight: 600; color: var(--soil); }

/* -------------------------------------------------------------- progress */

.journey__foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: clamp(14px, 2.4vh, 30px);
}

.journey-progress { display: flex; align-items: center; gap: clamp(14px, 2.6vw, 46px); list-style: none; margin: 0; padding: 0; }

.journey-progress__step {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  transition: color var(--normal) var(--ease);
}

.journey-progress__step + .journey-progress__step::before {
  content: "";
  width: clamp(16px, 2vw, 40px);
  height: 1px;
  margin-right: clamp(4px, 1vw, 14px);
  background: var(--rule);
}

.journey-progress__index { font-variant-numeric: tabular-nums; }
.journey-progress__step.is-active { color: var(--forest); font-weight: 700; }

.journey__cue {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
}

/* -------------------------------------------------- vertical composition */

/* An <ol> because the five stages are a sequence and a screen reader should
   hear that. The visible numbering is the 01/SEED label, so the list marker
   itself is dropped — scoped here rather than globally, so the commerce pages'
   ordinary lists keep their markers. */
.journey-stages {
  display: grid;
  gap: clamp(40px, 7vw, 72px);
  margin-top: clamp(34px, 5vw, 64px);
  position: relative;
  list-style: none;
  padding-left: 0;
}

/* One root line running the height of the sequence. */
.journey-stages::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 10px;
  bottom: 40px;
  width: 1px;
  background: linear-gradient(to bottom, var(--rule-strong), var(--rule) 82%, transparent);
}

.journey-stage { position: relative; padding-left: clamp(28px, 5vw, 46px); }

.journey-stage__node {
  position: absolute;
  left: 0;
  top: 8px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--sage-muted);
  box-shadow: 0 0 0 4px var(--ivory);
  transition: background-color var(--normal) var(--ease), transform var(--normal) var(--ease);
}

.journey-stage.is-visible .journey-stage__node { background: var(--forest); transform: scale(1.18); }

.journey-stage__index {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: 0.76rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.journey-stage__index span { font-weight: 700; color: var(--forest); }

.journey-stage__art { margin-top: 14px; border-radius: var(--radius-small); overflow: clip; }
.journey-stage__art img { width: 100%; height: auto; }

.journey-stage__headline {
  margin-top: 14px;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 5.4vw, 2rem);
  font-weight: 500;
  color: var(--forest);
}

.journey-stage__body { margin-top: 8px; max-width: 46ch; font-size: 0.95rem; line-height: 1.62; color: var(--ink-muted); }

@media (min-width: 768px) {
  .journey-stages { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(32px, 5vw, 56px); }
  .journey-stages::before { display: none; }
  .journey-stage { padding-left: 24px; }
}

/*
 * Once the panorama is pinned it *is* the section, so the stacked stage list
 * stops being a second telling of the same story and becomes 3,700px of
 * repetition between the journey and the newsletter.
 *
 * Only hidden when the script has actually pinned it — with JavaScript blocked
 * the class is never added and the list is what everybody gets.
 */
.journey--pinned .journey-stages { display: none; }

@media (max-width: 1023px) {
  .journey__intro { max-width: none; }

  /*
   * Below the pin breakpoint the panorama and its progress row are dead
   * weight: the track is a 4.2:1 landscape that gets clipped to a sliver, and
   * the stage captions inside it ("GROWER", "HARVEST") are sized for a 17vw
   * box and spill out of it. The vertical stage list below carries exactly the
   * same five stages as real text, so nothing is lost by dropping them.
   */
  .journey__track,
  .journey__foot { display: none; }

  .journey__pin { position: relative; }

.journey--pinned .journey__viewport {
    display: block;
    height: auto;
    min-height: 0;
    padding-top: 0;
    overflow: visible;
  }
}

/* ---- 07-newsletter-footer.css -------------------------------------- */

/* ============================================================================
   Let Something Good Take Root — the newsletter band that hands over to the
   footer's soil curve.
   ========================================================================= */

.newsletter {
  position: relative;
  padding-top: clamp(48px, 7vw, 110px);
  padding-bottom: clamp(30px, 4vw, 60px);
  text-align: center;
  /* shop.css paints this band dark green; the approved treatment is paper. */
  background: none;
  color: var(--ink);
}

.newsletter__inner { display: grid; justify-items: center; }
.newsletter__eyebrow { color: var(--forest); }
.newsletter__eyebrow::after { display: none; }
.newsletter__title { font-size: clamp(2.2rem, 3.6vw, 3.7rem); color: var(--forest); }
.newsletter__lede { margin-top: 12px; max-width: 52ch; }

.newsletter__form {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 10px;
  width: min(660px, 100%);
  margin-top: clamp(22px, 3vw, 34px);
}

.newsletter__input {
  flex: 1;
  min-width: 0;
  min-height: 56px;
  padding: 12px 20px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-button);
  background: var(--white);
  color: var(--ink);
  font-size: 1rem;
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}

.newsletter__input::placeholder { color: rgba(28, 38, 31, 0.45); }

.newsletter__input:focus-visible {
  outline: none;
  border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(23, 61, 43, 0.16);
}

.newsletter__input[aria-invalid="true"] { border-color: var(--terracotta-text); }

.newsletter__submit { flex: 0 0 auto; min-height: 56px; }

.newsletter__message { min-height: 26px; margin-top: 12px; font-size: 0.9rem; font-weight: 600; }
.newsletter__message--error { color: var(--terracotta-text); }
.newsletter__message--success { color: var(--forest); }

@media (max-width: 767px) {
  .newsletter { text-align: left; }
  .newsletter__inner { justify-items: start; }
  .newsletter__lede { max-width: none; }
  .newsletter__form { flex-direction: column; width: 100%; }
  .newsletter__submit { width: 100%; }
}

/* ============================================================================
   Root footer — the page settles into the soil it started in.
   ========================================================================= */

.footer {
  position: relative;
  z-index: 1;
  margin-top: clamp(60px, 9vw, 150px);
  padding-bottom: clamp(24px, 3vw, 40px);
  background: var(--forest);
  color: var(--sage);
  overflow-x: clip;
}

/* The curve is pulled above the block so the dark shape reads as an organic
   edge rather than a straight band. */
.footer__curve { position: absolute; left: 0; right: 0; bottom: 100%; margin-bottom: -1px; pointer-events: none; }
.footer__curve img { width: 100%; height: clamp(96px, 12vw, 190px); object-fit: fill; }

.footer__basket {
  position: absolute;
  right: clamp(-40px, -2vw, 0px);
  bottom: calc(100% - clamp(18px, 3vw, 44px));
  z-index: 2;
  width: clamp(180px, 23vw, 350px);
  max-width: none;
  height: auto;
  pointer-events: none;
}

.footer__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.1fr);
  gap: clamp(28px, 4vw, 72px);
  padding-top: clamp(24px, 4vw, 60px);
}

/* --------------------------------------------------------------- brand */

.footer__brand { display: grid; justify-items: start; gap: 4px; }
.footer__seal { width: clamp(56px, 6vw, 78px); margin-bottom: 10px; color: var(--sage); }

.footer__wordmark {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 2.6vw, 2.6rem);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ivory);
}

.footer__tagline { font-size: 0.94rem; color: var(--sage-muted); }

/* --------------------------------------------------------------- groups */

.footer__groups { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(16px, 2.5vw, 40px); }

.footer-group__title,
.footer-group__toggle {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ivory);
}

.footer-group__title { margin-bottom: 14px; }
.footer-group__toggle { display: none; }
.footer-group__list { display: grid; gap: 2px; list-style: none; margin: 0; padding: 0; }

.footer-group__list a {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  font-size: 0.94rem;
  color: var(--sage);
  text-decoration: none;
  transition: color var(--fast) var(--ease);
}

.footer-group__list a:hover,
.footer-group__list a:focus-visible { color: var(--ivory); text-decoration: underline; text-underline-offset: 4px; }

/* --------------------------------------------------------------- strip */

.footer__strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px clamp(20px, 3vw, 48px);
  margin-top: clamp(28px, 4vw, 56px);
  padding-top: clamp(18px, 2.4vw, 28px);
  border-top: 1px solid rgba(220, 232, 212, 0.24);
}

.footer__contact,
.footer__trust { display: flex; flex-wrap: wrap; align-items: center; gap: 8px clamp(14px, 2vw, 28px); list-style: none; margin: 0; padding: 0; }

.footer__contact a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--sage);
  text-decoration: none;
}

.footer__contact a:hover,
.footer__contact a:focus-visible { color: var(--ivory); }

/* Social profile links — only the ones set in Settings render (see the footer
   partial). Circular icon buttons that pick up their glyph's currentColor. */
.footer__social { display: flex; align-items: center; gap: 10px; list-style: none; margin: 0; padding: 0; }
.footer__social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: var(--sage); text-decoration: none;
  transition: color 0.15s, background 0.15s, border-color 0.15s, transform 0.12s;
}
.footer__social a:hover,
.footer__social a:focus-visible {
  color: var(--forest-deep); background: var(--ivory); border-color: var(--ivory);
  transform: translateY(-1px);
}
.footer__social svg { display: block; }
@media (prefers-reduced-motion: reduce) { .footer__social a { transition: color 0.15s, background 0.15s, border-color 0.15s; } .footer__social a:hover { transform: none; } }

.footer__trust {
  margin-inline: auto;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sage-muted);
}

.footer__trust li + li::before { content: "\2022"; margin-right: clamp(14px, 2vw, 28px); color: var(--honey); }

.footer__top {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 10px 22px;
  border: 1px solid rgba(220, 232, 212, 0.4);
  border-radius: var(--radius-button);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ivory);
  text-decoration: none;
  transition: background-color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.footer__top:hover,
.footer__top:focus-visible { background: rgba(220, 232, 212, 0.12); border-color: var(--sage); color: var(--ivory); }

/*
 * Tracking is the one thing people come to a footer looking for, so it is the
 * only filled control down here — a ghost button beside a ghost button reads as
 * two equal afterthoughts, which is what this must not be.
 */
.footer__track {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 10px 22px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-button);
  background: var(--sage);
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--forest);
  text-decoration: none;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}

.footer__track:hover,
.footer__track:focus-visible { background: var(--ivory); border-color: var(--ivory); color: var(--forest-deep); }

.footer__track svg { flex: 0 0 auto; }

/* --------------------------------------------------------------- legal */

/* Editable footer note (Settings → Footer text), above the copyright line. */
.footer__note {
  margin: clamp(14px, 2vw, 22px) 0 0;
  text-align: center;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--sage-muted);
  max-width: 68ch;
  margin-inline: auto;
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 12px;
  margin-top: clamp(10px, 1.6vw, 20px);
  font-size: 0.78rem;
  color: var(--sage-muted);
}

.footer__legal a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 10px; color: var(--sage-muted); text-decoration: none; }
.footer__legal ul { display: flex; flex-wrap: wrap; gap: 8px 12px; list-style: none; margin: 0; padding: 0; }
.footer__legal li + li::before, .footer__legal ul::before { content: "\2022"; margin-right: 12px; }
.footer__legal a:hover, .footer__legal a:focus-visible { color: var(--ivory); text-decoration: underline; text-underline-offset: 4px; }

/* ------------------------------------------------------------ responsive */

@media (max-width: 1023px) {
  .footer__inner { grid-template-columns: minmax(0, 1fr); }
  .footer__basket { width: clamp(170px, 30vw, 260px); }
}

@media (max-width: 767px) {
  /* Groups collapse into accordions; the brand, trust strip and legal line
     stay visible at all times. */
  .footer__groups { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .footer-group { border-top: 1px solid rgba(220, 232, 212, 0.2); }
  .footer-group__title { display: none; }

  .footer-group__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: 52px;
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
  }

  .footer-group__chevron { position: relative; width: 14px; height: 14px; flex: 0 0 auto; }

  .footer-group__chevron::before,
  .footer-group__chevron::after {
    content: "";
    position: absolute;
    inset: 50% 0 auto 0;
    height: 1.5px;
    background: var(--sage);
    transition: transform var(--normal) var(--ease);
  }

  .footer-group__chevron::after { transform: rotate(90deg); }
  .footer-group.is-open .footer-group__chevron::after { transform: rotate(0deg); }

  .footer-group__list { padding-bottom: 12px; }

  .footer__basket { right: -14vw; width: 190px; opacity: 0.9; }
  .footer__strip { flex-direction: column; align-items: flex-start; }
  .footer__track { order: 1; }
  .footer__top { order: 2; }
  .footer__trust { margin-inline: 0; }
  .footer__trust li + li::before { display: none; }
  .footer__legal { justify-content: flex-start; }
  .footer__legal ul::before { display: none; }
}

@media (max-width: 359px) {
  .footer__basket { display: none; }
}

/* ---- 08-bands.css -------------------------------------------------- */

/* ============================================================================
   Editorial bands, voices and journal cards

   The three-up blocks the homepage uses for its wellness/care/food bands, its
   "what we hold ourselves to" list, real customer voices and journal teasers.
   One rhythm for all four so the lower half of the page reads as one page.
   ========================================================================= */

.section-head { max-width: 46ch; }

.grid-bands {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 268px), 1fr));
  gap: clamp(20px, 3vw, 44px);
}

.band { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.band__art {
  width: 100%;
  height: auto;
  aspect-ratio: 8 / 5;
  object-fit: cover;
  border-radius: var(--radius-small);
  margin-bottom: 6px;
}

.band__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.8vw, 1.7rem);
  font-weight: 500;
  line-height: 1.16;
  color: var(--forest);
  margin: 0;
}

.band__title a { color: inherit; text-decoration: none; }
.band__title a:hover,
.band__title a:focus-visible { text-decoration: underline; text-underline-offset: 4px; }

.band__body {
  margin: 0;
  max-width: 40ch;
  font-size: clamp(0.9rem, 0.95vw, 1rem);
  line-height: 1.62;
  color: var(--ink-muted);
}

.band .quiet-link { margin-top: auto; align-self: flex-start; }

/* ------------------------------------------------------------------ voices */

.voice {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: clamp(18px, 2.2vw, 28px);
  background: var(--ivory-warm);
  border-radius: var(--radius-small);
}

.voice__stars { margin: 0; color: var(--honey-text); font-size: 0.95rem; letter-spacing: 0.08em; }

.voice__body {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.06rem, 1.3vw, 1.28rem);
  line-height: 1.42;
  color: var(--forest);
}

.voice__who {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: 0.84rem;
  color: var(--ink-muted);
}

.voice__verified {
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--forest);
  background: var(--sage);
  padding: 2px 8px;
  border-radius: 10px;
}

.voice__who a { color: var(--forest); text-decoration: underline; text-underline-offset: 3px; }

/* ---- 09-touch-targets.css ------------------------------------------ */

/* ============================================================================
   Touch targets

   Below 768px every control a finger is meant to hit gets at least 44px of
   height. The rules live in one place because the components they cover were
   written at different times and sized for a mouse.

   Deliberately *not* included: links inside running prose ("…just tell us",
   "…on our contact page"). WCAG exempts inline links in a sentence, and
   padding them out breaks the line rhythm of the paragraph they sit in — the
   fix would be worse than the finding.
   ========================================================================= */

@media (max-width: 767px) {
  /* Every button, including the small variant the commerce pages use for
     Remove, Clear filters, View order and Order again. */
  .btn,
  .btn--sm,
  .linkbtn {
    min-height: 44px;
  }

  /* .linkbtn is a text button; it needs the height as padding, not as a box. */
  .linkbtn {
    display: inline-flex;
    align-items: center;
    padding-block: 11px;
  }

  /* Breadcrumbs. A 37x18 "Home" is a real navigation control, not prose. */
  .crumbs a,
  .crumbs span {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /*
   * The facet panel does double duty: the account tabs, the child-category
   * list on a category page and the refine filters all use it. Its links were
   * 19px tall.
   */
  .facets ul { gap: 0; }

  .facets ul a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .facets label {
    min-height: 44px;
  }

  /* Journal category chips. */
  .journal__filters a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Pagination, on listings and on the reviews block. */
  .pager a,
  .pager span,
  .reviews__pager a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* The product page's disclosure panels. */
  .panel > summary,
  .review-form > summary,
  .coupon__toggle > summary {
    min-height: 44px;
    align-items: center;
  }

  /* The rating on a product page jumps to the reviews; it is a control. */
  .pdp__rating a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* A product card's title is the card's primary target. */
  .card__name a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Basket line titles and account order numbers — both use .line__name. */
  .line__name a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Journal card titles, on the journal index and in the homepage teaser. */
  .jcard__title a,
  .band__title a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* The category tag above an article is a filter link, not prose. */
  .eyebrow a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---- 10-prose.css -------------------------------------------------- */

/* ============================================================================
   Long-form pages — information pages and journal articles
   ========================================================================= */

/*
 * A centred measure for CMS pages.
 *
 * They were running flush-left inside the full container: 664px of text with
 * roughly 700px of empty paper beside it on a desktop screen, which reads as
 * an unfinished layout rather than a deliberate one. The article template
 * already centred itself; these now match it.
 */
.infopage {
  width: 100%;
  /* 68ch matches .prose's own measure, so the heading and the body share one
     left edge. Giving the wrapper a *wider* measure centres the wrapper but
     leaves the narrower text column flush-left inside it, which just moves the
     imbalance somewhere less obvious. */
  max-width: 68ch;
  margin-inline: auto;
}

/* Inside the wrapper the measure belongs to the wrapper. */
.infopage .prose { max-width: none; }

/*
 * Cormorant has a much smaller x-height than Manrope, so a serif heading set a
 * couple of pixels above the sans body optically reads *smaller* than the
 * paragraph beneath it. On an article, `.prose h3` at 20px against 17px body
 * looked subordinate to its own content. Both levels get a real step up and
 * the weight to hold it.
 */
.prose h2 {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.3vw, 2.15rem);
  font-weight: 600;
  line-height: 1.14;
  color: var(--forest);
  margin: clamp(30px, 3.4vw, 46px) 0 12px;
}

.prose h3 {
  font-family: var(--font-display);
  font-size: clamp(1.32rem, 1.7vw, 1.6rem);
  font-weight: 600;
  line-height: 1.2;
  color: var(--forest);
  margin: clamp(24px, 2.6vw, 34px) 0 8px;
}

/* The first heading in a body of text should not push away from the standfirst
   above it as hard as one that follows a paragraph. */
.prose > h2:first-child,
.prose > h3:first-child { margin-top: 0; }

.prose p,
.prose li { color: var(--ink-muted); }

.prose a {
  color: var(--forest);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.prose a:hover,
.prose a:focus-visible { text-decoration-thickness: 2px; }

.prose strong { color: var(--ink); font-weight: 600; }

/* Bullets in the brand's own colour rather than the browser's black dot. */
.prose ul { list-style: none; padding-left: 0; }

.prose ul li {
  position: relative;
  padding-left: 22px;
}

.prose ul li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--sage-muted);
}

.prose ol { padding-left: 22px; }
.prose ol li::marker { color: var(--ink-muted); }

/* ---------------------------------------------------------- facet panels */

/*
 * The refine panel, the child-category list and the account tabs all share
 * `.facets`, and their headings were <h3> under a page whose title was an
 * <h2>. With the page title promoted to <h1> those became a level-skip, so
 * the markup moved to <h2> — and the panel's heading style, which keyed on
 * h3 alone, has to follow it.
 */
.facets h2 {
  font: 600 13px/1 var(--font-body);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--honey-text);
  margin-bottom: 12px;
}

/* ============================================================================
   Order tracking

   Two fields and a button. It is deliberately narrower than the prose around
   it: a form that runs the full measure of an article reads as a long task,
   and this one takes about fifteen seconds.
   ========================================================================= */

.track-form {
  max-width: 30rem;
  margin-top: clamp(20px, 3vw, 30px);
  padding: clamp(22px, 3vw, 34px);
  border: 1px solid var(--line);
  border-radius: var(--radius-button);
  background: var(--ivory-warm);
}

.track-form .field:last-of-type { margin-bottom: clamp(18px, 2.4vw, 26px); }

.track-form .btn { width: 100%; justify-content: center; }

/* The order number is read off an email and typed in, so it is set in a face
   where a 0 cannot be mistaken for an O. */
.mono {
  font-family: ui-monospace, "SFMono-Regular", "Consolas", "Liberation Mono", monospace;
  font-size: 0.94em;
  letter-spacing: 0.02em;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--sage);
  color: var(--forest-deep);
  white-space: nowrap;
}

@media (max-width: 479px) {
  .track-form { padding: 20px 18px; }
}

/* ---- 11-fixes.css -------------------------------------------------- */

/* ============================================================================
   Fixes found in the page-by-page review
   ========================================================================= */

/*
 * The basket line's thumbnail tile.
 *
 * `.line__img` is styled to hold an image, but the basket never has one — the
 * cart query selects no media, so the markup renders an empty <span> and the
 * page shows a bare beige square that reads as a broken image.
 *
 * Rather than reach into the cart service to add a thumbnail (presentation is
 * not a reason to change a service), the empty tile gets the same leaf mark the
 * product cards use when a product has no picture. `:empty` means the rule
 * turns itself off the day a real thumbnail is passed in.
 */
.line__img:empty {
  background:
    radial-gradient(circle at 50% 46%, var(--sage) 0 42%, transparent 42%),
    var(--ivory-warm);
  position: relative;
}

.line__img:empty::after {
  content: "";
  position: absolute;
  inset: 0;
  background: no-repeat center / 28px 28px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233d7256' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M12 21c0-6 3-10 8-12-1 7-4 10-8 12Z'/%3E%3Cpath d='M12 21c0-5-2.5-8.5-7-10 .8 6 3.5 8.5 7 10Z'/%3E%3Cpath d='M12 21v-6'/%3E%3C/svg%3E");
  opacity: 0.55;
}

/*
 * The empty-state block.
 *
 * `.empty` carries an <h2> that inherited the section-title scale, so "Your
 * basket is empty" and "Nothing here yet" were set almost as large as the page
 * title above them and fought it for attention.
 */
.empty {
  /* A hard white panel with a dashed outline reads as a placeholder that
     failed to load. On the approved paper ground an empty shelf should look
     composed, not broken: warm paper, a hairline, no dashes. */
  background: var(--ivory-warm);
  border: 1px solid var(--rule);
  border-radius: var(--radius-small);
}

.empty h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2.05rem);
  font-weight: 500;
  color: var(--forest);
  margin-bottom: 8px;
}

.empty p { color: var(--ink-muted); }

/*
 * Summary panels — basket and checkout.
 *
 * The definition list puts the label and its figure on one row. A long product
 * name in the checkout summary wraps to three lines while its price stays
 * pinned to the first, leaving the number floating away from what it belongs
 * to. Aligning the pair to the top keeps them together.
 */
.summary dl { align-items: start; }
.summary dt { padding-right: 10px; }

/* Money reads as a column, so the digits have to line up. */
.summary dd,
.line__total { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------- saved items */

/*
 * Saved items are a grid of cards with a Remove control under each one. The
 * cards are different heights — one product has a rating row, another does not
 * — so each Remove sat at its own card's natural bottom and the row of them
 * came out ragged.
 *
 * Stretching the card to the grid row's height puts every Remove on the same
 * baseline, which is what makes a row of repeated controls read as a row.
 */
.saved { height: 100%; }
.saved .card { flex: 1 1 auto; }

.saved form {
  margin-top: 10px;
  text-align: right;
}

/* ------------------------------------------------------- journal cards */

/*
 * An article with no hero image renders `.jcard__blank`, which had no styling
 * of its own — so the card showed a bare pale rectangle that reads as a failed
 * image. It gets the same leaf mark the product cards and the basket use, so
 * every missing-image slot on the shop looks like one deliberate thing.
 */
.jcard__blank {
  display: block;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(circle at 50% 46%, var(--sage) 0 26%, transparent 26%),
    var(--ivory-warm);
  position: relative;
}

.jcard__blank::after {
  content: "";
  position: absolute;
  inset: 0;
  background: no-repeat center / 34px 34px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233d7256' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M12 21c0-6 3-10 8-12-1 7-4 10-8 12Z'/%3E%3Cpath d='M12 21c0-5-2.5-8.5-7-10 .8 6 3.5 8.5 7 10Z'/%3E%3Cpath d='M12 21v-6'/%3E%3C/svg%3E");
  opacity: 0.5;
}

/* --------------------------------------------------------------- footer */

@media (max-width: 767px) {
  /*
   * The trust claims lose their bullet separator at this width, which left
   * "CASH ON DELIVERY  DELIVERED ACROSS PAKISTAN" reading as one run-on
   * phrase. Two short claims are clearer stacked than they are chained
   * together with nothing between them.
   */
  .footer__trust {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
}

/* ------------------------------------------- footer decoration vs. content */

/*
 * The harvest basket and the soil curve both hang *above* the footer by design
 * — that overhang is what makes the boundary read as an edge rather than a
 * band. But the footer is later in the DOM than the newsletter, so at equal
 * z-index its decoration painted over the newsletter's submit button: on
 * mobile the basket sat squarely on "Join the field notes".
 *
 * Lifting the newsletter above the footer keeps the overhang and puts the
 * control back on top. Decoration must never cover something you can press.
 */
.newsletter { position: relative; z-index: 2; }

/*
 * The regulatory disclaimer under a product's claims.
 *
 * Deliberately outside the accordion the panels use: a disclaimer folded away
 * behind a summary is one nobody has read. Quiet, but present and selectable.
 */
.product__disclaimer {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--ink-soft);
}

/*
 * The product page overflowed a 320px screen by 64px, on some products only.
 *
 * `.pdp` is a grid that declares its columns only from 900px up. Below that it
 * falls back to a single IMPLICIT track, and an implicit track is `auto`: it
 * sizes to the content's min-content width and will not shrink past it. On a
 * product whose gallery reported a 368px minimum that is 48px wider than the
 * screen, and the whole page scrolled sideways.
 *
 * Declaring the single column as minmax(0, 1fr) gives it permission to be
 * narrower than its contents, which is what every other grid on the site
 * already does.
 *
 * Scoped below 900px rather than declared outright: this file loads after
 * shop.css, so an unconditional rule here would beat shop.css's own
 * min-width:900px two-column rule at equal specificity and flatten the desktop
 * layout to one column.
 */
@media (max-width: 899px) {
  .pdp { grid-template-columns: minmax(0, 1fr); }
}

/*
 * "Price confirmed on enquiry" is a sentence wearing the price class, and
 * `.price` sets white-space: nowrap so that "Rs. 1,450" can never break across
 * two lines. Prose inherits that and refuses to wrap at all, holding the whole
 * product column open at 368px on a 320px screen.
 *
 * The nowrap is right for a number and wrong for a sentence, so only the
 * sentence is let go.
 */
.price--enquiry { white-space: normal; }

/*
 * The shop-wide notice — "we are closed for Eid, orders resume Monday".
 *
 * Sits under the header rather than inside it: the header is sticky, and a
 * notice that follows you down the page is an alert, not a note. This one
 * scrolls away like the rest of the page.
 */
.shop-notice {
  margin: 0;
  padding: 10px 20px;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--honey, #f3e6c8);
  border-bottom: 1px solid var(--line);
}

/* ---- 12-why.css ---------------------------------------------------- */

/* ============================================================================
   Why NURIVA — the standards, set out as a journey

   An editorial composition, not a row of cards: a narrow column of copy on the
   left and four principles threaded along one organic line on the right, over
   a green wave that carries the trust indicators.

   The layout is a grid throughout. Absolute positioning is used only for the
   decorative connector, its leaves and the background botanicals — never for
   the content itself, which has to reflow at every width on its own.
   ========================================================================= */

.why {
  --olive: #79894d;
  --olive-soft: #a6ad75;
  --why-line: rgba(121, 137, 77, 0.55);
  /* The marker's own size, so the connector and the copy can both key off it. */
  --marker: clamp(44px, 4vw, 62px);

  position: relative;
  padding-top: clamp(64px, 8vw, 130px);
  padding-bottom: 0;
  overflow-x: clip;
}

/*
 * The section fades in but must not move. The shared reveal offsets an element
 * by 18px until it is seen, and on a full-width block that briefly puts its box
 * 18px into the section below — a real overlap, and one the collision check is
 * right to flag. The intro and the four principles carry the movement instead.
 */
.why[data-reveal] { transform: none; }

/* -------------------------------------------------------- decoration */

.why__branch {
  position: absolute;
  top: clamp(-10px, 1vw, 30px);
  right: clamp(-40px, -1vw, 0px);
  width: clamp(180px, 22vw, 340px);
  height: auto;
  color: var(--olive);
  opacity: 0.16;
  pointer-events: none;
}

/*
 * The foot of the copy column, which the four staggered principles leave empty.
 * Absolutely positioned inside the grid container, so it occupies the hole
 * without ever being able to push a word out of place.
 */
.why__roots {
  position: absolute;
  left: 0;
  bottom: clamp(50px, 6vw, 110px);
  width: clamp(240px, 27vw, 400px);
  height: auto;
  color: var(--olive);
  opacity: 0.14;
  transform: scaleX(-1);
  pointer-events: none;
}

.why__sprig {
  width: clamp(84px, 8vw, 120px);
  height: auto;
  margin-top: clamp(20px, 2.4vw, 34px);
  color: var(--olive);
  opacity: 0.55;
}

/* ------------------------------------------------------------ layout */

.why__inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 35fr) minmax(0, 65fr);
  gap: clamp(32px, 5vw, 90px);
  align-items: start;
  padding-bottom: clamp(70px, 9vw, 150px);
}

/*
 * The four principles make a much taller column than the copy, which would
 * otherwise leave a screen-high hole under the left column. Sticking the copy
 * keeps the question in view while the answers scroll past it, and the hole
 * closes on its own.
 */
@media (min-width: 1024px) {
  .why__intro {
    /* A sticky grid item travels within its grid area, and that area is the
       full height of the row — the tall principles column — however the item
       itself is aligned inside it. */
    position: sticky;
    align-self: start;
    /* Clear of the compressed header, the only fixed thing above. */
    top: clamp(96px, 11vh, 150px);
  }
}

.why__title {
  font-family: var(--font-display);
  font-size: clamp(2.3rem, 3.5vw, 3.9rem);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.015em;
  color: var(--forest);
  margin: clamp(14px, 1.6vw, 22px) 0 0;
  /* The line breaks are the browser's, but they should break evenly rather
     than leaving one word alone on the last line. */
  text-wrap: balance;
}

.why__lede {
  max-width: 34ch;
  margin: clamp(16px, 1.8vw, 26px) 0 0;
  font-size: clamp(0.96rem, 1vw, 1.05rem);
  line-height: 1.7;
  color: var(--ink-muted);
}

/* ----------------------------------------------------------- journey */

.why__journey { position: relative; }

/*
 * The connector covers whatever box the principles occupy. Its viewBox is
 * rewritten to that box in pixels by the script, so the curve it measures
 * through the markers is drawn 1:1 with no stretching. Until then the authored
 * fallback path is stretched to fit, which is only ever approximately right —
 * good enough for a reader with the script blocked, not good enough to ship as
 * the normal case.
 */
.why__path {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--why-line);
  pointer-events: none;
  z-index: 0;
}

/*
 * Drawn in as the section arrives. The dash pattern itself is set inline from
 * the path's measured length by the script — see organica-ui.js — because a
 * normalised `pathLength` does not scale it in Chrome. With no script the path
 * carries no dash pattern at all and is simply solid, which is the right
 * fallback: undrawn is invisible.
 */
.why.is-visible .why__path path {
  animation: why-draw 1400ms var(--ease) 220ms forwards;
}

@keyframes why-draw { to { stroke-dashoffset: 0; } }

/*
 * Leaves are positioned by script on the connector's midpoints, as x/y of their
 * own centre — hence the translate before the rotation. They are added only
 * where nothing else is, so this layer never needs to fight the copy.
 */
.why__leaves {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

.why__leaf {
  position: absolute;
  width: clamp(46px, 4.6vw, 74px);
  height: auto;
  color: var(--olive);
  opacity: 0.38;
  transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
  pointer-events: none;
}

.why__principles {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  row-gap: clamp(38px, 5vw, 74px);
  list-style: none;
  margin: 0;
  padding: 0;
}

/*
 * Staggered rather than stacked, so the four read as stops along a route.
 * Column spans, not pixel offsets — the composition holds at any width and a
 * long title simply wraps inside its own span.
 */
.why-principle { display: flex; align-items: flex-start; gap: clamp(14px, 1.6vw, 24px); min-width: 0; }
.why-principle:nth-child(1) { grid-column: 2 / 9; }
.why-principle:nth-child(2) { grid-column: 6 / 13; }
.why-principle:nth-child(3) { grid-column: 1 / 8; }
.why-principle:nth-child(4) { grid-column: 5 / 12; }

.why-principle__marker {
  flex: 0 0 auto;
  /* Positioned so it paints above the mobile rail, which is an absolutely
     positioned pseudo-element and would otherwise strike through the numeral. */
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--marker);
  height: var(--marker);
  border: 1px solid var(--why-line);
  border-radius: 50%;
  /* Cream, not transparent: the connector passes behind the markers and must
     not show through the numeral. */
  background: var(--ivory);
  font-family: var(--font-display);
  font-size: calc(var(--marker) * 0.36);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--olive);
}

.why-principle__body { min-width: 0; padding-top: clamp(2px, 0.6vw, 8px); }

.why-principle__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 6px;
}

.why-principle__icon { display: inline-flex; color: var(--olive); flex: 0 0 auto; }

.why-principle__title {
  font-family: var(--font-display);
  font-size: clamp(1.24rem, 1.6vw, 1.62rem);
  font-weight: 600;
  line-height: 1.16;
  color: var(--forest);
}

.why-principle__text {
  margin: 0;
  max-width: 42ch;
  font-size: clamp(0.9rem, 0.95vw, 1rem);
  line-height: 1.62;
  color: var(--ink-muted);
}

/* -------------------------------------------------------------- band */

.why__band {
  position: relative;
  margin-top: clamp(-40px, -3vw, -10px);
  color: var(--sage);
}

/* The wave is the band's own top edge, so the two must not leave a seam. */
.why__wave {
  display: block;
  width: 100%;
  height: clamp(70px, 8vw, 140px);
  color: var(--forest);
  margin-bottom: -1px;
}

.why__band-inner {
  background: var(--forest);
  padding: clamp(6px, 1vw, 18px) 0 clamp(30px, 4vw, 56px);
}

.why__values {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 2vw, 34px);
  width: 100%;
  max-width: calc(var(--content-width) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
  list-style: none;
}

.why__values li {
  display: flex;
  align-items: center;
  gap: clamp(9px, 1.2vw, 15px);
  min-width: 0;
  color: var(--sage);
  font-size: clamp(0.84rem, 0.95vw, 0.98rem);
  line-height: 1.35;
}

/* Hairline dividers between the values, never around them — a border on all
   four sides is a badge, and a badge is what this must not look like. */
.why__values li + li {
  padding-left: clamp(14px, 2vw, 34px);
  border-left: 1px solid rgba(220, 232, 212, 0.24);
}

.why__values svg { flex: 0 0 auto; color: var(--sage); opacity: 0.9; }

.why__promise {
  max-width: calc(var(--content-width) + var(--gutter) * 2);
  margin: clamp(24px, 3vw, 44px) auto 0;
  padding-inline: var(--gutter);
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.5vw, 1.5rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ivory);
}

/* ============================================================ responsive */

/* ---- below the two-column composition: one vertical journey ------------ */

/*
 * The stagger and its connector need a column of their own to work in. Once the
 * copy stacks above the principles and the text runs the full width, the curve
 * has nowhere left to travel that is not behind a sentence — it ends up broken
 * into stubs by the routing, which reads worse than not drawing it. So below
 * 1024px the four become one vertical rail, which is the same journey told the
 * way a narrow screen can tell it.
 */
@media (max-width: 1023px) {
  .why__inner { grid-template-columns: minmax(0, 1fr); }
  .why__lede { max-width: 52ch; }

  /* Stacked, the copy runs the full width and the top-right branch would sit
     straight across the headline. The sprig under the lede carries the
     botanical note on its own here. */
  .why__branch,
  .why__roots { display: none; }

  .why__principles {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(40px, 6vw, 64px);
  }

  .why-principle:nth-child(1),
  .why-principle:nth-child(2),
  .why-principle:nth-child(3),
  .why-principle:nth-child(4) { grid-column: 1; }

  /* A measured curve cannot describe a straight rail, and the leaves come off
     with it — both are replaced by the hairline below. */
  .why__path,
  .why__leaves { display: none; }

  .why__principles::before {
    content: "";
    position: absolute;
    left: calc(var(--marker) / 2);
    top: calc(var(--marker) / 2);
    bottom: calc(var(--marker) / 2);
    width: 1px;
    background: linear-gradient(to bottom, var(--why-line), var(--why-line) 82%, transparent);
  }

  /* A full-width measure at tablet sizes is too long to read comfortably; the
     principles keep their own. */
  .why-principle__text { max-width: 60ch; }
}

/* ---- mobile: a vertical journey, rebuilt rather than shrunk ------------ */

@media (max-width: 767px) {
  .why { padding-top: 64px; }
  .why__inner { gap: clamp(30px, 8vw, 48px); padding-bottom: clamp(48px, 12vw, 80px); }

  .why__title {
    font-size: clamp(38px, 11vw, 52px);
    line-height: 1.02;
  }

  .why__lede { max-width: none; font-size: 15.5px; line-height: 1.6; }
  .why__sprig { margin-top: 20px; }

  .why__principles { row-gap: clamp(48px, 13vw, 72px); }

  .why-principle__text { font-size: 15px; line-height: 1.6; }

  /*
   * Four columns of icon-plus-label at 320px is four unreadable slivers, and a
   * scrolling rail hides half of them behind a gesture nothing advertises.
   * Two rows of two shows all four at full size, which is the point of them.
   */
  .why__values {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
  }

  .why__values li {
    align-items: flex-start;
    padding: 14px 14px 14px 0;
    font-size: 0.92rem;
  }

  /* Dividers follow the grid rather than the source order: a rule between the
     columns, and one between the rows. */
  .why__values li + li { padding-left: 0; border-left: 0; }
  .why__values li:nth-child(even) { padding-left: 16px; border-left: 1px solid rgba(220, 232, 212, 0.24); }
  .why__values li:nth-child(n + 3) { border-top: 1px solid rgba(220, 232, 212, 0.24); }

  .why__promise { font-size: clamp(1.05rem, 5vw, 1.3rem); text-align: left; }
}

/* Narrower than this, two labels side by side wrap to three lines each and the
   pair reads worse than a plain list. */
@media (max-width: 399px) {
  .why__values { grid-template-columns: minmax(0, 1fr); }
  .why__values li { padding: 12px 0; font-size: 0.9rem; }
  .why__values li:nth-child(even) { padding-left: 0; border-left: 0; }
  .why__values li + li { border-top: 1px solid rgba(220, 232, 212, 0.24); }
}

/* ----------------------------------------------------------- motion */

/* The script leaves the offset at zero under reduced motion, so there is
   nothing to animate away from — this only stops the keyframe running. */
@media (prefers-reduced-motion: reduce) {
  .why.is-visible .why__path path { animation: none; }
}

/* ---- 13-card-add.css ----------------------------------------------- */

/* ============================================================================
   Adding to the basket from a listing card

   The card used to end at the price: buying anything meant opening the product
   page first, on every screen size. This is the control that fixes that, and
   the two honest alternatives for cards that cannot take one.

   Loaded after shop.css, so the card's own layout is untouched — this adds a
   row to the foot of it and styles what sits in that row.
   ========================================================================= */

.card__act {
  margin-top: auto;
  padding-top: clamp(10px, 1.4vw, 14px);
}

/*
 * `margin-top: auto` above only pushes this to the bottom if the card body is
 * a column that fills the card. Without it a short card (no description, no
 * rating) puts its button halfway up while its neighbour's sits at the foot,
 * and a row of cards reads as ragged.
 */
.card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.card { display: flex; flex-direction: column; }

.card__act form { margin: 0; }

.card__add {
  width: 100%;
  justify-content: center;
  /* The mobile audit's floor. A control this important must not be the one
     thing on the page that is awkward to hit. */
  min-height: 44px;
}

/* A product with sizes goes to its own page to be chosen from, so its control
   is deliberately quieter than the one that buys. */
.card__add.btn--ghost {
  display: inline-flex;
  align-items: center;
}

/* Nothing is for sale here, so nothing should look like a buy button. */
.card__ask {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9rem;
}

@media (max-width: 767px) {
  .card__act { padding-top: 10px; }
  .card__add { font-size: 0.92rem; }
}

/* Below this the grid is two cards wide and the label has to fit in half a
   phone; "Add to basket" wraps to two lines and the button doubles in height. */
@media (max-width: 400px) {
  .card__add { padding-inline: 10px; font-size: 0.86rem; }
}
