/*
 * Green St Kitchen - design tokens
 * ---------------------------------------------------------------------------
 * THE single source of truth for colour, type, spacing and layout.
 * No other stylesheet in this theme may contain a literal colour value.
 *
 * Derived by measuring 01_GSK_Web_June-2026_Home.pdf, a 960 x 2977.7pt
 * artboard. Type sizes and positions on that artboard resolve to round CSS
 * pixels at exactly 4/3 scale (46.5pt -> 62px, 22.5pt -> 30px, 12pt -> 16px,
 * x=48pt -> 64px), so the design canvas is 1280px wide with 64px gutters.
 * See MAINTAINER.md "Where the numbers came from" before changing anything here.
 */

:root {
  /* ---- Global colour ------------------------------------------------------
   * The three global values are fixed brand colours.
   */
  --gs-warm-beige: #f0e8e2;   /* global page background */
  --gs-beige-rose: #D8CFC7;   /* global grey color */
  --gs-ink: #0d0d0d;          /* primary text, dark sections, nav, primary buttons */
  --gs-paper: #f2f2f2;        /* text on dark backgrounds, light buttons */
  --gs-stone-grey: #8A827B;   /* global grey color */
  --gs-darker-grey: #2A2A2A;   /* global grey color */

  /* Pure white. Distinct from Paper and used deliberately in the Contact design
   * for card surfaces and form field fills, where it was sampled as #ffffff over
   * tens of thousands of pixels while the pill on the same card sampled as Paper.
   * Surfaces only. Text on a dark or coloured surface stays Paper, per Home. */
  --gs-white: #ffffff;

  /* Warm greys for text, sampled from the Contact mockup. These are not tints of
   * Ink: each is its own value in the artwork. Named by the role they play so a
   * component never has to pick between three near-identical greys.
   * Contrast on their own surfaces, measured: soft 7.90:1 on warm beige,
   * muted 7.56:1 on white, label 4.91:1 on warm beige and 5.92:1 on white. */
  --gs-ink-soft: #4a4540;     /* centred standfirst on warm beige */
  --gs-ink-muted: #5a534c;    /* body copy inside a white card */
  --gs-ink-label: #6a635c;    /* field labels, and contact detail labels/values */

  /* Body copy inside a tinted card. Sampled from the Our Story mockup, where all
   * three value cards set their copy in this one colour whatever their tint. It
   * carries a real violet cast rather than the warm cast the three greys above
   * share: dE76 against ink-muted is 16.8, well past anything that could be
   * called the same colour, so it is its own token rather than a reuse.
   * Measured on its own three tints: 6.26:1, 6.42:1 and 6.32:1. */
  --gs-ink-tinted: #5b4f63;

  /* Form field border, sampled from the Contact mockup. */
  --gs-field-border: #e0d5cb;

  /* Placeholder text, sampled from the Store Locator search field. The only grey
   * on this site with no warm cast at all: dE76 is 7.6 from the nearest of the
   * four warm greys above, so it is its own value rather than one of them
   * rendered differently. Measured 4.61:1 on white. */
  --gs-placeholder: #757575;

  /* ---- Store Locator map -------------------------------------------------
   * assets/js/locator.js reads all four off this file at run time and hands them
   * to a Google styled map, so no hex is repeated in the script and this stays
   * the only place any of them lives.
   *
   * THE MOCKUP DRAWS A PLACEHOLDER, NOT A MAP STYLE. What it draws is a flat
   * beige rectangle with an even grid ruled over it: no coastline, no water, no
   * state borders. Taken literally it produced an unusable map - land and sea
   * were both --gs-map-surface, 2.3 dE76 apart, and Australia's coastline
   * disappeared. So the palette below is the placeholder read as intent rather
   * than as pixels, and it is a 7A decision. Nothing outside the brand palette
   * appears on it.
   *
   * --gs-map-surface is sampled from the drawing and is the land. It is dE76 3.0
   * from --gs-beige-rose, close enough to be a near-duplicate by the usual test,
   * and split out anyway: the map is a 742 x 500 flat field, which is where a 3.0
   * shift shows most rather than least, and it has to stay adjustable without
   * moving a token that text elsewhere sits on. */
  --gs-map-surface: #d2c8bd;   /* land */
  /* Water, several steps lighter than the land. That one contrast is what makes
   * the coastline readable, and it sits the continent on the page's own colour
   * rather than in a box. Deliberately the same value as --gs-warm-beige. */
  --gs-map-water: #f0e8e2;
  /* Roads, lighter than the land so a city reads as a network without competing
   * with the stockist pins over it. The same value as --gs-beige-rose. */
  --gs-map-road: #d8cfc7;
  /* State and country lines. This was the drawn grid colour and is now used for
   * the thing a real map actually has in that role. */
  --gs-map-line: #cbc2b7;

  /* ---- Range accent colour -----------------------------------------------
   * Sampled from the Home mockup. These are range-level accents used on Home;
   * the per-product colour system is a separate concern and is not defined here.
   * See BUILD-REPORT.md: these values are not yet traceable to a written
   * colour table and need confirming before the product template is built.
   */
  --gs-wild-ferments: #5b2d85;
  --gs-pickled-things: #b05a26;
  --gs-jamu-jamu: #b07a1e;
  --gs-pickled-things-alt: #9c1e5c;   /* used only on the Home two-up card */

  /* Forest green, sampled from the FAQ mockup's closing band. The only place a
   * green this dark is drawn, and like the values above it is not yet traceable
   * to a written colour table. White on it measures 7.51:1. */
  --gs-forest: #375c4c;

  /* A darker rust than the Pickled Things accent, sampled from the FAQ eyebrow.
   * It is its own fill in the artwork rather than the accent with something over
   * it. It reads as the designer already darkening that rust for contrast: it
   * measures 4.13:1 on Warm Beige against the accent's 4.0. Still short of the
   * 4.5 an eyebrow needs - see BUILD-REPORT.md. */
  --gs-rust-deep: #a25f26;

  /* Kraut, sampled from the Our Story mockup's middle value card. Wild Ferments
   * splits into Kimchi and Kraut (PROJECT-BRIEF section 6), and Our Story is the
   * first surface that draws Kraut with a colour of its own rather than under the
   * shared Wild Ferments purple: the card is green, and the shape motif on it is
   * the supplied Kraut artwork. Like the four values above it, this one is not yet
   * traceable to a written colour table. See BUILD-REPORT.md. */
  --gs-kraut: #496d40;

  /* Surface tints, sampled from the Home mockup, and Kraut from Our Story. */
  --gs-tint-neutral: #e7dcd3;         /* two-up card, wild ferments side */
  --gs-tint-wild-ferments: #ede6f0;
  --gs-tint-pickled-things: #f6e7d8;
  --gs-tint-jamu-jamu: #f7eedc;
  --gs-tint-kraut: #e7ede3;

  /* Brand shape motif colours. The shapes themselves are the supplied SVGs in
   * assets/svg/, applied as a CSS mask so the colour comes from here rather
   * than being baked into the file. One SVG per range serves every tint.
   * These were sampled from the mockup and then confirmed against the supplied
   * artwork: #f3d2a4 is exactly the fill in the JAMU label-colour variant. */
  --gs-shape-wild-ferments: #d0c6dd;
  --gs-shape-pickled-things: #f7d3ba;
  --gs-shape-jamu-jamu: #f3d2a4;
  --gs-shape-pickled-things-alt: #aa3d73; /* on the magenta two-up card */
  --gs-shape-kraut: #d4e0ce;              /* Our Story's middle value card */

  /* ---- Product colour schemes --------------------------------------------
   * PROJECT-BRIEF section 10, decided 11 August 2026. Each product page picks
   * ONE named scheme, and the scheme sets the hero wordmark, the section
   * headings, the ghost pill, the shape cluster behind the jar, the product's
   * own title in a related card, and its title and link on the Products
   * catalogue. An editor chooses a name; nobody types a hex.
   *
   * WHY NAMES AND NOT PICKERS. Eleven free colour pickers would mean eleven
   * invented values, which is PROJECT-BRIEF section 2B's "plausible invented
   * design". A closed set means a twelfth product picks an existing scheme or
   * somebody supplies a new one deliberately.
   *
   * ELEVEN SCHEMES, NOT SIX, AS OF 12 AUGUST 2026 (session 7). The two
   * paragraphs this block used to carry said the eleven-product colour table
   * had never been found and that six named schemes were the best that could be
   * traced. That is no longer true and the record is corrected rather than
   * quietly rewritten: 02_GSK_Web_June-2026_Products.pdf draws all eleven
   * products as cards, and each card's title and "view product" link are set in
   * that product's own colour. Eleven titles, eleven colours, one artboard.
   *
   * The four kimchi came out identical to the four schemes already built from
   * the Product Details artboard, which is what establishes that a card title
   * and a page scheme are the same value in this design system rather than two
   * unrelated choices. Ten of the eleven are corroborated a second time by the
   * hue of that product's own supplied shape file in assets/svg/shapes/ -
   * #ab7436 beside amber, #40676a beside forest, #894347 beside plum.
   *
   * Seven products were re-pointed as a result. See BUILD-REPORT.md session 7.
   *
   * WHERE EACH VALUE COMES FROM. purple, magenta, rust and crimson were read
   * out of the Product Details mockup's own vector data. The other seven are
   * the modal ink of each card title on the Products artboard, measured over
   * 6,000 to 13,000 raster pixels of solid glyph interior, so they are the
   * fill and not an antialiased edge.
   *
   * Values that already exist above are referenced, not repeated, so there is
   * still exactly one literal per colour in this theme. Three of the seven new
   * schemes needed no new literal at all: amber is --gs-rust-deep, terracotta
   * is --gs-pickled-things and forest is --gs-forest, each arriving at the same
   * hex from a different artboard.
   *
   * MEASURED, on white (the catalogue and related-card surface) and on warm
   * beige (the product hero):
   *   purple      9.73 / 8.03      magenta     7.63 / 6.30
   *   crimson     7.80 / 6.45      plum        9.41 / 7.77
   *   forest      7.51 / 6.20      rust        7.18 / 5.93
   *   green       5.92 / 4.89      amber       5.00 / 4.13
   *   terracotta  4.84 / 4.00      orange      4.21 / 3.48
   *   gold        3.72 / 3.07
   *
   * A card title is 16.5px bold, which is under WCAG's 18.66px large-bold
   * threshold, so it needs 4.5:1 and ORANGE FAILS IT at 4.21:1. That is the
   * drawn colour on the Carrot & Daikon Radish card and it is granted as an
   * exception on the same basis as the six on Home and the breadcrumb on the
   * product pages: PROJECT-BRIEF 7A gives Webstein authority over what the
   * mockup does not cover, not over a colour it does. Listed in
   * BUILD-REPORT.md. Where a scheme fails on a surface the mockup does NOT
   * draw, product.css falls back to Ink instead - that case is 7A's.
   *
   * GOLD IS NO LONGER ASSIGNED TO ANY PRODUCT. Turmeric Elixir is drawn
   * terracotta on the Products artboard, not gold. Gold stays defined because
   * it is still the Jamu Jamu range accent on Home, and stays selectable so
   * that retiring it is not a silent data migration. At 3.72:1 on white it
   * would fail a card title, so do not assign it to a product without raising
   * it first.
   */
  --gs-scheme-purple: var(--gs-wild-ferments);              /* Black Miso & Garlic */
  --gs-scheme-purple-shape: var(--gs-shape-wild-ferments);
  --gs-scheme-magenta: var(--gs-pickled-things-alt);        /* Spicy Pink Radish & Ginger */
  --gs-scheme-magenta-shape: #e8adbc;
  --gs-scheme-rust: #87461f;                                /* Szechuan Pepper & Turmeric */
  --gs-scheme-rust-shape: #e8b792;
  --gs-scheme-crimson: #9e1f2f;                             /* White Miso & Dry Red Pepper */
  --gs-scheme-crimson-shape: #ddc2b3;
  --gs-scheme-green: var(--gs-kraut);                       /* Zesty Lemon & Dill */
  --gs-scheme-green-shape: var(--gs-shape-kraut);
  --gs-scheme-gold: var(--gs-jamu-jamu);                    /* range accent only - see above */
  --gs-scheme-gold-shape: var(--gs-shape-jamu-jamu);

  /* The five added in session 7. Each shape colour is the modal fill of that
   * product's shape cluster over its catalogue card photograph.
   *
   * Terracotta's shape reuses --gs-shape-pickled-things: the card draws
   * #f1cfb2 and the token is #f7d3ba, dE76 2.75, inside the 3.0 this file
   * already treats as a near-duplicate. The same is not true of the other
   * four, which are their own values. */
  --gs-scheme-amber: var(--gs-rust-deep);                   /* Ginger & Turmeric */
  --gs-scheme-amber-shape: #e9d8c3;
  --gs-scheme-terracotta: var(--gs-pickled-things);         /* Daikon, and Turmeric Elixir */
  --gs-scheme-terracotta-shape: var(--gs-shape-pickled-things);
  --gs-scheme-orange: #ce5628;                              /* Carrot & Daikon Radish */
  --gs-scheme-orange-shape: #eac9b6;
  --gs-scheme-plum: #782a4b;                                /* Togarashi Spiced Wombok */
  --gs-scheme-plum-shape: #e6c6cd;
  --gs-scheme-forest: var(--gs-forest);                     /* Wombok w. Wakame */
  --gs-scheme-forest-shape: #cad7d0;

  /* ---- Range band palettes ------------------------------------------------
   * The Products catalogue draws one band per sub-range, and the band's accent
   * is a RANGE colour rather than a product one: purple over the kimchi, green
   * over the kraut, the Pickled Things rust over the pickles, gold over the
   * tonic. Every value it needs already exists in this file, so a palette is a
   * grouping rather than a new set of colours - see the .gs-rangeband--*
   * classes in blocks/product-catalogue/style.css.
   *
   * ONE EXCEPTION, AND IT IS A CONFLICT IN THE SUPPLIED DESIGN. The tonic band
   * draws its range word and eyebrow #a77c33, where the Home artboard draws the
   * same Jamu Jamu accent #b07a1e. dE76 10.32 apart, so this is not sampling
   * noise: both were re-measured as the dominant fill of their own artboard
   * (19,984 samples on Home, 61,161 on Products). Neither PDF is newer than the
   * other.
   *
   * Both are reproduced, each on its own page, because PROJECT-BRIEF 7A gives
   * Webstein no authority to pick between two drawn colours. Curiously the
   * darker one buys nothing: both measure exactly 3.23:1 against their own
   * tint, so the 12.5px "TONIC" eyebrow fails either way and carries the same
   * granted exception the Home tile already carries. Flagged for Oakie in
   * BUILD-REPORT.md; unifying them is one line here. */
  --gs-jamu-jamu-products: #a77c33;

  /* ---- Product page surfaces ---------------------------------------------
   * Measured from the Product Details artboard. Only three values here, because
   * the other four the page needs turned out to be colours this file already
   * holds:
   *   specification labels  #8f867e  is dE76 1.75 from --gs-stone-grey
   *   taste bar labels      #cfc7bf  is dE76 2.98 from --gs-beige-rose
   *   dark band body copy   #cfc7bf  the same again
   * All three are inside the dE76 3.0 that this file already treats as a
   * near-duplicate (see the --gs-map-surface note), so they reuse the existing
   * token rather than adding a fourth warm grey nobody could tell apart.
   * Measured on ink: stone grey 5.15:1, beige rose 12.65:1.
   */

  /* Values in the specification list. Genuinely its own colour, dE76 5.98 from
   * beige rose, and noticeably brighter: it is the answer to the label beside
   * it and the design separates the two by weight of colour alone. 14.89:1. */
  --gs-spec-value: #e8e0d8;

  /* The hairline above the specification list, and the unfilled part of a taste
   * bar. One value doing both jobs in the artwork, so one token here. */
  --gs-spec-rule: #2e2e2e;

  /* Row rules inside the white nutrition panel. 1.27:1 on white, which is
   * deliberate: they separate rows in a table that is already aligned into
   * columns, so they are decoration rather than the thing carrying the meaning,
   * and the figures themselves measure 14.9:1. */
  --gs-nutrition-rule: #eee2d8;

  /* ---- Semantic colour ---------------------------------------------------
   * Components reference these, never the raw brand values above, so a
   * section can be re-themed by reassigning one custom property.
   */
  --gs-bg: var(--gs-warm-beige);
  --gs-fg: var(--gs-ink);
  --gs-bg-inverse: var(--gs-ink);
  --gs-fg-inverse: var(--gs-paper);
  --gs-accent: var(--gs-ink);

  /* Focus ring. Deliberately not a subtle treatment: the acceptance criteria
   * require a visible indicator at 3:1 against its own background. */
  --gs-focus: var(--gs-ink);
  --gs-focus-inverse: var(--gs-paper);
  --gs-focus-width: 3px;
  --gs-focus-offset: 3px;

  /* The minimum interactive target the acceptance criteria ask for, at 375px and
   * at 1440px. A control drawn smaller than this keeps its drawn size and grows
   * its hit area to meet it. */
  --gs-target-min: 44px;

  /* ---- Type families ----------------------------------------------------- */
  --gs-font-display: "NaN Jaune", ui-sans-serif, system-ui, sans-serif;
  --gs-font-heading: "Unbounded", ui-sans-serif, system-ui, sans-serif;
  --gs-font-body: "Figtree", ui-sans-serif, system-ui, sans-serif;

  /* ---- Type scale --------------------------------------------------------
   * Measured values, largest first. Fluid steps clamp between the phone size
   * and the measured desktop size, so the desktop end always matches the
   * mockup exactly and nothing overflows at 375px.
   */
  --gs-step-hero: clamp(2.25rem, 1.06rem + 5.06vw, 3.875rem);   /* 36 -> 62px */
  /* Contact's centred h1 "Say g'day", 55.5pt on the artboard. Larger than Home's
   * hero because it is the only thing on the page competing for attention. */
  --gs-step-hero-xl: clamp(2.5rem, 1.04rem + 6.25vw, 4.625rem); /* 40 -> 74px */
  --gs-step-display: clamp(2rem, 1.18rem + 3.5vw, 3.375rem);    /* 32 -> 54px */
  --gs-step-jar: clamp(2rem, 1.36rem + 2.73vw, 2.875rem);       /* 32 -> 46px */
  --gs-step-statement: clamp(1.5rem, 1.05rem + 1.93vw, 2.0625rem); /* 24 -> 33px */
  --gs-step-section: clamp(1.5rem, 1.23rem + 1.14vw, 1.875rem); /* 24 -> 30px */
  --gs-step-range: clamp(1.5rem, 1.23rem + 1.14vw, 1.875rem);   /* 24 -> 30px */
  --gs-step-lead: 1.1875rem;   /* 19px - hero standfirst */
  --gs-step-intro: 1.125rem;   /* 18px - centred intro paragraph */
  --gs-step-card-title: 1.0625rem; /* 17px */
  --gs-step-body: 1.03125rem;  /* 16.5px - two-up card body */
  --gs-step-base: 1rem;        /* 16px - default body */
  --gs-step-sm: 0.90625rem;    /* 14.5px - three-up card body, white card body */
  --gs-step-pill: 0.9375rem;   /* 15px - pill label, nav, select value */
  --gs-step-pill-sm: 0.875rem; /* 14px - small pill label */
  --gs-step-label: 0.8125rem;  /* 13px - credential label, field label */
  --gs-step-eyebrow: 0.78125rem; /* 12.5px - eyebrow / kicker */
  --gs-step-chip: 0.75rem;     /* 12px - chips */
  --gs-step-tag: 0.71875rem;   /* 11.5px - image tag */

  /* Contact page steps, measured from 05_GSK_Web_June-2026_Contact.pdf. */
  --gs-step-card-heading: clamp(1.375rem, 1.16rem + 0.9vw, 1.625rem); /* 22 -> 26px */
  --gs-step-reach: 1.09375rem;      /* 17.5px - the white card's heading */
  --gs-step-detail: 0.91625rem;     /* 14.67px (11pt) - contact detail label */
  --gs-step-detail-value: 0.84375rem; /* 13.5px - contact detail value */
  --gs-step-body-sm: 0.875rem;      /* 14px - body copy inside a coloured card */

  /* Our Story steps, measured from 07_GSK_Web_June-2026_Our-Story.pdf. Only one
   * size on that page had no existing step: the closing band's heading. Its prose
   * reuses --gs-step-body, its value card titles --gs-step-range, their copy
   * --gs-step-sm, and its "What we make" subheading --gs-step-card-heading, which
   * lands on exactly the 26px drawn even though it was named for Contact. */
  --gs-step-cta: clamp(2rem, 1.639rem + 1.541vw, 2.625rem); /* 32 -> 42px */

  /* FAQ steps, measured from 06_GSK_Web_June-2026_FAQ.pdf. Its eyebrow, headline,
   * standfirst, chips and closing body line all reuse existing steps; only the
   * group heading and the answer copy needed their own. The answer is 15px, which
   * --gs-step-pill also is, but that token is named for pill labels and nav links
   * and body copy should not borrow it. */
  --gs-step-faq-group: clamp(1.25rem, 1.181rem + 0.293vw, 1.375rem); /* 20 -> 22px */
  --gs-step-faq-answer: 0.9375rem;  /* 15px */
  --gs-leading-faq-answer: 1.733;   /* 26px on 15px, the drawn pitch */

  --gs-leading-tight: 1;
  --gs-leading-heading: 1.21;
  --gs-leading-body: 1.5;
  --gs-leading-body-tight: 1.18;
  /* Our Story runs its prose looser and its card copy tighter than the site
   * default. Both are the drawn line pitch divided by the drawn size: 26.66 on
   * 16.5, and 22.73 on 14.5. */
  --gs-leading-prose: 1.616;
  --gs-leading-card: 1.568;

  /* Eyebrows and tags are letterspaced in the design. */
  --gs-tracking-eyebrow: 0.18em;
  --gs-tracking-label: 0.1em;
  /* Form labels are letterspaced less than an eyebrow. Derived from two labels
   * in the Contact mockup: "FIRST NAME" implies 0.072em and
   * "I'M ENQUIRING ABOUT" implies 0.076em. */
  --gs-tracking-field: 0.075em;
  /* The white card's heading is the one piece of outlined text in the Contact
   * PDF, so its font could not be read from the text layer. Stem thickness and
   * ink mass identify it as Unbounded Bold (within 2%, against 15-22% for
   * Medium). At the size that matches its drawn ink height it renders 3.4% wider
   * than drawn, where the page's two live-text Unbounded headings match within
   * 1%, so this one carries tracking. See BUILD-REPORT.md. */
  --gs-tracking-reach: -0.03em;

  /* ---- Layout ------------------------------------------------------------
   * 12 column grid. Content 1152px, gutter 64/3px. Every row on Home is a
   * span of this grid: two-up = span 6, three-up = span 4, four-up = span 3.
   */
  --gs-canvas: 1280px;
  --gs-content: 1152px;
  --gs-gutter: 64px;
  --gs-grid-columns: 12;
  --gs-grid-gap: 21.3333px;

  /* The Contact page sets its content in a narrower column than the rest of the
   * site: 952px, measured from equal 164px margins on the 1280px canvas. Inside
   * it the split is 1.2fr / 1fr with a 50px gap, which reproduces the drawn
   * 492px form column and 410px card column exactly. */
  --gs-content-narrow: 952px;
  --gs-column-gap-wide: 50px;

  /* ---- Spacing ----------------------------------------------------------- */
  --gs-space-3xs: 4px;
  --gs-space-2xs: 8px;
  --gs-space-xs: 12px;
  --gs-space-sm: 16px;
  --gs-space-md: 24px;
  --gs-space-lg: 32px;
  --gs-space-xl: 48px;
  --gs-space-2xl: 64px;
  --gs-space-3xl: 80px;
  --gs-space-4xl: 104px;

  /* Section padding. Adjacent sections each contribute one of these, so the
   * gap between two blocks of content is twice the value. Measured from the
   * mockup's baselines. */
  --gs-section-y: 32px;
  --gs-section-y-lg: 42px;

  /* Contact's single content section does not follow the shared section rhythm:
   * it is the only band between the header and the footer, and the drawing gives
   * it 52px above the eyebrow and 140px below the last card. Measured, not
   * averaged. */
  --gs-contact-pad-top: 56px;
  --gs-contact-pad-bottom: 140px;
  /* Standfirst to the top of the two column body. */
  --gs-contact-body-gap: 49px;
  /* The white card's foot is drawn deeper than its head: 32px above the heading,
   * 51px below the last address line. Derived from the card's drawn height rather
   * than assumed symmetrical. */
  --gs-contact-card-foot: 51px;

  /* The Contact standfirst is set to the drawn longest line, 506px, so it wraps
   * to the same two lines without a hard break. See PROJECT-BRIEF 7A. */
  --gs-measure-standfirst: 512px;

  /* ---- Our Story ---------------------------------------------------------
   * Measured from 07_GSK_Web_June-2026_Our-Story.pdf, a 960 x 1711.87pt artboard
   * that resolves to the same 1280px canvas at 4/3 scale as Home and Contact,
   * which is now the third independent confirmation of that scale.
   *
   * Like Contact, this page does not follow the shared section rhythm. Its band
   * edges were read off the rendered artboard directly - the header ends at 93,
   * the hero image at 533, the closing colour band starts at 1762 and the footer
   * at 1990 - so each depth below is measured rather than averaged.
   */
  /* Prose column, from equal 264px margins on the 1280px canvas. Narrower than
   * both the site's 1152px and Contact's 952px: this page is one long read and
   * the designer set it to a reading measure. */
  --gs-story-measure: 752px;
  --gs-story-prose-top: 58px;
  --gs-story-prose-bottom: 50px;
  /* The drawn paragraph gap is exactly one blank line of the prose leading. */
  --gs-story-para-gap: 27px;
  --gs-story-sub-top: 31px;
  --gs-story-sub-bottom: 21px;

  /* The Value cards block does not take the shared section rhythm. Our Story is
   * the only surface that draws it and it draws the row tight under the slider
   * and further off the band below, so both depths are measured. A later page
   * that wants the row spaced differently reassigns these two rather than
   * editing the block. */
  --gs-valuecards-pad-top: 13px;
  --gs-valuecards-pad-bottom: 50px;

  /* One value card, drawn 369 x 230. The foot is deep because that space is not
   * empty: it is where the shape motif sits, so it is padding rather than a
   * margin and it holds even when the copy is short. */
  --gs-valuecard-pad-x: 30px;
  --gs-valuecard-pad-top: 26px;
  --gs-valuecard-pad-foot: 92px;
  --gs-valuecard-title-gap: 14px;

  /* ---- FAQ ---------------------------------------------------------------
   * Measured from 06_GSK_Web_June-2026_FAQ.pdf, a 960 x 1545pt artboard that
   * resolves to the same 1280px canvas at 4/3 scale as every other template.
   *
   * The page sets its cards in a 732px column, from equal 274px margins. That is
   * the fourth measure on this site - 1152 everywhere, 952 on Contact, 752 on Our
   * Story, 732 here - and each is drawn, not chosen.
   */
  --gs-faq-measure: 732px;
  --gs-faq-pad-top: 56px;
  --gs-faq-pad-bottom: 85.9px;
  --gs-faq-eyebrow-gap: 15.4px;
  --gs-faq-title-gap: 22.8px;
  --gs-faq-chips-gap: 26.6px;
  /* The chips sit further off the first group heading than the groups sit off
   * each other - 100.5px against 56px in the drawing - so these are two values,
   * not one. */
  --gs-faq-chips-to-group: 79.5px;
  --gs-faq-group-gap: 38.8px;
  --gs-faq-group-head-gap: 15.4px; /* group heading to its first card */
  --gs-faq-card-gap: 12px;

  /* One accordion card, drawn 732 wide with a 27px inset each side. Its head and
   * its foot are not the same depth in the drawing, so they are two values. */
  --gs-faq-card-pad-x: 27px;
  --gs-faq-card-pad-top: 22px;
  --gs-faq-card-pad-bottom: 17.3px;
  --gs-faq-q-gap: 7.45px;          /* question to answer */

  /* The plus is drawn 7.25px across with 1.14px bars, which is small and thin on
   * purpose. It is not the hit area: the whole question row is. */
  --gs-faq-icon: 8px;
  --gs-faq-icon-bar: 1.14px;

  /* The filter chips. Bigger than the .gs-chip tags on Home, which are a
   * different component at 12px in a 6/14 box. */
  --gs-faq-chip-height: 38px;
  --gs-faq-chip-pad-x: 20px;
  --gs-faq-chip-gap: 11px;

  /* ---- Closing colour band ------------------------------------------------
   * Two pages now end with a full bleed colour band carrying a centred heading
   * and one pill, so the structure is a shared component in components.css and
   * only these numbers are per surface. They are measurements, not a scale: the
   * two bands are drawn to different depths with different heading sizes.
   *
   * Our Story: band 228px deep, 42px heading, no body line, dark pill.
   * FAQ:       band 252px deep, 40px heading, a 16px body line, light pill.
   */
  --gs-cta-title: var(--gs-step-cta);
  --gs-cta-pad-top: 54px;
  --gs-cta-pad-bottom: 56px;
  --gs-cta-gap: 22px;
  --gs-cta-body-gap: 0px;

  --gs-cta-title-faq: clamp(2rem, 1.669rem + 1.414vw, 2.5rem);  /* 32 -> 40px */
  --gs-cta-pad-top-faq: 52px;
  --gs-cta-pad-bottom-faq: 54px;
  --gs-cta-gap-faq: 19px;
  --gs-cta-body-gap-faq: 9.6px;

  /* ---- Pills -------------------------------------------------------------
   * Fully pill shaped at 40px radius per the brief. Two measured heights.
   * Both clear the 44px minimum target size in the acceptance criteria.
   */
  --gs-pill-radius: 40px;
  --gs-pill-height: 48px;
  --gs-pill-height-sm: 45px;
  /* 30px, corrected from 28px on 10 August 2026. Derived from three separately
   * drawn pills rather than one: "find a stockist" at 149px implies 30.2px per
   * side, "send message" at 152px implies 31.2px, "wholesale enquiry" at 177.2px
   * implies 31.9px. At 28px every pill on the site rendered 3 to 4px narrow -
   * the header pill measured 146.6px against the mockup's 149px. 30px is the
   * value that gets all three closest. Changing it moves every pill on the site,
   * which is the point: the old value was wrong everywhere, not just on Contact. */
  --gs-pill-padding-x: 30px;
  --gs-pill-gap: 12px;

  /* ---- Play control ------------------------------------------------------
   * Two drawn sizes, not one. The hero ring measures 82px on the Home artboard
   * and is built at 84; the reel ring measures 69px on Home and 69px again on
   * Our Story. Both were built at 84 until 10 August 2026. Below 1024px both
   * take the small size, which is a 7A decision rather than a measurement.
   */
  --gs-play-hero: 84px;
  --gs-play-reel: 69px;
  --gs-play-sm: 64px;

  /* ---- Banner depth ------------------------------------------------------
   * The design draws two, and the Banner block picks between them with its
   * Height field: 640px on Home, 440px on Our Story (the header ends at 93 on
   * that artboard and the hero image ends at 533). Desktop values; below 1024px
   * every banner takes the single floor below and grows with its own copy.
   */
  /* Eyebrow to headline. Both artboards draw 71px between those two baselines,
   * Home and Our Story alike; the block had 24px here, which rendered 59.8. This
   * moves Home's hero as well as Our Story's, which is the point: the gap was
   * short on both. See BUILD-REPORT.md. */
  --gs-hero-eyebrow-gap: 11.2px;

  --gs-hero-tall: 640px;
  --gs-hero-short: 440px;
  --gs-hero-floor: 480px;
  /* The short banner's content is not centred in its band the way the tall one
   * is: Our Story sets it about 17px above centre, so it is placed from the top
   * edge instead. 118.2px puts the eyebrow's baseline on the drawn 224.19. */
  --gs-hero-short-pad-top: 118.2px;

  --gs-card-radius: 16px;
  /* The two Contact cards measure 20px, derived from their corner inset profiles.
   * Home's cards are 16px, so both values are real. */
  --gs-card-radius-lg: 20px;
  --gs-card-padding: 48px;

  /* The Products artboard draws two more radii, and like the four content
   * measures this project already carries, each is drawn rather than chosen.
   * Both were derived from the corner inset profile - the horizontal inset of
   * the fill measured every 2px down from the corner, then fitted against
   * r - sqrt(2.r.dy - dy^2). The range band fits r=18 within 0.4px at every
   * sample and r=20 is a consistent 1px out; the card fits r=14 within 0.4px
   * and r=16 is a consistent 1px out. Neither is the 16 or the 20 above, so
   * neither reuses them. */
  --gs-band-radius: 18px;
  --gs-productcard-radius: 14px;

  /* ---- Form fields -------------------------------------------------------
   * Measured from the Contact mockup. The select is drawn 2px taller than the
   * text inputs beside it; that is reproduced rather than tidied, and noted in
   * BUILD-REPORT.md.
   */
  --gs-field-radius: 16px;
  --gs-field-height: 48px;
  --gs-field-height-select: 50px;
  --gs-field-height-textarea: 130px;
  --gs-field-padding-x: 23px;
  --gs-field-label-gap: 9px;
  --gs-field-col-gap: 16px;

  /* ---- Store Locator -----------------------------------------------------
   * Measured from 04_GSK_Web_June-2026_Store-Locator.pdf, a 960 x 968.2pt
   * artboard that resolves to the same 1280px canvas at 4/3 scale as every other
   * template. That is the fifth independent confirmation of the scale.
   *
   * THIS IS THE TEMPLATE THAT USES UNBOUNDED MEDIUM. Five artboards had been
   * opened without it appearing once, and PROJECT-BRIEF 7B had it down as a font
   * worth asking Oakie about. The store names are the only outlined text on this
   * page, so the text layer cannot name their face; scaled to the drawn cap
   * height of 11.52px and compared ink box to ink box across four separate store
   * names, Unbounded Medium lands within 1.4% where Unbounded Bold is 5.4% wide,
   * NaN Jaune 5.7% narrow and both Figtrees about 19% narrow. See
   * BUILD-REPORT.md; the harness is C:\webstein-qa\name-face.js.
   */
  --gs-step-store-name: 0.9375rem;   /* 15px - Unbounded Medium, the store name */
  --gs-step-store-card: 0.875rem;    /* 14px - the same face on the map's info card */
  --gs-step-store-address: 0.84375rem; /* 13.5px */
  --gs-leading-store-address: 1.481; /* 20px on 13.5px, the drawn pitch */
  --gs-step-store-meta: 0.8125rem;   /* 13px - the info card's body lines */
  --gs-leading-store-meta: 1.131;    /* 14.7px on 13px, the drawn pitch */

  /* Vertical rhythm, from the drawn baselines: eyebrow 158.7, headline 230.7,
   * standfirst 274.7 and 296, the band 357 to 857, the footnote 933.3 and the
   * footer at 998. Each gap below is the distance between two line boxes derived
   * from those baselines, not a scale. */
  --gs-locator-pad-top: 55px;
  --gs-locator-pad-bottom: 59px;
  --gs-locator-eyebrow-gap: 5.4px;
  --gs-locator-title-gap: 17.8px;
  --gs-locator-body-gap: 56.6px;   /* standfirst to the top of the band */
  --gs-locator-note-gap: 60.9px;   /* band to the footnote line */

  /* The standfirst is set to the drawn longest line so it wraps to the same two
   * lines without a hard break, per PROJECT-BRIEF 7A. Wider than Contact's 512px
   * because this page's second line is longer. */
  --gs-measure-locator: 672px;

  /* The band is one row inside the site's standard 1152px column: a 380px panel,
   * a 30px gap and the map taking the remaining 742px. Both are 500px tall and
   * both take the larger of the two drawn card radii. */
  --gs-locator-panel: 380px;
  --gs-locator-gap: 30px;
  --gs-locator-height: 500px;

  /* The panel is a fixed height at every width, not only at the drawn one. It
   * holds 412 stockists and the list scrolls inside it; without a height at
   * phone and tablet the panel simply grew to fit all 412, which rendered a page
   * 98,000px long and put the map below all of it. No artefact covers small
   * screens, so these two are 7A decisions rather than measurements: enough rows
   * to be worth scrolling, and still short enough that the map is on screen. */
  --gs-locator-height-sm: 420px;
  --gs-locator-height-md: 460px;

  /* Panel interior. 28px on all four sides, derived from the search row: the
   * input starts 29px in from the panel's left edge, the pill ends 28px off its
   * right, and the row sits 28px down from its top. */
  --gs-locator-panel-pad: 28px;
  --gs-locator-list-gap: 19.75px;   /* search row to the first store */

  /* One store row, drawn on a 96.5px pitch between hairlines: 16.25px of padding
   * each side of the content, a 5px gap between the name and the address, the
   * address's own two 20px lines, and the 1px hairline itself.
   *
   * The padding is 16.25 rather than the 17 the baselines first suggested because
   * the drawn 96.5 is measured hairline to hairline and therefore includes the
   * hairline. At 17 the rows pitched 98 and the error accumulated down the list:
   * row two was 1.3px low, row three 1.6px, and by row ten it would have been
   * visible. The list gap above absorbs the 0.75px so the first store's name
   * still lands on its drawn ink top. */
  --gs-locator-row-pad: 16.25px;
  --gs-locator-name-gap: 5px;

  /* The map's info card, drawn 239 x 78 and anchored 25px in from the map's left
   * edge and 24px up from its foot. */
  --gs-locator-card-pad-x: 18px;
  --gs-locator-card-pad-y: 15px;
  --gs-locator-card-width: 239px;
  --gs-locator-card-inset: 24px;

  /* ---- Products catalogue ------------------------------------------------
   * Measured from 02_GSK_Web_June-2026_Products.pdf, a 960 x 3409.7pt artboard
   * that resolves to the same 1280px canvas at 4/3 scale as every other
   * template. Sixth independent confirmation of the scale, and the last of the
   * seven artboards to be opened.
   *
   * The page is four range bands, each followed by its own grid of product
   * cards, then the shared reel and the shared locator band.
   */

  /* The band. 1152 wide inside the shell, 270 tall, its type inset 50px from
   * the band's own left edge - derived from four separate first characters
   * across the four bands, each corrected for its glyph's left sidebearing.
   * The 270 is a minimum rather than a height: no artefact says what a band
   * does when its description wraps to three lines at 375px. */
  --gs-rangeband-height: 270px;
  --gs-rangeband-pad-x: 50px;
  /* Band top edge to the range word's ascender top. */
  --gs-rangeband-pad-top: 49.2px;
  /* The foot is 46.1px below the "Best with" line's ink on the artboard. 43.7 is
   * that measured against the rendered line box rather than the ink, which is
   * where the difference goes. Not --gs-space-xl: at 48 the band's own content
   * pushed it to 288.8 tall against the drawn 270. */
  --gs-rangeband-pad-bottom: 43.7px;

  /* Inside the band, from the drawn baselines: range word 572.0, sub-range 596.0,
   * body 638.67 and 664.0, "Best with" 701.33. Each is a gap between two line
   * boxes derived from those, corrected against the rendered page. */
  --gs-rangeband-sub-gap: 4.6px;
  --gs-rangeband-body-gap: 21.6px;
  --gs-rangeband-best-gap: 16px;

  /* The band's text measure. Taken from the TONIC band, which is the only one of
   * the four whose drawn line break falls mid-sentence and therefore the only one
   * that reveals the designer's actual text box width: its first line runs 501.9px
   * and " your" is 42px, so the window is 502 to 544. The other three break at a
   * sentence end, which a hard break and a natural wrap cannot be told apart. */
  --gs-rangeband-measure: 33rem;   /* 528px, mid-window */

  /* The shape cluster, identical on all four bands: about 345 x 221, its right
   * edge on the band's right edge and its top clipped by the band's top edge.
   * Measured 345.8 / 344.9 / 345.8 / 344.2 wide and 222.3 / 221.1 / 220.1 /
   * 219.5 tall across kimchi, japanese style, kraut and tonic - so one value
   * for all four rather than four values within 3px of each other. */
  --gs-rangeband-shape-w: 370px;
  --gs-rangeband-shape-h: 221px;

  /* The card grid. Four-up, 272.9 wide with 20.4 gaps, which is 1152 exactly.
   *
   * THE KRAUT ROW IS DRAWN DIFFERENTLY AND IS NOT REPRODUCED. Its two cards
   * measure 311.3 wide on a 21.2 gap, filling only 643.6 of the 1152 - so
   * neither the shell nor any grid the other three rows sit on. No rule
   * generates 311.3 from "two cards": a 12-column span-4 would be 370.4 and a
   * half-shell card 565.8. The other three rows are all exactly 272.9, single
   * card and four-card alike, including the lone tonic card which stays narrow
   * rather than stretching.
   *
   * So the fixed 272.9 is the rule and the kraut row is the exception, which is
   * a PROJECT-BRIEF 7A decision: it is the only reading that survives a twelfth
   * product, which section 9 requires. Flagged for Oakie in BUILD-REPORT.md.
   * Reproducing the drawing instead would mean a card width that changes with
   * how many products a range happens to hold. */
  --gs-productcard-width: 272.9px;
  --gs-productcard-gap: 20.4px;
  /* Card interior. 22px on all three sides that are drawn, derived the same way
   * as the band inset from the title, the body and the link independently. The
   * foot is 24.7px below the link's ink, which is 22px of padding plus the
   * link line box's own descender space. */
  --gs-productcard-pad: 22px;
  --gs-productcard-pad-bottom: 24px;

  /* Vertical rhythm between a band and its cards, and between a card row and
   * the next band. Both measured four times and identical each time: 33.9px
   * and 89.9-91.1px. The second is the same 90px the page already uses between
   * the standfirst and the first band. */
  --gs-rangeband-gap: 34px;
  --gs-rangeband-rhythm: 90px;

  /* The centred intro, from the drawn baselines: eyebrow 165.1, headline 245.3
   * and 316, standfirst 368 and 389.3, the first band at 479.9. Each is a gap
   * between two line boxes derived from those baselines, corrected against the
   * rendered page rather than calculated from font metrics. */
  --gs-products-pad-top: 61.4px;
  --gs-products-eyebrow-gap: 15.4px;
  --gs-products-title-gap: 28.4px;
  --gs-products-body-gap: 85.4px;   /* standfirst to the top of the first band */

  /* Around the reel. The drawn gaps are 101.4px above the slides and 59.5px below
   * the dots: the last card row ends at 3402, the slides run 3503.4 to 3863, the
   * dots 3883.2 to 3891.2, and the locator band starts at 3950.7.
   *
   * The values below are 42px smaller at each end, and that is not a correction -
   * it is the Media slider block's own section padding, 42px top and bottom, which
   * it brings to all three pages that use it. Subtracting it here rather than
   * removing it from the block is deliberate: Home and Our Story are verified
   * against that padding, and this page is the third caller, not the owner. */
  --gs-products-reel-gap-top: 59.4px;
  --gs-products-reel-gap-bottom: 11.3px;

  /* ---- Motion ------------------------------------------------------------ */
  --gs-transition: 150ms ease;

  /* ---- Breakpoints (documented; media queries cannot read custom properties)
   * phone   : up to 767px   - the base, built first
   * tablet  : 768px - 1023px
   * desktop : 1024px and up
   */
}

/* Interaction states are Webstein's to define per PROJECT-BRIEF section 7A.
 * Hover is a single consistent treatment across all four pill variants:
 * the fill shifts one step toward its own contrast partner. Defined here so
 * every variant inherits it rather than each deciding separately. */
:root {
  --gs-hover-shift: 14%;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --gs-transition: 0ms;
  }
}

/* The fixed header's rendered height, matching .gs-header__inner's min-height
 * in components.css. Custom properties only inherit downward, so this lives
 * at :root rather than on .gs-header itself - body's top padding and the
 * Products page anchor offset both need to read it without being header
 * descendants. */
:root {
  --gs-header-height: 72px;
}

@media (min-width: 1024px) {
  :root {
    --gs-header-height: 93px;
  }
}
