/* ==========================================================================
   BioCheese — design tokens
   --------------------------------------------------------------------------
   TYPEFACES, per Identity Guidelines p.9-12. All three brand faces are
   self-hosted as .woff2 in assets/fonts/ and declared below, so no Adobe
   Fonts kit is required:

     Halyard Display     page titles (Bold), all body text           --font-display
     NT Wagner           section headings at the large size (incl.
                         "What people are saying", "Fresh from Bio" and
                         "Awards"), small section labels, accordion
                         titles, filter buttons and tags, the tagline --font-logo
     Perfectly Nineties  reserved for emphasis; no structural job    --font-script

   The site makes no external font request. Nothing is fetched from Google
   Fonts or an Adobe kit; the fallback after a brand face is the reader's own
   system UI font.

   Only the faces the site actually renders are shipped — Halyard Display
   Regular 400, Medium 500, SemiBold 600, Bold 700 and Black 900, plus
   Perfectly Nineties Bold and NT Wagner. There is no 800 file, so nothing
   asks for 800. NT Wagner and Perfectly Nineties ship 700 only, so every
   rule that sets either face states 700. Adding a weight means adding
   both the .woff2 and its @font-face rule.
   ========================================================================== */
/* --- Halyard Display ------------------------------------------------- */
@font-face {
  font-family: 'Halyard Display';
  src: url('../fonts/fonnts.com-Halyard_Display_Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Halyard Display';
  src: url('../fonts/fonnts.com-Halyard_Display_Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Halyard Display';
  src: url('../fonts/fonnts.com-Halyard_Display_SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Halyard Display';
  src: url('../fonts/fonnts.com-Halyard_Display_Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Halyard Display';
  src: url('../fonts/fonnts.com-Halyard_Display_Black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* --- Perfectly Nineties ---------------------------------------------- */
@font-face {
  font-family: 'Perfectly Nineties';
  src: url('../fonts/PerfectlyNineties-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --- NT Wagner ------------------------------------------------------- */
@font-face {
  font-family: 'NT Wagner';
  src: url('../fonts/nt_wagner-webfont.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --font-display: 'Halyard Display', system-ui, sans-serif;
  --font-script:  'Perfectly Nineties', Georgia, 'Times New Roman', Times, serif;
  --font-logo:    'NT Wagner', Georgia, 'Times New Roman', Times, serif;
  --font-body:    var(--font-display);

  /* --- Primary palette (Identity Guidelines v1.0, p.14-20) --------------- */
  --nourishing-green:  #083215;  /* headings, body copy, nav */
  --herb-garden-green: #006920;  /* logo green */
  --zesty-green:       #B0EE5A;  /* logo flash, accents */
  --everyday-glow:     #EFFFBF;  /* pale lime, gradient end */
  --cream-linen:       #FFF3E5;  /* panels, gradient start */
  --bright-white:      #FFFFFF;

  /* --- Cheddar Shred accents (p.21-24) ----------------------------------- */
  --sunny-melt:        #FFC832;
  --roast-capsicum:    #CF5300;
  --extra-cheesy:      #FDFB85;

  /* --- Pizza Shred accents (p.25-28) ------------------------------------- */
  --oven-glow:         #F6472C;
  --pizza-dough:       #FFF4B6;
  --golden-slice:      #EEEC5A;

  /* --- Semantic aliases: use THESE in components, not the names above ---- */
  --ink:            var(--nourishing-green);
  --brand:          var(--herb-garden-green);
  --accent:         var(--zesty-green);
  --surface:        var(--cream-linen);
  --surface-raised: var(--bright-white);
  /* Product pages recolour this one token from their own accent palette. */
  --product-accent: var(--roast-capsicum);
  --rule:           rgba(8, 50, 21, .35);

  --page-gradient: linear-gradient(180deg, var(--cream-linen) 0%, var(--everyday-glow) 100%);

  --container: 1200px;
  --gutter: clamp(20px, 3.2vw, 38px);
  --radius-card: 14px;
  --radius-panel: 22px;
  --shadow-card: 0 6px 22px rgba(8, 50, 21, .07), 0 1px 3px rgba(8, 50, 21, .05);

  --header-h: clamp(104px, 11vw, 132px);
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-optical-sizing: auto;
  color: var(--ink);
  background: var(--cream-linen);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3, p, ul { margin: 0; }
ul { list-style: none; padding: 0; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ==========================================================================
   Header — "Menu" left, logo centred, social icons right.
   --------------------------------------------------------------------------
   Fixed to the top of the viewport. It was already out of flow (absolute),
   and every page already reserves --header-h beneath it, so fixing it moves
   nothing. At rest it is transparent over the hero or the page gradient; as
   soon as the page scrolls, main.js adds .is-solid and it takes --surface,
   so nothing scrolling underneath shows through.
   The row runs to the edges of the screen, not the 1200px container: Menu
   and the icons sit --gutter in from each side. The two outer columns are
   equal 1fr tracks, so the logo stays centred whatever their contents.
   ========================================================================== */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  height: var(--header-h);
  display: flex; align-items: center;
  transition: background-color .2s ease;
}
.site-header.is-solid { background: var(--surface); }
.site-header--page.is-solid {
  background-color: var(--everyday-glow);   /* past the gradient's end: its last colour */
  background-image: var(--page-gradient);
  background-repeat: no-repeat;
  background-size: 100% var(--page-h, 100vh);
  background-position: 0 var(--page-y, 0px);
}
.site-header .container {
  max-width: none;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
}
/* Jumping to an anchor or tabbing to a control lands below the header. */
html { scroll-padding-top: var(--header-h); }
.menu-toggle {
  justify-self: start;
  font-family: var(--font-display);
  font-size: clamp(16px, 1.6vw, 19px);
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
  padding: 4px 0;
  transition: color .2s ease;
}
.site-header--on-photo:not(.is-solid) .menu-toggle,
.site-header--on-photo:not(.is-solid) .social { color: var(--surface-raised); }

/* Social icons - one colour, set by the same rule as Menu. Sized against
   Menu's type (clamp(16px, 1.6vw, 19px)): 1.2x, so the glyphs carry the same
   visual weight as the bold word. The padding makes each a 32px+ target. */
.social {
  justify-self: end;
  display: flex; align-items: center;
  gap: clamp(4px, 0.6vw, 8px);
  color: var(--ink);
  transition: color .2s ease;
  margin-right: -6px;   /* the link padding, so the icon itself sits on the gutter */
}
.social__link { display: block; padding: 6px; transition: opacity .18s ease; }
.social__link:hover { opacity: .7; }
.social__icon { display: block; width: clamp(19px, 1.92vw, 23px); height: auto; aspect-ratio: 1; }
.brand-logo { justify-self: center; }
.brand-logo img {
  height: clamp(72px, 8.5vw, 96px);
  width: auto;
}

/* ---------- menu overlay ---------- */
.menu-panel {
  position: fixed; inset: 0; z-index: 200;
  background: var(--page-gradient);
  display: grid; place-items: center;
  opacity: 0; visibility: hidden; transition: opacity .28s ease, visibility .28s;
}
.menu-panel[data-open='true'] { opacity: 1; visibility: visible; }
.menu-panel__close {
  position: absolute; top: 0; left: 0; right: 0;
  height: var(--header-h);
  display: flex; align-items: center;
  padding-inline: var(--gutter);
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(17px, 1.7vw, 20px);
}
.menu-panel__nav { display: grid; gap: clamp(10px, 1.6vw, 18px); text-align: center; }
.menu-panel__nav a {
  font-family: var(--font-display);
  font-size: clamp(28px, 4.6vw, 52px);
  font-weight: 700; line-height: 1.08; letter-spacing: -.02em;
  text-transform: uppercase;
  transition: color .18s ease;
}
/* Menu options turn Zesty Green on hover and on keyboard focus (30 Sep
   brief). The focus outline stays as well. */
.menu-panel__nav a:hover,
.menu-panel__nav a:focus-visible { color: var(--accent); }

/* ==========================================================================
   Home — hero
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  background: #2b1c10;
  overflow: hidden;
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: center 48%; }
.hero::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(12,20,10,.42) 0%, rgba(12,20,10,0) 30%),
    linear-gradient(0deg,   rgba(12,20,10,.50) 0%, rgba(12,20,10,0) 42%);
  pointer-events: none;
}
.hero__inner { position: relative; z-index: 2; padding-bottom: clamp(26px, 3.4vw, 52px); }
.eyebrow {
  font-family: var(--font-logo);
  font-size: clamp(12px, 1.25vw, 14px);
  font-weight: 700; text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--surface-raised);
}
.hero__grid {
  display: grid;
  /* 0.70fr against the panel's 1fr gives the strip 445px at 1440, which the
     two renders split into 213px each - the midpoint between the 154px they
     drew before the tile was fixed and the 274px a 1.1fr column gave. It also
     returns the featured panel to its original 636px. */
  grid-template-columns: minmax(0, 0.70fr) minmax(0, 1fr);
  /* Space between "Discover the range" and the Featured Product panel:
     beside it above 860px, above it once stacked. */
  gap: clamp(36px, 4.4vw, 64px);
  align-items: end;
  margin-top: clamp(12px, 1.6vw, 20px);
}

/* range strip of pack shots */
.pack-strip { display: flex; gap: clamp(10px, 1.4vw, 18px); align-items: flex-end; }
.pack-strip a { flex: 0 1 clamp(96px, 11vw, 132px); transition: transform .25s ease; }
.pack-strip a:hover { transform: translateY(-6px); }
.pack-strip img { filter: drop-shadow(0 10px 22px rgba(0,0,0,.28)); }

/* featured product panel */
.featured {
  background: var(--surface);
  border-radius: var(--radius-panel);
  display: grid; grid-template-columns: 1fr minmax(0, 46%);
  gap: clamp(14px, 2vw, 26px);
  align-items: stretch;
  overflow: hidden;
}
.featured__body { padding: clamp(18px, 2.2vw, 28px); align-self: center; }
.featured__label {
  font-family: var(--font-logo);
  font-size: clamp(10px, 1vw, 12px);
  font-weight: 700; text-transform: uppercase; letter-spacing: .13em;
}
.featured__title {
  font-family: var(--font-display);
  font-size: clamp(17px, 1.9vw, 24px);
  font-weight: 700; line-height: 1.28; letter-spacing: -.015em;
  margin-top: clamp(8px, 1vw, 14px);
  max-width: 19ch;
}
.featured__media { align-self: stretch; }
.featured__media img { height: 100%; width: 100%; object-fit: cover; }

/* ==========================================================================
   Inner page shell (Range, Product)
   ========================================================================== */
.page {
  min-height: 100svh;
  background: var(--page-gradient);
  padding-top: var(--header-h);
  padding-bottom: clamp(56px, 8vw, 110px);
}
.page-title {
  font-family: var(--font-display);
  font-weight: 700; text-transform: uppercase;
  font-size: clamp(29px, 3.7vw, 52px);
  line-height: 1.06;
  letter-spacing: -.02em;
  text-align: center;
  margin-block: clamp(18px, 2.4vw, 34px) clamp(22px, 3vw, 40px);
}

/* ---------- filter tabs ---------- */
.filters { display: flex; flex-wrap: wrap; gap: clamp(14px, 2vw, 28px); margin-bottom: clamp(20px, 2.6vw, 34px); }
/* NT Wagner ships 700 only, so the selected tab no longer steps from 500 to
   700. It is marked by colour as well as the underline: --brand against the
   --ink of the other tabs. The underline follows the text colour. */
.filters button {
  font-family: var(--font-logo);
  font-size: clamp(13px, 1.45vw, 17px);
  font-weight: 700;
  padding-bottom: 3px;
  border-bottom: 1.5px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.filters button[aria-selected='true'] { color: var(--brand); border-bottom-color: currentColor; }

/* ---------- product grid ---------- */
.product-grid {
  display: flex; flex-wrap: wrap;
  gap: clamp(16px, 2.2vw, 32px);
}
.product-card {
  flex: 0 0 clamp(150px, 17.9vw, 215px);
  background: transparent;
  border-radius: var(--radius-card);
  box-shadow: none;
  padding: clamp(14px, 1.6vw, 22px);
  display: flex; flex-direction: column; gap: 12px;
  transition: transform .25s ease, box-shadow .25s ease;
}
.product-card:hover { transform: translateY(-5px); background: color-mix(in srgb, var(--surface) 55%, transparent); }
.product-card__media {
  aspect-ratio: 1 / 1;
  display: grid; place-items: center;
}
.product-card__media img { max-height: 100%; width: auto; object-fit: contain; }
.product-card__name {
  font-family: var(--font-display);
  font-size: clamp(13px, 1.3vw, 16px);
  font-weight: 500; line-height: 1.35;
  text-align: center;
  margin-top: auto;
}
.product-card[hidden] { display: none; }

/* ==========================================================================
   Product detail
   ========================================================================== */
.product-title {
  font-family: var(--font-display);
  font-weight: 700; text-transform: uppercase;
  color: var(--product-accent);
  font-size: clamp(24px, 3.2vw, 44px);
  line-height: 1.1;
  letter-spacing: -.02em;
  text-align: center;
  max-width: 24ch;
  margin: clamp(16px, 2.2vw, 30px) auto clamp(26px, 3.4vw, 46px);
}
.product-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.94fr) minmax(0, 1fr);
  gap: clamp(22px, 3vw, 44px);
  align-items: start;
}
/* --- product media -------------------------------------------------------
   .product-media is the swappable slot. data-mode="carousel" today;
   a 360 spinner drops into the same slot as data-mode="spin" later
   without touching the surrounding layout.
   ------------------------------------------------------------------------ */
.product-media { display: flex; flex-direction: column; gap: clamp(12px, 1.5vw, 18px); }
.product-shot {
  position: relative;
  background: transparent;
  border-radius: var(--radius-panel);
  padding: clamp(22px, 3vw, 48px);
  display: grid; place-items: center;
  min-height: clamp(240px, 32vw, 420px);
  overflow: hidden;
}
.product-shot__track { display: grid; place-items: center; width: 100%; height: 100%; }
.product-shot__slide {
  grid-area: 1 / 1;
  display: grid; place-items: center;
  opacity: 0; transition: opacity .35s ease;
  pointer-events: none;
}
.product-shot__slide[data-active='true'] { opacity: 1; pointer-events: auto; }
.product-shot__slide img { max-height: clamp(200px, 26vw, 340px); width: auto; object-fit: contain; }

.product-shot__nav {
  position: absolute; top: 50%; translate: 0 -50%;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); color: var(--ink);
  opacity: 0; transition: opacity .2s ease;
}
.product-shot:hover .product-shot__nav,
.product-shot__nav:focus-visible { opacity: 1; }
.product-shot__nav[data-dir='prev'] { left: 12px; }
.product-shot__nav[data-dir='next'] { right: 12px; }
.product-shot__nav::before {
  content: ''; width: 8px; height: 8px;
  border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor;
}
.product-shot__nav[data-dir='prev']::before { rotate: 225deg; translate: 2px 0; }
.product-shot__nav[data-dir='next']::before { rotate: 45deg; translate: -2px 0; }

.product-dots { display: flex; justify-content: center; gap: 8px; }
.product-dots button {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--rule);
  transition: background .2s ease, scale .2s ease;
}
.product-dots button[aria-current='true'] { background: var(--ink); scale: 1.25; }
.product-copy { padding-top: clamp(4px, 1vw, 14px); }
.product-copy p {
  font-size: clamp(13px, 1.35vw, 16px);
  line-height: 1.75;
  text-align: center;
}

/* ---------- accordion ---------- */
.accordion { margin-top: clamp(26px, 3.4vw, 46px); }
.accordion__item { border-bottom: 1px solid var(--rule); }
.accordion__trigger,
.accordion__heading {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: clamp(9px, 1.05vw, 14px) 0;
  font-family: var(--font-display);
  font-size: clamp(13px, 1.4vw, 17px);
  font-weight: 500;
  text-align: left;
}
.accordion__trigger::after {
  content: ''; width: 8px; height: 8px; flex: none; opacity: .45;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .25s ease;
}
.accordion__trigger[aria-expanded='true']::after { transform: rotate(-135deg) translate(-2px, -2px); }
.accordion__panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .3s ease;
}
.accordion__item[data-open='true'] .accordion__panel { grid-template-rows: 1fr; }
.accordion__panel > div { overflow: hidden; }
.accordion__panel p, .accordion__panel li {
  font-size: clamp(13px, 1.35vw, 16px); line-height: 1.7; text-align: left;
}
.accordion__panel > div > * { padding-bottom: clamp(12px, 1.5vw, 18px); }
/* A static item (e.g. Stockists): titled like the rows above it but always
   open, with no arrow and no toggle. Its title is .accordion__heading, not a
   button, so the accordion script leaves it alone. Nothing here animates, so
   the panel need not clip - which keeps a hover lift or focus ring whole. */
.accordion__item--static .accordion__panel > div { overflow: visible; }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  background: var(--ink);
  color: var(--surface);
  padding-block: clamp(34px, 4.5vw, 60px);
}
.site-footer .container {
  display: flex; flex-wrap: wrap; gap: 20px 40px;
  align-items: center; justify-content: space-between;
}
.site-footer nav { display: flex; flex-wrap: wrap; gap: clamp(14px, 2vw, 28px); }
.site-footer a, .site-footer p { font-size: clamp(12px, 1.25vw, 15px); }
.site-footer a:hover { color: var(--accent); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 860px) {
  .hero__grid { grid-template-columns: 1fr; }
  /* Stacked, the strip has the whole container, which would take each render
     to 396px - half the viewport apiece. 430px holds them at ~210px, matching
     the two-column size above. */
  .pack-strip { max-width: 430px; }
  .featured { border-radius: var(--radius-panel); }
  .product-layout { grid-template-columns: 1fr; }
  .product-copy p { text-align: left; }
}
@media (max-width: 560px) {
  .product-card { flex: 1 1 calc(50% - 10px); }
  .pack-strip a { flex: 0 1 92px; }
  .featured { grid-template-columns: 1fr; }
  .featured__media { max-height: 180px; }
}

/* ==========================================================================
   Shared page furniture
   ========================================================================== */
[hidden] { display: none !important; }
.container--narrow { max-width: 860px; }

.section { padding-block: clamp(44px, 6vw, 92px); }
.section--tight { padding-block: clamp(28px, 3.6vw, 52px); }
.section--cream { background: var(--surface); }

.section-head {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: baseline; justify-content: space-between;
  margin-bottom: clamp(20px, 2.6vw, 34px);
}
.section-title {
  font-family: var(--font-logo);
  font-size: clamp(21px, 2.5vw, 34px);
  font-weight: 700; line-height: 1.15; letter-spacing: -.02em;
  text-wrap: balance;
}
.section-title--center { text-align: center; margin-bottom: clamp(22px, 3vw, 40px); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: clamp(13px, 1.3vw, 15px); font-weight: 600; letter-spacing: .01em;
  padding: clamp(10px, 1.1vw, 14px) clamp(20px, 2.2vw, 30px);
  border-radius: 999px;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
  white-space: nowrap;
}
.btn--solid { background: var(--ink); color: var(--surface); }
.btn--solid:hover { background: var(--brand); }
.btn--ghost { border: 1.5px solid var(--rule); color: var(--ink); }
.btn--ghost:hover { border-color: var(--ink); }

/* ---------- placeholder markers ---------- */
.ph {
  background: rgba(193, 85, 0, .07);
  box-shadow: inset 0 -1px 0 rgba(193, 85, 0, .35);
  border-radius: 2px;
}
.ph-note {
  font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--product-accent); opacity: .75; margin-top: 10px;
}
.ph-note--center { text-align: center; }

/* ---------- header tagline ----------
   Packaging lockup: "Less Dairy." and "More Life." sit either side of the
   centred logo, sentence case. It lives in the fixed header on every page, so
   it stays beside the logo when the header turns solid on scroll. It is laid
   over the header band (absolute, not part of the grid) so the two halves line
   up with the logo, and it takes no pointer events, so Menu, the logo and the
   icons stay clickable through it. */
.site-header__tagline {
  position: absolute; z-index: 1;
  pointer-events: none;
  --logo-h: clamp(72px, 8.5vw, 96px);   /* mirrors .brand-logo img height */
  top: 0; height: var(--header-h);
  left: 50%;
  /* "Less Dairy." (5.3647em) is wider than "More Life." (4.9771em), so centring
     the row as a whole would leave the logo off-centre inside the gap. Nudging
     the row by half the difference puts equal clear space either side. */
  /* ...and down by 0.03em, which centres the words' cap height on the logo
     rather than centring their line box (NT Wagner sits high in its box).
     The offset is not proportional to the type size, so it is re-measured
     whenever the size changes; tuned at 26.6px, the size the lockup renders
     beside the logo, which is constant wherever this layout applies. */
  translate: calc(-50% - 0.1938em) 0.03em;
  display: flex; align-items: center;
  /* The flex gap spans the centred logo, so the surplus splits evenly either
     side: logo width (the mark is square) plus 0.55em of clear space per side
     — comfortably more than twice NT Wagner's 0.248em word space. */
  gap: calc(var(--logo-h) * 1.007 + 1.1em);
  font-family: var(--font-logo);
  /* Cap height matches the height of the word "cheese" inside the logo,
     measured off logo.png: the word sits on a slight upward arc and spans
     193px of the 993px asset, i.e. 19.44% of the logo's height. NT Wagner's
     cap is 0.7002em, so the size is 0.1944 / 0.7002 = 0.2776 x the logo
     height, against the logo's clamp(72px, 8.5vw, 96px) — the two scale
     together. */
  font-size: clamp(20px, 2.36vw, 26.6px); font-weight: 700;
  /* NT Wagner's default line box is close to 2em. Left alone it makes the
     stacked lockup twice as tall as the words, which runs it into the hero
     content on small screens. */
  line-height: 1;
  letter-spacing: normal;
  /* Same colour as Menu and the icons in each state: --ink on the page
     gradient and on the solid header, white with a soft shadow over the home
     photograph. All of them change together over the header's .2s fade. */
  color: var(--ink);
  white-space: nowrap;
  transition: color .2s ease, text-shadow .2s ease, opacity .2s ease, visibility .2s;
}
.site-header--on-photo:not(.is-solid) .site-header__tagline {
  color: var(--surface-raised);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .45);
}

/* ---------- about intro ---------- */
.about-intro { display: grid; justify-items: center; gap: clamp(20px, 2.4vw, 32px); text-align: center; }
.about-intro__body {
  max-width: 62ch;
  font-size: clamp(15px, 1.6vw, 20px); line-height: 1.65;
}

/* ---------- feature / tick row ---------- */
.feature-row {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(18px, 3.4vw, 56px);
}
.feature-row--start { justify-content: flex-start; gap: clamp(14px, 2vw, 28px); }
.feature-row--compact { justify-content: center; gap: clamp(12px, 1.8vw, 26px); margin-top: clamp(18px, 2.2vw, 28px); }
.feature { display: grid; justify-items: center; gap: 8px; text-align: center; }
.feature span {
  font-size: clamp(11px, 1.15vw, 13px); font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
}
.feature__icon { width: clamp(26px, 2.8vw, 34px); height: auto; color: var(--brand); }
.feature-row--compact .feature__icon { width: 24px; }

/* ---------- story cards ---------- */
.card-grid {
  display: grid; gap: clamp(16px, 2.2vw, 30px);
  grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
}
.story-card {
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .25s ease, box-shadow .25s ease;
}
.story-card:hover { transform: translateY(-5px); box-shadow: 0 14px 34px rgba(8, 50, 21, .12); }
.story-card__media { aspect-ratio: 4 / 3; }
.story-card__media img { width: 100%; height: 100%; object-fit: cover; }
.story-card__kicker {
  font-family: var(--font-logo);
  font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--brand);
  padding: clamp(14px, 1.6vw, 20px) clamp(14px, 1.6vw, 20px) 0;
}
.story-card__title {
  font-family: var(--font-display);
  font-size: clamp(15px, 1.6vw, 19px); font-weight: 600; line-height: 1.3;
  letter-spacing: -.01em;
  padding: 8px clamp(14px, 1.6vw, 20px) clamp(14px, 1.6vw, 20px);
}
.story-card__excerpt {
  font-size: clamp(13px, 1.3vw, 15px); line-height: 1.6;
  padding: 0 clamp(14px, 1.6vw, 20px) clamp(16px, 1.8vw, 22px);
  margin-top: -6px;
}

/* ---------- testimonials ---------- */
.quote-grid { display: grid; gap: clamp(16px, 2.2vw, 30px); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.quote {
  margin: 0; padding: clamp(20px, 2.4vw, 32px);
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  display: grid; gap: 14px; align-content: start;
}
.quote p { font-size: clamp(14px, 1.5vw, 17px); line-height: 1.6; }
.quote cite {
  font-style: normal; font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; opacity: .7;
}

/* ---------- prose ---------- */
.prose { max-width: 68ch; margin-inline: auto; display: grid; gap: clamp(14px, 1.6vw, 20px); }
.prose p { font-size: clamp(14px, 1.45vw, 17px); line-height: 1.75; }
.prose__lead { font-size: clamp(16px, 1.75vw, 21px) !important; line-height: 1.6 !important; }

.wide-figure { margin: clamp(34px, 4.5vw, 64px) 0 0; }
.wide-figure img { width: 100%; aspect-ratio: 21 / 9; object-fit: cover; border-radius: var(--radius-panel); }
.wide-figure figcaption { text-align: center; }

/* ---------- awards ---------- */
/* One trophy above each award, painted in --ink so it is the same green as
   the award names and the Awards heading. The PNG ships as #006920 (Herb
   Garden Green), so rather than filter-hacking it towards the target or baking
   a second colour into the file, the artwork is used as an alpha mask over the
   token - exact, and it follows --ink if the token ever moves. That needs an
   element whose own background can show through, hence a span rather than an
   img. The box is sized explicitly, so there is nothing to shift as the mask
   loads. The award text barely scales (13px to 16px) so the icon is close to
   constant: 36px up to 1241px wide, 42px from 1449px. The artwork fills 196 of
   the PNG's 256 rows, so the trophy you see is 28px to 32px. The 3px sits on
   top of the .award grid's own 5px gap. */
.award__icon {
  width: clamp(36px, 2.9vw, 42px);
  height: clamp(36px, 2.9vw, 42px);
  margin-bottom: 3px;
  background-color: var(--brand);
  -webkit-mask: url('../img/icon-award-256.png') center / contain no-repeat;
          mask: url('../img/icon-award-256.png') center / contain no-repeat;
}
.awards { display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(14px, 2vw, 26px); }
/* The awards read as text on the page, not as tiles — no fill, no corner
   radius. The padding stays: it is what sets them apart from each other and
   from the heading, and the spacing is not changing. */
.award {
  padding: clamp(16px, 1.8vw, 24px) clamp(20px, 2.4vw, 32px);
  display: grid; gap: 5px; justify-items: center; min-width: 170px; max-width: 240px;
  /* The awards are flex items, so they all take the tallest one's height. A
     grid container defaults to align-content: normal, i.e. stretch, which
     shares that surplus out across all four auto rows - so an award whose name
     runs to one line instead of two had its icon row grown by 5.5px and every
     line under it pushed down by the same. Packing the rows to the top keeps
     the trophy, the year and the name on shared lines across all three. */
  align-content: start;
  /* Equal columns. Sized to their own text the three came out 195/240/240 wide,
     which centres the row as a whole but leaves the middle award - and its
     trophy - off the page's centre line, out of step with the heading above.
     Same basis and grow factor on each puts them on an even rhythm. */
  flex: 1 1 170px;
}
/* Stays small, but reads as part of the award rather than as a label pinned
   above it: the +0.1em tracking comes off and it takes --ink, so the block is
   one colour of type instead of two greens. */
.award__year { font-size: 11px; font-weight: 700; color: var(--ink); }
.award__name { font-family: var(--font-display); font-size: clamp(13px, 1.4vw, 16px); font-weight: 600; text-align: center; }
.award__body { font-size: 11px; letter-spacing: .04em; opacity: .65; text-align: center; }

/* ---------- split sections ---------- */
.split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(22px, 3.4vw, 56px); align-items: center;
  margin-top: clamp(38px, 5vw, 76px);
}
.split--reverse .split__media { order: 2; }
.split__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-panel); }
.split__body { display: grid; gap: clamp(12px, 1.5vw, 18px); }
.split__body p { font-size: clamp(14px, 1.45vw, 17px); line-height: 1.7; }

/* ---------- accordion as a whole page ---------- */
.accordion--page .accordion__trigger { font-size: clamp(15px, 1.6vw, 19px); padding-block: clamp(14px, 1.6vw, 20px); }
.accordion--page .accordion__item:first-child { border-top: 1px solid var(--rule); }

/* ---------- contact ---------- */
.contact-layout {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(26px, 3.6vw, 56px); align-items: start;
}
.contact-form { display: grid; gap: clamp(14px, 1.6vw, 20px); justify-items: start; }
.field { display: grid; gap: 6px; width: 100%; }
.field label { font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.field input, .field select, .field textarea {
  font: inherit; font-size: clamp(14px, 1.4vw, 16px);
  color: var(--ink); background: var(--surface-raised);
  border: 1px solid var(--rule); border-radius: 10px;
  padding: 11px 14px; width: 100%;
}
.field textarea { resize: vertical; }
.contact-aside { display: grid; gap: clamp(10px, 1.4vw, 16px); }
.contact-aside p { font-size: clamp(13px, 1.4vw, 16px); line-height: 1.7; }
.contact-details { display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; margin: 0; }
.contact-details dt { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; opacity: .7; }
.contact-details dd { margin: 0; font-size: clamp(13px, 1.4vw, 16px); }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer__grid {
  display: grid; gap: clamp(26px, 3.4vw, 54px);
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr) minmax(0, .7fr);
  align-items: start;
}
.site-footer__tagline {
  font-family: var(--font-logo);
  font-size: clamp(20px, 2.2vw, 28px); font-weight: 700; line-height: 1.15;
  letter-spacing: -.02em;
}
.site-footer__fine { margin-top: 12px; opacity: .75; max-width: 30ch; }
.site-footer__nav { display: grid; gap: 8px; }
.site-footer__nav a { font-family: var(--font-display); }
.site-footer__base {
  margin-top: clamp(26px, 3.4vw, 46px); padding-top: clamp(14px, 1.8vw, 22px);
  border-top: 1px solid rgba(255, 243, 229, .18);
}
.site-footer__base p { opacity: .65; }

.newsletter { display: grid; gap: 8px; font-family: var(--font-display); }
.newsletter__label { font-family: var(--font-display); font-size: clamp(16px, 1.8vw, 21px); font-weight: 700; letter-spacing: -.01em; }
.newsletter__note { font-family: var(--font-display); opacity: .75; }
.newsletter__field { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.newsletter__field input {
  flex: 1 1 200px; font: inherit; font-family: var(--font-display); font-size: 14px;
  background: rgba(255, 243, 229, .1); color: var(--surface);
  border: 1px solid rgba(255, 243, 229, .28); border-radius: 999px;
  padding: 11px 18px;
}
.newsletter__field input::placeholder { color: rgba(255, 243, 229, .5); }
.newsletter .btn--solid { background: var(--accent); color: var(--ink); }
.newsletter .btn--solid:hover { background: var(--surface); }
.site-footer .ph-note { color: var(--accent); opacity: .6; }
.site-footer .ph { background: rgba(255, 243, 229, .1); box-shadow: inset 0 -1px 0 rgba(255, 243, 229, .3); }

/* ==========================================================================
   Product page accent themes — one token, per the guidelines' palettes
   ========================================================================== */
.page--cheddar { --product-accent: var(--roast-capsicum); }
.page--pizza   { --product-accent: var(--oven-glow); }
/* Product name colour, set per product page (28 Sep follow-up brief):
   Roast Capsicum 173C for the cheddar products and Pizza Shred, Creamy 3537C
   for the two BioCreamy tubs, the approved #1b2b55 for Feta and BioMarinated,
   and Herb Garden Green for Block and Slices Original and everything else.
   Zesty Green is not used for any product name. Only the product name reads
   --product-accent on these pages; the recipe links below keep the hover
   colour they had. */
.page--accent-roast-capsicum     { --product-accent: var(--roast-capsicum); }     /* 173C  #CF5300 */
.page--accent-nourishing-green   { --product-accent: var(--nourishing-green); }   /* 3537C #083215 */
.page--accent-herb-garden-green  { --product-accent: var(--herb-garden-green); }  /* #006920 */
.page--accent-feta-blue          { --product-accent: #1b2b55; }
.page--cheddar .recipe-list a:hover { color: var(--roast-capsicum); }
.page--pizza .recipe-list a:hover   { color: var(--oven-glow); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 900px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr; }
  .site-footer__nav { grid-column: 1 / -1; grid-template-columns: repeat(3, 1fr); }
  .contact-layout { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .split, .split--reverse { grid-template-columns: 1fr; }
  .split--reverse .split__media { order: 0; }
  .site-footer__grid { grid-template-columns: 1fr; }
  .site-footer__nav { grid-template-columns: repeat(2, 1fr); }
}

/* ==========================================================================
   Product data — nutrition, claims, recipe tip
   ========================================================================== */
.product-weight {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand); text-align: center; margin-bottom: 10px;
}
.claims-note {
  text-align: center; margin-top: clamp(14px, 1.8vw, 22px);
  font-size: clamp(11px, 1.15vw, 13px); opacity: .6; max-width: 52ch; margin-inline: auto;
}
.certs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 12px;
}
.certs li {
  background: var(--surface-raised); border-radius: 999px;
  padding: 9px 18px;
  font-size: clamp(11px, 1.2vw, 13px); font-weight: 600;
  letter-spacing: .03em;
}

.table-scroll { overflow-x: auto; }
.nutrition {
  width: 100%; border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: clamp(12px, 1.3vw, 15px);
}
.nutrition th, .nutrition td { padding: 7px 10px; text-align: right; }
.nutrition thead th {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  border-bottom: 1px solid var(--rule);
}
.nutrition tbody th {
  text-align: left; font-weight: 400; padding-left: 0;
}
.nutrition tbody tr + tr th, .nutrition tbody tr + tr td {
  border-top: 1px solid rgba(8, 50, 21, .12);
}
.nutrition td:last-child { padding-right: 0; }
.nutrition__meta {
  font-size: clamp(11px, 1.2vw, 13px); font-weight: 600;
  opacity: .7; margin-bottom: 10px;
}
.nutrition__storage {
  margin-top: 14px;
  font-size: clamp(12px, 1.25vw, 14px); line-height: 1.6; opacity: .85;
}

.recipe-tip {
  margin-top: clamp(22px, 2.8vw, 34px);
  background: var(--surface);
  border-radius: var(--radius-card);
  padding: clamp(18px, 2.2vw, 28px);
  display: grid; gap: 10px; justify-items: start;
}
.recipe-tip__kicker {
  font-family: var(--font-display);
  font-size: clamp(14px, 1.5vw, 17px); font-weight: 700;
  letter-spacing: -.01em; color: var(--product-accent);
}
.recipe-tip p { font-size: clamp(13px, 1.35vw, 15px); line-height: 1.65; text-align: left; }

/* flat pack artwork sits edge-to-edge in its card rather than floating */
.product-card--flat .product-card__media { aspect-ratio: 4 / 5; }
.product-card--flat .product-card__media img {
  max-height: 100%; height: 100%; width: auto; object-fit: contain;
  border-radius: 6px;
}

.site-footer__address {
  font-family: var(--font-display);
  font-style: normal; margin-top: 14px; line-height: 1.7; opacity: .8;
  font-size: clamp(12px, 1.25vw, 14px);
}
.site-footer__address a:hover { color: var(--accent); }
.contact-details a:hover { color: var(--brand); }

/* ---------- breadcrumb ---------- */
.crumb { margin-bottom: clamp(-4px, 0.4vw, 8px); }
/* Back link. It was the only navigation on the site rendered through an
   opacity wash, which greyed --ink out to a colour no token produces. It now
   takes the same treatment as the filter row on Range and Blog - the pages it
   points back to: --font-display at 500, full-strength --ink, and --brand on
   hover, the same hover the contact details use. */
.crumb a {
  font-size: clamp(12px, 1.25vw, 14px); font-weight: 500;
  letter-spacing: .02em; color: var(--ink);
}
.crumb a:hover { color: var(--brand); }
/* Product pages: the back link is a single "<" (aria-label="Back"), in the
   same place as the old text link, at 22px so a lone glyph reads. Padding
   gives it a 44px target; the matching negative margin keeps the glyph where
   the text started and the title where it was. */
.crumb .crumb__back {
  display: inline-block;
  font-size: 22px; font-weight: 700;
  min-width: 44px; min-height: 44px; line-height: 44px;
  margin: -12px 0 -12px -14px; padding-inline: 14px;
}

.page-intro {
  max-width: 60ch; margin: 0 auto clamp(22px, 3vw, 36px);
  text-align: center; font-size: clamp(14px, 1.4vw, 17px); line-height: 1.65; opacity: .8;
}

/* ---------- product awaiting data ---------- */
.product-pending {
  font-size: clamp(13px, 1.35vw, 16px); line-height: 1.7; text-align: center;
  background: rgba(193, 85, 0, .06);
  box-shadow: inset 0 0 0 1px rgba(193, 85, 0, .18);
  border-radius: var(--radius-card);
  padding: clamp(16px, 2vw, 24px);
}

/* ---------- single featured recipe ---------- */
.recipe-feature {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 44px); align-items: center;
  background: var(--surface-raised);
  border-radius: var(--radius-panel);
  overflow: hidden;
  transition: transform .25s ease, box-shadow .25s ease;
  box-shadow: var(--shadow-card);
}
.recipe-feature:hover { transform: translateY(-4px); box-shadow: 0 16px 38px rgba(8,50,21,.13); }
.recipe-feature__media { align-self: stretch; min-height: 220px; }
.recipe-feature__media img { width: 100%; height: 100%; object-fit: cover; }
.recipe-feature__body { padding: clamp(20px, 3vw, 44px) clamp(20px, 3vw, 44px) clamp(20px, 3vw, 44px) 0; display: grid; gap: 10px; }
.recipe-feature__title {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.4vw, 31px); font-weight: 700; line-height: 1.15; letter-spacing: -.02em;
}
.recipe-feature__body p { font-size: clamp(13px, 1.4vw, 16px); line-height: 1.65; }
.recipe-feature__cta {
  font-size: clamp(12px, 1.25vw, 14px); font-weight: 700;
  letter-spacing: .04em; color: var(--product-accent); margin-top: 4px;
}
.wide-figure--tight { margin-top: 0; }
.wide-figure--tight img { aspect-ratio: 16 / 7; }

@media (max-width: 760px) {
  .recipe-feature { grid-template-columns: 1fr; }
  .recipe-feature__body { padding: clamp(18px, 4vw, 28px); }
}

/* ==========================================================================
   About Us — layout from Christiana's design, centred
   ========================================================================== */
.page--about .page-title { margin-bottom: clamp(26px, 3.4vw, 46px); }

.about-block {
  display: grid; gap: clamp(12px, 1.4vw, 18px);
  justify-items: center; text-align: center;
  max-width: 74ch;
  margin-bottom: clamp(34px, 4.4vw, 62px);
}
.about-block--close { margin-bottom: clamp(26px, 3.4vw, 44px); }
.about-block p { font-size: clamp(14px, 1.45vw, 17px); line-height: 1.7; }

.about-h {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.2vw, 28px);
  font-weight: 700; line-height: 1.2; letter-spacing: -.02em;
  text-wrap: balance;
}

.about-figure { margin: 0 0 clamp(34px, 4.6vw, 66px); }
.about-figure img {
  width: 100%; aspect-ratio: 21 / 8; object-fit: cover;
  border-radius: var(--radius-panel);
}

/* ---------- two-column sections ---------- */
.about-split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 70px); align-items: center;
  margin-bottom: clamp(38px, 5vw, 72px);
}
.about-split--reverse .about-split__media { order: -1; }
.about-split__body { display: grid; gap: clamp(10px, 1.3vw, 16px); justify-items: start; }
.about-split__body p { font-size: clamp(14px, 1.4vw, 16px); line-height: 1.7; }
.about-split__media { margin: 0; }
.about-split__media img {
  width: 100%; height: auto; object-fit: cover;
  border-radius: var(--radius-panel);
}
.about-split__media--portrait img { aspect-ratio: 4 / 5; }
.about-note { width: clamp(96px, 11vw, 130px); height: auto; margin-bottom: 4px; }

/* ---------- photo beside a cream card ---------- */
.about-split--card { align-items: stretch; }
.about-split--card .about-split__media img { height: 100%; aspect-ratio: 4 / 3; }
.about-card {
  background: var(--surface);
  border-radius: var(--radius-panel);
  padding: clamp(22px, 3vw, 40px);
  display: grid; gap: clamp(10px, 1.2vw, 16px); align-content: center;
}
.about-card p { font-size: clamp(13px, 1.4vw, 16px); line-height: 1.7; }

.about-mark { width: clamp(54px, 6vw, 72px); height: auto; margin-top: clamp(6px, 1vw, 12px); }

@media (max-width: 760px) {
  .about-split, .about-split--reverse, .about-split--card { grid-template-columns: 1fr; }
  .about-split--reverse .about-split__media { order: 0; }
  .about-split__media--portrait img { aspect-ratio: 3 / 2; }
  .about-split--card .about-split__media img { aspect-ratio: 16 / 10; }
}

/* ==========================================================================
   Flow fixes - cream instead of white on gradient pages, social post tiles
   ========================================================================== */
/* Cards that sit on the cream-to-lime gradient use Cream Linen, not white,
   so they sit in the page the way Christiana's About cards do. White stays
   only where the comps show it: range product cards and the product-shot panel. */
.page .story-card,
.page .certs li,
.page .quote { background: var(--surface); }
.page .story-card { box-shadow: 0 6px 22px rgba(8, 50, 21, .06); }

/* two Instant Happy posts side by side on About */
.about-posts {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(10px, 1.4vw, 18px);
}
/* Instant Happy posts sit square. The rounding was on the link, which clips
   the image, so it has to come off there — the img already has radius 0.
   .about-posts is only used on about.html, so the other images on that page
   (and every other page) keep their corners. */
.about-posts a { display: block; border-radius: 0; overflow: hidden; transition: transform .25s ease; }
.about-posts a:hover { transform: translateY(-4px); }
.about-posts img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 0; }

/* social post tiles on the blog */
.story-card__media--tall { aspect-ratio: 4 / 5; }
.story-card--post .story-card__excerpt { color: var(--brand); font-weight: 600; }

/* ---------- full recipes ---------- */
.recipe-meta { text-align: center; font-size: 12px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand); margin: -10px 0 clamp(18px, 2.4vw, 30px); }
.recipe { gap: clamp(10px, 1.3vw, 16px); }
.recipe .about-h { margin-top: clamp(14px, 1.8vw, 24px); }
.recipe-sub { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .7; }
.recipe-ingredients { display: grid; gap: 6px; padding-left: 0; }
.recipe-ingredients li { font-size: clamp(14px, 1.4vw, 16px); line-height: 1.5;
  padding-left: 18px; position: relative; }
.recipe-ingredients li::before { content: ''; position: absolute; left: 0; top: .6em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand); }
.recipe-method { display: grid; gap: 12px; padding-left: 0; counter-reset: step; list-style: none; }
.recipe-method li { font-size: clamp(14px, 1.45vw, 17px); line-height: 1.7;
  padding-left: 40px; position: relative; counter-increment: step; }
.recipe-method li::before { content: counter(step); position: absolute; left: 0; top: .15em;
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ink); color: var(--surface); font-size: 12px; font-weight: 700; }
.recipe-uses { display: flex; flex-wrap: wrap; gap: 10px; margin-top: clamp(14px, 1.8vw, 24px); }
.recipe-list { display: grid; gap: 6px; }
.recipe-list a { font-size: clamp(13px, 1.35vw, 15px); font-weight: 600; }
.recipe-list a:hover { color: var(--product-accent); }
.story-card--noimg .story-card__media { background: var(--surface); }
.story-card--noimg .story-card__media img { object-fit: contain; padding: 18%; }

/* September refinement: retain the brand palette and existing page structure. */
body { font-size: 1rem; }
h1, h2, h3 { text-wrap: balance; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 5px; }
.site-footer :focus-visible { outline-color: var(--accent); }
.filters button { min-height: 44px; font-size: 1rem; }
.product-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.product-card { min-width: 0; padding: 20px 14px; gap: 20px; }
.product-card__media { height: clamp(170px, 20vw, 235px); aspect-ratio: auto; }
.product-card__media img { max-width: 100%; max-height: 100%; filter: drop-shadow(0 12px 10px rgb(8 50 21 / .12)); }
.product-card__name { font-size: 1rem; font-weight: 600; line-height: 1.4; max-width: 22ch; margin-inline: auto; }
.product-shot { min-height: 460px; padding: 24px 50px; }
.product-shot__slide { width: 100%; height: 100%; }
.product-shot__slide img { max-height: 400px; max-width: 100%; filter: drop-shadow(0 14px 14px rgb(8 50 21 / .12)); }
.product-shot__slide--food img { width: 100%; height: 350px; object-fit: cover; border-radius: var(--radius-card); filter: none; }
.product-shot__nav { width: 44px; height: 44px; opacity: 1; background: var(--surface); border: 1px solid var(--rule); }
.product-dots { gap: 2px; }
.product-dots button { width: 32px; height: 32px; padding: 11px; background: transparent; scale: 1; }
.product-dots button::before { content: ''; display: block; width: 10px; height: 10px; border-radius: 50%; background: var(--rule); }
.product-dots button[aria-current='true'] { background: transparent; scale: 1; }
.product-dots button[aria-current='true']::before { background: var(--brand); }
.product-copy p, .accordion__panel p, .accordion__panel li,
.prose p, .recipe-ingredients li, .recipe-method li,
.about-block p, .about-split__body p, .about-card p,
.split__body p, .contact-aside p, .contact-details dd { font-size: 1rem; }
.accordion__trigger, .accordion__heading { min-height: 48px; font-size: 1rem; }
.recipe-tip__kicker { color: var(--brand); }
.recipe-meta, .crumb a, .recipe-sub { font-size: .875rem; }
.recipe-hero { margin: 0 0 clamp(28px, 4vw, 48px); }
.recipe-hero img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; object-position: var(--recipe-position, center); border-radius: var(--radius-panel); }
.recipe .prose__lead { max-width: 60ch; }
.story-card__media img { transition: transform .35s ease; }
.story-card:hover .story-card__media img { transform: scale(1.025); }
.story-card__kicker, .story-card__excerpt, .field label, .feature span { font-size: .875rem; }
.site-footer .site-footer__grid { display: grid; align-items: start; }
.site-footer nav.site-footer__nav { display: grid; }
.site-footer__address, .site-footer p { font-size: .875rem; }
.site-footer .site-footer__tagline { font-size: clamp(24px, 2.2vw, 28px); }
.newsletter__field input { background: var(--brand); border-color: var(--brand); min-width: 0; }
.newsletter__field input::placeholder { color: var(--surface); opacity: .85; }
.page--about .about-block { max-width: var(--container); text-align: left; justify-items: start; }
.page--about .about-figure img { border-radius: 0; }
@media (min-width: 761px) {
  .page--about .about-split:not(.about-split--reverse):not(.about-split--card) { grid-template-columns: minmax(0, 1.8fr) minmax(0, .8fr); }
  .about-split--card { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 0; }
  .about-split--card .about-split__media { grid-column: 1 / -1; grid-row: 1; }
  .about-split--card .about-split__media img { min-height: 420px; max-height: 560px; aspect-ratio: 21 / 9; border-radius: 0; }
  .about-split--card .about-card { grid-column: 7 / 13; grid-row: 1; z-index: 1; margin: 20px; }
}
@media (max-width: 760px) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  .product-card { padding: 16px 8px; }
  .product-card__media { height: 190px; }
  .product-shot { min-height: 360px; padding: 20px 48px; }
  .product-shot__slide img { max-height: 310px; }
  .product-shot__slide--food img { height: 280px; }
  .recipe-hero img { aspect-ratio: 4 / 3; }
  .about-split--card { gap: 0; }
  .about-split--card .about-card { margin-top: -18px; position: relative; }
}
@media (max-width: 380px) {
  .product-card__media { height: 155px; }
  .product-card__name { font-size: .875rem; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
img { height: auto; }
.recipe-hero img[src*="patatas"], .recipe-hero img[src*="lasagna"],
.story-card__media img[src*="patatas"], .story-card__media img[src*="lasagna"] { object-position: center 68%; }
.recipe-hero img[src*="crustless"] { object-position: center 58%; }
.product-shot__nav[hidden], .product-dots[hidden] { display: none; }

/* Small refinements within the approved layout. */
.page--recipe .container--narrow { max-width: 800px; }
.page--recipe .page-title {
  max-width: 28ch;
  margin-inline: auto;
  font-size: clamp(28px, 3.4vw, 42px);
  line-height: 1.12;
}
.page--recipe .recipe-hero {
  max-width: 680px;
  margin-inline: auto;
  margin-bottom: clamp(24px, 3.5vw, 36px);
}
.page--recipe .recipe-hero img {
  height: auto;
  max-height: 390px;
  aspect-ratio: 16 / 10;
}
.page--recipe .recipe {
  max-width: 680px;
  width: 100%;
  gap: 14px;
}
.page--recipe .prose__lead {
  font-size: clamp(17px, 1.7vw, 19px) !important;
  line-height: 1.6 !important;
}
.page--recipe .recipe .about-h { margin-top: 24px; }
.page--recipe .recipe-ingredients { gap: 8px; }
.page--recipe .recipe-method { margin-block: 0; gap: 18px; }
.page--recipe .recipe-uses .btn { white-space: normal; }
.page--quick-recipe .recipe-hero { max-width: 600px; }
.page--quick-recipe .recipe-hero img { max-height: 320px; }
.page--quick-recipe .recipe { max-width: 600px; }
.story-card__media { flex: 0 0 auto; }
.story-card__kicker { padding: 20px 22px 0; }
.story-card__title { padding: 8px 22px 12px; font-size: 1.125rem; line-height: 1.3; }
.story-card__excerpt { padding: 0 22px 24px; margin-top: 0; line-height: 1.6; }
.about-split__media img[src$="about-market-source.webp"] { object-position: center; }
/* "A staple, not a speciality." - this photograph alone has square corners.
   The section is the plain .about-split (not --reverse, not --card), so the
   Instant Happy posts and the card photo below keep their own treatment. */
.page--about .about-split:not(.about-split--reverse):not(.about-split--card) .about-split__media img { border-radius: 0; }
/* The grated cheese sits right-of-centre and low in this frame (x 53-91%,
   y 32-87% of the image), which above 761px is exactly where the card sits on
   top of it. Mirroring the image puts the cheese at x 9-47%, clear of the card.
   The flip is horizontal only, so the vertical part of object-position is
   unchanged; the horizontal part is `center`, which is symmetric and so reads
   the same either way. 90% holds the whole of the cheese inside the crop at
   both ratios the image is used at — 16:10 below 761px and 21:9 above it. */
.about-split--card .about-split__media img[src$="karolag.jpg"] {
  object-position: center 90%;
  transform: scaleX(-1);
}
@media (max-width: 760px) {
  .page--recipe .recipe-hero img { aspect-ratio: 4 / 3; max-height: 330px; }
  .page--quick-recipe .recipe-hero img { max-height: 280px; }
  .story-card__kicker { padding: 18px 20px 0; }
  .story-card__title { padding-inline: 20px; }
  .story-card__excerpt { padding: 0 20px 22px; }
}

.about-posts img, .story-card__media--tall img { object-fit: contain; }

/* Consistent editorial frames and contained product artwork. */
.story-card { min-width: 0; }
.story-card[hidden] { display: none; }
.story-card__media { position: relative; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; }
.story-card__media img { position: absolute; inset: 0; width: 100%; height: 100%; }
.story-card__excerpt { margin-top: auto; }
.page--recipe .recipe-hero { position: relative; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; border-radius: var(--radius-panel); }
.page--recipe .recipe-hero img { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; aspect-ratio: auto; }
.product-card__media { position: relative; flex: none; overflow: hidden; }
.product-card__media img { position: absolute; inset: 0; margin: auto; width: 100%; height: 100%; object-fit: contain; }
.product-card__name { position: relative; margin-top: 0; overflow-wrap: anywhere; }
.product-layout > *, .product-shot__track, .product-shot__slide { min-width: 0; min-height: 0; }
.product-shot { height: 460px; min-height: 0; }
.product-shot__track { position: relative; }
.product-shot__slide { position: absolute; inset: 0; }
.product-copy p { text-align: left; overflow-wrap: break-word; }
.product-title { position: relative; line-height: 1.2; overflow-wrap: break-word; }
.about-happy-heading { display: flex; align-items: center; gap: clamp(12px, 2vw, 24px); width: 100%; }
.about-happy-heading .about-h { flex: 1; min-width: 0; margin: 0; }
.about-happy-heading .about-note { flex: none; width: clamp(70px, 9vw, 110px); margin: 0; }
/* The cheese-topped flatbread sits in the lower half of this frame (its cheese
   mass runs from about 46% to 95% of the image height). At 21:8 only 57% of the
   height survives the crop, so the band is pushed down to keep the whole
   flatbread, including its front edge, in shot. */
.about-figure img[src$="katerina.jpg"] { object-position: center 85%; }
.freshly-wrapped-products { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; width: 100%; margin-top: 16px; }
.freshly-wrapped-products figure { margin: 0; }
.freshly-wrapped-products img { width: 100%; height: 340px; object-fit: cover; border-radius: var(--radius-card); }
.freshly-wrapped-products figcaption { padding-top: 12px; font-weight: 600; line-height: 1.4; }
@media (max-width: 700px) {
  .freshly-wrapped-products { grid-template-columns: minmax(0, 1fr); }
  .freshly-wrapped-products img { height: 300px; }
  .product-layout { grid-template-columns: minmax(0, 1fr); }
  .product-shot { height: 360px; }
}

/* ==========================================================================
   Landing page — September design feedback
   ========================================================================== */

/* Discover the range — the supplied 3D pack renders sit straight on the
   section background: no border, no background fill, no corner radius, and no
   synthetic drop shadow (the renders carry their own). Both tiles share one
   box and one baseline so the row still lines up.

   The two files carry different amounts of transparent space under the pack
   (CheddarShred 16/593 = 2.70%, PizzaShred 50/634 = 7.89%), so bottom-aligning
   the FILES left Pizza Shred floating ~6% of a tile high. Each image is
   nudged down by its own transparent padding instead, which puts the bottom of
   the pack artwork on the tile's bottom edge in both cases. The offsets are
   percentages of the tile, so they hold at every width. */
/* Both renders sit on a 1200x1200 canvas with their artwork occupying the
   same 673x937 box (263,132)-(936,1069) - the normalisation pass left them
   identical to the pixel. A 5/6 tile with object-fit: contain therefore spent
   44% of its width on transparent margin: a 274px tile drew a 154px pack. The
   tile now takes the artwork's own 673:937 ratio and the image is scaled and
   offset so the artwork lands exactly on it, so the box you can measure is the
   pack you can see. The surplus canvas overflows on all four sides and is
   fully transparent. */
.pack-strip__item--render {
  aspect-ratio: 673 / 937;
  align-self: flex-end;
  position: relative;
}
/* The two renders split their column evenly rather than sitting on a fixed
   clamp, so they are always the largest they can be at that width and always
   identical to each other. flex-basis 0 with equal grow makes the split exact
   regardless of the images' own dimensions. */
.pack-strip a.pack-strip__item--render { flex: 1 1 0; min-width: 0; }
.pack-strip__item--render img {
  /* 1200 / 673 = 178.3% puts the artwork's width on the tile's width; the
     offsets are the artwork's own origin in the canvas, 263/1200 of the
     scaled image across and 132/1200 down. */
  position: absolute;
  width: 178.3%;
  height: auto;
  left: -39.08%;
  top: -14.09%;
  max-width: none;
  border: 0;
  border-radius: 0;
  background: none;
  filter: none;
}
/* The two per-file nudges that used to sit here are gone: they corrected for
   different framing between the old artworks, and the normalised pair share
   one bounding box, so one rule covers both. */
/* The separate 560px cap that used to sit here is gone: .featured stacks its
   own two columns at that width and doubles in height, which is what used to
   push the hero's content up into the header band, but the 430px cap above is
   already tighter than the 440px that fixed it. Below about 450px the
   container is narrower than the cap, so phone widths are set by the container
   and are unaffected by it. */

/* "Discover the range" now sits inside the left hero column, directly above
   the strip it labels, rather than on the line above the grid pushed back down
   over it with a transform. The transform never reserved any space, so once the
   renders grew tall enough to reach that line they ran straight through the
   label. Stacked in flow it cannot collide at any width, and because the column
   is bottom-aligned it still falls over the dark foot of the hero gradient
   where white reads cleanly. */
.hero__range {
  display: grid;
  gap: clamp(8px, 1vw, 14px);
  align-content: end;
  min-width: 0;
}
/* The hero row runs to the same edges as the header: "Discover the range"
   and the packs start on Menu's line, and the Featured Product panel ends on
   the icons' line. Up to 1200px the 1200px container already put them there;
   above it they drifted inwards. The panel keeps the 630px it reaches at
   1200px rather than growing, so the extra width opens between the columns.
   This is the home hero only; every other section stays in the container. */
.hero__inner.container { max-width: none; }
@media (min-width: 1201px) {
  .hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 630px); }
}
/* Pack renders about 13% smaller: 87% of their column, capped so each is
   185px at most (was 209px at 1440). Both tiles share one flex basis and are
   bottom-aligned, so they stay level and equal. */
.hero__range .pack-strip { width: 87%; max-width: 388px; }
/* Phones: no "Discover the range" (30 Sep brief). It stays from 768px. */
@media (max-width: 767px) { .hero__range { display: none; } }

/* The glen lifestyle shot is portrait (2268x4032) in a landscape slot. Pin it
   inside its column so it crops to fill, instead of its intrinsic ratio
   setting the panel height. Absolute + inset:0 also defeats the global
   `img { height: auto }` further up. */
.featured__media { position: relative; overflow: hidden; }
.featured__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Panel stacks below 560px, where the media row has no content height of its
   own; the existing max-height alone would leave it at zero. */
@media (max-width: 560px) {
  .featured__media { height: 180px; }
}

/* Featured product — pack shot beneath the product name, centred in the
   text column. */
.featured__pack {
  margin-top: clamp(12px, 1.6vw, 20px);
  display: flex; justify-content: center;
}
.featured__pack img {
  width: clamp(150px, 15vw, 216px);
  height: auto;
}
/* Ticks / benefits strip — its own green band to break the page up, with the
   packaging tick: a filled disc, white tick, to the left of each line. */
.section--benefits {
  background: var(--brand);
  color: var(--surface-raised);
}
.section--benefits .feature {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.2vw, 14px);
  text-align: left;
}
.section--benefits .feature__tick {
  flex: none;
  width: clamp(22px, 2.4vw, 28px);
  height: auto;
}
.section--benefits .feature__tick-disc { fill: var(--product-accent); }
.section--benefits .feature__tick-mark {
  fill: none;
  stroke: var(--surface-raised);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Ticks band - matches docs/reference/"green tick layout - homepage and
   default.png" and "orange tick layout .png" (30 Sep brief). A pill in the
   band colour; each claim led by a scalloped Everyday Glow disc with a check,
   in bold uppercase, with a thin rule between claims. The Plant-Based badge
   sits over the pill's right-hand end, centred on it, tilted like a sticker
   (the tilt is in the SVG). Default is Zesty Green with Nourishing Green text
   and ticks; the Cheddar and Pizza product pages use Roast Capsicum with
   Everyday Glow text and Roast Capsicum ticks. The pill's corner radius is
   half its one-row height, so one row is a full pill and a wrapped band keeps
   the same corners. Claims run from the left edge of the list; the rule
   before the first claim on each row falls outside the list and is clipped. */
.section--claims { background: var(--surface); }
.claims-band {
  --band-bg: var(--zesty-green);
  --band-fg: var(--ink);
  --tick-disc: var(--everyday-glow);
  --tick-mark: var(--ink);
  --claims-pad-y: clamp(10px, 1.1vw, 16px);
  --claims-tick: clamp(22px, 1.8vw, 25px);
  --claims-gap-x: clamp(18px, 1.6vw, 22px);
  --badge: clamp(78px, 7.4vw, 108px);
  position: relative;
  width: fit-content; max-width: 100%;
  margin-inline: auto;
  padding-right: calc(var(--badge) / 2);
}
.claims-band--orange {
  --band-bg: var(--roast-capsicum);
  --band-fg: var(--everyday-glow);
  --tick-mark: var(--roast-capsicum);
}
/* Feta: the orange layout in the Feta name blue (--product-accent on
   .page--accent-feta-blue, #1b2b55): white claims, Everyday Glow discs with a
   blue tick. The dark green badge gets a thin white ring so it stands out on
   the blue. */
.claims-band--blue {
  --band-bg: var(--product-accent);
  --band-fg: var(--surface-raised);
  --tick-mark: var(--product-accent);
}
.claims-band--blue .claims-band__badge {
  filter: drop-shadow(1.5px 0 0 var(--surface-raised)) drop-shadow(-1.5px 0 0 var(--surface-raised))
          drop-shadow(0 1.5px 0 var(--surface-raised)) drop-shadow(0 -1.5px 0 var(--surface-raised));
}
.claims-band__pill {
  background: var(--band-bg);
  color: var(--band-fg);
  border-radius: calc(var(--claims-pad-y) + var(--claims-tick) / 2);
  padding: var(--claims-pad-y) calc(var(--badge) / 2 + clamp(8px, 0.9vw, 14px)) var(--claims-pad-y) clamp(14px, 1.6vw, 22px);
}
.claims {
  display: flex; flex-wrap: wrap; justify-content: flex-start; align-items: center;
  gap: clamp(8px, 0.9vw, 12px) var(--claims-gap-x);
  margin: 0; padding: 0; list-style: none;
  overflow: hidden;
}
.claims__item {
  position: relative;
  display: flex; align-items: center; gap: clamp(7px, 0.7vw, 10px);
  font-size: clamp(12.5px, 1.02vw, 13.5px); font-weight: 700; line-height: 1.15;
  letter-spacing: .01em; text-transform: uppercase;
  white-space: nowrap;
}
.claims__item::before {
  content: ''; position: absolute;
  left: calc(var(--claims-gap-x) / -2); top: 12%; bottom: 12%;
  border-left: 1.5px solid currentColor;
}
.claims__tick { flex: none; width: var(--claims-tick); height: auto; }
.claims__tick-disc { fill: var(--tick-disc); }
.claims__tick-mark { fill: var(--tick-mark); }
.claims-band__badge {
  position: absolute; top: 50%; right: 0;
  width: var(--badge); height: auto;
  transform: translateY(-50%);
  pointer-events: none;
}
/* On product pages the band sits in the copy column, between the
   description and the accordions, with the space the old strip had. */
.product-copy .claims-band {
  --claims-tick: 20px; --claims-gap-x: 20px; --badge: clamp(74px, 6.6vw, 92px);
  margin-inline: 0; margin-block: clamp(14px, 1.8vw, 22px);
}
.product-copy .claims__item { font-size: 13px; gap: 7px; }
/* Product-page claims sit in equal-width columns, so every tick lines up
   under the one above and every claim starts at the same point in its
   column; no rules between claims. main.js sets --claims-cols to 3, 2 or 1 -
   the most (up to 3) that fit the longest claim on one line - and adds
   .claims--fit, which keeps each claim on one line. Without JavaScript it is
   two columns and a long claim wraps inside its column. */
.product-copy .claims-band { width: 100%; }
.product-copy .claims {
  display: grid;
  grid-template-columns: repeat(var(--claims-cols, 2), minmax(0, 1fr));
}
.product-copy .claims__item { white-space: normal; }
.product-copy .claims.claims--fit .claims__item { white-space: nowrap; }
.product-copy .claims__item::before { display: none; }
/* Measuring pass (main.js): each claim at its one-line width. */
.product-copy .claims.claims--measure { display: flex; flex-wrap: nowrap; width: max-content; }
.product-copy .claims.claims--measure .claims__item { flex: none; white-space: nowrap; }
/* Once the homepage claims no longer fit on one row they go into even
   columns - three, then two - so no claim is left alone on a row. */
@media (min-width: 836px) and (max-width: 1023px) {
  .section--claims .claims { display: grid; grid-template-columns: repeat(3, auto); }
}
@media (max-width: 835px) {
  .claims { display: grid; grid-template-columns: repeat(3, auto); }
}
/* Phones: two even columns, smaller type, and the badge hangs 14px into the
   page gutter so the claims keep the room. */
@media (max-width: 559px) {
  .claims-band,
  .product-copy .claims-band {
    --claims-tick: 18px; --claims-gap-x: 14px; --badge: 60px;
    padding-right: calc(var(--badge) / 2 - 14px);
  }
  .claims { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .claims__item, .product-copy .claims__item { font-size: 11.5px; gap: 6px; }
  .claims__item { white-space: normal; }
  .claims-band__pill { padding-left: 12px; padding-right: calc(var(--badge) / 2 + 20px); }
}
/* Product pages: where the last row of claims leaves room in the band's
   bottom-right corner, main.js adds .claims-band--corner and the badge moves
   down into that gap - still over the right edge, still tilted - so the
   claims get the full width. It is decided per page and per width, by
   testing that the badge touches no claim; otherwise (and without
   JavaScript) the badge stays centred on the right-hand end. */
.product-copy .claims-band.claims-band--corner { padding-right: calc(var(--badge) * .3); }
.claims-band--corner .claims-band__pill { padding-right: clamp(14px, 1.6vw, 22px); }
.claims-band--corner .claims-band__badge { top: auto; bottom: calc(var(--badge) * -.14); transform: none; }
@media (max-width: 559px) {
  .product-copy .claims-band.claims-band--corner { padding-right: max(0px, calc(var(--badge) * .3 - 14px)); }
  .claims-band--corner .claims-band__pill { padding-right: 12px; }
}
/* Smallest phones: the homepage's six short claims, a little smaller. */
@media (max-width: 399px) {
  .section--claims .claims-band { --claims-tick: 16px; --claims-gap-x: 12px; --badge: 54px; }
  .section--claims .claims__item { font-size: 11px; gap: 5px; }
}
/* Homepage band, 560-699px: two columns, as on phones - three do not fit
   beside the badge. */
@media (min-width: 560px) and (max-width: 699px) {
  .section--claims .claims { grid-template-columns: repeat(2, auto); }
}

/* Fresh from Bio — the card tag is set exactly like .featured__label:
   same family, weight, size, tracking and case. */
.section--fresh .story-card__kicker {
  font-family: var(--font-logo);
  font-size: clamp(10px, 1vw, 12px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
}
/* "Fresh from Bio" and "What people are saying" (Home) take the plain
   .section-title, so they match the "Awards" heading on About Us: NT Wagner
   section headings at the large size.
   (It was Perfectly Nineties until 1 Oct.) */
.section--fresh .story-card__title { font-family: var(--font-display); }
.section--fresh .story-card__excerpt { font-family: var(--font-display); }

/* Footer — the menu column sat crammed against the newsletter block. The
   effective gap comes from `.site-footer .container` (gap: 20px 40px), which
   out-specifies `.site-footer__grid`, so the new spacing has to be set at that
   specificity. Column gap: 40px -> clamp(56px, 6.5vw, 104px) (94px at 1440). */
.site-footer .site-footer__grid {
  row-gap: clamp(26px, 3.4vw, 54px);
  column-gap: clamp(56px, 6.5vw, 104px);
}

/* The site header and its tagline are both laid over the hero, so the
   hero reserved no space for either. That was invisible while the renders were
   small, but at their new height the content stopped fitting underneath them on
   a short viewport and rode up into the header band - at 480x800 .hero__inner
   started at y=6, behind the Menu button. The hero now reserves the header's
   height, plus the tagline's own line in the band below 550px where it drops
   under the logo, and grows past 100svh rather than overlapping. Where the
   content already fitted, it stays bottom-anchored and nothing moves. */
.hero { padding-top: calc(var(--header-h) + clamp(10px, 1.4vw, 18px)); }
@media (max-width: 549px) {
  .hero { padding-top: calc(var(--header-h) + 60px); }
}

/* Hero lockup — the tagline and the logo both scale with the viewport,
   clamp(20px, 2.36vw, 26.6px) against clamp(72px, 8.5vw, 96px), so the row
   shrinks along with the header band instead of overrunning it. Both bottom
   out at 847px; below that the lockup is a fixed 299px wide and the clear
   space to the Menu button closes by 0.5px per viewport px. Measured on the
   rendered page: "Less Dairy." keeps at least --gutter (20px at this size) of
   clear space down to 467px, and does not touch the Menu button until 426px.
   The split is set at the gutter reading rather than the touch point, so the
   words never sit flush against Menu. The earlier 1199px threshold was set
   when the type was 76px and did not survive the drop to 26.6px.
   The social icons on the right of the header are wider than Menu, so
   "More Life." reaches them first: it overlaps them below 510px and keeps
   less than --gutter of clear space until 550px. The tagline therefore
   leaves the header at 549px, measured the same way, rather than the 466px
   Menu alone allowed. */
/* Below 550px there is no room for the words beside the logo, so the tagline
   is removed from the header altogether: on phones the header is Menu, logo
   and icons only. Pages keep the spacing they had before it was added. */
@media (max-width: 549px) {
  .site-header__tagline { display: none; }
}


/* ==========================================================================
   Our Range - product image tiles and type
   ========================================================================== */
/* Every product image sits on the same tile as the recipe cards use: the
   --surface-raised white and the --radius-card corner, same size on every
   card, with the same padding inside it. The image is laid out normally and
   capped at the tile's content box, so it shows in full and a pack render
   keeps its edges - nothing is cropped to fill. The earlier rule pinned the
   image absolutely at inset 0; an absolutely positioned child resolves
   against the padding box, so padding had no effect on it. */
.product-grid .product-card__media {
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  padding: clamp(12px, 1.4vw, 18px);
  display: block;
}
/* The image fills the tile's content box - inside the padding - and is fitted
   with `contain`, so the whole of it is always in shot, letterboxed rather
   than cropped, whatever its aspect ratio. Sizing it with max-width/max-height
   instead does not work here: as a grid or flex item its percentage resolves
   against a track that has already grown to fit it, so a tall render ended up
   121% of the tile and was clipped. A plain block child resolves 100% against
   the tile's own definite height. */
.product-grid .product-card__media img {
  position: static; inset: auto;
  width: 100%; height: 100%;
  object-fit: contain;
}

/* Product names in Halyard Display Bold. .product-card is used on range.html
   alone, so this needs no page scope. The card itself is the link; the name
   is not one, and the markup is unchanged. */
.product-card__name { font-family: var(--font-display); font-weight: 700; }

/* Range cards, 28 Sep - larger, with the name inside the white tile.
   The card itself is now the white tile (--surface-raised, --radius-card)
   and holds the pack and the name beneath it; the image box inside it is
   transparent and square. Three columns from 561px (was four), two on
   phones with a tighter gap, and every grid row takes the height of the
   tallest, so every card is the same size whatever its name's length. */
.product-grid { grid-auto-rows: 1fr; }
.product-grid .product-card {
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  padding: clamp(10px, 1.4vw, 20px);
  gap: clamp(10px, 1.2vw, 16px);
}
.product-grid .product-card:hover { background: var(--surface-raised); }
.product-grid .product-card__media {
  background: none;
  border-radius: 0;
  padding: 0;
  height: auto;
  aspect-ratio: 1 / 1;
}
.product-grid .product-card__name {
  font-size: clamp(15px, calc(14.4px + 0.39vw), 20px);
  margin-top: 0;
}
@media (min-width: 561px) {
  .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
}


/* ==========================================================================
   Product detail pages - name, image tile, sub-headings
   ========================================================================== */
/* The pack sits on the same tile the range cards use: --surface-raised on
   --radius-card, no new colour or radius. Padding is one value for every page
   and both carousel slides, and the image is fitted with `contain` inside it,
   so the whole pack is always in shot and nothing is cropped. The slides are
   absolutely positioned inside the shot, so the padding is applied to them
   rather than to the shot itself, which they would otherwise cover. */
.product-shot {
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  padding: 0;
  /* The pack renders are square, so the tile is square: a 1200x1200 image then
     fills it edge to edge instead of letterboxing inside a landscape box. This
     replaces the fixed 460px/360px heights, which left the pack small at 320
     and 375 and, at 768, made the box wider than it was tall. Capped and
     centred so the tile does not run away with the page in one column. */
  aspect-ratio: 1 / 1;
  height: auto; min-height: 0; max-height: none;
}
/* The cap goes on the media column, not the tile. An auto inline margin
   cancels the default stretch on both a flex and a grid item, so the box then
   sizes to its own percentage-sized content and collapses; width: 100% keeps
   it filling the column before max-width caps it. Below 861px the layout is a
   single column, so the column is capped and centred; above it the grid
   column already sets the width. */
@media (max-width: 860px) {
  .product-media { width: 100%; max-width: 520px; margin-inline: auto; }
}
.product-shot__slide {
  /* The slide was a grid with place-items: center, which made the image a
     centred grid item; its height: 100% then resolved against an auto row that
     had already grown to fit it. At 768 that blew the image out to 682px tall
     inside a 460px tile and `overflow: hidden` cropped it. A plain block
     resolves the percentage against the slide's own definite height. */
  display: block;
  padding: clamp(12px, 1.6vw, 22px);
}
.product-shot__slide img {
  display: block;
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  object-fit: contain;
}

/* Accordion titles and the recipe box label take --font-logo, which ships
   700 only. The accordion titles are also used on the FAQs page, where they
   stay on --font-display, so this is scoped to .product-copy, which exists
   on product detail pages alone. Body copy and sub-text are left on
   --font-display. */
.product-copy .accordion__trigger,
.product-copy .accordion__heading,
.product-copy .recipe-tip__kicker { font-family: var(--font-logo); font-weight: 700; }

/* Product pages carry up to 12 claims where the homepage carries 7, and they
   sit in the narrow right-hand column, so the same strip ran to eight rows.
   Here the claims read as inline chips: smaller type, a smaller disc and
   tighter gaps, so several fit per row. Same band, same accent disc, same
   packaging look - just denser. Scoped to .product-copy, so the homepage
   strip is untouched. */
.product-copy .section--benefits { padding-block: clamp(14px, 1.8vw, 22px); }
.product-copy .section--benefits .container { padding-inline: clamp(12px, 1.6vw, 20px); }
.product-copy .section--benefits .feature-row { gap: clamp(7px, 0.9vw, 11px); }
.product-copy .section--benefits .feature { gap: 6px; }
.product-copy .section--benefits .feature span {
  font-size: clamp(10px, 0.95vw, 11px);
  letter-spacing: .03em;
  line-height: 1.25;
}
.product-copy .section--benefits .feature__tick { width: clamp(13px, 1.4vw, 16px); }


/* One shadow rule for every card. The pack renders carry their own cast
   shadow, so the CSS drop-shadow was doubling up on them - and it was being
   switched off by filename for the Feta, which showed once the cards gained
   white tiles. No card gets an added shadow now. */
.product-grid .product-card__media img { filter: none; }

/* ==========================================================================
   Blog - marketing feedback, 17 Sep
   --------------------------------------------------------------------------
   .story-card is shared with the landing page, where the same cards sit in
   .section--fresh inside an unclassed <main>. Everything below is scoped to
   .page--blog (added to blog.html's <main>) so none of it can reach index.html.
   ========================================================================== */

/* Cards take the white surface the range page image tiles use. They were on
   --surface (Cream Linen) via the `.page .story-card` flow-fix rule above;
   the radius was already --radius-card, so it is restated, not changed. */
.page--blog .story-card {
  background: var(--surface-raised);
  border-radius: var(--radius-card);
}

/* ==========================================================================
   Recipe pages - section labels
   --------------------------------------------------------------------------
   "Ingredients", "Method" and the sub-headings under them are section labels,
   so they take --font-logo (700 only). .about-h is shared with about.html,
   where it stays on --font-display, so it is scoped to .page--recipe.
   ========================================================================== */
.page--recipe .about-h,
.page--recipe .recipe-sub { font-family: var(--font-logo); font-weight: 700; }

/* ==========================================================================
   Type scale - larger, punchier headings, slightly larger text
   --------------------------------------------------------------------------
   Every size scales linearly with the viewport between 375px and 1440px and
   is floored so it still fits at 320px. Fonts, weights, colours, tracking and
   line heights are unchanged; only font-size moves. Selectors match or beat
   the specificity of the rules they replace, including the recipe title
   override and the !important on .prose__lead.
   ========================================================================== */
/* Page titles and product names: 52/44 -> 80px at 1440, 29/24 -> 38px at
   375. */
.page-title,
.product-title { font-size: clamp(34px, calc(23.2px + 3.94vw), 80px); }
/* Recipe titles are long names, so one step down: 42 -> 64px at 1440,
   28 -> 32px at 375. */
.page--recipe .page-title { font-size: clamp(30px, calc(20.7px + 3vw), 64px); }
/* Section headings: 34 -> 56px at 1440, 21 -> 28px at 375. */
.section-title { font-size: clamp(26px, calc(18.1px + 2.63vw), 56px); }
/* About and recipe headings (.about-h), one step below: 28 -> 46px at 1440,
   19 -> 25px at 375. */
.about-h { font-size: clamp(23px, calc(17.6px + 1.97vw), 46px); }

/* Sub-headings, slightly larger. */
.featured__title { font-size: clamp(18px, calc(15.5px + 0.87vw), 28px); }
.story-card__title,
.section--fresh .story-card__title { font-size: clamp(18px, calc(18.3px + 0.19vw), 21px); }
.award__name { font-size: clamp(14px, calc(12.9px + 0.35vw), 18px); }
.accordion__trigger, .accordion__heading { font-size: clamp(17px, calc(16.6px + 0.1vw), 18px); }
.accordion--page .accordion__trigger { font-size: clamp(17px, calc(15.6px + 0.47vw), 22px); }
.recipe-tip__kicker,
.product-copy .recipe-tip__kicker { font-size: clamp(17px, calc(16.6px + 0.1vw), 18px); }
.newsletter__label { font-size: clamp(18px, calc(15.9px + 0.56vw), 24px); }
.recipe-sub { font-size: clamp(15px, calc(14.6px + 0.1vw), 16px); }

/* Body text: 16 -> 18px at 1440, 16 -> 17px at 375. */
.product-copy p, .accordion__panel p, .accordion__panel li,
.prose p, .recipe-ingredients li, .recipe-method li,
.about-block p, .about-split__body p, .about-card p,
.split__body p, .contact-aside p, .contact-details dd {
  font-size: clamp(16px, calc(16.3px + 0.16vw), 18px);
}
.page--about .about-block p { font-size: clamp(16px, calc(16.3px + 0.16vw), 18px); }
.story-card__excerpt { font-size: clamp(14px, calc(14.6px + 0.1vw), 16px); }
/* Lead paragraphs: 19 -> 22px (recipes) and 20 -> 23px (home intro). */
.prose__lead,
.page--recipe .prose__lead { font-size: clamp(18px, calc(17.9px + 0.28vw), 22px) !important; }
.about-intro__body { font-size: clamp(16px, calc(14.5px + 0.59vw), 23px); }

/* ==========================================================================
   Home - testimonials, above Fresh from Bio
   --------------------------------------------------------------------------
   Heading set like "Fresh from Bio" (.section-title, NT Wagner at the large
   size). Cards are the Our Range white tile (--surface-raised,
   --radius-card) on the cream section: three in a row, equal height, from
   768px; one per row on phones. Quote in Halyard Display at body size,
   attribution smaller in --brand (Herb Garden Green), opening mark in
   --accent (Zesty Green). The bottom padding is the .section--tight value, so
   the space from the cards down to "Fresh from Bio" equals the space from
   the ticks band down to the label - the gap those two sections had before.
   ========================================================================== */
.section--testimonials { padding-bottom: clamp(28px, 3.6vw, 52px); }
/* "What people are saying" is a .section-title too (1 Oct brief), so it
   matches "Fresh from Bio" and "Awards": NT Wagner section heading at the
   large size. Only its space below is set here. */
.testimonials__label {
  margin: 0 0 clamp(20px, 2.6vw, 34px);
}
.testimonials {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(14px, 1.8vw, 24px);
}
@media (min-width: 768px) {
  .testimonials { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.testimonial {
  margin: 0;
  display: flex; flex-direction: column; gap: clamp(12px, 1.3vw, 18px);
  background: var(--surface-raised);
  border-radius: var(--radius-card);
  padding: clamp(20px, 2.2vw, 32px);
}
.testimonial__mark { width: clamp(26px, 2.4vw, 34px); height: auto; fill: var(--accent); flex: none; }
.testimonial__quote { margin: 0; flex: 1 1 auto; }
.testimonial__quote p {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(16px, calc(16.3px + 0.16vw), 18px);
  line-height: 1.55;
}
.testimonial__by {
  font-family: var(--font-display);
  font-size: clamp(14px, calc(14.6px + 0.1vw), 16px);
  font-weight: 700;
  color: var(--brand);
}

/* Privacy page - the policy text in the recipe/.prose column, section
   headings in the .about-h style, lists at body size. */
/* Privacy text runs the same width as the About Us text: the full
   container, left-aligned (30 Sep brief). */
.page--privacy .container--narrow { max-width: var(--container); }
.page--privacy .prose { max-width: none; margin-inline: 0; }
.page--privacy .prose h2 { margin: clamp(10px, 1.4vw, 18px) 0 0; }
.page--privacy .prose ul { margin: 0; padding-left: 1.25em; display: grid; gap: 8px; }
.page--privacy .prose li { font-size: clamp(16px, calc(16.3px + 0.16vw), 18px); line-height: 1.75; }

/* ==========================================================================
   Contact - email and phone details (every width)
   --------------------------------------------------------------------------
   Two columns, label then value: every value starts on the value column's
   edge, and each label sits on its value's baseline rather than the top of
   the row. Fonts, sizes and colours unchanged.
   ========================================================================== */
.contact-details { align-items: baseline; }

/* ==========================================================================
   Phones - mobile pass, 28 Sep (max-width 767px only)
   --------------------------------------------------------------------------
   Nothing below reaches 768px and up.
   ========================================================================== */
@media (max-width: 767px) {
  /* Home hero. The tagline is hidden below 550px, but the hero still held
     60px for it under the header, which pushed its content past the bottom
     of a short phone. The hero now clears the header band alone. */
  .hero { padding-top: calc(var(--header-h) + 12px); }

  /* Tap targets: 44px at least. */
  .menu-toggle { min-height: 44px; min-width: 44px; text-align: left; }
  /* As wide as the space beside the logo allows, up to 44px: the three
     icons share what is left of the right-hand column. The negative margin
     keeps the last icon's glyph on the gutter line, where it was. */
  .social {
    --tap: clamp(32px, calc((100vw - 2 * var(--gutter) - 74px) / 6), 44px);
    gap: 0;
    margin-right: calc((var(--tap) - 19px) / -2);
  }
  .social__link {
    display: flex; align-items: center; justify-content: center;
    width: var(--tap); height: 44px; padding: 0;
  }
  .btn { min-height: 44px; }
  .filters button { min-width: 44px; }
  .field input, .field select { min-height: 44px; }
  .newsletter__field input { min-height: 44px; }
  .site-footer nav.site-footer__nav { row-gap: 0; }
  .site-footer__nav a { display: flex; align-items: center; min-height: 44px; }
  .site-footer__address a { display: inline-flex; align-items: center; min-height: 44px; }
  .site-footer__address br { display: none; }
  .site-footer__address { display: grid; justify-items: start; line-height: 1.3; margin-top: 2px; }

  /* "Recipes with ..." on product pages: body-size links, each a 44px row. */
  .recipe-list { gap: 0; }
  .recipe-list a { display: flex; align-items: center; min-height: 44px; font-size: 16px; line-height: 1.35; padding-block: 6px; }

  /* Body text below 16px. */
  .story-card__excerpt { font-size: 16px; }
  .nutrition { font-size: 14px; }
}

/* Home hero, phones: the Featured Product panel keeps the two columns it has
   on larger screens - name and pack on the left, the photo filling the right
   - instead of stacking the photo underneath, which made the hero taller
   than a short phone. */
@media (max-width: 560px) {
  .featured { grid-template-columns: minmax(0, 1fr) minmax(0, 40%); }
  .featured__media { max-height: none; height: auto; }
  .featured__body { padding: 18px 0 18px 18px; }
  .featured__pack img { width: clamp(84px, 27vw, 118px); }
}
/* Short phones (iPhone SE / 8 and shorter): smaller pack renders, so the
   whole hero fits on the first screen. */
@media (max-width: 767px) and (max-height: 700px) {
  .hero__range .pack-strip { width: 70%; }
}

/* Phones: footer text at 15px - links, phone and email, the newsletter note,
   field and button, the placeholder note and the copyright line. The two
   larger lines ("Less Dairy. More Life." and "Stay in the loop") keep their
   size. Desktop unchanged. */
@media (max-width: 767px) {
  .site-footer a,
  .site-footer p:not(.site-footer__tagline),
  .site-footer .site-footer__address,
  .site-footer .newsletter__note,
  .site-footer .ph-note,
  .site-footer .newsletter .btn,
  .site-footer .newsletter__field input { font-size: 15px; }
}

/* ==========================================================================
   Recipes, Media cards, Blog "Load more", Fresh from Bio carousel - 29 Sep
   ========================================================================== */
/* Method lists split by a sub-heading ("To make the sauce:") keep counting:
   the continuing list does not reset the step counter. */
.recipe-method--cont { counter-reset: none; }
/* Photo credit under a recipe photo. */
.recipe-hero__credit {
  margin-top: 10px; text-align: center;
  font-size: .875rem; line-height: 1.5; opacity: .75;
}

/* Recipe cards without an excerpt close at the same bottom padding. */
.story-card__title:last-child { padding-bottom: 24px; }
/* Media cards: source and date under the description, at the card's foot. */
.story-card--media .story-card__excerpt { padding-bottom: 12px; }
.story-card__source {
  margin-top: auto;
  padding: 0 22px 24px;
  font-family: var(--font-display);
  font-size: .875rem; font-weight: 600; line-height: 1.5;
  color: var(--brand);
}

/* Blog - filters and search box on one line: filters left, search right,
   both centred on the line. Below 768px the filters sit on top and the search
   box runs full width underneath. The box is the Contact form field: white
   surface, --rule border, 10px radius, 44px tall. 16px text so phones do not
   zoom in on focus. */
.blog-tools {
  display: flex; flex-direction: column; align-items: stretch;
  gap: 12px; margin-bottom: clamp(20px, 2.6vw, 34px);
}
.blog-tools .filters { margin-bottom: 0; }
@media (min-width: 768px) {
  .blog-tools { flex-direction: row; align-items: center; justify-content: space-between; gap: 24px; }
  .blog-tools .filters { flex-wrap: nowrap; }
  .blog-tools .blog-search { flex: 0 1 clamp(290px, 22.2vw, 320px); }
}
.blog-search[hidden] { display: none; }
.blog-search input {
  font: inherit; font-size: 16px; line-height: 1.4;
  color: var(--ink); background: var(--surface-raised);
  border: 1px solid var(--rule); border-radius: 10px;
  padding: 10px 14px; width: 100%; min-height: 44px;
}
.blog-search input::placeholder { color: var(--ink); opacity: .7; }
.blog-search input:focus-visible { outline-offset: 2px; border-color: var(--ink); }
/* Blog - shown when the search finds nothing. */
.blog-empty { padding-block: clamp(8px, 1.6vw, 20px); font-size: clamp(15px, 1.4vw, 17px); line-height: 1.6; }
.blog-empty[hidden] { display: none; }

/* Blog - "Load more" under the grid. */
.load-more { display: flex; justify-content: center; margin-top: clamp(28px, 3.6vw, 48px); }

/* Home - Fresh from Bio carousel. Cards stay 260px. From 1024px the carousel
   is as wide as the whole cards that fit the container (set by main.js as
   --visible; four at 1440 with the 24px gap); below that the track runs to
   the screen edge so the next card peeks in from the right, and swiping
   scrolls it. The arrows are the
   product image arrows (44px, --surface, --rule border), centred on the
   card images. */
.carousel {
  --card-w: 260px;
  --gap: clamp(16px, 2vw, 24px);
  position: relative;
}
.carousel__track {
  position: relative;
  display: flex; gap: var(--gap);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* room for the card lift, shadow and focus ring inside the scroller */
  padding: 10px 12px 30px; margin: -10px -12px -30px;
  scroll-padding-inline: 12px;
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track > .story-card { flex: 0 0 var(--card-w); width: var(--card-w); scroll-snap-align: start; }
.carousel__nav {
  position: absolute; z-index: 1;
  top: calc(var(--card-w) * 3 / 8); translate: 0 -50%;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule);
  box-shadow: 0 4px 14px rgb(8 50 21 / .12);
}
.carousel__nav[data-dir='prev'] { left: 8px; }
.carousel__nav[data-dir='next'] { right: 8px; }
.carousel__nav::before {
  content: ''; width: 8px; height: 8px;
  border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor;
}
.carousel__nav[data-dir='prev']::before { rotate: 225deg; translate: 2px 0; }
.carousel__nav[data-dir='next']::before { rotate: 45deg; translate: -2px 0; }
@media (min-width: 1024px) {
  .carousel { max-width: calc(var(--visible, 4) * var(--card-w) + (var(--visible, 4) - 1) * var(--gap)); }
}
@media (max-width: 1023px) {
  .carousel__track {
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    scroll-padding-inline: var(--gutter);
  }
  /* the arrows sit 8px in from the screen edge, over the peeking card */
  .carousel__nav[data-dir='prev'] { left: calc(8px - var(--gutter)); }
  .carousel__nav[data-dir='next'] { right: calc(8px - var(--gutter)); }
}
@media (prefers-reduced-motion: reduce) {
  .carousel__track { scroll-behavior: auto; }
}
/* Media cards that use a pack render: the render already sits on a large
   empty canvas, so the no-image padding comes off. */
.story-card--media.story-card--noimg .story-card__media img { padding: 0; }

/* Recipe photos under 700px wide: shown at their own size or smaller -
   never stretched - centred in the photo column, same corners. The height
   cap is the one the full-width photos use, so tall photos stay in
   proportion; nothing is cropped. */
.page--recipe .recipe-hero--small img {
  display: block;
  width: auto; height: auto;
  max-width: 100%; max-height: 390px;
  aspect-ratio: auto;
  object-fit: contain;
  margin-inline: auto;
}

/* Where to buy (product pages): inside the Stockists item of the accordion,
   one logo per retailer that stocks the product, each linking to it at that
   retailer. The logos sit
   straight on the page, centred on one line. Each is sized so the two read
   as equally big: the stacked Woolworths logo is taller than the Coles
   wordmark. The row is a wrapping flex list, so another retailer
   (e.g. "Independent stores") is just one more <li>; at 375 they stay on
   one line. */
.where-to-buy {
  display: grid; gap: 10px; justify-items: start;
}
.product-copy .where-to-buy__note { font-size: .875rem; }
.retailers {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 32px;
}
.retailer {
  display: flex; align-items: center;
  transition: transform .2s ease;
}
.retailer img { width: auto; max-width: none; }
.retailer .retailer__logo--woolworths { height: 50px; }
.retailer .retailer__logo--coles { height: 24px; }
.retailer:hover { transform: translateY(-2px); }
.retailer:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .retailer { transition: none; }
  .retailer:hover { transform: none; }
}

/* Forms: newsletter (Mailchimp) and Contact (Formspree). The bot-trap field
   sits off-screen and must stay empty. The status line is the live region
   main.js writes the result into; while empty it is visually hidden, so it
   adds no row to the form's grid. */
.form-trap { position: absolute; left: -5000px; }
.form-status { font-family: var(--font-display); line-height: 1.5; }
.form-status:empty {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.form-status a { text-decoration: underline; text-underline-offset: 2px; }
.newsletter__field[hidden] { display: none; }
.contact-form button[disabled] { opacity: .6; cursor: progress; }
.contact-done { font-family: var(--font-display); font-size: clamp(17px, 1.6vw, 20px); line-height: 1.5; }
.contact-done:focus { outline: none; }

/* 404 */
.not-found { text-align: center; }
.not-found__text { font-size: clamp(15px, 1.4vw, 17px); line-height: 1.6; }
.not-found__actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;
  margin-top: clamp(24px, 3vw, 40px);
}
