/* File: themes/craftysales/assets/theme.css
 * File Version: 39
 * History:
 *   V39 20261030  V0.6.230: American English, the owner's word of 2026-10-30
 *   V38 20261015  An upload's "or drop it here" line, in the hint's voice (F-545)
 *   V37 20261014  The currencies row at the foot of the page, styled as the languages' (docs/22 Later 11)
 *   V36 20261012  A video with no still chosen is a plain tile the size of its picture (F-528)
 *   V35 20261009  The row of languages, on the footer's deep ground (docs/22 Later 12)
 *   V34 20261006  A row somebody arranged, drawn on the shop: a tinted one is a band, a plain
 *                 one the page's own ground (F-492)
 *   V33 20261006  The error pages and the page of a shop that is down, now that they load this
 *                 sheet: its banner is a notice and its own words are not a refusal's (F-481)
 *   V32 20261006  The launch page: a panel of the theme's paper over the picture the shop chose, and on
 *                 a phone under it. Until now no page loaded this sheet's rules for it (F-479)
 *   V31 20261004  Small words in the brand or the accent wear brand-text and accent-text: a theme
 *                 whose own color is too light to read as words names a deeper one (F-445);
 *                 the chosen gallery chip's count is read on its dark ground (F-450); the
 *                 hero's shade is whole under its words, and on a phone its photograph
 *                 is above them (F-456)
 *   V30 20261004  A box to tick in a field keeps a focus ring (F-444); a product's tags
 *                 rule no longer draws a second pill round a category's links (F-446);
 *                 on a phone a month is its initial, not its name cut to a width (F-447)
 *   V29 20261004  The quick look's quantity and buttons, the shop's sort box and the consent
 *                 prompt's choices, drawn: each was the browser's own (F-440)
 *   V28 20261003  The lookup page's registration form, set off from the record above it
 *                 (docs/22 Later 9)
 *   V27 20261003  Products side by side, the catalog's way, and its picker (docs/22 Later 8)
 *   V26 20261001  The account screens, drawn: the menu, the tables, the forms (F-372)
 *   V25 20261001  The shop's transfer details on the order page, kept as typed (F-340)
 *   V24 20260930  A field's control is never wider than its field (F-359)
 *   V23 20260930  Find us: the places to come in person, a card each -- address, how to find it,
 *                 hours with their seasons, and closed days (docs/22 Later 3)
 *   V22 20260930  Sold by weight: the estimate's note on the rail, an option, a tile, the
 *                 featured block, a basket line and the checkout; on a phone an option's
 *                 pieces wrap whole, never inside a figure (docs/22 Later 2)
 *   V21 20260929  Seats held for an order's payment: said plainly, not as a problem (F-250);
 *                 a door reference breaks across lines on a phone rather than running
 *                 off its card (F-285)
 *   V20 20260928  A share's monthly offer under the button, in the rail's small print (R10)
 *   V19 20260928  The events band's picture keeps to its column beside the words: its
 *                 aspect ratio sized it from the stretched row and ran it over them
 *                 (F-265); a panel's tags wrap in their cell (F-267); a long name gives
 *                 way on a phone instead of pushing the tools to a second row (F-268);
 *                 a composed page's body is the page's width, so its full-bleed bands
 *                 center on the window (F-269); a story's picture goes on the side
 *                 chosen for it (F-270) -- all five found by R9's captures
 *   V18 20260927  The approved boards (R8): the cream page and paper cards, the header,
 *                 the phone's full-screen menu, the deep-green footer, the hero over its
 *                 photograph, promises, the featured card, the shelf and its tile, the
 *                 events band with its visit card, and the journal
 *   V17 20260927  The scheduler: the booking board and a shopper's own visit (R7)
 *   V16 20260927  Merchandising: the struck price and the price per unit (R6)
 *   V15 20260927  Records and documents: the record panel, document lists, a line's
 *                 record on the receipt, and the lookup page (R5)
 *   V14 20260927  A scale's words sit on the bars' middle line (R4)
 *   V13 20260927  The product type's panel: scale bars, chips, one-per-line lists,
 *                 a pass mark, sub-headings, the year strip, the rail and the shut
 *                 placements (R4)
 *   V12 20260927  The save button on the tile and the product page, the search
 *                 results page, and the phone menu (R2: F-219, F-220)
 *   V11 20260920  The badge modifiers take the presenter's names, so the card can
 *                 draw whatever it decided rather than re-deriving two cases
 *                 of it (ruling 71, F-208)
 *   V10 20260918  Core's journal card gained a category and a rail; both sit inside the inset (ruling 65)
 *   V9 20260918  The class prefix is cs-, not cf- (ruling 64)
 *   V8 20260917  craftyfarm renamed craftysales - the theme takes the platform's name (ruling 62)
 *   V7 20260917  The per-axis picker's pills, swatches and combination note (ruling 60)
 *   V6 20260917  Section 9: the other twelve pages in the theme's own DOM (ruling 55, second half)
 *   V5 20260917  Section 8: the commerce path in the theme's own DOM (ruling 55)
 *   V4 20260917  The downloads panel on the order page, and the refused page (ruling 57)
 *   V3 20260913  Two gift-card panels join the shared fieldset rule
 *   V2 20260903  The Hollowfield design. Same classes, same wiring, new skin.
 *   V1 20260901  Initial - the default theme gets a skin (F-98)
 *
 * The default theme's stylesheet.
 *
 * **V2 is a reskin, not a rewrite of the contract.** The design arrived as a
 * Claude Design artboard -- one page, every rule an inline `style=""`. What was
 * absorbed is the *appearance*: the palette, the two radii, the serif display
 * face, the dark bands, the card and pill treatments. **No function came from
 * it.** Every class below is one the product already emits and
 * `docs/20_theme_authoring.md` already documents; the artboard's `<sc-if>` and
 * `{{ }}` placeholders are Claude Design's own and have no counterpart here.
 *
 * THE PALETTE WAS ALREADY OURS. Eight of the design's eleven colors are the
 * craftysales tokens unchanged -- ink #22261f, brand #3a6b45, accent #b4762a,
 * surface #fdfdfb, muted #f2f0e9, border #ddd9cd. Three were new and are now
 * tokens: a deeper brand hover, a lifted accent for dark grounds, and a muted
 * ink for dark grounds. So this is a reskin of a theme, not a fork of one.
 *
 * THE RULES IT IS WRITTEN UNDER, unchanged from V1:
 *
 *   1. Every color is a token. `check_stylesheet` refuses a literal.
 *   2. Every spacing value is a token. 1px is exempt -- a hairline is not
 *      spacing -- and so is a border width.
 *   3. No layout that needs JavaScript, and none that breaks without it.
 *   4. Mobile first. `bin/check_mobile_overflow.py` is the gate.
 *   5. Nothing assumes a photograph exists. `.cs-ph` is the placeholder and it
 *      has to look deliberate rather than broken.
 *
 * WHAT THE DESIGN ADDED TO THOSE. Two radii and only two: a pill for anything
 * you press, a soft rectangle for anything that holds content. A dark band
 * (`--cs-color-surface-inverse`) for the announcement, the traceability
 * section and the footer, so the page has three grounds rather than one.
 */

/* ------------------------------------------------------------------ *
 * 0 · The display face
 *
 * Self-hosted, latin and latin-ext only -- four files, 460 KB. The other eight
 * subsets in the design's bundle (cyrillic, greek, vietnamese) are about 1.1 MB
 * of coverage a US farm shop will not use, and every merchant would download
 * them. `font-display: swap` so a slow font never blanks the headline.
 * OFL 1.1; see NOTICES.md.
 * ------------------------------------------------------------------ */

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/source-serif-4-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/source-serif-4-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Source Serif 4";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/source-serif-4-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Source Serif 4";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/source-serif-4-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------ *
 * 1 · Foundations
 * ------------------------------------------------------------------ */

body {
  font-family: var(--cs-font-body);
  font-size: var(--cs-size-text-md);
  line-height: 1.6;
  color: var(--cs-color-ink);
  /* R8: the page is the boards' cream, and cards and panels are the paper
     laid on it. `surface-page` is `surface` by default, so a theme that draws
     both on one ground loses nothing. */
  background: var(--cs-color-surface-page);
  /* The two full-bleed bands below are `100vw` wide, and `100vw` counts the
     scrollbar. Without this, every page on a desktop browser with a classic
     scrollbar scrolls sideways by the scrollbar's width. */
  overflow-x: hidden;
  /* `core.css` puts a 24px gutter on `body`. That is the right default for an
     unthemed page, and it is a *second* gutter here: this theme's shell,
     sections and bands all carry their own, so below 79rem the page's contents
     sat at 48px while the bands re-imposed 24 and the two stopped lining up.
     Measured at 1024 and 375. */
  padding: 0;
}

h1, h2, h3, h4 {
  font-family: var(--cs-font-heading);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--cs-color-ink);
  text-wrap: balance;
}

/* The headline scales with the viewport rather than stepping at a breakpoint:
   it is the one element on the page big enough for the difference to show. */
h1 { font-size: clamp(2.2rem, 5.2vw, 3.6rem); line-height: 1.04; letter-spacing: -0.015em; }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.15rem); }
h3 { font-size: 1.2rem; line-height: 1.25; }
h4 { font-size: 1.05rem; }

/* An italic clause inside a headline is the design's one typographic move --
   "A working farm that *shows its work*" -- and it is why the italic subset is
   worth its 240 KB. */
h1 em, h2 em { font-style: italic; color: var(--cs-color-brand); }

p { max-width: 68ch; }

.lede {
  font-size: var(--cs-size-text-lg);
  color: var(--cs-color-ink-muted);
  line-height: 1.5;
}

.hint, .field-hint, .field-note, .fine-print, .notice {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.fine-print { max-width: 68ch; }

.notice {
  border: var(--cs-border-default);
  border-left: var(--cs-space-px-3) solid var(--cs-color-accent);
  background: var(--cs-color-surface-muted);
  padding: var(--cs-space-3) var(--cs-space-4);
  border-radius: 0 var(--cs-radius-sm) var(--cs-radius-sm) 0;
}

.visually-hidden, .honeypot, .hp-field, .enquiry-honeypot, .coming-soon__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.breadcrumb {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
  margin-bottom: var(--cs-space-4);
}

.breadcrumb a { color: var(--cs-color-ink-muted); }

/* ---- the eyebrow ----
 * A mono, letter-spaced, uppercase label with a small brand dot. The design
 * uses it above the hero and above the traceability band, and it is what makes
 * a section read as a record rather than a headline. */
.eyebrow,
.traceability-eyebrow,
.data-strip-link-label,
.ugc-verified,
.gallery-tile-handle,
.cs-footer-heading {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cs-color-accent);
  font-weight: 600;
}

/* ---- buttons ----
 * Pills. Primary is the brand green; secondary is a hairline outline on the
 * paper. On a dark ground the primary lifts to the inverse accent, because
 * green on #22261f reads as a hole. */

.button, .button-primary, .button-secondary, .checkout-place, .coming-soon__submit {
  display: inline-block;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  padding: var(--cs-space-3) var(--cs-space-6);
  border-radius: var(--cs-radius-control);
  border: 1px solid var(--cs-color-border);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}

.button-primary, .checkout-place, .coming-soon__submit {
  background: var(--cs-color-brand);
  border-color: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
}

.button-primary:hover, .checkout-place:hover, .coming-soon__submit:hover {
  background: var(--cs-color-brand-hover);
  border-color: var(--cs-color-brand-hover);
}

.button:hover, .button-secondary:hover { border-color: var(--cs-color-ink); }

.block-traceability .button-primary {
  background: var(--cs-color-accent-on-inverse);
  border-color: var(--cs-color-accent-on-inverse);
  color: var(--cs-color-surface-inverse);
}

.button:focus-visible,
.button-primary:focus-visible,
.button-secondary:focus-visible,
.checkout-place:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.button[disabled], .button-primary[disabled] { opacity: 0.55; cursor: not-allowed; }

/* ---- form fields ----
 * Pill inputs on paper with a drawn edge (R8). They sat on the muted ground
 * with no edge until the page itself became that ground -- then a field on
 * the page was invisible, as the sign-in page's password box was. The boards
 * draw every field as paper with a line round it. */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  margin-bottom: var(--cs-space-4);
  max-width: 34rem;
  /* A field inside a flex or grid form may shrink below its control's own
     width (F-359): without this the receipt form's file control held its
     field, and the field its panel, wider than a phone. */
  min-width: 0;
}

.field label { font-weight: 600; font-size: var(--cs-size-text-sm); }

.field input, .field select, .field textarea,
.enquiry-field input, .enquiry-field textarea,
.gallery-search input, .cs-browse__row select {
  font: inherit;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink);
  background: var(--cs-color-surface);
  border: var(--cs-border-strong);
  border-radius: var(--cs-radius-control);
  padding: var(--cs-space-2) var(--cs-space-4);
  min-height: var(--cs-space-px-44);
  /* Never wider than its field (F-359). */
  min-width: 0;
  max-width: 100%;
}

/* A checkbox or a radio in a field is a box to tick, not a text pill: the
   rule above made the sign-in page's "stay signed in" a 44px square. */
.field input[type="checkbox"],
.field input[type="radio"] {
  min-height: 0;
  width: var(--cs-space-px-20);
  height: var(--cs-space-px-20);
  padding: 0;
  margin: 0;
  accent-color: var(--cs-color-brand);
}

.field-check { flex-direction: row; align-items: center; gap: var(--cs-space-px-10); }

/* The account screens' forms end on a bare submit button; it is the page's
   primary action, so it is drawn as one. */
.site-main form button[type="submit"]:not([class]) {
  font: inherit;
  font-weight: 600;
  min-height: var(--cs-space-px-48);
  padding: var(--cs-space-px-12) var(--cs-space-px-28);
  border: 1px solid var(--cs-color-brand);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
  cursor: pointer;
}

.site-main form button[type="submit"]:not([class]):hover { background: var(--cs-color-brand-hover); }

.site-main form button[type="submit"]:not([class]):focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.field textarea { border-radius: var(--cs-radius-md); }

.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible,
.enquiry-field input:focus-visible, .enquiry-field textarea:focus-visible,
.gallery-search input:focus-visible, .cs-browse__row select:focus-visible {
  border-color: var(--cs-color-accent);
  background: var(--cs-color-surface);
  outline: none;
}

/* A box to tick has no edge to color, so the rule above left it with nothing:
   tabbed to, the sign-in page's "stay signed in" showed no focus at all (F-444).
   It keeps a ring, the buttons' own. */
.field input[type="checkbox"]:focus-visible,
.field input[type="radio"]:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.field-error, .booking-problem,
.cart-line-problem, .checkout-line-problem, .coming-soon__error {
  color: var(--cs-color-danger);
  font-size: var(--cs-size-text-sm);
}

.enquiry-field {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  margin-bottom: var(--cs-space-4);
}

/* ---- flashes ---- */

.flashes {
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-2);
}

.flash, .error-banner {
  padding: var(--cs-space-3) var(--cs-space-5);
  border-radius: var(--cs-radius-md);
  border: var(--cs-border-default);
  background: var(--cs-color-brand-tint);
  border-color: var(--cs-color-brand-tint-border);
  font-size: var(--cs-size-text-sm);
}

/* R8: an ordinary notice is paper on the cream, not the default scale's blue. */
.flash-info { background: var(--cs-color-surface); border-color: var(--cs-color-border); }
.flash-warning { background: var(--cs-color-accent-tint); border-color: var(--cs-color-accent-tint-border); }
/* Something that did not work -- a code refused, two-factor not switched off (F-372). */
.flash-error { background: var(--cs-color-danger-tint); border-color: var(--cs-color-danger); }

/* ---- a page that is not there, and a shop that is down ----
   No page loaded these until V0.6.134: an error page linked core's sheet alone
   (F-481). Seen for the first time, the banner was a red box round "orders
   already placed are unaffected" and the shop's own words were small and red,
   as a refused field's are. The banner is a notice, and the words are words. */
.error-page { text-align: center; }
.error-shop {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-text-lg);
}
.error-status, .error-detail, .error-actions { color: var(--cs-color-ink-muted); }
.error-countdown { font-variant-numeric: tabular-nums; }
.error-channels { justify-content: center; }

/* ---- image placeholders ----
 * The design draws every unphotographed thing as a soft diagonal weave rather
 * than a gray box, with the note in the corner. Half the products in a new shop
 * have no picture for weeks, so this is the state a merchant actually lives in
 * and it has to look deliberate. */

.cs-ph {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--cs-radius-sm);
  background:
    repeating-linear-gradient(
      45deg,
      var(--cs-color-placeholder-cool) 0 var(--cs-space-px-14),
      var(--cs-color-surface-muted) var(--cs-space-px-14) var(--cs-space-px-28)
    );
}

.cs-ph--warm {
  background:
    repeating-linear-gradient(
      45deg,
      var(--cs-color-placeholder-warm) 0 var(--cs-space-px-14),
      var(--cs-color-surface-muted) var(--cs-space-px-14) var(--cs-space-px-28)
    );
}
/* ---- the section rhythm ----
 * Every block on a page is one of these. The design runs a 79rem measure with
 * a 24px gutter and lets the sections breathe rather than boxing them, so the
 * container is the only thing holding the page together horizontally and the
 * heading rule is the only thing dividing it vertically.
 */

/* THE MEASURE IS ON `.site-main`, AND ONLY THERE. This carried its own
   `max-width: 79rem` and its own 24px gutter as well, which stacked on top of
   the ones `.site-main` already applies -- so every section heading sat 24px
   further in than the two full-bleed bands, on every page. Measured, not
   noticed: `.block-heading` at x=136 against `.data-strip-cell` at x=112. */
.block {
  margin: 0 0 var(--cs-space-7);
}

.block:last-child { margin-bottom: var(--cs-space-px-72); }

/* The section heading is the design's loudest voice: large, serif, tight, and
   sitting on a hairline that runs the width of the section. It is set with
   clamp() so the 38px it was drawn at does not overrun a phone. */
.block-heading {
  font-family: var(--cs-font-heading);
  font-size: clamp(var(--cs-size-px-24), 4vw, var(--cs-size-px-38));
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0 0 var(--cs-space-px-28);
  padding-bottom: var(--cs-space-px-14);
  border-bottom: var(--cs-border-default);
}

/* ---- the shop's own name, and the away notice (F-112) ----
 * `storefront/index.html` in this theme draws the shop's name above whatever
 * the merchant composed, and an away notice when the shop is in vacation mode.
 * **All three of these classes had no rule at all** and had not had one since
 * the theme got a stylesheet -- so on every shipped shop the name rendered at
 * the browser's default h1 and the away notice rendered as a bare paragraph
 * with nothing marking it as a notice.
 *
 * The gate could not see them: it scanned `app/templates` only, and these are
 * emitted by a theme template. Scanning both trees is the fix; these rules are
 * what the first run of the widened gate turned up.
 */

/* No measure and no gutter of its own: `.site-main` carries both. Giving this
   its own stacked a second 24px on top and put the shop's name 24px right of
   every heading under it -- the same mistake `.block` had. */
.farm-hero {
  padding-block: var(--cs-space-px-56) var(--cs-space-px-22);
}

/* The shop's name, not a headline the merchant wrote -- so it is set below the
   hero block's own heading, which is the thing that should be loudest. */
.farm-hero-title {
  font-family: var(--cs-font-heading);
  font-size: clamp(var(--cs-size-px-26), 4vw, var(--cs-size-px-38));
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

/* Vacation mode is the single most important thing a visitor can be told, and
   it was drawing as an ordinary paragraph. The accent tint rather than the
   danger tint: the shop is away, not broken. */
.farm-vacation {
  margin: var(--cs-space-4) 0 0;
  padding: var(--cs-space-3) var(--cs-space-4);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-accent-tint);
  border: 1px solid var(--cs-color-accent-tint-border);
  color: var(--cs-color-accent-deep);
  font-weight: 500;
  max-width: 68ch;
}

/* ---- hero ---- *
 * R8, the approved Home board: the words over the photograph. A rounded card
 * the width of the page, the picture filling it, a shade over its left side so
 * white words read on whatever the merchant uploaded, and the words at the
 * lower left. With no photograph the card is the deep green itself.
 *
 * The source order is words first (a screen reader meets the <h1> before a
 * decorative picture); the picture is laid underneath by position, not order.
 */

.cs-hero {
  position: relative;
  isolation: isolate;
  display: grid;
  align-items: end;
  min-height: clamp(26rem, 46vw, 41rem);
  margin: var(--cs-space-px-24) 0 var(--cs-space-px-40);
  padding: clamp(var(--cs-space-px-24), 5vw, var(--cs-space-px-72));
  border-radius: var(--cs-radius-xl);
  overflow: hidden;
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
}

.cs-hero__image {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The shade: the theme's dark color over the photograph, **whole under the
   whole of the words** and thinning only past them. The words keep to 55% of
   the card (the rule below) and the shade holds to 58% of it.
 *
 * Until V0.6.118 the shade thinned from the card's left edge -- 78% there, 42%
 * by the middle -- under words that reached the middle on a desk and the far
 * edge on a phone, so the end of every line lay on the bare photograph.
 * Weighed against the pixels really behind them, with each example shop's own
 * picture: the heading's second sentence at 2.3:1 or worse in every shop that
 * has one (F-456). The board draws this over a dark greenhouse, where any shade
 * reads.
 *
 * 80% is not a taste. Over a white photograph, the hardest there is for light
 * words, it leaves the sentence under the heading at 6.3:1 or better and the
 * heading's second line at 3.6:1 or better in every theme that ships, and
 * `tests/test_words_can_be_read.py` works that out from each palette. Mixed
 * from the token rather than written as a color, so a recoloured shop shades
 * in its own ink. */
.cs-hero--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--cs-color-surface-inverse) 86%, transparent) 0%,
      color-mix(in srgb, var(--cs-color-surface-inverse) 80%, transparent) 58%,
      color-mix(in srgb, var(--cs-color-surface-inverse) 8%, transparent) 78%
    ),
    linear-gradient(
      0deg,
      color-mix(in srgb, var(--cs-color-surface-inverse) 45%, transparent) 0%,
      transparent 45%
    );
}

.cs-hero__words { max-width: 38rem; }

/* Over a photograph the words keep to the shaded side of the card, however
   narrow the card is: a long line wraps sooner rather than running out over
   the picture. */
.cs-hero--photo .cs-hero__words { max-width: min(38rem, 55%); }

/* The board's chip: a dot and a short fact, on a glassy pill. */
.cs-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--cs-space-px-8);
  margin: 0 0 var(--cs-space-px-24);
  padding: var(--cs-space-px-6) var(--cs-space-px-14);
  border: 1px solid var(--cs-color-border-inverse);
  border-radius: var(--cs-radius-pill);
  background: color-mix(in srgb, var(--cs-color-surface-inverse) 55%, transparent);
  font-size: var(--cs-size-px-14);
  font-weight: 600;
}

.cs-hero__eyebrow::before {
  content: "";
  width: var(--cs-space-px-8);
  height: var(--cs-space-px-8);
  border-radius: var(--cs-radius-circle);
  background: var(--cs-color-brand-on-inverse);
}

/* The one place the theme shouts. The second sentence is italic, on its own
   line, in the light green -- the board's two-tone headline. */
.cs-hero__heading {
  font-family: var(--cs-font-heading);
  font-size: clamp(2.6rem, 6.2vw, 5rem);
  font-weight: 450;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--cs-color-ink-inverse);
  margin: 0 0 var(--cs-space-px-24);
  text-wrap: balance;
}

.cs-hero__heading em {
  font-style: italic;
  font-weight: 400;
  color: var(--cs-color-brand-on-inverse);
}

.cs-hero__lede {
  font-size: clamp(var(--cs-size-px-17), 1.6vw, var(--cs-size-px-20));
  line-height: 1.5;
  color: var(--cs-color-ink-inverse);
  max-width: 32rem;
  margin: 0 0 var(--cs-space-px-36);
  text-wrap: pretty;
}

.cs-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-px-12);
}

.cs-hero__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--cs-space-px-10);
  min-height: var(--cs-space-px-52);
  padding: var(--cs-space-px-12) var(--cs-space-px-28);
  border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-color-surface);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-weight: 600;
  font-size: var(--cs-size-px-16);
  text-decoration: none;
  transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}

.cs-hero__cta:hover { background: var(--cs-color-brand-tint); border-color: var(--cs-color-brand-tint); }

.cs-hero__cta--quiet {
  background: color-mix(in srgb, var(--cs-color-surface-inverse) 35%, transparent);
  border-color: var(--cs-color-ink-inverse-muted);
  color: var(--cs-color-ink-inverse);
}

.cs-hero__cta--quiet:hover {
  background: var(--cs-color-border-inverse);
  border-color: var(--cs-color-ink-inverse);
}

.cs-hero__cta:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent-on-inverse);
  outline-offset: var(--cs-space-px-2);
}

@media (max-width: 47.99rem) {
  .cs-hero {
    min-height: 34rem;
    margin-top: var(--cs-space-px-12);
    border-radius: var(--cs-radius-lg);
  }
  .cs-hero__actions { flex-direction: column; align-items: stretch; }
  .cs-hero__cta { justify-content: center; }

  /* On a phone the words are as wide as the card: there is no side of the
     photograph to keep clear for them, and a shade strong enough to read on
     hides the picture altogether. So the photograph goes above, whole and
     unshaded, and the words below it on the card's own dark ground (F-456).
     The page's order is unchanged -- the words first, for a screen reader. */
  .cs-hero--photo {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0;
  }
  .cs-hero--photo::after { content: none; }
  .cs-hero--photo .cs-hero__image {
    position: static;
    order: -1;
    height: auto;
    aspect-ratio: 4 / 3;
  }
  .cs-hero--photo .cs-hero__words {
    max-width: none;
    padding: var(--cs-space-px-24);
  }
}

/* ---- product grid ---- *
 * `auto-fill` rather than `auto-fit`: a shop with two products in a category
 * should show two cards at card width, not two cards stretched across the
 * whole viewport. A new shop is mostly small categories.
 */

.product-grid,
.event-cards,
.post-list,
.channel-grid,
.document-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--cs-space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The photograph runs to the card's own edge rather than sitting inside a
   padded box -- `overflow: hidden` on the card and no padding on the card
   itself, with the words in their own padded body. It is the single change
   that makes a grid of farm produce look photographed rather than cataloged. */
.product-card,
.event-card,
.post-card,
.channel-card {
  display: flex;
  flex-direction: column;
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  overflow: hidden;
  transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
}

/* The card rises rather than glowing. 4px is enough to read as a lift on a
   trackpad and small enough that a grid of twelve does not ripple. */
.product-card:hover,
.event-card:hover,
.post-card:hover {
  transform: translateY(-4px);
  border-color: var(--cs-color-border-strong);
  box-shadow: var(--cs-shadow-lg);
}

@media (prefers-reduced-motion: reduce) {
  .product-card,
  .event-card,
  .post-card,
  .channel-card { transition: none; }
  .product-card:hover,
  .event-card:hover,
  .post-card:hover { transform: none; }
}

/* 4:3 and cropped: a merchant photographing on a phone gets portrait, landscape
   and square in the same grid, and a row of cards that do not line up reads as
   a broken page rather than as variety. */
.product-card img,
.event-card-image img,
.post-card img,
.product-card .cs-ph,
.post-card .cs-ph {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 0;
}

/* Everything below the photograph. The theme's own `blocks/product_grid.html`
   wraps the price and the sold-out pill in `.product-card-body`; the title
   still lives inside the card's link, so it is padded on its own. The card
   kinds core draws without a body wrapper -- events, posts, channels -- are
   padded per child, which is what the product card did before the override. */
.product-card-body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--cs-space-2);
  padding: 0 var(--cs-space-px-18) var(--cs-space-px-18);
}

.product-card-title,
.event-card-summary,
.event-card-when,
.event-card-price,
.event-card-soldout,
.post-card-title,
.post-card-meta,
.post-card-category,
.post-card > .post-products,
.channel-name,
.channel-note {
  margin-inline: var(--cs-space-px-18);
}

/* Core's card leads with its category since V0.6.14; the padded-children rule
 * above is what keeps it inside the card's inset. */
.post-card-category { margin-top: var(--cs-space-px-16); }

.product-card-title,
.event-card-summary,
.post-card-title,
.channel-name {
  display: block;
  margin-top: var(--cs-space-px-16);
  margin-bottom: var(--cs-space-1);
}

.event-card > :last-child,
.post-card > :last-child,
.channel-card > :last-child { margin-bottom: var(--cs-space-px-18); }

/* Inside the body wrapper the two children are already padded by it. */
.product-card-body > .product-card-price,
.product-card-body > .product-card-badge {
  margin-inline: 0;
  margin-top: 0;
}

.product-card-title,
.event-card-summary,
.post-card-title,
.channel-name {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-19);
  font-weight: 600;
  line-height: 1.25;
}

/* THE ANCHOR WRAPS THE TITLE, NOT THE OTHER WAY ROUND. Core's card markup is
 * `<a><img><span class="product-card-title"></span></a>`, so `.product-card-title a`
 * -- which is what V0.5.144 and this file's first draft both wrote -- matches
 * nothing at all, and every card title on the shipped theme rendered as an
 * underlined brand-green link. Found by looking at a rendered page; the markup
 * gate cannot see this, because the class *is* styled, just not by a selector
 * that reaches it.
 *
 * The whole card is the click target and the lift is its hover state, so the
 * title inside it is ink and undecorated. */
.product-card > a,
.post-card > a,
.event-card > a {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
}

.product-card-title,
.post-card-title { color: var(--cs-color-ink); }

.product-card > a:hover .product-card-title,
.post-card > a:hover .post-card-title { color: var(--cs-color-brand-text); }

/* Keyboard focus still has to be visible: the card does not lift on focus, so
   without this a keyboard user has no idea which card they are on. */
.product-card > a:focus-visible,
.post-card > a:focus-visible,
.event-card > a:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: calc(var(--cs-space-px-2) * -1);
  border-radius: var(--cs-radius-md);
}

/* The price is set in the display face, not the body face. It is the number
   the buyer came for and the design gives it the same weight as the name. */
.product-card-price,
.event-card-price,
.gallery-tile-price {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-20);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-top: var(--cs-space-2);
}

.event-card-when,
.post-card-meta,
.channel-note,
.gallery-tile-note {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
  line-height: 1.45;
  margin-top: var(--cs-space-1);
}

/* **One pill for whatever the card has to say.** Sold out, out of season and a
   full CSA season are the states a farm shop is in most of the year, and they
   are quiet rather than alarming: the product is still worth looking at. The
   card used to carry two classes for two of those states and the template chose
   between them, which is how a full season came out reading "Sold out"
   (F-208). The presenter decides the words now and this draws them, whatever
   they are. */
.product-card-badge,
.event-card-soldout,
.product-sold-out,
.product-out-of-season {
  align-self: flex-start;
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-px-11);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: var(--cs-space-px-5) var(--cs-space-px-10);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-muted);
  color: var(--cs-color-ink-muted);
  margin-top: var(--cs-space-2);
}

.product-out-of-season {
  background: var(--cs-color-accent-tint);
  color: var(--cs-color-accent-deep);
}

/* ---- farm story, newsletter ---- */

.block-farm-story {
  display: grid;
  gap: var(--cs-space-5);
}

.farm-story-words { max-width: 40rem; }

.farm-story-image {
  width: 100%;
  height: auto;
  border-radius: var(--cs-radius-lg);
}

@media (min-width: 48rem) {
  .block-farm-story { grid-template-columns: 1fr 1fr; align-items: center; }
  .block-farm-story.block-image-left .farm-story-image { order: -1; }
  /* The picture is first in the markup, so "left" needed nothing and "right"
   * needed this -- without it every story's picture sat on the left, whichever
   * side the merchant chose (F-270). */
  .block-farm-story.block-image-right .farm-story-image { order: 1; }
}

.block-newsletter,
.block-enquiry {
  background: var(--cs-color-surface-muted);
  border-radius: var(--cs-radius-lg);
  padding: var(--cs-space-6) var(--cs-space-5);
}

.newsletter-blurb,
.enquiry-blurb,
.ugc-blurb,
.rates-blurb,
.traceability-body {
  color: var(--cs-color-ink-muted);
  max-width: 52ch;
}

.newsletter-contact { margin-top: var(--cs-space-3); }

/* ---- data strip ---- *
 * The row of live figures under a hero: soil temperature, current lot, median
 * time to the door. Tabular numerals because the whole point is that they are
 * measurements, and measurements that jiggle as they update read as decoration.
 */

/* Full-bleed and dark. The figures are the first thing under the hero and the
   design treats them as instrumentation rather than as marketing: a band of
   ink with the numbers set in the mono face, each cell fenced off by a hairline
   on its left the way a column on a printed record sheet is. */
.block-data-strip {
  max-width: none;
  padding-inline: 0;
  padding-block: var(--cs-space-px-22);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  border-block: none;
}

.data-strip-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--cs-space-px-24);
  list-style: none;
  margin-inline: auto;
  max-width: 79rem;
  padding-inline: var(--cs-space-px-24);
}

.data-strip-cell {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-3);
  font-family: var(--cs-font-mono);
  font-variant-numeric: tabular-nums;
  border-left: 1px solid var(--cs-color-ink-inverse-muted);
  padding-left: var(--cs-space-px-18);
}

/* The label is the accent lifted for the dark ground; the value is the loud
   part; the note is the quiet part. All three in the mono face, because the
   whole band is a reading off an instrument. */
.data-strip-cell dt {
  font-size: var(--cs-size-px-10-5);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cs-color-accent-on-inverse);
}

.data-strip-cell dd {
  font-size: var(--cs-size-px-18);
  font-weight: 600;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-3);
}

.data-strip-cell dd a { color: var(--cs-color-ink-inverse); }

.traceability-eyebrow,
.ugc-verified,
.gallery-tile-handle {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
}

.data-strip-link-label {
  font-size: var(--cs-size-px-11);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--cs-color-ink-inverse-muted);
}

.data-strip-note {
  font-size: var(--cs-size-px-11);
  font-weight: 400;
  color: var(--cs-color-ink-inverse-muted);
}

/* ---- traceability, buyer photographs, rates, documents ---- */

/* The second dark band, and the loudest argument the page makes. Full-bleed
   ink, the words at 1.1fr and the record panel at 0.9fr, and a heading second
   in size only to the hero's. The design's "not marketing -- records" reading
   is carried by the ground, not by an adjective. */
.block-traceability {
  max-width: none;
  padding-inline: 0;
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  border-radius: 0;
  display: grid;
  gap: var(--cs-space-px-18) var(--cs-space-px-56);
  padding-block: var(--cs-space-px-80);
  margin-block: var(--cs-space-px-80);
}

/* The theme's own `blocks/traceability_band.html` wraps the words, so this is
   two real columns rather than the explicit child placement V0.5.144 needed to
   do the same job against core's flat child list.
 *
 * THE GUTTER IS PADDING, NOT A TRACK, AND IT IS MEASURED IN `vw`.
 *
 * Two measurements, both taken in a browser rather than reasoned about:
 *
 *   1. The first attempt made the gutter two extra `minmax(24px, 1fr)` tracks
 *      either side. Those divide as an equal `fr` share, so on a 1440px window
 *      each "24px gutter" came out **318px** wide and the band's contents sat
 *      in the middle half of the band.
 *   2. The second used `calc(50% - 39.5rem)`. A percentage in `padding` resolves
 *      against the **containing block's** width, not the element's own -- and
 *      this element is `100vw` while its container is the 79rem main column. So
 *      the calc went negative, `max()` took the 24px floor, and the words sat
 *      hard against the window edge, 88px left of every other section on the
 *      page. Caught by measuring `.traceability-words` against `.data-strip-cell`
 *      and finding them at x=24 and x=112.
 *
 * `50vw` is the element's own half-width because the element is `100vw`. The
 * `+ 24px` is the same gutter `.block` carries inside its 79rem measure, so the
 * band's first word lines up with the section headings above and below it. */
.block-traceability {
  padding-inline: max(
    var(--cs-space-px-24),
    calc(50vw - 39.5rem + var(--cs-space-px-24))
  );
}

.traceability-words { max-width: 52ch; }

@media (min-width: 48rem) {
  .block-traceability {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: center;
    column-gap: var(--cs-space-px-56);
  }
  /* No panel, no second column. A merchant who leaves the record out should
     get a full-width band, not a half-width one beside a hole. */
  .block-traceability:not(:has(.traceability-figure)) {
    grid-template-columns: minmax(0, 1fr);
  }
}

.block-traceability h2 {
  font-size: clamp(var(--cs-size-px-26), 3.6vw, var(--cs-size-px-38));
  line-height: 1.1;
  text-wrap: balance;
  color: var(--cs-color-ink-inverse);
  margin: 0 0 var(--cs-space-px-18);
}

.block-traceability p { color: var(--cs-color-ink-inverse-muted); }

.block-traceability .traceability-eyebrow { color: var(--cs-color-accent-on-inverse); }

/* On a dark ground the green brand button disappears. The design swaps it for
   the lifted accent with ink text -- the one button on the page that reads as
   a lamp rather than as a leaf. */
.block-traceability .button-primary {
  background: var(--cs-color-accent-on-inverse);
  color: var(--cs-color-surface-inverse);
  box-shadow: none;
}

.block-traceability .button-primary:hover {
  background: var(--cs-color-accent);
  color: var(--cs-color-brand-contrast);
}

/* The record panel. A pane of slightly-lifted ink with a hairline, set in the
   mono face at a generous line height: the design draws it as a terminal
   because a terminal is what a record looks like when nobody has dressed it.
   A merchant who uploads a photograph instead gets the photograph, framed the
   same way -- the panel is a container, not a picture frame with opinions. */
.traceability-figure {
  margin: 0;
  border: 1px solid var(--cs-color-ink-inverse-muted);
  border-radius: var(--cs-radius-lg);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-sm);
  line-height: 2;
  overflow: hidden;
}

.traceability-figure img {
  display: block;
  width: 100%;
  height: auto;
}

.traceability-cta { margin-top: var(--cs-space-4); }

.traceability-hint {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-inverse-muted);
}

/* Buyer photographs are the one part of a farm shop the merchant does not
   art-direct, and the design leans into that: a tight mosaic on a fixed row
   height rather than a tidy grid of equal cards. Every tile is cropped to the
   cell, so a mix of phone portraits and flat-lays still reads as a wall. */
.ugc-list,
.gallery-chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--cs-space-px-14);
  list-style: none;
  margin: 0;
  padding: 0;
}

.ugc-item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  border-radius: var(--cs-radius-sm);
  overflow: hidden;
  transition: box-shadow 160ms ease;
}

.ugc-item:hover { box-shadow: var(--cs-shadow-md); }

@media (prefers-reduced-motion: reduce) {
  .ugc-item { transition: none; }
}

.ugc-item img,
.ugc-item .cs-ph {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 0;
}

/* The caption sits under the tile rather than over it: text laid on a stranger's
   photograph is unreadable about a third of the time and there is no way to
   know which third in advance. */
.ugc-by, .ugc-title {
  font-size: var(--cs-size-text-sm);
  padding-inline: var(--cs-space-2);
}

.ugc-title { font-family: var(--cs-font-heading); }
.ugc-by { color: var(--cs-color-ink-muted); padding-bottom: var(--cs-space-2); }
.ugc-blurb { max-width: 56ch; }

.ugc-more {
  margin-top: var(--cs-space-px-26);
  display: inline-block;
  font-weight: 600;
}

.rates-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.rates-table th,
.rates-table td {
  text-align: left;
  padding: var(--cs-space-2) var(--cs-space-3);
  border-bottom: var(--cs-border-hairline);
}

.rates-table th { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); font-weight: 600; }
.rates-footnote { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.document {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  padding: var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
}

.document-category { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ------------------------------------------------------------------ *
 * 3 · The product page
 * ------------------------------------------------------------------ */

.product {
  display: grid;
  gap: var(--cs-space-6);
  max-width: 72rem;
  margin: 0 auto var(--cs-space-7);
  padding-inline: var(--cs-space-4);
}

@media (min-width: 52rem) {
  .product { grid-template-columns: 1.1fr 1fr; align-items: start; }
}

.product-images {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-3);
}

.product-images img { width: 100%; height: auto; border-radius: var(--cs-radius-md); }
.product-video { width: 100%; border-radius: var(--cs-radius-md); }

.product-subtitle {
  font-size: var(--cs-size-text-lg);
  color: var(--cs-color-ink-muted);
  margin: 0 0 var(--cs-space-4);
}

.product-price {
  font-size: var(--cs-size-text-lg);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin: 0 0 var(--cs-space-4);
}

.product-sale-ends,
.stock-note,
.delivery-estimate,
.booking-note,
.calendar-note {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.product-description,
.product-materials,
.post-body,
.page,
.legal-section { max-width: 68ch; }

.product-description :is(h2, h3) { margin-top: var(--cs-space-5); }

/* The buy form is the one control on the page that must never be ambiguous:
   quantity, variant, personalization and the button read as a single unit. */
.buy-form {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-3);
  padding: var(--cs-space-5);
  background: var(--cs-color-surface-muted);
  border-radius: var(--cs-radius-lg);
  margin-block: var(--cs-space-5);
}

.buy-form .field { margin-bottom: 0; }

/* ------------------------------------------------------------------ *
 * 4 · Basket, checkout and the order
 * ------------------------------------------------------------------ */

.cart-lines,
.checkout-lines,
.order-lines,
.bookings,
.order-bookings {
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-4);
}

.cart-lines > li,
.checkout-lines > li,
.order-lines > li,
.bookings > li {
  display: grid;
  gap: var(--cs-space-3);
  padding-bottom: var(--cs-space-4);
  border-bottom: var(--cs-border-hairline);
}

@media (min-width: 40rem) {
  .cart-lines > li { grid-template-columns: var(--cs-space-px-80) 1fr auto; align-items: start; }
}

.cart-line-image img { width: 100%; height: auto; border-radius: var(--cs-radius-sm); }

.cart-line-variant,
.cart-line-personalization,
.cart-line-seats,
.checkout-line-personalization,
.order-line-personalization,
.order-line-sku {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.cart-line-total,
.cart-subtotal,
.checkout-line-total,
.checkout-grand-total,
.order-line-total,
.order-grand-total,
.expedite-price,
.delivery-price,
.ticket-price,
.ticket-deposit {
  font-variant-numeric: tabular-nums;
}

.cart-subtotal,
.checkout-grand-total,
.order-grand-total {
  font-size: var(--cs-size-text-lg);
  font-weight: 600;
}

.cart-subtotal-note { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* The way out of the core basket (F-195). Core's own page, dressed here for
   a shop whose theme overrides nothing. */
.cart-checkout { margin: var(--cs-space-4) 0; }

.cart-line-form {
  display: flex;
  gap: var(--cs-space-2);
  align-items: center;
}

.cart-line-form input[type="number"] { width: var(--cs-space-px-72); }

.checkout-form {
  display: grid;
  gap: var(--cs-space-6);
  max-width: 72rem;
  margin: 0 auto;
  padding-inline: var(--cs-space-4);
}

@media (min-width: 56rem) {
  .checkout-form { grid-template-columns: 1.3fr 1fr; align-items: start; }
  .checkout-summary { position: sticky; top: var(--cs-space-4); }
}

.checkout-contact,
.checkout-address,
.checkout-delivery,
.checkout-payment,
.checkout-discount,
.checkout-gift-card,
.checkout-expedite,
.checkout-summary,
.order-gift-cards,
.order-downloads,
.download-refused,
.order-address,
.order-delivery,
.order-pickup,
.order-status,
.privacy-cookies,
.privacy-purposes,
.privacy-history {
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  padding: var(--cs-space-5);
  background: var(--cs-color-surface);
  margin-bottom: var(--cs-space-5);
}

.checkout-summary { background: var(--cs-color-surface-muted); }

.checkout-totals,
.order-totals {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-2);
  padding-top: var(--cs-space-3);
  border-top: var(--cs-border-default);
  font-variant-numeric: tabular-nums;
}

.delivery-option,
.payment-option {
  display: flex;
  gap: var(--cs-space-3);
  align-items: flex-start;
  padding: var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  margin-bottom: var(--cs-space-2);
  cursor: pointer;
}

.delivery-option:hover,
.payment-option:hover { border-color: var(--cs-color-border-strong); }

.delivery-window,
.delivery-note,
.delivery-pickup,
.expedite-promise,
.order-note,
.order-claim,
.order-claimed,
.order-keep-link {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.checkout-place { width: 100%; margin-top: var(--cs-space-4); }

.order-document {
  display: inline-block;
  margin-top: var(--cs-space-3);
}

.order-line-title,
.checkout-line-title { font-weight: 600; }

.order-line-quantity,
.checkout-line-quantity { font-variant-numeric: tabular-nums; color: var(--cs-color-ink-muted); }

/* ------------------------------------------------------------------ *
 * 5 · Events and bookings
 * ------------------------------------------------------------------ */

.event,
.post,
.legal,
.page {
  max-width: 72rem;
  margin: 0 auto var(--cs-space-7);
  padding-inline: var(--cs-space-4);
}

.event-hero img { width: 100%; height: auto; border-radius: var(--cs-radius-lg); }

.event-body { max-width: 68ch; }

.event-where,
.event-age,
.event-policy,
.event-instructions,
.occurrence-when,
.occurrence-seats,
.ticket-seats,
.booking-seats {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.event-dates,
.occurrences,
.ticket-types,
.event-tickets {
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-3);
}

.ticket-type,
.occurrences > li {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-3);
  align-items: baseline;
  justify-content: space-between;
  padding: var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
}

.occurrence-closed { opacity: 0.6; }
.ticket-name { font-weight: 600; }

.booking-form {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-3);
  padding: var(--cs-space-5);
  background: var(--cs-color-surface-muted);
  border-radius: var(--cs-radius-lg);
}

.booking-title { margin-top: 0; }

.booking-reference {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-lg);
  letter-spacing: 0.04em;
  word-break: break-all;
}

.booking-reference-label {
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
}

.booking-held { font-weight: 600; }

.add-to-calendar,
.calendar-subscribe { display: inline-block; margin-top: var(--cs-space-3); }

.calendar-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
}

/* ------------------------------------------------------------------ *
 * 6 · Articles, pages and the legal shelf
 * ------------------------------------------------------------------ */

.post-body :is(h2, h3) { margin-top: var(--cs-space-6); }
.post-body img { max-width: 100%; height: auto; border-radius: var(--cs-radius-md); }

.post-meta,
.post-card-excerpt,
.legal-updated,
.privacy-version,
.privacy-generated {
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.legal-toc {
  list-style: none;
  margin: 0 0 var(--cs-space-6);
  padding: var(--cs-space-4);
  background: var(--cs-color-surface-muted);
  border-radius: var(--cs-radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-2);
}

.legal-section { margin-bottom: var(--cs-space-6); }

/* The generated half of the privacy page -- what the software stores, as
   opposed to what the merchant wrote. Visibly separate on purpose: a reader
   should be able to tell the farm's promise from the machine's inventory. */
.privacy-generated {
  border-top: var(--cs-border-default);
  margin-top: var(--cs-space-6);
  padding-top: var(--cs-space-5);
}

.page-privacy table,
.page-do-not-sell table { width: 100%; border-collapse: collapse; }

.page-privacy th,
.page-privacy td,
.page-do-not-sell th,
.page-do-not-sell td {
  text-align: left;
  padding: var(--cs-space-2) var(--cs-space-3);
  border-bottom: var(--cs-border-hairline);
  font-size: var(--cs-size-text-sm);
}

/* ------------------------------------------------------------------ *
 * 7 · The buyer-photograph gallery and quick view
 * ------------------------------------------------------------------ */

.gallery-search,
.gallery-sort {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  align-items: center;
  margin-bottom: var(--cs-space-5);
}

.gallery-count { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.gallery-chips a {
  display: inline-block;
  padding: var(--cs-space-1) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  font-size: var(--cs-size-text-sm);
  text-decoration: none;
}

.gallery-tile-title { font-weight: 600; }
.gallery-tile-product,
.gallery-tile-rating { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* "Verified buyer" is a factual claim about a purchase record, so it is drawn
   as a fact and not as a badge to be proud of. */
.gallery-tile-tick,
.gallery-tile-flag {
  font-size: var(--cs-size-text-xs);
  color: var(--cs-color-success);
}

.gallery-tile-flag { color: var(--cs-color-ink-muted); }

.gallery-pager {
  display: flex;
  gap: var(--cs-space-3);
  justify-content: center;
  margin-top: var(--cs-space-6);
}

.cs-quick {
  display: grid;
  gap: var(--cs-space-4);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  padding: var(--cs-space-5);
  box-shadow: var(--cs-shadow-overlay);
}

@media (min-width: 40rem) {
  .cs-quick { grid-template-columns: 1fr 1fr; align-items: start; }
}

.cs-quick__media img { width: 100%; height: auto; border-radius: var(--cs-radius-md); }
.cs-quick__title { font-family: var(--cs-font-heading); margin: 0 0 var(--cs-space-2); }
.cs-quick__price { font-weight: 600; font-variant-numeric: tabular-nums; }
.cs-quick__sub,
.cs-quick__note,
.cs-quick__rating,
.cs-quick__blurb { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-quick__body { display: flex; flex-direction: column; gap: var(--cs-space-3); }
.cs-quick__options,
.cs-quick__links { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }
/* How many and the button on one line, as the product page draws them. Both
   were written with no name and were the browser's own (F-440). */
.cs-quick__buy {
  display: flex;
  align-items: stretch;
  gap: var(--cs-space-px-12);
  margin-top: var(--cs-space-2);
}
.cs-quick__buy .button-primary { flex: 1 1 auto; padding-inline: var(--cs-space-3); }
.cs-quick__links { align-items: center; }
.cs-quick__links form { margin: 0; }
.cs-quick__go { text-decoration: underline; }

/* ---- the upload dropzone (buyer photographs) ---- */

.dropzone {
  border: var(--cs-space-px-2) dashed var(--cs-color-border-strong);
  border-radius: var(--cs-radius-lg);
  padding: var(--cs-space-6);
  text-align: center;
  background: var(--cs-color-surface-muted);
}

.dropzone__prompt { font-weight: 600; }
.dropzone__hint,
.dropzone__drop,
.dropzone__file { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.dropzone__browse { text-decoration: underline; cursor: pointer; }

/* ------------------------------------------------------------------ *
 * 8 · Consent, coming-soon and the channel list
 *
 * The consent banner is the one element on the site that must not be prettier
 * on one choice than the other. Accepting and declining are the same size, the
 * same weight and the same distance from the thumb -- a design that makes
 * "Accept" the easy one is a dark pattern whatever the copy says.
 * ------------------------------------------------------------------ */

.consent-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 40;
  background: var(--cs-color-surface);
  border-top: var(--cs-border-strong);
  box-shadow: var(--cs-shadow-lg);
  padding: var(--cs-space-4);
}

.consent-intro { max-width: 60ch; font-size: var(--cs-size-text-sm); }

.consent-actions,
.consent-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-3);
  margin-top: var(--cs-space-3);
}

/* Equal shares of the row whatever each says: sized from its words, the longer
   label made the wider button (measured 612 and 624, F-440). Too narrow for
   two, they stack whole. */
.consent-actions .button,
.consent-actions .button-primary,
.consent-actions .button-secondary { flex: 1 1 0; min-width: 12rem; }

/* Boxes to tick, not a bulleted list of them (F-440). */
.consent-choices { list-style: none; padding: 0; }

.consent-links { font-size: var(--cs-size-text-sm); margin-top: var(--cs-space-2); }

/* ---- the launch page (F-479) ----
 * What a shop that has not opened shows the public: one panel of the theme's
 * paper in the middle of the window, and the picture the shop chose filling
 * the window behind it. No words are laid on the photograph, so how well they
 * read does not depend on what was uploaded. On a phone the picture is a band
 * above the panel.
 *
 * Until V0.6.130 no page loaded these: the launch page linked core's sheet and
 * nothing else, and its box and button were the browser's own.
 */

.coming-soon__main { max-width: none; margin: 0; padding: 0; }

.coming-soon__stage {
  position: relative;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--cs-space-6) var(--cs-space-4);
}

.coming-soon__picture { position: absolute; inset: 0; overflow: hidden; }

.coming-soon__picture img {
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: cover;
}

.coming-soon__panel {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  max-width: 34rem;
  padding: var(--cs-space-7) var(--cs-space-6);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  box-shadow: var(--cs-shadow-lg);
  text-align: center;
}

.coming-soon__shop {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cs-space-2);
  margin: 0 0 var(--cs-space-5);
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-text-lg);
  font-weight: 600;
}

.coming-soon__logo { max-height: var(--cs-space-px-56); }
.coming-soon__mark { height: var(--cs-space-px-28); max-height: none; }

.coming-soon__eyebrow { color: var(--cs-color-brand-text); font-weight: 600; }

.coming-soon__title {
  margin: var(--cs-space-2) 0 var(--cs-space-5);
  font-family: var(--cs-font-heading);
  font-size: clamp(var(--cs-size-px-28), 5vw, var(--cs-size-px-38));
  line-height: 1.15;
}

.coming-soon__countdown {
  justify-content: center;
  gap: var(--cs-space-5);
  margin-block-end: var(--cs-space-6);
}

.coming-soon__unit > [data-countdown-part] {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-38);
  line-height: 1.1;
}

.coming-soon__label { color: var(--cs-color-ink-muted); letter-spacing: 0.08em; }

/* The box takes the row and the button keeps its words; too narrow for both,
   they stack whole. */
.coming-soon__form { align-items: flex-end; gap: var(--cs-space-3); text-align: start; }
.coming-soon__field { flex: 1 1 14rem; max-width: none; margin: 0; }
.coming-soon__field input { width: 100%; }

.coming-soon__note,
.coming-soon__done {
  margin: var(--cs-space-4) 0 0;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

@media (max-width: 47.99rem) {
  .coming-soon__stage { display: block; min-height: 0; padding: 0; }
  .coming-soon__picture { position: static; aspect-ratio: 16 / 10; }

  /* The page itself, not a card laid on it: nothing under the panel to be a
     second color at the foot of a phone. */
  .coming-soon__panel {
    max-width: none;
    padding: var(--cs-space-6) var(--cs-space-4);
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: var(--cs-shadow-none);
  }

  .coming-soon__submit { width: 100%; }
}

.channel-detail { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.category-children {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
}

.category-children a {
  display: inline-block;
  padding: var(--cs-space-1) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  font-size: var(--cs-size-text-sm);
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------------------------ *
 * 9 · The shell: width, header, navigation, footer
 *
 * THE WIDTH IS THE IMPORTANT PART OF THIS SECTION. `app/static/css/core.css`
 * sets `--measure: 38rem` and applies it to `.site-header`, `.site-main` and
 * `.site-footer`. 38rem is a *reading* measure and it is the right default for
 * a stylesheet whose job is to make an unthemed page legible -- but it means
 * the whole shop renders in a 608px column on any screen, which is why a
 * four-across product grid came out two-across and why the page looked like a
 * document rather than a storefront.
 *
 * Widening it is a theme's decision, not core's: core cannot know whether the
 * next theme is a shop or a newsletter. So the shell widens here and prose
 * keeps its own measure -- `p`, `.product-description`, `.post-body` and the
 * legal sections are all capped at 68ch above, independently of the container.
 * ------------------------------------------------------------------ */

/* THE HOLLOWFIELD CHANGE TO THIS: the header and the footer lose their
 * container, `.site-main` keeps its.
 *
 * The design runs three full-bleed grounds through the page -- the announcement
 * bar, the footer, and two dark bands inside the content -- and a ground cannot
 * bleed out of a centered container. The header and the footer are safe to
 * unconstrain because their contents are the theme's own markup and each inner
 * row re-imposes the measure itself.
 *
 * `.site-main` is NOT unconstrained, and that is the important half. Only the
 * block-built pages put everything inside a `.block`; the product page, the
 * basket, checkout, the order pages and every account screen render straight
 * into `.site-main` with no wrapper of their own, so taking the measure off it
 * would have set the whole shop edge to edge and left one line in a diff to
 * explain it. The two bands that need the full width break out of it instead,
 * below.
 */
.site-main {
  max-width: 79rem;
  width: 100%;
  padding-inline: var(--cs-space-px-24);
}

.site-header,
.site-footer {
  max-width: none;
  width: 100%;
  padding-inline: 0;
}

/* The two bands that bleed. `calc(50% - 50vw)` is the width the centered parent
   is inset by, so a negative margin of exactly that much puts the band's edges
   on the window's edges without knowing the container's width.
 *
 * `100vw` counts the scrollbar and `100%` does not, which is the whole reason
 * `body` carries `overflow-x: hidden` -- without it every page on a desktop
 * browser with a classic scrollbar scrolls sideways by about 15px. The mobile
 * overflow gate is what would have caught that; it is cheaper to say so here. */
.block-data-strip,
.block-traceability {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/* The header keeps no rule under it and no padding of its own: the
   announcement bar bleeds to the window edges and `.cs-header` inside it
   carries the measure and the padding. The division under the header is the
   hero's own ground change, not a line. */
.site-header {
  border-bottom: none;
  padding-block: 0;
  margin-bottom: 0;
}

/* The footer is a different ground, not a ruled-off part of the same sheet:
   R8 closes the page on the deep green the boards open it with. */
.site-footer {
  border-top: none;
  background: var(--cs-color-surface-inverse);
  margin-top: var(--cs-space-px-72);
  padding-block: var(--cs-space-px-64) var(--cs-space-px-28);
  color: var(--cs-color-ink-inverse-muted);
}

.site-footer > * {
  max-width: 79rem;
  margin-inline: auto;
  padding-inline: var(--cs-space-px-24);
}

/* ---- announcement ---- */

/* The inverse ground, which R8's palette makes the boards' deep green: the
   bar every board opens with. */
.cs-announce {
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  text-align: center;
  padding: var(--cs-space-px-10) var(--cs-space-px-44);
  font-size: var(--cs-size-px-13-5);
  font-weight: 500;
  letter-spacing: 0.01em;
  position: relative;
}

.cs-announce a { color: var(--cs-color-accent-on-inverse); }
.cs-announce__close {
  position: absolute;
  right: var(--cs-space-3);
  top: var(--cs-space-px-7);
  color: var(--cs-color-ink-inverse);
  text-decoration: none;
}

/* ---- header ---- */

/* R8, the approved boards: the header sits on the page's own cream with a
   hairline under it, and the row is the Home board's -- the shop's mark and
   name, the menu, then the search box, two round marked buttons and the
   basket pill at the far end. */
.site-header { border-bottom: var(--cs-border-hairline); }

.cs-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-px-24);
  max-width: 79rem;
  margin-inline: auto;
  padding: var(--cs-space-px-20) var(--cs-space-px-24);
  border-bottom: none;
  margin-bottom: 0;
}

.cs-brand {
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--cs-space-px-12);
  margin-right: var(--cs-space-px-16);
  color: var(--cs-color-ink);
}

.cs-brand__mark {
  display: block;
  height: var(--cs-space-px-32);
  width: auto;
}

.cs-brand__name {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-28);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1;
  color: var(--cs-color-ink);
}

.cs-brand__logo { max-height: var(--cs-space-px-44); width: auto; display: block; }

/* ---- navigation ----
 * The dropdown opens on hover AND on keyboard focus, in CSS, with no script.
 * `:focus-within` is what makes it keyboard-reachable; without it the children
 * are tab-focusable but invisible, which is worse than not having them.
 */

.cs-nav__list,
.cs-nav__panel,
.cs-footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The `<nav>` takes the row's slack, so the search box and the buttons sit
   together at the far end as the board draws them. */
.cs-nav { flex: 1 1 auto; min-width: 0; }

.cs-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-px-30);
}

.cs-nav__item { position: relative; }

/* The board marks the page you are on by weight, not by a rule under it, and
   colors a link on hover: two states that cannot be confused. */
.cs-nav__link {
  text-decoration: none;
  color: var(--cs-color-ink);
  font-weight: 500;
  font-size: var(--cs-size-px-15-5);
  padding-block: var(--cs-space-2);
  display: inline-block;
  transition: color 120ms ease;
}

.cs-nav__link:hover { color: var(--cs-color-brand-text); }

.cs-nav__link--current { font-weight: 700; }

.cs-nav__panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 30;
  min-width: var(--cs-space-px-80);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  box-shadow: var(--cs-shadow-md);
  padding: var(--cs-space-2);
}

.cs-nav__item--has-children:hover > .cs-nav__panel,
.cs-nav__item--has-children:focus-within > .cs-nav__panel { display: block; }

.cs-nav__child {
  display: block;
  padding: var(--cs-space-2) var(--cs-space-3);
  text-decoration: none;
  color: var(--cs-color-ink);
  border-radius: var(--cs-radius-sm);
  white-space: nowrap;
}

.cs-nav__child:hover { background: var(--cs-color-surface-muted); }

/* ---- the header's search box, account, saved and basket ---- */

.cs-header .cs-search { flex: 0 1 15rem; min-width: 9rem; }

.cs-header .cs-search__input {
  width: 100%;
  min-height: var(--cs-space-px-44);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
}

.cs-actions {
  display: flex;
  align-items: center;
  gap: var(--cs-space-px-10);
}

/* The board's round marked buttons. The word is kept for a screen reader and
   drawn inside the phone's menu, where these become pills. */
.cs-action {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cs-space-2);
  min-width: var(--cs-space-px-44);
  min-height: var(--cs-space-px-44);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  text-decoration: none;
  font-weight: 600;
  font-size: var(--cs-size-px-15);
  transition: border-color 120ms ease, color 120ms ease;
}

.cs-action:hover { border-color: var(--cs-color-ink); color: var(--cs-color-brand-text); }

.cs-action:focus-visible,
.cs-find:focus-visible,
.cs-basket:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.cs-action__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* How many are saved, on the heart's shoulder. */
.cs-action .cs-count {
  position: absolute;
  top: calc(var(--cs-space-px-4) * -1);
  right: calc(var(--cs-space-px-4) * -1);
  min-width: var(--cs-space-px-18);
  padding-inline: var(--cs-space-px-4);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-accent);
  color: var(--cs-color-accent-contrast);
  font-size: var(--cs-size-px-11);
  font-weight: 700;
  line-height: var(--cs-space-px-18);
  text-align: center;
}

/* The phone's magnifier. A desktop has the box itself. */
.cs-find { display: none; }

/* The basket is the only solid thing in the header, a pill in the brand green
   with the bag and the count inside it, as the board draws it. */
.cs-basket {
  display: flex;
  align-items: center;
  gap: var(--cs-space-px-10);
  font-weight: 600;
  font-size: var(--cs-size-px-15-5);
  min-height: var(--cs-space-px-44);
  padding: var(--cs-space-px-10) var(--cs-space-px-12) var(--cs-space-px-10) var(--cs-space-px-24);
  background: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
  text-decoration: none;
  border: none;
  border-radius: var(--cs-radius-pill);
  white-space: nowrap;
}

.cs-basket:hover {
  background: var(--cs-color-brand-hover);
  color: var(--cs-color-brand-contrast);
}

.cs-basket .cs-basket__icon { display: block; flex: none; }

/* Inverted against the pill it sits in, so the number stays legible when the
   merchant recolours the brand to something pale. */
.cs-basket__count {
  display: inline-grid;
  place-items: center;
  min-width: var(--cs-space-px-24);
  height: var(--cs-space-px-24);
  padding-inline: var(--cs-space-px-6);
  font-variant-numeric: tabular-nums;
  background: var(--cs-color-surface);
  color: var(--cs-color-brand-text);
  border-radius: var(--cs-radius-pill);
  font-size: var(--cs-size-px-13);
  font-weight: 700;
}

/* ---- the phone menu (F-219, and R8's board) ----
 *
 * F-219 replaced a header that forced every dropdown panel open on a phone
 * with a Menu button and sections that open and close. R8 draws it as the
 * approved board *Phone -- menu open* does: the menu fills the screen in the
 * deep green, the shop's name at the top, a cross where the bars were, the
 * search box, the sections in the display face, and Account and Saved as two
 * pills along the bottom.
 *
 * Three states, and the markup is the same in all of them:
 *
 * - **desktop**: `.cs-menu` is `display: contents`, so the nav, the search and
 *   the account buttons sit in the header's row, and the dropdowns open on
 *   hover and focus as above;
 * - **phone, scripting off**: both kinds of button stay `hidden`, and the menu
 *   is a plain column under the header with every section open;
 * - **phone, scripting on**: `phone-menu.js` adds `.cs-header--menu`; the menu
 *   is shut until the button opens it, and then it fills the screen.
 *
 * Every target is 44 by 44: a thumb's width, the plan's number.
 */

/* A button the script has not woken is never drawn, whatever display the
   rules below give it -- author styles would otherwise beat `hidden`. */
.cs-menu-toggle,
.cs-nav__toggle,
.cs-menu-toggle[hidden],
.cs-nav__toggle[hidden] {
  display: none;
}

@media (min-width: 48rem) {
  .cs-menu { display: contents; }
}

/* Between a tablet and a small laptop the row is too short for the box: the
   magnifier stands in for it, as on the Home board. The magnifier is a link to
   the box (`#cs-q`), and a box that is the page's target shows in its place --
   so it opens with no script, and `phone-menu.js` puts the cursor in it. */
@media (min-width: 48rem) and (max-width: 71.99rem) {
  .cs-header .cs-search { display: none; }
  .cs-header .cs-search:has(.cs-search__input:target) { display: block; }
  .cs-header:has(.cs-search__input:target) .cs-find { display: none; }
  .cs-find {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--cs-space-px-44);
    min-height: var(--cs-space-px-44);
    border: var(--cs-border-default);
    border-radius: var(--cs-radius-pill);
    background: var(--cs-color-surface);
    color: var(--cs-color-ink);
  }
}

@media (max-width: 47.99rem) {
  .cs-header {
    gap: var(--cs-space-px-6);
    padding: var(--cs-space-px-10) var(--cs-space-px-12);
  }

  /* One row, as both phone boards draw it: the bars, the shop's name in the
     middle, the magnifier and the bag. The name gives way first -- from a
     basis of nothing, so a long one shortens rather than wrapping the row: at
     `auto` its whole width counted before anything shrank, and a spaced
     wordmark put the tools on a row of their own (F-268). */
  .cs-brand {
    order: 0;
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    margin-right: 0;
  }
  .cs-brand__mark { height: var(--cs-space-px-24); }
  .cs-brand__name {
    display: block;
    min-width: 0;
    font-size: var(--cs-size-px-24);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .cs-menu-toggle__label,
  .cs-basket__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  .cs-find,
  .cs-menu-toggle:not([hidden]) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--cs-space-px-44);
    min-height: var(--cs-space-px-44);
    padding: 0;
    border: 0;
    border-radius: var(--cs-radius-circle);
    background: transparent;
    color: var(--cs-color-ink);
    font: inherit;
    cursor: pointer;
  }

  .cs-menu-toggle:not([hidden]) { order: -1; }
  .cs-find { order: 1; }

  .cs-menu-toggle .cs-menu-toggle__shut,
  .cs-menu-toggle[aria-expanded="true"] .cs-menu-toggle__open { display: none; }
  .cs-menu-toggle[aria-expanded="true"] .cs-menu-toggle__shut { display: block; }

  .cs-menu-toggle:focus-visible,
  .cs-nav__toggle:focus-visible {
    outline: var(--cs-space-px-2) solid var(--cs-color-accent);
    outline-offset: var(--cs-space-px-2);
  }

  /* The bag, with its count on its shoulder in the accent. */
  .cs-header .cs-basket {
    order: 2;
    position: relative;
    justify-content: center;
    min-width: var(--cs-space-px-44);
    padding: 0;
    background: transparent;
    color: var(--cs-color-ink);
    border-radius: var(--cs-radius-circle);
  }

  .cs-header .cs-basket__count {
    position: absolute;
    top: 0;
    right: 0;
    min-width: var(--cs-space-px-18);
    height: var(--cs-space-px-18);
    padding-inline: var(--cs-space-px-4);
    background: var(--cs-color-accent);
    color: var(--cs-color-accent-contrast);
    font-size: var(--cs-size-px-11);
  }

  /* The menu takes a row of its own under the header row -- the column a
     phone with scripting off gets, every section open. */
  .cs-menu {
    order: 10;
    flex: 1 0 100%;
    display: flex;
    flex-direction: column;
    gap: var(--cs-space-px-16);
    padding: var(--cs-space-px-12) var(--cs-space-px-6) var(--cs-space-px-18);
    border-top: var(--cs-border-hairline);
  }

  .cs-header--menu .cs-menu:not(.cs-menu--open) { display: none; }

  /* The search box first, as the board draws it. */
  .cs-menu .cs-search { order: -1; flex: none; width: 100%; min-width: 0; }
  .cs-menu .cs-search__input { width: 100%; min-height: var(--cs-space-px-48); }

  .cs-nav { flex: none; }

  .cs-nav__list {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
  }

  .cs-nav__item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    border-bottom: var(--cs-border-hairline);
  }

  /* The board sets the sections in the display face, large: a menu a thumb
     reads from arm's length. */
  .cs-nav__link {
    display: flex;
    align-items: center;
    min-height: var(--cs-space-px-56);
    padding-block: var(--cs-space-2);
    font-family: var(--cs-font-heading);
    font-size: var(--cs-size-px-28);
    font-weight: 500;
    letter-spacing: -0.01em;
  }

  .cs-nav__link--current { font-weight: 600; }

  .cs-nav__toggle:not([hidden]) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--cs-space-px-44);
    min-height: var(--cs-space-px-44);
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    cursor: pointer;
  }

  .cs-nav__toggle[aria-expanded="true"] .icon { transform: rotate(180deg); }

  /* A section's pages as the board's two-across tiles. */
  .cs-nav__panel {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--cs-space-px-10);
    position: static;
    min-width: 0;
    padding: var(--cs-space-px-4) 0 var(--cs-space-px-16);
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: var(--cs-shadow-none);
  }

  /* The desktop's hover-and-focus rule outranks the tiles above; on a phone
     an open section is the tiles whatever has focus. */
  .cs-nav__item--has-children:hover > .cs-nav__panel,
  .cs-nav__item--has-children:focus-within > .cs-nav__panel { display: grid; }

  /* Shut unless its button opened it -- hover and focus included, because on
     a phone a tap is also a hover, and the desktop's rule would open it. */
  .cs-header--menu .cs-nav__item--has-children:not(.cs-nav__item--open) > .cs-nav__panel,
  .cs-header--menu .cs-nav__item--has-children:not(.cs-nav__item--open):hover > .cs-nav__panel,
  .cs-header--menu .cs-nav__item--has-children:not(.cs-nav__item--open):focus-within > .cs-nav__panel {
    display: none;
  }

  .cs-nav__child {
    display: flex;
    align-items: center;
    min-height: var(--cs-space-px-56);
    padding: var(--cs-space-px-10) var(--cs-space-px-14);
    white-space: normal;
    font-weight: 600;
    border-radius: var(--cs-radius-px-12);
    background: var(--cs-color-surface-muted);
  }

  .cs-menu .cs-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: var(--cs-space-px-10);
    margin-top: var(--cs-space-px-16);
  }

  .cs-menu .cs-action {
    min-height: var(--cs-space-px-52);
    padding-inline: var(--cs-space-px-16);
    background: transparent;
    border: var(--cs-border-strong);
  }

  .cs-menu .cs-action__icon { display: none; }
  .cs-menu .cs-action__label { position: static; width: auto; height: auto; clip: auto; overflow: visible; }
  .cs-menu .cs-action .cs-count {
    position: static;
    background: transparent;
    color: inherit;
    font-size: inherit;
    line-height: inherit;
  }
  .cs-menu .cs-action .cs-count::before { content: "("; }
  .cs-menu .cs-action .cs-count::after { content: ")"; }

  /* **Open, with scripting on: the menu fills the screen.** The header row
     stays on top of it -- the cross closes it, the name stays in the middle --
     and the magnifier and the bag step out of the way, as on the board. */
  .cs-header:has(.cs-menu--open) {
    position: fixed;
    inset: 0;
    z-index: 60;
    align-content: flex-start;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--cs-color-surface-inverse);
    color: var(--cs-color-ink-inverse);
    padding-bottom: var(--cs-space-px-24);
  }

  html:has(.cs-menu--open) { overflow: hidden; }

  .cs-header:has(.cs-menu--open) .cs-find,
  .cs-header:has(.cs-menu--open) .cs-basket { visibility: hidden; }

  .cs-header:has(.cs-menu--open) .cs-menu-toggle {
    color: var(--cs-color-ink-inverse);
    background: var(--cs-color-border-inverse);
  }

  .cs-header:has(.cs-menu--open) .cs-brand__name,
  .cs-header:has(.cs-menu--open) .cs-nav__link,
  .cs-header:has(.cs-menu--open) .cs-nav__child,
  .cs-header:has(.cs-menu--open) .cs-action { color: var(--cs-color-ink-inverse); }

  .cs-header:has(.cs-menu--open) .cs-menu {
    border-top: 0;
    /* The screen's height under the header row, so Account and Saved sit at
       its foot as the board draws them. */
    min-height: calc(100dvh - var(--cs-space-px-72));
  }

  .cs-header:has(.cs-menu--open) .cs-actions { margin-top: auto; }

  .cs-header:has(.cs-menu--open) .cs-nav__item {
    border-bottom: 1px solid var(--cs-color-border-inverse);
  }

  .cs-header:has(.cs-menu--open) .cs-nav__child { background: var(--cs-color-border-inverse); }

  .cs-header:has(.cs-menu--open) .cs-search__input {
    background: var(--cs-color-border-inverse);
    border-color: var(--cs-color-border-inverse);
    color: var(--cs-color-ink-inverse);
  }

  .cs-header:has(.cs-menu--open) .cs-search__input::placeholder { color: var(--cs-color-ink-inverse-muted); }

  .cs-header:has(.cs-menu--open) .cs-action { border-color: var(--cs-color-ink-inverse-muted); }
}

/* ---- footer ---- */

/* R8. The boards open every page on the deep green -- the announcement bar --
   and the Home board sets its workshops on it too; the footer closes the page
   on the same ground. The newsletter stays a paper card, which is what makes
   it read as the one column asking for something. */

.cs-footer-menus {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--cs-space-px-32);
  margin-bottom: var(--cs-space-px-40);
  align-items: start;
}

/* The newsletter needs room for an input and a button side by side, so it
   takes two tracks where there are two to take. */
@media (min-width: 48rem) {
  .cs-footer-group--newsletter { grid-column: span 2; }
}

/* A footer column. `min-width: 0` so a long link in a narrow column wraps
   rather than widening the track and squeezing the ones beside it. */
.cs-footer-group { min-width: 0; }

/* The column headings are the board's eyebrow on a dark ground: the light
   green the Home board gives "Workshops". */
.cs-footer-heading {
  font-family: var(--cs-font-body);
  font-size: var(--cs-size-px-12);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cs-color-brand-on-inverse);
  margin: 0 0 var(--cs-space-px-14);
}

.cs-footer-list {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-9);
  font-size: var(--cs-size-px-15);
}

.cs-footer-list a {
  color: var(--cs-color-ink-inverse);
  text-decoration: none;
}

.cs-footer-list a:hover { text-decoration: underline; }

/* The channel column is the merchant's off-site presence, so it reads as a
   list of destinations rather than as site navigation.
 *
 * The design draws these as a row of raised square tiles carrying each
 * network's own glyph. WE DO NOT SHIP THE GLYPHS -- `macros/icons.html` is
 * deliberately free of brand marks, because a set of network logos is a
 * third-party asset whose license notices would have to ship with the box and
 * whose trademarks are not ours to redistribute. So the tile shape is kept and
 * the merchant's own label goes inside it: a row of chips that reads as the
 * same object at a glance, and says "Instagram" rather than showing a mark we
 * would have had to borrow. */
.cs-footer-group--channels .cs-footer-list {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--cs-space-px-10);
  align-items: center;
}

.cs-footer-group--channels .cs-footer-list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--cs-space-px-44);
  padding-inline: var(--cs-space-px-16);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-border-inverse);
  border: 1px solid var(--cs-color-border-inverse);
  color: var(--cs-color-ink-inverse);
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}

.cs-footer-group--channels .cs-footer-list a:hover {
  background: var(--cs-color-brand-on-inverse);
  border-color: var(--cs-color-brand-on-inverse);
  color: var(--cs-color-surface-inverse);
  text-decoration: none;
}

/* "All channels" is a link, not a destination chip -- it stays plain so the
   row does not read as five equal networks one of which is a page on this
   site. It is the last child of the list by construction in base.html. */
.cs-footer-group--channels .cs-footer-list li:last-child a {
  background: none;
  border: none;
  padding-inline: var(--cs-space-1);
  min-height: 0;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-inverse-muted);
  white-space: nowrap;
}

.cs-footer-group--channels .cs-footer-list li:last-child a:hover {
  background: none;
  color: var(--cs-color-ink-inverse);
  text-decoration: underline;
}

/* Block margins only: the footer's rows are centered by `margin-inline: auto`
   (`.site-footer > *`), and a `margin` shorthand here put the shop's name 8px
   left of every column above it. */
.business-name {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-24);
  font-weight: 500;
  color: var(--cs-color-ink-inverse);
  margin-block: 0 var(--cs-space-2);
  display: block;
}
.contact { margin-block: 0; font-size: var(--cs-size-text-sm); }
.site-footer .contact a { color: var(--cs-color-ink-inverse-muted); }

/* A placeholder inside a card sits where the photograph would, at the card's
   own width, so a grid of pictureless products still reads as a grid. */
.product-card .cs-ph,
.event-card .cs-ph { aspect-ratio: 4 / 3; margin-bottom: var(--cs-space-1); }

/* ---- search, saved, newsletter and the legal row (F-106) ---- */

/* It sits in the header's flex row between the nav and the account links, so
   without a floor it is the thing that gives: at 1440px it shrank to the width
   of the word "Sea". Found by looking at the header, not by any assertion. */
.cs-search { flex: 0 1 14rem; min-width: 9rem; }

/* A pill of paper with a line round it (R8). It was a recessed pill on the
   muted ground, which is the page's own color now -- a box that would vanish
   into the cream on the search page. */
.cs-search__input {
  font: inherit;
  font-size: var(--cs-size-px-14-5);
  color: var(--cs-color-ink);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  padding: var(--cs-space-2) var(--cs-space-4);
  min-height: var(--cs-space-px-40);
  width: 100%;
  box-sizing: border-box;
}

.cs-search__input:focus {
  background: var(--cs-color-surface);
  border-color: var(--cs-color-accent);
}

.cs-search__input:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-1);
}

.cs-count {
  font-variant-numeric: tabular-nums;
  background: var(--cs-color-surface-muted);
  border-radius: var(--cs-radius-pill);
  padding-inline: var(--cs-space-2);
  font-size: var(--cs-size-text-sm);
}

.cs-news {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  margin-top: var(--cs-space-3);
}

.cs-news__blurb { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); margin: 0; }

.cs-news__input {
  font: inherit;
  font-size: var(--cs-size-px-14-5);
  flex: 1 1 var(--cs-space-px-80);
  min-height: var(--cs-space-px-44);
  padding: var(--cs-space-2) var(--cs-space-px-14);
  border: var(--cs-border-strong);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  box-sizing: border-box;
}

.cs-news__input:focus {
  border-color: var(--cs-color-accent);
  outline: none;
}

/* The newsletter is the one footer column that is a card. It is asking for
   something, and the design gives it a raised surface so it does not read as
   another list of links. */
.cs-footer-group--newsletter {
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  padding: var(--cs-space-px-22) var(--cs-space-px-24);
}

.cs-footer-group--newsletter .cs-footer-heading {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-20);
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  color: var(--cs-color-ink);
  margin-bottom: var(--cs-space-px-6);
}

/* The legal row. Small, quiet, and always present -- a policy link a shopper
   cannot find is a policy the shop does not really have. */
.cs-legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2) var(--cs-space-4);
  align-items: baseline;
  margin-top: var(--cs-space-5);
  padding-top: var(--cs-space-4);
  border-top: 1px solid var(--cs-color-border-inverse);
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-inverse-muted);
}

.cs-legal a { color: var(--cs-color-ink-inverse-muted); }
.cs-legal a:hover { color: var(--cs-color-ink-inverse); }
.cs-legal__right { margin-left: auto; }

/* ---- the languages the shop speaks (docs/22 Later 12) ----
 *
 * Core draws the row (`storefront/_languages.html`) and this footer is the deep
 * ground: the page's link color would be unread on it, which is how the
 * footer's own links were once drawn twice and seen once (F-452). The language
 * the page is in is the brighter of the two inks, and is not a link. */
.site-languages,
.site-currencies {
  margin-top: var(--cs-space-4);
  font-size: var(--cs-size-text-sm);
}
.site-languages ul,
.site-currencies ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2) var(--cs-space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-footer .site-language { color: var(--cs-color-ink-inverse-muted); }
.site-footer a.site-language:hover { color: var(--cs-color-ink-inverse); }
.site-footer .site-currency { color: var(--cs-color-ink-inverse-muted); }
.site-footer a.site-currency:hover { color: var(--cs-color-ink-inverse); }
.site-footer .site-currency-note { margin: var(--cs-space-1) 0 0; color: var(--cs-color-ink-inverse-muted); }
.site-footer .site-language--current,
.site-footer .site-currency--current {
  color: var(--cs-color-ink-inverse);
  font-weight: 600;
}

/* ---- the buyer-photograph gallery page (F-109) ----
 *
 * `core.css` styles `.gallery-grid` and `.gallery-item` -- and the gallery
 * *page* uses `.gallery-tile` for its list items, while only the gallery
 * *block* uses `.gallery-item`. So the grid tracks existed and nothing
 * constrained the pictures inside them: the images overflowed their columns
 * and the page collapsed after the first row.
 *
 * It went unseen because the V0.5.140 markup gate reads `class="..."` with a
 * regex that skips any attribute containing a Jinja expression, and this one
 * is `class="gallery-tile gallery-tile-{{ tile.kind }}"` (F-108).
 */

.gallery-tile {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  min-width: 0;
}

.gallery-tile img,
.gallery-tile .cs-ph {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--cs-radius-md);
  margin-bottom: var(--cs-space-2);
}

.gallery-tile figure { margin: 0; }

/* One chip per category, plus "All". A filter that is on reads as pressed
   rather than merely colored, because color alone is not a state. */
.gallery-chip {
  display: inline-block;
  padding: var(--cs-space-1) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  font-size: var(--cs-size-text-sm);
  text-decoration: none;
  color: var(--cs-color-ink);
}

.gallery-chip:hover { border-color: var(--cs-color-ink-muted); }

.gallery-chip-on {
  background: var(--cs-color-brand);
  border-color: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
  font-weight: 600;
}

/* ------------------------------------------------------------------ *
 * 10 · The row and cell system (F-108, F-492)
 *
 * `blocks/_rows.html` draws a page's rows of twelfth-width cells -- the
 * merchant's two-column and three-column layouts.
 *
 * **Until V0.6.138 no page of the shop drew them** (F-492). These rules were
 * written against the builder's preview, the one place that included the
 * file, and had never been seen under the shop's own shell. Seen there, on a
 * page of four arranged rows:
 *
 *   - a plain row was a panel of the paper cards are made of, on the page's
 *     cream, and its words 16px further in than the page's;
 *   - a muted row was `surface-muted`, which is the page's own color here:
 *     no tint at all;
 *   - a dark row was a box as wide as the page's column and not a band, and
 *     its heading was the page's dark ink on it, 1.3:1;
 *   - the last block in every column kept the 72px that ends a page.
 *
 * A row that is only its blocks -- one column, the page's measure, the page's
 * ground -- is drawn as its blocks (`row.bare`) and never reaches these rules:
 * a page nobody arranged is the markup it always was. What does reach them is
 * a row somebody split, tinted or narrowed.
 *
 * `span` is a class rather than an inline style on purpose: `style-src 'self'`
 * blocks inline styles, a lesson the product page's quantity box already paid
 * for once.
 * ------------------------------------------------------------------ */

/* One section of the page, with a block's own rhythm. Plain is the page's own
   ground: nothing is painted, and the columns sit on the page's measure. */
.cs-row { margin: 0 0 var(--cs-space-7); }

/* A tinted row is a band from one edge of the window to the other, its columns
   still on the page's measure: the two lines the data strip and the
   traceability band bleed with, and their gutter arithmetic (see `.site-main`
   and `.block-traceability`). A row asked to be full width bleeds as well. */
.cs-row--muted,
.cs-row--inverse,
.cs-row--full {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

.cs-row--muted,
.cs-row--inverse {
  padding-block: var(--cs-space-px-56);
  padding-inline: max(
    var(--cs-space-px-24),
    calc(50vw - 39.5rem + var(--cs-space-px-24))
  );
}

/* The sunken ground, not `surface-muted`: that one is the page itself in this
   theme, and sunken is a shade below the page in every shipped theme. */
.cs-row--muted { background: var(--cs-color-surface-sunken); }

.cs-row--inverse { background: var(--cs-color-surface-inverse); }

/* Words written straight onto the dark ground take its ink. A heading is set
   in the page's ink wherever it is, which there was 1.3:1. */
.cs-row--inverse .block-rich-text { color: var(--cs-color-ink-inverse); }
.cs-row--inverse .block-rich-text h1,
.cs-row--inverse .block-rich-text h2,
.cs-row--inverse .block-rich-text h3,
.cs-row--inverse .block-rich-text h4 { color: inherit; }
.cs-row--inverse .block-rich-text a { color: var(--cs-color-brand-on-inverse); }

/* **Every other block brings the page's ground with it.** Each was drawn for
   the light page: its titles in the page's ink, its quiet lines in the muted
   one, its own panels of paper. Given the row's ink instead, 27 kinds of text
   in the example shop's twelve blocks were under 2.2:1 -- a card's title on
   the dark ground, and a white heading on a block's own pale panel (measured,
   V0.6.138). A dark dress for every block is a second theme. So a block that
   is not plain words sits on a panel of the page's own ground, where each of
   its colors is the one it was measured with. The four that are dark
   themselves -- the hero, the what's-on band, the data strip and the
   traceability band -- are left as they are: on the page's ground their white
   words were 1.1:1. */
.cs-row--inverse
  .cs-cell
  > .block:not(.block-rich-text):not(.cs-hero):not(.cs-band):not(.block-data-strip):not(.block-traceability) {
  padding: var(--cs-space-px-24);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-page);
  color: var(--cs-color-ink);
}

/* Two bands one after the other touch. The page's ground between them was a
   stripe across the window that nobody arranged. A band is a row that is not
   plain. */
.cs-row:not(.cs-row--plain) + .cs-row:not(.cs-row--plain) {
  margin-top: calc(-1 * var(--cs-space-7));
}

/* Full width is the window's, gutter and all: what was asked for. */
.cs-row--full { padding-inline: 0; }
.cs-row--narrow .cs-row__cells { max-width: 46rem; margin-inline: auto; }

.cs-row__cells {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--cs-space-6);
  align-items: start;
}

/* Full width by default: a cell whose span the merchant has not set should
   take the row rather than collapse to a twelfth. */
.cs-cell { min-width: 0; grid-column: span 12; }

.cs-cell--1  { grid-column: span 1; }
.cs-cell--2  { grid-column: span 2; }
.cs-cell--3  { grid-column: span 3; }
.cs-cell--4  { grid-column: span 4; }
.cs-cell--5  { grid-column: span 5; }
.cs-cell--6  { grid-column: span 6; }
.cs-cell--7  { grid-column: span 7; }
.cs-cell--8  { grid-column: span 8; }
.cs-cell--9  { grid-column: span 9; }
.cs-cell--10 { grid-column: span 10; }
.cs-cell--11 { grid-column: span 11; }
.cs-cell--12 { grid-column: span 12; }

.cs-cell--top    { align-self: start; }
.cs-cell--middle { align-self: center; }
.cs-cell--bottom { align-self: end; }

/* On a phone a twelfth-width cell is unreadable, so every cell takes the row.
   `bin/check_mobile_overflow.py` is the gate; this is the rule it checks. */
@media (max-width: 47.99rem) {
  .cs-row__cells { gap: var(--cs-space-5); }
  .cs-cell[class*="cs-cell--"] { grid-column: span 12; }
}

/* A block inside a cell has already been given its rhythm by the row, and the
   last one in a column ends the column, not the page. */
.cs-cell > .block { max-width: none; padding-inline: 0; }
.cs-cell > .block:last-child { margin-bottom: 0; }

/* The two bands that bleed to the window's edges are a column wide inside a
   column: `50% - 50vw` is the window's edge only from the page's middle. */
.cs-cell > .block-data-strip,
.cs-cell > .block-traceability {
  width: auto;
  margin-inline: 0;
}

.cs-cell > .block-traceability { padding-inline: var(--cs-space-px-24); }

/* ---- the icon macro ----
 * `macros/icons.html` draws inline SVG with `stroke="currentColor"`, so an
 * icon inherits its color from the text beside it and needs only alignment. */
.icon {
  display: inline-block;
  vertical-align: -0.125em;
  flex: none;
}

/* --- Gift cards on the order page -----------------------------------------
 *
 * The code is set in the monospace face for the same reason the booking
 * reference is: it is read off a screen and typed into another box, often by
 * somebody who was given the card rather than the person who bought it, and a
 * proportional face makes a run of capitals ambiguous at exactly the moment it
 * must not be.
 */
.gift-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--cs-space-3);
}

.gift-card {
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-sm);
  padding: var(--cs-space-3);
}

.gift-card-code {
  margin: 0;
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-lg);
  font-weight: 700;
  letter-spacing: 0.08em;
  word-break: break-all;
}

.gift-card-amount {
  margin: var(--cs-space-1) 0 0;
  color: var(--cs-color-ink-muted);
}

.gift-card-expiry {
  margin: var(--cs-space-1) 0 0;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

/* The files a paid order bought (ruling 57). A list of links, each with the
 * product it belongs to and its size, and a note saying the links expire. */
.downloads {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--cs-space-2);
}

.download {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--cs-space-2);
}

.download-link {
  font-weight: 600;
  word-break: break-all;
}

.download-meta {
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

.download-note {
  margin: var(--cs-space-3) 0 0;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

.gift-card-note {
  margin: var(--cs-space-3) 0 0;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

/* ------------------------------------------------------------------ *
 * 8 · The commerce path in the theme's own DOM (ruling 55)
 *
 * Until V0.6.7 the five pages a shopper pays through -- catalog, product,
 * basket, checkout, receipt -- fell through to the core templates, and the
 * rules in sections 3 and 4 above dressed core's DOM. Those rules stay: a
 * merchant who installs a theme that overrides only one of these pages still
 * gets core's markup on the rest, and it still has to look deliberate.
 *
 * Everything below is for the `cs-` markup in
 * `themes/craftysales/templates/storefront/{product,category,cart,checkout,order}.html`.
 * One tile (`.cs-tile`) serves the catalog and the product page's related
 * row; one choice row (`.cs-choice`) serves delivery, expedite and payment;
 * one panel (`.cs-panel`) serves every section of the receipt that exists
 * only when it has something to say.
 * ------------------------------------------------------------------ */

/* ---- shared: eyebrow, crumbs, stars ---- */

.cs-eyebrow {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cs-color-accent-text);
  font-weight: 600;
  margin: 0 0 var(--cs-space-2);
}

.cs-crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  align-items: center;
  max-width: none;
  margin: 0 0 var(--cs-space-4);
  padding-inline: 0;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

.cs-crumbs a { color: inherit; text-decoration: none; }
.cs-crumbs a:hover { color: var(--cs-color-brand-text); text-decoration: underline; }
.cs-crumbs__sep { color: var(--cs-color-border-strong); }
.cs-crumbs__here { color: var(--cs-color-ink); }

/* Stars are drawn from a data attribute, so a rating needs no image and no
   script. The glyphs are text: a screen reader gets the sentence beside them. */
.cs-stars { color: var(--cs-color-accent); letter-spacing: 0.05em; white-space: nowrap; }
.cs-stars::before { content: "\2606\2606\2606\2606\2606"; }
.cs-stars[data-stars="1"]::before { content: "\2605\2606\2606\2606\2606"; }
.cs-stars[data-stars="2"]::before { content: "\2605\2605\2606\2606\2606"; }
.cs-stars[data-stars="3"]::before { content: "\2605\2605\2605\2606\2606"; }
.cs-stars[data-stars="4"]::before { content: "\2605\2605\2605\2605\2606"; }
.cs-stars[data-stars="5"]::before { content: "\2605\2605\2605\2605\2605"; }

/* ---- the tile: catalog and related ---- */

.cs-tiles {
  list-style: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
  max-width: none;
  display: grid;
  gap: var(--cs-space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 40rem) { .cs-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .cs-tiles--catalog, .cs-related .cs-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Positioned so the save button can sit over the photograph: it is a form
   beside the tile's link, not inside it, because a form cannot live inside
   an anchor. */
.cs-tile { margin: 0; position: relative; }
.cs-tile--sold-out .cs-tile__image { filter: grayscale(0.6); opacity: 0.8; }

.cs-tile__link {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  color: inherit;
  text-decoration: none;
}

.cs-tile__frame {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--cs-radius-md);
  border: var(--cs-border-default);
  background: var(--cs-color-surface-muted);
  transition: transform 160ms ease, box-shadow 160ms ease;
}

.cs-tile__link:hover .cs-tile__frame { transform: translateY(-3px); box-shadow: var(--cs-shadow-md); }
@media (prefers-reduced-motion: reduce) { .cs-tile__frame { transition: none; } }

.cs-tile__image,
.cs-tile__frame .cs-ph {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 0;
}

.cs-tile__ribbon {
  position: absolute;
  top: var(--cs-space-2);
  left: var(--cs-space-2);
  padding: var(--cs-space-px-3) var(--cs-space-2);
  border-radius: var(--cs-radius-pill);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  border: var(--cs-border-default);
}

.cs-tile__ribbon--out-of-season { background: var(--cs-color-accent-tint); border-color: var(--cs-color-accent-tint-border); color: var(--cs-color-accent-deep); }
.cs-tile__ribbon--sold-out { background: var(--cs-color-surface-inverse); color: var(--cs-color-ink-inverse); border-color: var(--cs-color-surface-inverse); }
.cs-tile__ribbon--sale { background: var(--cs-color-brand-tint); border-color: var(--cs-color-brand-tint-border); color: var(--cs-color-brand-text); }
.cs-tile__ribbon--low { background: var(--cs-color-danger-tint); border-color: var(--cs-color-danger); color: var(--cs-color-danger); }

.cs-tile__title {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-text-md);
  line-height: 1.25;
  margin-top: var(--cs-space-2);
}

.cs-tile__price { font-weight: 600; font-variant-numeric: tabular-nums; }
/* R6. The quick look: a small link under the tile, a dialog with the script. */
.cs-tile__quick {
  display: inline-block;
  margin-top: var(--cs-space-1);
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

/* ---- saving a product (R2) ----
 * The header's "Saved" link had nothing on this theme to fill it. A round
 * button over the photograph's corner on a tile, and a labeled one under
 * the buy form on the page. 44 by 44: it is a thumb's target on a phone. */

.cs-save { margin: 0; }

.cs-tile .cs-save {
  position: absolute;
  top: var(--cs-space-2);
  right: var(--cs-space-2);
}

.cs-save__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cs-space-2);
  min-width: var(--cs-space-px-44);
  min-height: var(--cs-space-px-44);
  padding: 0;
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-circle);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}

.cs-save__button:hover { color: var(--cs-color-brand-text); }

.cs-save__button:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

/* Saved: the heart filled in the color the shop uses for "this matters". */
.cs-save__button--on { color: var(--cs-color-danger); }
.cs-save__button--on .icon { fill: currentColor; }

/* On the product page it says what it does, beside its heart. */
.cs-save__button--labeled {
  border-radius: var(--cs-radius-pill);
  padding-inline: var(--cs-space-4);
  font-weight: 600;
}
.cs-tile__stock,
.cs-tile__rating { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ---- search results (F-220) ----
 * The catalog's own head and tiles; a second search box on the page itself,
 * because the header's is off-screen on a phone once the menu is shut. */

.cs-search--page {
  display: flex;
  gap: var(--cs-space-2);
  max-width: 36rem;
  margin-top: var(--cs-space-4);
}

.cs-search--page .cs-search__input { flex: 1 1 auto; min-width: 0; min-height: var(--cs-space-px-44); }
/* The box gives way, not the button: "Look it up" folded to two lines (R5). */
.cs-search--page .button { flex: none; }

.cs-search-links {
  max-width: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
}

.cs-search-links__heading {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-text-lg);
  margin: 0 0 var(--cs-space-3);
}

.cs-search-links__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--cs-space-2);
}

.cs-search-links__list a { overflow-wrap: anywhere; }

.cs-search-links__kind {
  margin-left: var(--cs-space-2);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
}

/* ---- the catalog head ---- */

.cs-catalog {
  max-width: none;
  margin: 0 0 var(--cs-space-6);
  padding-inline: 0;
}

.cs-catalog .cs-crumbs { padding-inline: 0; margin-inline: 0; }
.cs-catalog__title { margin: 0 0 var(--cs-space-3); }
.cs-catalog__lede { max-width: 60ch; font-size: var(--cs-size-text-lg); color: var(--cs-color-ink-muted); margin: 0 0 var(--cs-space-4); }

.cs-catalog__empty {
  max-width: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
  font-size: var(--cs-size-text-lg);
  color: var(--cs-color-ink-muted);
}

/* The child categories as a row of chips a thumb can flick through. It
   scrolls sideways on a phone rather than wrapping into four lines. */
.cs-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--cs-space-2);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.cs-chips::-webkit-scrollbar { display: none; }

.cs-chip {
  display: inline-block;
  white-space: nowrap;
  padding: var(--cs-space-px-6) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  color: var(--cs-color-ink);
  text-decoration: none;
  font-size: var(--cs-size-text-sm);
}

.cs-chip:hover { border-color: var(--cs-color-ink); }

/* ---- the product sheet ---- *
 * R8, the approved ProductPlant board: the photograph large on the left with
 * its strip under it, the buying rail on the right, and below both, at the
 * page's full width, the description, the type's panel as a paper card, the
 * record, and the offers. The rail is a column, not a sticky one: the board's
 * rail is longer than its photograph.
 */

.cs-sheet {
  display: grid;
  gap: var(--cs-space-px-32);
  margin: 0 0 var(--cs-space-px-72);
  grid-template-areas: "stage" "rail" "body";
}

@media (min-width: 52rem) {
  .cs-sheet {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    grid-template-areas: "stage rail" "body body";
    column-gap: clamp(var(--cs-space-px-32), 4.4vw, var(--cs-space-px-64));
    row-gap: var(--cs-space-px-56);
    align-items: start;
  }
}

.cs-sheet__stage { grid-area: stage; min-width: 0; }
.cs-rail { grid-area: rail; min-width: 0; }
.cs-sheet__body { grid-area: body; min-width: 0; }

.cs-stage {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-sunken);
}

.cs-stage__image,
.cs-stage--empty .cs-ph {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* The board's chip: the accent, at the photograph's top left. */
.cs-stage__chip {
  position: absolute;
  top: var(--cs-space-px-20);
  left: var(--cs-space-px-20);
  z-index: 1;
  padding: var(--cs-space-px-6) var(--cs-space-px-14);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-accent);
  color: var(--cs-color-accent-contrast);
  font-size: var(--cs-size-px-14);
  font-weight: 700;
}

/* The corner button: the photograph at full size. */
.cs-stage__expand {
  position: absolute;
  right: var(--cs-space-px-20);
  bottom: var(--cs-space-px-20);
  display: grid;
  place-items: center;
  width: var(--cs-space-px-44);
  height: var(--cs-space-px-44);
  border-radius: var(--cs-radius-circle);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  box-shadow: var(--cs-shadow-sm);
}

.cs-stage__expand:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.cs-stage__video { position: relative; display: block; color: inherit; }

.cs-stage__play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: var(--cs-space-2) var(--cs-space-4);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  font-size: var(--cs-size-text-sm);
  white-space: nowrap;
}

/* The strip: every further photograph, four across as the board draws it,
   snapping as it scrolls when there are more. Nothing to switch and nothing
   to script. */
.cs-strip {
  list-style: none;
  margin: var(--cs-space-px-16) 0 0;
  padding: 0;
  display: flex;
  gap: var(--cs-space-px-14);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.cs-strip__item {
  flex: 0 0 calc(25% - var(--cs-space-px-12));
  scroll-snap-align: start;
  position: relative;
  border-radius: var(--cs-radius-md);
  overflow: hidden;
  background: var(--cs-color-surface-sunken);
}

.cs-strip__image { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.cs-strip__video { position: relative; display: block; }

/* A video with no still chosen for it (F-528): a tile the size its picture
   would have been, on the stage's own ground, with the play label where the
   picture would be. Nothing is fetched from where the video is kept. */
.cs-stage__video--plain { aspect-ratio: 1 / 1; }
.cs-strip__video--plain { aspect-ratio: 4 / 3; }

.cs-rail .cs-eyebrow { margin: var(--cs-space-px-12) 0 var(--cs-space-px-12); }

.cs-rail__title {
  margin: 0 0 var(--cs-space-px-14);
  font-family: var(--cs-font-heading);
  font-size: clamp(2.2rem, 4vw, 3.5rem);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.025em;
}

.cs-rail__rating {
  display: inline-flex;
  gap: var(--cs-space-px-10);
  align-items: center;
  margin-bottom: var(--cs-space-px-24);
  color: inherit;
  text-decoration: none;
  font-size: var(--cs-size-px-15);
}

.cs-rail__rating-words { color: var(--cs-color-ink); text-decoration: underline; text-underline-offset: var(--cs-space-px-3); }

.cs-rail__priceline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--cs-space-px-4) var(--cs-space-px-14);
  margin-bottom: var(--cs-space-px-10);
}

.cs-rail__price {
  margin: 0;
  font-family: var(--cs-font-body);
  font-size: clamp(2rem, 3vw, 2.6rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.cs-rail__subtitle { margin: 0; font-size: var(--cs-size-px-17); color: var(--cs-color-ink-muted); }

.cs-rail__sale,
.cs-rail__stock,
.cs-rail__monthly {
  margin: 0 0 var(--cs-space-3);
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

/* R10: the season paid monthly, under the button -- its link the one thing to press. */
.cs-rail__monthly { margin-top: var(--cs-space-3); }
.cs-rail__monthly-link { font-weight: 600; color: var(--cs-color-accent-deep); }

.cs-rail__sale time { font-family: var(--cs-font-mono); color: var(--cs-color-accent-deep); }

.cs-soldout {
  margin: var(--cs-space-4) 0;
  padding: var(--cs-space-3) var(--cs-space-4);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface-muted);
  font-weight: 600;
}

/* The season notice, in this theme's names (the macro takes them). */
.cs-season {
  margin: var(--cs-space-4) 0;
  padding: var(--cs-space-4);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-accent-tint);
  border: 1px solid var(--cs-color-accent-tint-border);
}

.cs-season__heading { margin: 0 0 var(--cs-space-1); font-family: var(--cs-font-heading); font-size: var(--cs-size-text-lg); }
.cs-season__lede { margin: 0; color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-sm); }
.cs-season__notify { display: grid; gap: var(--cs-space-2); margin-top: var(--cs-space-3); }
.cs-season__notify label { font-weight: 600; font-size: var(--cs-size-text-sm); }
.cs-season__notify input[type="email"] {
  padding: var(--cs-space-2) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-control);
  font: inherit;
}
.cs-season__notify button {
  justify-self: start;
  padding: var(--cs-space-2) var(--cs-space-4);
  border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-color-brand);
  background: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

/* The buy box: the options as cards, then how many beside the button. No box
   around it -- the board sets it straight on the paper. */
.cs-buy {
  display: grid;
  gap: var(--cs-space-px-16);
  margin: var(--cs-space-px-24) 0 var(--cs-space-px-16);
}

.cs-buy__variants {
  margin: 0;
  padding: 0;
  border: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: var(--cs-space-px-10);
}

.cs-buy__variants .cs-buy__label { grid-column: 1 / -1; padding: 0; margin-bottom: var(--cs-space-px-4); }

.cs-buy__label {
  display: block;
  font-weight: 600;
  font-size: var(--cs-size-px-15);
  margin-bottom: var(--cs-space-1);
}

/* An option: a card with its name, and its price under it. */
.cs-pill {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--cs-space-px-2);
  min-height: var(--cs-space-px-64);
  padding: var(--cs-space-px-10) var(--cs-space-px-12);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
  cursor: pointer;
  font-size: var(--cs-size-px-13-5);
  text-align: center;
}

/* The radio is real and focusable; it is drawn as the card's border. */
.cs-pill input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.cs-pill:hover { border-color: var(--cs-color-ink-faint); }
.cs-pill:has(input:checked) {
  border: var(--cs-space-px-2) solid var(--cs-color-brand);
  background: var(--cs-color-brand-tint);
}
.cs-pill:has(input:focus-visible) { outline: var(--cs-space-px-2) solid var(--cs-color-accent); outline-offset: var(--cs-space-px-2); }
.cs-pill--gone { color: var(--cs-color-ink-faint); border-style: dashed; background: transparent; cursor: not-allowed; }
.cs-pill--gone .cs-pill__label { text-decoration: line-through; }
.cs-pill__label { font-weight: 700; font-size: var(--cs-size-px-16); color: inherit; }
.cs-pill__price { font-weight: 500; color: var(--cs-color-ink-muted); font-variant-numeric: tabular-nums; }

/* The per-axis picker's values stay pills in a row: a size or a color is a
   word, not a card. */
.cs-buy__axis { display: flex; flex-wrap: wrap; gap: var(--cs-space-px-8); }
.cs-buy__axis .cs-pill {
  flex-direction: row;
  min-height: var(--cs-space-px-44);
  padding: var(--cs-space-px-8) var(--cs-space-px-16);
  border-radius: var(--cs-radius-pill);
}
.cs-buy__axis .cs-pill__label { font-size: var(--cs-size-px-15); }

/* R6. The ordinary price struck out beside a sale, and a price per unit of
   weight: quieter than the price they explain. On an option card the unit
   price stays on the card. */
.cs-price__was {
  margin-left: var(--cs-space-2);
  color: var(--cs-color-ink-muted);
  font-weight: 400;
}
.cs-price__unit {
  display: block;
  margin: 0 0 var(--cs-space-2);
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
  font-variant-numeric: tabular-nums;
}
.cs-pill .cs-price__was,
.cs-pill .cs-price__unit { display: inline; margin: 0; }

/* R6. Buy more, pay less, under the price; the size guide beside the options. */
.cs-breaks { margin: 0 0 var(--cs-space-3); font-size: var(--cs-size-text-sm); }
.cs-breaks__heading { margin: 0; font-weight: 600; }
.cs-breaks__for { font-weight: 400; color: var(--cs-color-ink-muted); }
.cs-breaks__list { margin: var(--cs-space-1) 0 0; padding-left: var(--cs-space-4); }
.cs-buy__guide { margin: 0; font-size: var(--cs-size-px-14); font-weight: 600; }

/* R6. A pre-order says when it is sent, beside the price and on an option. */
.cs-rail__preorder {
  margin: 0 0 var(--cs-space-3);
  font-weight: 600;
  color: var(--cs-color-ink);
}
.cs-pill__ships { color: var(--cs-color-ink-muted); }
.cs-pill__gone { font-size: var(--cs-size-px-12-5); }

/* docs/22 Later 2. Sold by weight: the note that the price is an estimate,
   quieter than the price it explains -- on the rail, an option, a tile, the
   featured block, a basket line and the checkout's payment step. */
.cs-rail__weighed {
  display: block;
  margin: 0 0 var(--cs-space-3);
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}
.cs-pill__weight { color: var(--cs-color-ink-muted); }
.cs-tile__weighed,
.cs-featured__weighed {
  display: block;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}
.cs-slip__weighed { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-step__weighed {
  margin: var(--cs-space-2) 0 0;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

/* The per-axis picker (ruling 60). A value no buyable variant reaches, given
   the other axes' choices, is drawn as struck through rather than removed:
   "there is no Large in Blue" is information, and a pill that vanishes is a
   pill somebody looks for. The note under the rows says why the button is
   held. */
.cs-pill[data-unavailable], .cs-pill:has(input[data-unavailable]) { color: var(--cs-color-ink-muted); border-style: dashed; text-decoration: line-through; }
.cs-pill--swatch .swatch {
  width: var(--cs-size-px-14-5);
  height: var(--cs-size-px-14-5);
  border-radius: var(--cs-radius-circle);
  border: 1px solid var(--cs-color-border-strong);
  background: var(--swatch);
  align-self: center;
}
.cs-buy__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-danger); font-weight: 600; }
.cs-buy__note[hidden] { display: none; }
.combination-note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-danger); font-weight: 600; }
.combination-note[hidden] { display: none; }
.buy-form select option[data-unavailable] { color: var(--cs-color-ink-muted); text-decoration: line-through; }

.cs-buy__row { display: grid; gap: var(--cs-space-1); }
.cs-buy__row:empty { display: none; }

/* How many, and the button, on one line. The word "Quantity" stays for a
   screen reader; the box says the number. */
.cs-buy__go {
  display: flex;
  align-items: stretch;
  gap: var(--cs-space-px-12);
}

.cs-buy__row--qty .cs-buy__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.cs-buy__qty,
.cs-quick__qty,
.cs-buy__text {
  width: 100%;
  max-width: 100%;
  min-height: var(--cs-space-px-56);
  padding: var(--cs-space-2) var(--cs-space-px-16);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface);
  font: inherit;
}

.cs-buy__qty,
.cs-quick__qty {
  width: 7.5rem;
  text-align: center;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* The quick look is narrower than the page, and the button's words need the
   room: a child theme's spaced capitals folded "Add to cart" in two. */
.cs-quick__qty { width: 5.5rem; }

.cs-buy__hint { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-buy__submit {
  flex: 1 1 auto;
  min-height: var(--cs-space-px-56);
  font-size: var(--cs-size-px-17);
}

/* The heart under the button, labeled, as a quiet pill. */
.cs-rail .cs-save { margin: 0 0 var(--cs-space-px-16); }

/* The notes a shopper reads before pressing the button: rows on hairlines, as
   the board draws "Delivered and planted Thursday", "Or collect today". */
.cs-trust {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  margin: var(--cs-space-px-8) 0 0;
  font-size: var(--cs-size-px-15);
}

.cs-trust dt,
.cs-trust dd {
  padding: var(--cs-space-px-14) 0;
  border-top: var(--cs-border-default);
}

.cs-trust dt { padding-right: var(--cs-space-px-14); font-weight: 600; color: var(--cs-color-ink); }
.cs-trust dd { margin: 0; color: var(--cs-color-ink-muted); }

.cs-prose { max-width: 68ch; font-size: var(--cs-size-px-17); line-height: 1.65; }
.cs-prose :is(h2, h3) { margin-top: var(--cs-space-5); }
.cs-prose img { max-width: 100%; height: auto; border-radius: var(--cs-radius-md); }

/* The type's panel: a paper card the page's width, its lines as a grid of
   soft boxes -- "Light, Part shade to sun", with a scale's bars under its
   words. The DOM is still the table it has always been; the boxes are how it
   is drawn, so a screen reader keeps a label for every answer. */
.cs-specs {
  margin-top: var(--cs-space-px-48);
  padding: clamp(var(--cs-space-px-20), 4vw, var(--cs-space-px-56));
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-xl);
  background: var(--cs-color-surface);
}

.cs-specs__heading {
  margin: 0 0 var(--cs-space-px-12);
  font-family: var(--cs-font-heading);
  font-size: clamp(1.8rem, 3vw, 2.5rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.cs-specs__blurb { margin: 0 0 var(--cs-space-px-28); color: var(--cs-color-ink-muted); max-width: 68ch; }

.cs-specs__table { display: block; width: 100%; font-size: var(--cs-size-px-15); }

.cs-specs__table tbody {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: var(--cs-space-px-16);
}

.cs-specs__table tbody + tbody { margin-top: var(--cs-space-px-16); }

.cs-specs__table tr {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-8);
  padding: var(--cs-space-px-20);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-muted);
}

.cs-specs__table th,
.cs-specs__table td {
  display: block;
  text-align: left;
  padding: 0;
  border: 0;
}

.cs-specs__table th { width: auto; font-weight: 500; color: var(--cs-color-ink-muted); font-size: var(--cs-size-px-14); }
.cs-specs__table td { font-weight: 600; font-size: var(--cs-size-px-17); color: var(--cs-color-ink); }

/* A section's own heading spans the grid, on no box. */
.cs-specs__table tr.cs-specs__section { grid-column: 1 / -1; padding: 0; background: transparent; }

.cs-specs__section th {
  padding-top: var(--cs-space-px-8);
  font-size: var(--cs-size-px-13);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cs-color-accent-text);
}

/* R4. The panel beside the buy button (a sticker's size and finish), and
   shut until opened (a long spec sheet). In the rail it is the rail's width,
   one box to a row. */
.cs-specs--rail { margin-top: var(--cs-space-px-24); padding: var(--cs-space-px-20); }
.cs-specs--rail .cs-specs__table tbody { grid-template-columns: minmax(0, 1fr); }
.cs-specs--collapsed > summary { cursor: pointer; }
.cs-specs--collapsed[open] > summary { margin-bottom: var(--cs-space-3); }

/* A scale: the words, then four bars under them as the board draws it. */
.cs-specs__row--scale td { display: flex; flex-direction: column-reverse; gap: var(--cs-space-px-10); }
.cs-scale { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--cs-space-px-4); width: 100%; }
.cs-scale__bar {
  display: block;
  height: var(--cs-space-px-6);
  border-radius: var(--cs-radius-sm);
  background: var(--cs-color-border);
}
.cs-scale__bar--on { background: var(--cs-color-brand); }
.cs-scale__words { display: block; }

.cs-chips,
.cs-lines { list-style: none; margin: 0; padding: 0; }
.cs-chips { display: flex; flex-wrap: wrap; gap: var(--cs-space-px-6); }
/* A panel's tags, and only those (F-446): written for any `.cs-chips li`, this
   also drew a second, tinted pill round each link to what is within a
   category -- whose row is a list of links, and already pills. */
.cs-specs__row--tags .cs-chips li {
  padding: var(--cs-space-px-4) var(--cs-space-px-10);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand-text);
  font-size: var(--cs-size-px-13-5);
  font-weight: 600;
}
.cs-lines li + li { margin-top: var(--cs-space-1); }
/* A panel's tags wrap inside their cell. `.cs-chips` is also the scrolling row
 * of filter links on the shop, the gallery and the journal, whose later
 * `flex-wrap: nowrap` won here and ran a third tag out of the cell, clipped
 * mid-word (F-267). */
.cs-specs__row--tags .cs-chips { flex-wrap: wrap; overflow: visible; }

.cs-pass {
  margin-left: var(--cs-space-2);
  padding: var(--cs-space-px-2) var(--cs-space-2);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-brand-tint);
  font-size: var(--cs-size-text-xs);
}

/* R5. The record the merchant chose -- a build record, a provenance --
   drawn as the details panel is, with its code in the receipt's mono. */
.cs-record__code {
  margin: 0 0 var(--cs-space-3);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-sm);
  letter-spacing: 0.02em;
}
.cs-record__note {
  margin: var(--cs-space-3) 0 0;
  font-size: var(--cs-size-text-sm);
  color: var(--cs-color-ink-muted);
}

/* A document list: a manual, a certificate, each with its kind beside it. */
.cs-docs { list-style: none; margin: var(--cs-space-3) 0 0; padding: 0; }
.cs-docs__item + .cs-docs__item { margin-top: var(--cs-space-1); }
.cs-docs__kind {
  margin-left: var(--cs-space-2);
  font-size: var(--cs-size-text-xs);
  color: var(--cs-color-ink-muted);
}

/* The lookup's answer, on the catalog head's line: its width, its gutter. */
.cs-lookup {
  max-width: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
}
.cs-lookup .cs-specs { margin-top: 0; }
.cs-lookup__none { max-width: 60ch; margin: 0; color: var(--cs-color-ink-muted); }

/* docs/22 Later 9. Registering a unit's warranty, under the record that was found:
   set off from it by a rule, on the same card. */
.cs-register {
  margin-top: var(--cs-space-5);
  padding-top: var(--cs-space-5);
  border-top: var(--cs-border-default);
}
.cs-register__heading { margin: 0 0 var(--cs-space-2); }

/* Through the year: a row per months line, a column per month -- the board's
   strip, one color per line. Fixed layout, so twelve columns share the width
   on a phone rather than pushing past it. */
.cs-year { margin-top: var(--cs-space-px-36); }
.cs-year__heading { margin: 0 0 var(--cs-space-px-12); font-family: var(--cs-font-body); font-size: var(--cs-size-px-15); font-weight: 700; }
.cs-year__table { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: var(--cs-space-px-4); }
.cs-year__table th {
  font-size: var(--cs-size-px-13);
  font-weight: 500;
  color: var(--cs-color-ink-muted);
  text-align: left;
}
.cs-year__table thead th { font-weight: 500; overflow: hidden; text-align: center; }
/* A fixed table takes its column widths from the first row, so the label
   column's width goes on the header row's first cell. */
.cs-year__table thead td:first-child { width: 22%; }
.cs-year__table tbody th { padding-right: var(--cs-space-2); }
@media (max-width: 47.99rem) {
  /* On a phone each month is its initial -- J F M A -- and still read in full: the
     rest of the name is kept from the eye, not cut to a width. One character's
     width showed a sliver of the next letter after a J and took the side off an O
     (F-447). */
  .cs-year__rest {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .cs-year__table thead td:first-child { width: 30%; }
}
.cs-year__cell {
  height: var(--cs-space-px-24);
  border-radius: var(--cs-radius-px-6);
  background: var(--cs-color-surface-sunken);
}
.cs-year__cell--on { background: var(--cs-color-brand); }
.cs-year__table tbody tr:nth-child(2) .cs-year__cell--on { background: var(--cs-color-brand-tint-border); }
.cs-year__table tbody tr:nth-child(3) .cs-year__cell--on { background: var(--cs-color-accent); }

.cs-tags { list-style: none; margin: var(--cs-space-5) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }
.cs-tags__tag {
  padding: var(--cs-space-px-4) var(--cs-space-px-12);
  border-radius: var(--cs-radius-pill);
  border: var(--cs-border-default);
  background: var(--cs-color-surface);
  font-size: var(--cs-size-px-13-5);
}

/* Reviews and related sit under the sheet at the page's width. */
.cs-reviews,
.cs-related {
  margin: 0 0 var(--cs-space-px-72);
}

/* The board's reviews: the score on the left, the words on the right. */
.cs-reviews {
  display: grid;
  gap: var(--cs-space-px-32);
}

@media (min-width: 52rem) {
  .cs-reviews { grid-template-columns: minmax(0, 18rem) minmax(0, 1fr); column-gap: var(--cs-space-px-48); align-items: start; }
}

.cs-reviews__head { display: grid; gap: var(--cs-space-px-10); align-content: start; }

.cs-reviews__heading {
  margin: 0;
  font-family: var(--cs-font-body);
  font-size: var(--cs-size-px-13);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cs-color-accent-text);
}

.cs-related__heading {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: clamp(1.8rem, 3vw, 2.5rem);
  font-weight: 400;
  letter-spacing: -0.02em;
}

.cs-reviews__score {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: clamp(3.5rem, 6vw, 5rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.03em;
}

.cs-reviews__summary { margin: 0; color: var(--cs-color-ink-muted); font-size: var(--cs-size-px-15); }

/* How the stars spread: one bar a row, drawn in SVG so no width is written
   into a style attribute. */
.cs-spread { list-style: none; margin: var(--cs-space-px-8) 0 0; padding: 0; display: grid; gap: var(--cs-space-px-8); }
.cs-spread__row {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr) 2rem;
  align-items: center;
  gap: var(--cs-space-px-10);
  font-size: var(--cs-size-px-13-5);
  color: var(--cs-color-ink-muted);
}
.cs-spread__bar { display: block; width: 100%; height: var(--cs-space-px-6); }
.cs-spread__track { fill: var(--cs-color-border); }
.cs-spread__fill { fill: var(--cs-color-brand); }
.cs-spread__star,
.cs-spread__count { font-variant-numeric: tabular-nums; }
.cs-spread__count { text-align: right; }

.cs-reviews__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--cs-space-px-20);
}

@media (min-width: 64rem) { .cs-reviews__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.cs-review {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-14);
  padding: var(--cs-space-px-28);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}

.cs-review__meta { display: flex; flex-wrap: wrap; gap: var(--cs-space-px-10); align-items: baseline; margin: 0; font-size: var(--cs-size-px-14); }
.cs-review__who { font-weight: 700; }
.cs-review__when { color: var(--cs-color-ink-muted); }
.cs-review__verified {
  font-size: var(--cs-size-px-13);
  font-weight: 600;
  color: var(--cs-color-brand-text);
}
.cs-review__body { margin: 0; font-size: var(--cs-size-px-16); line-height: 1.6; }

.cs-related .cs-tiles { max-width: none; padding-inline: 0; margin: var(--cs-space-px-24) 0 0; gap: var(--cs-space-px-24); }

@media (max-width: 51.99rem) {
  /* On a phone the options are the board's pills in a row -- "3 gal $52" --
     rather than cards. */
  .cs-buy__variants { display: flex; flex-wrap: wrap; gap: var(--cs-space-px-8); }
  .cs-buy__variants .cs-buy__label { flex-basis: 100%; }
  .cs-buy__variants .cs-pill {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--cs-space-px-6);
    min-height: var(--cs-space-px-44);
    padding: var(--cs-space-px-8) var(--cs-space-px-16);
    border-radius: var(--cs-radius-pill);
  }
  .cs-buy__variants .cs-pill__label { font-size: var(--cs-size-px-15); }
  /* docs/22 Later 2. A pill with more to say -- a price per unit and a usual
     weight beside the price -- takes a second line for a whole piece, rather
     than breaking "$3.00 / 100 g" inside itself. The name may still wrap. */
  .cs-buy__variants .cs-pill__price,
  .cs-buy__variants .cs-price__unit,
  .cs-buy__variants .cs-pill__weight,
  .cs-buy__variants .cs-pill__ships { white-space: nowrap; }

  /* On a phone the photograph runs to the screen's edges, as the phone board
     draws it, and the rail follows straight under it. */
  .cs-sheet__stage { margin-inline: calc(var(--cs-space-px-24) * -1); }
  .cs-stage { border-radius: 0; }
  .cs-strip { padding-inline: var(--cs-space-px-24); }
  .cs-strip__item { flex-basis: 30%; }
  .cs-buy__variants { grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr)); }
  .cs-specs__table tbody { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--cs-space-px-10); }
  .cs-specs__table tr { padding: var(--cs-space-px-14); }
}

/* ---- the basket slip ---- */

.cs-cart,
.cs-checkout {
  max-width: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
}

.cs-cart__head,
.cs-checkout__head { margin-bottom: var(--cs-space-5); }
.cs-cart__title,
.cs-checkout__title { margin: 0; }

.cs-cart__empty,
.cs-checkout__empty { font-size: var(--cs-size-text-lg); color: var(--cs-color-ink-muted); }

.cs-slip {
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
  border-top: var(--cs-border-default);
}

.cs-slip__line {
  display: grid;
  grid-template-columns: var(--cs-space-px-80) minmax(0, 1fr);
  grid-template-areas: "frame words" "frame controls" "frame figure";
  gap: var(--cs-space-2) var(--cs-space-3);
  padding: var(--cs-space-4) 0;
  border-bottom: var(--cs-border-default);
}

@media (min-width: 52rem) {
  .cs-slip__line {
    grid-template-columns: var(--cs-space-px-80) minmax(0, 1fr) auto auto;
    grid-template-areas: "frame words controls figure";
    align-items: center;
  }
}

.cs-slip__line--problem { background: var(--cs-color-danger-tint); }

.cs-slip__frame {
  grid-area: frame;
  display: block;
  overflow: hidden;
  border-radius: var(--cs-radius-sm);
  background: var(--cs-color-surface-muted);
}

.cs-slip__image,
.cs-slip__frame .cs-ph { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 0; }

.cs-slip__words { grid-area: words; display: flex; flex-direction: column; gap: var(--cs-space-px-2); min-width: 0; }
.cs-slip__title { font-family: var(--cs-font-heading); font-size: var(--cs-size-text-md); color: inherit; text-decoration: none; }
a.cs-slip__title:hover { text-decoration: underline; }
.cs-slip__variant,
.cs-slip__each { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-slip__note { font-size: var(--cs-size-text-sm); font-style: italic; }
.cs-slip__problem { font-size: var(--cs-size-text-sm); color: var(--cs-color-danger); font-weight: 600; }

.cs-slip__controls { grid-area: controls; display: flex; flex-wrap: wrap; gap: var(--cs-space-2); align-items: center; }
.cs-slip__seats { font-weight: 600; }

.cs-slip__qty {
  width: 4.5rem;
  padding: var(--cs-space-px-6) var(--cs-space-2);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-control);
  font: inherit;
  text-align: center;
}

.cs-slip__update { padding-block: var(--cs-space-px-6); }

.cs-slip__remove {
  padding: var(--cs-space-px-6) var(--cs-space-2);
  border: 0;
  background: none;
  color: var(--cs-color-ink-muted);
  font: inherit;
  font-size: var(--cs-size-text-sm);
  text-decoration: underline;
  cursor: pointer;
}

.cs-slip__remove:hover { color: var(--cs-color-danger); }
.cs-slip__figure { grid-area: figure; font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }

.cs-cart__sum {
  display: grid;
  gap: var(--cs-space-3);
  margin-left: auto;
  max-width: 26rem;
  padding: var(--cs-space-5);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-muted);
}

.cs-cart__subtotal { display: flex; justify-content: space-between; margin: 0; font-size: var(--cs-size-text-lg); }
.cs-cart__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-cart__checkout { text-align: center; }
.cs-cart__continue { justify-self: center; font-size: var(--cs-size-text-sm); }

/* ---- checkout: the steps and the summary ---- */

.cs-checkout__columns { display: grid; gap: var(--cs-space-6); align-items: start; }

@media (min-width: 60rem) {
  .cs-checkout__columns { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
  .cs-summary { position: sticky; top: var(--cs-space-4); }
}

.cs-steps { display: grid; gap: var(--cs-space-5); min-width: 0; }

/* A grid item's minimum width is its content's, and a WTForms input carries an
   intrinsic width of about twenty characters plus this theme's padding -- on
   a 375px phone that is wider than the column, and the whole form dragged the
   page 48px sideways. Found by measuring the captured page, not by any gate:
   every field in the checkout is bounded to its column here. */
.cs-step__fields input:not([type="radio"]):not([type="checkbox"]),
.cs-step__fields select,
.cs-step__fields textarea {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.cs-step {
  padding: var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}

.cs-step__heading {
  display: flex;
  gap: var(--cs-space-3);
  align-items: center;
  margin: 0 0 var(--cs-space-4);
  font-size: var(--cs-size-text-lg);
}

.cs-step__number {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: var(--cs-size-px-30);
  height: var(--cs-size-px-30);
  border-radius: var(--cs-radius-circle);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-sm);
}

.cs-step__fields { display: grid; gap: var(--cs-space-3); }
.cs-step__fields .field { margin: 0; }
.cs-step__action { margin: 0; }
.cs-step__hint { margin: 0; color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-sm); }

/* One choice row for delivery options, expedite and payment: the control,
   the label, the price on the right, the notes under. */
.cs-choice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--cs-space-1) var(--cs-space-3);
  align-items: start;
  margin: 0;
  padding: var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
}

.cs-choice:has(input:checked) { border-color: var(--cs-color-brand); background: var(--cs-color-brand-tint); }
.cs-choice input[type="radio"],
.cs-choice input[type="checkbox"] { margin: var(--cs-space-px-3) 0 0; }
.cs-choice label { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); align-items: baseline; font-weight: 600; cursor: pointer; }
.cs-choice__price { margin-left: auto; font-variant-numeric: tabular-nums; }
.cs-choice__note { flex-basis: 100%; font-weight: 400; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-choice__window { grid-column: 2; margin-top: var(--cs-space-2); }

.cs-address { margin: 0; padding: 0; border: 0; display: grid; gap: var(--cs-space-3); }
.cs-address__legend { padding: 0; margin-bottom: var(--cs-space-2); font-weight: 600; }
.cs-address__pair { display: grid; gap: var(--cs-space-3); }
@media (min-width: 40rem) { .cs-address__pair { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.cs-code { display: grid; gap: var(--cs-space-1); }
.cs-code__row { display: flex; gap: var(--cs-space-2); }
.cs-code__row input { flex: 1 1 auto; min-width: 0; }
.cs-code__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-brand-text); }

.cs-place { margin: 0; }
.cs-place__button { width: 100%; text-align: center; font-size: var(--cs-size-text-md); }

.cs-summary {
  min-width: 0;
  padding: var(--cs-space-5);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-muted);
}

.cs-summary__heading { margin: 0 0 var(--cs-space-3); font-size: var(--cs-size-text-lg); }

.cs-summary__lines {
  list-style: none;
  margin: 0 0 var(--cs-space-4);
  padding: 0;
  display: grid;
  gap: var(--cs-space-2);
}

.cs-summary__line { display: flex; justify-content: space-between; gap: var(--cs-space-3); font-size: var(--cs-size-text-sm); }
.cs-summary__line--problem { color: var(--cs-color-danger); }
.cs-summary__words { display: flex; flex-wrap: wrap; gap: var(--cs-space-1) var(--cs-space-2); min-width: 0; }
.cs-summary__qty { color: var(--cs-color-ink-muted); }
.cs-summary__note { flex-basis: 100%; font-style: italic; }
.cs-summary__problem { flex-basis: 100%; font-weight: 600; }
.cs-summary__figure { flex: 0 0 auto; font-variant-numeric: tabular-nums; }

.cs-totals {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--cs-space-1) var(--cs-space-3);
  margin: 0;
  padding-top: var(--cs-space-3);
  border-top: var(--cs-border-default);
  font-size: var(--cs-size-text-sm);
}

.cs-totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.cs-totals__grand { font-size: var(--cs-size-text-lg); font-weight: 600; padding-top: var(--cs-space-2); }
.cs-summary__back { margin: var(--cs-space-4) 0 0; font-size: var(--cs-size-text-sm); }

/* ---- the receipt ---- */

.cs-receipt {
  max-width: 56rem;
  margin: 0 auto var(--cs-space-7);
  padding-inline: var(--cs-space-4);
}

.cs-receipt__head { margin-bottom: var(--cs-space-5); }
.cs-receipt__title { margin: 0 0 var(--cs-space-2); }
.cs-receipt__lede { margin: 0; font-size: var(--cs-size-text-lg); color: var(--cs-color-ink-muted); }

.cs-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cs-space-3);
  margin: 0 0 var(--cs-space-5);
}

@media (min-width: 52rem) { .cs-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.cs-fact {
  padding: var(--cs-space-3) var(--cs-space-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
}

.cs-fact dt {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
}

.cs-fact dd { margin: var(--cs-space-1) 0 0; font-weight: 600; }
.cs-fact__note { display: block; font-weight: 400; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-fact--paid { border-color: var(--cs-color-brand-tint-border); background: var(--cs-color-brand-tint); }
.cs-fact--owing { border-color: var(--cs-color-accent-tint-border); background: var(--cs-color-accent-tint); }
.cs-fact--parcel { border-color: var(--cs-color-border-strong); }

.cs-receipt__lines {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--cs-space-5);
}

.cs-receipt__lines th,
.cs-receipt__lines td {
  text-align: left;
  vertical-align: top;
  padding: var(--cs-space-2) 0;
  border-bottom: var(--cs-border-hairline);
}

.cs-receipt__lines thead th {
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
  font-weight: 600;
  border-bottom: var(--cs-border-default);
}

.cs-receipt__line--shipping td { color: var(--cs-color-ink-muted); }
.cs-receipt__item { display: block; }
.cs-receipt__sku { display: block; font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-ink-muted); }
.cs-receipt__note { display: block; font-size: var(--cs-size-text-sm); font-style: italic; }

/* R5. The record a line went out with, in a row under the line: its serial,
   its log. The line's own row gives up its rule so the two read as one. */
.cs-receipt__line--recorded td { border-bottom: 0; padding-bottom: 0; }
.cs-receipt__records td { padding-top: 0; }
.cs-receipt__record { margin-top: var(--cs-space-2); font-size: var(--cs-size-text-sm); }
.cs-receipt__record-heading { display: block; font-weight: 600; }
.cs-receipt__record-lines {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--cs-space-px-2) var(--cs-space-3);
  margin: var(--cs-space-1) 0 0;
}
.cs-receipt__record-lines dt { color: var(--cs-color-ink-muted); }
.cs-receipt__record-lines dd { margin: 0; }
.cs-receipt__qty { text-align: center; width: 3rem; }
.cs-receipt__figure { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cs-receipt__totals th { font-weight: 400; color: var(--cs-color-ink-muted); text-align: right; padding-right: var(--cs-space-4); }
.cs-receipt__lines td.cs-receipt__figure { padding-left: var(--cs-space-3); }
.cs-receipt__grand th,
.cs-receipt__grand td { font-size: var(--cs-size-text-lg); font-weight: 600; color: var(--cs-color-ink); border-top: var(--cs-border-default); }

.cs-panel {
  margin: 0 0 var(--cs-space-4);
  padding: var(--cs-space-4) var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}

.cs-panel--pay { background: var(--cs-color-info-tint); }
.cs-panel__heading { margin: 0 0 var(--cs-space-2); font-size: var(--cs-size-text-lg); }
.cs-panel__body { margin: 0 0 var(--cs-space-2); }
/* F-340. The shop's transfer details, kept as typed: an account number on its own line. */
.cs-transfer-details {
  white-space: pre-line;
  overflow-wrap: anywhere;
  padding: var(--cs-space-3);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}
.cs-panel__note { margin: var(--cs-space-3) 0 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-proof { display: grid; gap: var(--cs-space-2); margin-top: var(--cs-space-3); }
.cs-proof .field { margin: 0; }
.cs-proof button { justify-self: start; }
.cs-proof__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-proof__list { margin: var(--cs-space-3) 0 0; padding-left: var(--cs-space-4); font-size: var(--cs-size-text-sm); }
.cs-proof__caption { margin-left: var(--cs-space-2); color: var(--cs-color-ink-muted); }

.cs-cards,
.cs-files,
.cs-tickets,
.cs-parcels { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-3); }

.cs-card { display: grid; gap: var(--cs-space-1); padding: var(--cs-space-3); border: var(--cs-border-default); border-radius: var(--cs-radius-sm); }
.cs-card__code { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-lg); font-weight: 700; letter-spacing: 0.08em; word-break: break-all; }
.cs-card__amount { color: var(--cs-color-ink-muted); }
.cs-card__expiry { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-file { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--cs-space-2); }
.cs-file__link { font-weight: 600; word-break: break-all; }
.cs-file__meta { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-ticket { padding: var(--cs-space-3); border: var(--cs-border-default); border-radius: var(--cs-radius-sm); }
.cs-ticket--unconfirmed { border-color: var(--cs-color-danger); background: var(--cs-color-danger-tint); }
.cs-ticket__title { margin: 0; font-weight: 600; }
.cs-ticket__seats { margin: 0 0 var(--cs-space-2); color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-sm); }
.cs-ticket__reference { margin: 0 0 var(--cs-space-2); display: grid; gap: var(--cs-space-px-2); }
.cs-ticket__reference code { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-lg); font-weight: 700; letter-spacing: 0.08em; word-break: break-all; }
.cs-ticket__label { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-ink-muted); }
.cs-ticket__problem { margin: 0; color: var(--cs-color-danger); font-weight: 600; }
.cs-ticket__held { margin: 0; font-weight: 600; }

.cs-parcel { display: flex; flex-wrap: wrap; gap: var(--cs-space-2) var(--cs-space-3); align-items: center; }
.cs-parcel__carrier { font-weight: 600; }
.cs-parcel__state { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-brand-text); }
.cs-parcel__number { font-family: var(--cs-font-mono); letter-spacing: 0.06em; }
.cs-parcel__none { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-parcel__track { margin-left: auto; }

.cs-address-block { font-style: normal; white-space: pre-line; }

.cs-receipt__foot { display: grid; gap: var(--cs-space-3); margin-top: var(--cs-space-5); padding-top: var(--cs-space-4); border-top: var(--cs-border-default); }
.cs-claim { display: grid; gap: var(--cs-space-2); padding: var(--cs-space-4); border-radius: var(--cs-radius-md); background: var(--cs-color-brand-tint); }
.cs-claim__words { margin: 0; }
.cs-claim button { justify-self: start; }
.cs-receipt__claimed { margin: 0; color: var(--cs-color-brand-text); font-weight: 600; }
.cs-receipt__document { margin: 0; }
.cs-receipt__keep { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-receipt__continue { margin: 0; }

/* ------------------------------------------------------------------ *
 * 9 · The rest of the storefront in the theme's own DOM (ruling 55, second half)
 *
 * Twelve pages: what's on, one event, the photograph wall, the journal and a
 * post, a composed page, find us, the legal shelf, privacy, the opt-out, a
 * conversation, a dead download link. Shared parts from section 8 are reused
 * rather than redrawn: `.cs-eyebrow`, `.cs-crumbs`, `.cs-chips`/`.cs-chip`,
 * `.cs-tiles`/`.cs-tile`, `.cs-panel`, `.cs-choice`, `.cs-prose`,
 * `.cs-stage`, `.cs-address-block`.
 * ------------------------------------------------------------------ */

/* ---- page heads shared by the twelve ---- */

.cs-whatson, .cs-wild, .cs-journal, .cs-findus, .cs-shelf, .cs-privacy, .cs-optout, .cs-thread,
.cs-post, .cs-page, .cs-event {
  max-width: none;
  margin: 0 0 var(--cs-space-7);
  padding-inline: 0;
}

.cs-whatson__head, .cs-wild__head, .cs-journal__head, .cs-findus__head, .cs-shelf__head,
.cs-privacy__head, .cs-optout__head, .cs-thread__head, .cs-post__head, .cs-page__head {
  margin-bottom: var(--cs-space-5);
}

.cs-whatson__title, .cs-wild__title, .cs-journal__title, .cs-findus__title, .cs-shelf__title,
.cs-privacy__title, .cs-optout__title, .cs-thread__title, .cs-post__title, .cs-page__title,
.cs-event__title { margin: 0 0 var(--cs-space-2); }

.cs-wild__blurb, .cs-findus__blurb, .cs-event__summary {
  max-width: 60ch;
  margin: 0 0 var(--cs-space-3);
  font-size: var(--cs-size-text-lg);
  color: var(--cs-color-ink-muted);
}

.cs-whatson__empty, .cs-wild__empty, .cs-journal__empty, .cs-findus__empty, .cs-upcoming__none,
.cs-dates__none, .cs-fares__none {
  font-size: var(--cs-size-text-lg);
  color: var(--cs-color-ink-muted);
  max-width: 60ch;
}

.cs-chip__count { color: var(--cs-color-ink-muted); margin-left: var(--cs-space-1); }
.cs-chip--on { background: var(--cs-color-surface-inverse); color: var(--cs-color-ink-inverse); border-color: var(--cs-color-surface-inverse); }
/* The chosen chip is the dark band's colors, and its count was still the
   paper's muted ink: 2.1:1 on the green (F-450). The band's own muted ink. */
.cs-chip--on .cs-chip__count { color: var(--cs-color-ink-inverse-muted); }
.cs-chips { flex-wrap: nowrap; }
.cs-chips nav, nav.cs-chips { display: flex; }

/* ---- what's on: the month and the rail ---- */

.cs-whatson__columns { display: grid; gap: var(--cs-space-6); align-items: start; }
@media (min-width: 60rem) { .cs-whatson__columns { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); } }

.cs-cal { min-width: 0; }
.cs-cal__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--cs-space-3); margin-bottom: var(--cs-space-3); }
.cs-cal__month { margin: 0; font-size: var(--cs-size-text-lg); }
.cs-cal__nav { display: flex; gap: var(--cs-space-2); align-items: center; }

.cs-cal__arrow {
  display: inline-grid;
  place-items: center;
  width: var(--cs-size-px-30);
  height: var(--cs-size-px-30);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-circle);
  color: var(--cs-color-ink);
  text-decoration: none;
  font-size: var(--cs-size-text-lg);
  line-height: 1;
}

.cs-cal__arrow:hover { border-color: var(--cs-color-ink); }
.cs-cal__today { font-size: var(--cs-size-text-sm); }

.cs-cal__grid {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: var(--cs-size-text-sm);
}

.cs-cal__dow {
  padding: var(--cs-space-1) 0;
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-ink-muted);
  font-weight: 600;
  text-align: left;
}

.cs-cal__day {
  vertical-align: top;
  height: var(--cs-space-px-64);
  padding: var(--cs-space-1);
  border: var(--cs-border-hairline);
}

.cs-cal__day--out { color: var(--cs-color-ink-muted); background: var(--cs-color-surface-muted); }
.cs-cal__day--today .cs-cal__num { background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); }
.cs-cal__num {
  display: inline-grid;
  place-items: center;
  min-width: var(--cs-size-px-22);
  height: var(--cs-size-px-22);
  padding-inline: var(--cs-space-px-3);
  border-radius: var(--cs-radius-pill);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
}

.cs-cal__chip {
  display: block;
  margin-top: var(--cs-space-px-3);
  padding: var(--cs-space-px-2) var(--cs-space-1);
  border-radius: var(--cs-radius-sm);
  background: var(--cs-color-brand-tint);
  border: 1px solid var(--cs-color-brand-tint-border);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-text-xs);
  line-height: 1.3;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cs-cal__chip:hover { border-color: var(--cs-color-brand); }
.cs-cal__chip--full { background: var(--cs-color-surface-muted); border-color: var(--cs-color-border-strong); color: var(--cs-color-ink-muted); }
.cs-cal__chip--canceled { background: var(--cs-color-danger-tint); border-color: var(--cs-color-danger); color: var(--cs-color-danger); text-decoration: line-through; }
.cs-cal__chip-time { font-family: var(--cs-font-mono); }
.cs-cal__chip-state { font-family: var(--cs-font-mono); text-transform: uppercase; letter-spacing: 0.04em; }
.cs-cal__note { margin: var(--cs-space-3) 0 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-upcoming { min-width: 0; }
.cs-upcoming__heading { margin: 0 0 var(--cs-space-3); font-size: var(--cs-size-text-lg); }
.cs-upcoming__list { list-style: none; margin: 0; padding: 0; border-top: var(--cs-border-default); }

.cs-upcoming__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--cs-space-3);
  align-items: start;
  padding: var(--cs-space-3) 0;
  border-bottom: var(--cs-border-default);
}

.cs-datebox {
  display: grid;
  place-items: center;
  min-width: var(--cs-space-px-56);
  padding: var(--cs-space-1) var(--cs-space-2);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  line-height: 1.1;
}

.cs-datebox__month { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--cs-color-accent-on-inverse); }
.cs-datebox__day { font-family: var(--cs-font-heading); font-size: var(--cs-size-px-26); font-weight: 700; }

.cs-upcoming__words { display: grid; gap: var(--cs-space-px-2); min-width: 0; }
.cs-upcoming__name { font-family: var(--cs-font-heading); font-size: var(--cs-size-text-md); color: inherit; text-decoration: none; }
.cs-upcoming__name:hover { text-decoration: underline; }
.cs-upcoming__when, .cs-upcoming__where { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-upcoming__extras { display: flex; flex-wrap: wrap; gap: var(--cs-space-1); }
.cs-upcoming__extra {
  padding: var(--cs-space-px-2) var(--cs-space-2);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-muted);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
}
.cs-upcoming__add { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); font-size: var(--cs-size-text-sm); }
.cs-upcoming__go {
  align-self: center;
  padding: var(--cs-space-px-6) var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  color: var(--cs-color-ink);
  text-decoration: none;
  font-size: var(--cs-size-text-sm);
  white-space: nowrap;
}
.cs-upcoming__go:hover { border-color: var(--cs-color-ink); }
.cs-posters { margin-top: var(--cs-space-6); }
.cs-posters .cs-tiles { padding-inline: 0; margin-bottom: 0; }

/* ---- one event: the sheet and the booking rail ---- */

.cs-event { display: grid; gap: var(--cs-space-6); grid-template-areas: "main" "rail"; }
@media (min-width: 60rem) {
  .cs-event { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); grid-template-areas: "main rail"; align-items: start; }
  .cs-event__rail { position: sticky; top: var(--cs-space-4); }
}
.cs-event__main { grid-area: main; min-width: 0; display: grid; gap: var(--cs-space-5); }
.cs-event__rail { grid-area: rail; min-width: 0; display: grid; gap: var(--cs-space-4); }
.cs-event__head { margin: 0; }
.cs-event__age { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-dates, .cs-fares {
  padding: var(--cs-space-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}

.cs-dates__heading, .cs-fares__heading { margin: 0 0 var(--cs-space-3); font-size: var(--cs-size-text-lg); }
.cs-dates__list { list-style: none; margin: 0 0 var(--cs-space-3); padding: 0; display: grid; gap: var(--cs-space-2); }

.cs-date {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--cs-space-1) var(--cs-space-3);
  align-items: baseline;
  padding: var(--cs-space-2) var(--cs-space-3);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface-muted);
}

.cs-date--canceled { text-decoration: line-through; color: var(--cs-color-ink-muted); }
.cs-date__when { display: grid; }
.cs-date__time { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-date__seats { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-brand-text); }
.cs-date__closed { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-danger); }
.cs-date .add-to-calendar { grid-column: 1 / -1; font-size: var(--cs-size-text-sm); }

.cs-fares__list { margin: 0 0 var(--cs-space-3); display: grid; gap: var(--cs-space-2); }
.cs-fare {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--cs-space-px-2) var(--cs-space-3);
  padding-bottom: var(--cs-space-2);
  border-bottom: var(--cs-border-hairline);
}
.cs-fare__name { font-weight: 600; }
.cs-fare__price { margin: 0; font-variant-numeric: tabular-nums; font-weight: 600; }
.cs-fare__note { margin: 0; grid-column: 1 / -1; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-book { display: grid; gap: var(--cs-space-3); padding-top: var(--cs-space-3); border-top: var(--cs-border-default); }
.cs-book .field { margin: 0; max-width: none; }
.cs-book__seats input { max-width: 7rem; }
.cs-book__optional { font-weight: 400; color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-xs); }
.cs-book__submit { justify-self: start; }
.cs-book__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ---- the photograph wall ---- */

.cs-wild__share { margin-top: var(--cs-space-2); }
.cs-wild__bar { display: grid; gap: var(--cs-space-3); margin-bottom: var(--cs-space-5); }
/* Grid items default to their content's minimum width; the search form's
   intrinsic width is the input's twenty characters plus a button, which on a
   375px phone is nine pixels more than the page (measured, V0.6.8). */
.cs-wild__bar > * { min-width: 0; }
.cs-wild__search { min-width: 0; }
.cs-wild__search .button { flex: 0 0 auto; }
@media (min-width: 52rem) {
  .cs-wild__bar { grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; }
}
.cs-wild__search { display: flex; gap: var(--cs-space-2); }
.cs-wild__input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: var(--cs-size-text-sm);
  padding: var(--cs-space-2) var(--cs-space-4);
  border: 1px solid transparent;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-muted);
}
.cs-wild__input:focus-visible { border-color: var(--cs-color-accent); background: var(--cs-color-surface); outline: none; }
.cs-wild__sort { display: flex; gap: var(--cs-space-1); }
.cs-wild__sortlink {
  padding: var(--cs-space-px-6) var(--cs-space-3);
  border-radius: var(--cs-radius-pill);
  color: var(--cs-color-ink-muted);
  text-decoration: none;
  font-size: var(--cs-size-text-sm);
}
.cs-wild__sortlink--on { background: var(--cs-color-surface-inverse); color: var(--cs-color-ink-inverse); }

.cs-photos {
  display: grid;
  gap: var(--cs-space-4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 40rem) { .cs-photos { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .cs-photos { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.cs-photo { margin: 0; display: grid; gap: var(--cs-space-2); min-width: 0; }
.cs-photo__link { color: inherit; text-decoration: none; }
.cs-photo__frame {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface-muted);
}
.cs-photo__image, .cs-photo__frame .cs-ph { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 0; }
.cs-photo__flag {
  position: absolute;
  top: var(--cs-space-2);
  left: var(--cs-space-2);
  padding: var(--cs-space-px-3) var(--cs-space-2);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.cs-photo--shop .cs-photo__frame { border: 1px solid var(--cs-color-accent-tint-border); }
.cs-photo__caption { display: grid; gap: var(--cs-space-px-2); font-size: var(--cs-size-text-sm); }
.cs-photo__title { font-family: var(--cs-font-heading); font-size: var(--cs-size-text-md); }
.cs-photo__handle { color: var(--cs-color-ink-muted); }
.cs-photo__tick {
  margin-left: var(--cs-space-1);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-brand-text);
}
.cs-photo__product { color: var(--cs-color-ink); }
.cs-photo__price { font-weight: 600; font-variant-numeric: tabular-nums; }
.cs-photo__rating, .cs-photo__note { color: var(--cs-color-ink-muted); }
.cs-wild__foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--cs-space-3); margin-top: var(--cs-space-5); }
.cs-wild__count { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-pager { display: flex; gap: var(--cs-space-2); }

/* ---- the journal and a post ---- */

.cs-articles { display: grid; gap: var(--cs-space-5); }
.cs-article { display: grid; gap: var(--cs-space-3); padding-bottom: var(--cs-space-5); border-bottom: var(--cs-border-default); }
.cs-article__link { display: grid; gap: var(--cs-space-3); color: inherit; text-decoration: none; }
@media (min-width: 52rem) { .cs-article__link { grid-template-columns: 20rem minmax(0, 1fr); align-items: start; } }
.cs-article__figure { display: block; overflow: hidden; border-radius: var(--cs-radius-md); background: var(--cs-color-surface-muted); }
.cs-article__figure img, .cs-article__figure .cs-ph { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 0; }
.cs-article__words { display: grid; gap: var(--cs-space-2); min-width: 0; }
.cs-article__meta { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-article__when { color: var(--cs-color-ink-muted); }
.cs-article__cat { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-accent-text); }
.cs-article__title { font-family: var(--cs-font-heading); font-size: var(--cs-size-px-26); line-height: 1.15; }
.cs-article__link:hover .cs-article__title { text-decoration: underline; }
.cs-article__excerpt { color: var(--cs-color-ink-muted); max-width: 60ch; }
.cs-article__more { font-size: var(--cs-size-text-sm); color: var(--cs-color-brand-text); }

.cs-tagged { padding: var(--cs-space-3) var(--cs-space-4); border-radius: var(--cs-radius-md); background: var(--cs-color-surface-muted); }
.cs-tagged--trending { background: var(--cs-color-accent-tint); }
.cs-tagged__label { margin: 0 0 var(--cs-space-2); font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-ink-muted); }
.cs-tagged__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--cs-space-3); }
.cs-tagged--rail .cs-tagged__list { flex-direction: column; }
.cs-tagged__item { display: grid; grid-template-columns: var(--cs-space-px-56) minmax(0, 1fr); gap: var(--cs-space-px-2) var(--cs-space-2); align-items: center; color: inherit; text-decoration: none; }
.cs-tagged__thumb { display: block; grid-row: span 2; overflow: hidden; border-radius: var(--cs-radius-sm); background: var(--cs-color-surface); }
.cs-tagged__thumb img, .cs-tagged__thumb .cs-ph { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 0; }
.cs-tagged__name { font-size: var(--cs-size-text-sm); font-weight: 600; }
.cs-tagged__price { font-size: var(--cs-size-text-sm); font-variant-numeric: tabular-nums; color: var(--cs-color-ink-muted); }

.cs-post { max-width: none; }
.cs-post__head .cs-crumbs { padding-inline: 0; margin-inline: 0; }
.cs-post__meta { margin: 0; color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-sm); }
.cs-post__hero { margin: 0 0 var(--cs-space-5); overflow: hidden; border-radius: var(--cs-radius-lg); background: var(--cs-color-surface-muted); }
.cs-post__hero img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.cs-post__columns { display: grid; gap: var(--cs-space-6); align-items: start; }
@media (min-width: 60rem) { .cs-post__columns { grid-template-columns: minmax(0, 1fr) 18rem; } }
.cs-post__body { max-width: 68ch; }
.cs-post__foot { margin-top: var(--cs-space-6); padding-top: var(--cs-space-4); border-top: var(--cs-border-default); }

/* The page's own width, not a 72rem column at its left. The two full-bleed
 * bands -- the traceability band and the data strip -- reach the window's edges
 * with `50% - 50vw`, which is only the window's middle when their parent is
 * centered; in a left-aligned 72rem body they sat 32px left, their words on the
 * window's edge (F-269). A page's prose keeps its own measure, as it does on
 * the home page. */
.cs-page__body { max-width: none; }

/* ---- find us ---- */

.cs-channels { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-3); }
@media (min-width: 40rem) { .cs-channels { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .cs-channels { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.cs-channel { margin: 0; }
.cs-channel__link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--cs-space-3);
  align-items: center;
  padding: var(--cs-space-3) var(--cs-space-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  color: inherit;
  text-decoration: none;
  transition: border-color 160ms ease, transform 160ms ease;
}
.cs-channel__link:hover { border-color: var(--cs-color-ink); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .cs-channel__link { transition: none; } }
.cs-channel__mark {
  display: inline-grid;
  place-items: center;
  width: var(--cs-size-px-38);
  height: var(--cs-size-px-38);
  border-radius: var(--cs-radius-circle);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
  font-family: var(--cs-font-heading);
  font-weight: 700;
  font-size: var(--cs-size-text-lg);
}
.cs-channel--etsy .cs-channel__mark { background: var(--cs-color-accent); }
.cs-channel--instagram .cs-channel__mark,
.cs-channel--facebook .cs-channel__mark,
.cs-channel--youtube .cs-channel__mark,
.cs-channel--pinterest .cs-channel__mark,
.cs-channel--tiktok .cs-channel__mark { background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); }
.cs-channel__words { display: grid; min-width: 0; }
.cs-channel__name { font-weight: 600; }
.cs-channel__detail { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-channel__go { color: var(--cs-color-ink-muted); }
.cs-findus__note { margin: var(--cs-space-4) 0 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ---- Find us: the places to come in person, a card each (docs/22 Later 3) ---- */
.cs-places { margin: var(--cs-space-6) 0 0; }
.cs-places__title { margin: 0 0 var(--cs-space-3); }
.cs-places__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-3); }
@media (min-width: 40rem) { .cs-places__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cs-place {
  display: grid;
  gap: var(--cs-space-2);
  align-content: start;
  min-width: 0;
  margin: 0;
  padding: var(--cs-space-4) var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}
.cs-place__name { margin: 0; font-size: var(--cs-size-text-lg); }
.cs-place__address { margin: 0; }
.cs-place__how { margin: 0; white-space: pre-line; overflow-wrap: anywhere; color: var(--cs-color-ink-muted); }
.cs-place__facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--cs-space-2) var(--cs-space-3); align-items: baseline; margin: var(--cs-space-2) 0 0; }
.cs-place__label { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-ink-muted); }
.cs-place__fact { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.cs-place__hours, .cs-place__shut { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-1); }
.cs-place__window { display: flex; flex-wrap: wrap; gap: 0 var(--cs-space-2); }
.cs-place__day { font-weight: 600; }
.cs-place__times { font-variant-numeric: tabular-nums; }
.cs-place__season { flex-basis: 100%; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ---- the legal shelf (`cs-shelf`: `cs-legal` is the footer's legal row) ---- */

.cs-shelf__columns { display: grid; gap: var(--cs-space-6); align-items: start; }
@media (min-width: 60rem) {
  .cs-shelf__columns { grid-template-columns: 16rem minmax(0, 1fr); }
  .cs-shelf__toc { position: sticky; top: var(--cs-space-4); }
}
.cs-shelf__toc { padding: var(--cs-space-4); border-radius: var(--cs-radius-md); background: var(--cs-color-surface-muted); }
.cs-shelf__toc-label { margin: 0 0 var(--cs-space-2); font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cs-color-ink-muted); }
.cs-shelf__toc-list { margin: 0; padding-left: var(--cs-space-4); display: grid; gap: var(--cs-space-1); font-size: var(--cs-size-text-sm); }
.cs-shelf__contact { margin: var(--cs-space-3) 0 0; font-size: var(--cs-size-text-sm); }
.cs-shelf__zones { display: grid; gap: var(--cs-space-6); min-width: 0; }
.cs-shelf__zone { scroll-margin-top: var(--cs-space-5); }
.cs-shelf__zone-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--cs-space-3); margin-bottom: var(--cs-space-3); padding-bottom: var(--cs-space-2); border-bottom: var(--cs-border-default); }
.cs-shelf__zone-title { margin: 0; font-size: var(--cs-size-text-lg); }
.cs-shelf__updated { margin: 0; font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-ink-muted); }

/* ---- privacy and the opt-out ---- */

.cs-privacy__own { max-width: 68ch; margin-bottom: var(--cs-space-6); }
.cs-privacy__unwritten { max-width: 68ch; margin: 0 0 var(--cs-space-6); color: var(--cs-color-ink-muted); }
.cs-disclosure { display: grid; gap: var(--cs-space-4); padding: var(--cs-space-5); border-radius: var(--cs-radius-lg); background: var(--cs-color-surface-muted); }
.cs-disclosure__head { display: grid; gap: var(--cs-space-2); }
.cs-disclosure__heading { margin: 0; font-size: var(--cs-size-text-lg); }
.cs-disclosure__lede, .cs-disclosure__none { margin: 0; max-width: 68ch; }
.cs-disclosure__version { margin: 0; font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-ink-muted); }

.cs-cookies { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-2); }
@media (min-width: 52rem) { .cs-cookies { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cs-cookie {
  display: grid;
  gap: var(--cs-space-px-2);
  padding: var(--cs-space-3);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}
.cs-cookie__name { font-family: var(--cs-font-mono); font-weight: 700; word-break: break-all; }
.cs-cookie__purpose { font-size: var(--cs-size-text-sm); }
.cs-cookie__declinable { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); letter-spacing: 0.04em; color: var(--cs-color-ink-muted); }
.cs-cookie--optional .cs-cookie__declinable { color: var(--cs-color-brand-text); }

.cs-purposes { display: grid; gap: var(--cs-space-2); }
.cs-purposes button { justify-self: start; }
.cs-purposes .cs-choice { background: var(--cs-color-surface); }

.cs-asks { display: grid; gap: var(--cs-space-2); }
@media (min-width: 52rem) { .cs-asks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cs-ask {
  display: grid;
  gap: var(--cs-space-px-2);
  padding: var(--cs-space-3) var(--cs-space-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
  color: inherit;
  text-decoration: none;
}
.cs-ask:hover { border-color: var(--cs-color-ink); }
.cs-ask__title { font-weight: 600; }
.cs-ask__note { font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

.cs-history { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--cs-space-2); }
.cs-history__row { display: flex; flex-wrap: wrap; gap: var(--cs-space-1) var(--cs-space-3); align-items: baseline; padding-bottom: var(--cs-space-2); border-bottom: var(--cs-border-hairline); font-size: var(--cs-size-text-sm); }
.cs-history__row--stale { color: var(--cs-color-ink-muted); }
.cs-history__when { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); color: var(--cs-color-ink-muted); }
.cs-history__stale { flex-basis: 100%; font-style: italic; }
.cs-history__what { min-width: 0; }
.cs-optout__history { margin-top: var(--cs-space-5); display: grid; gap: var(--cs-space-3); }

.cs-status {
  max-width: 44rem;
  padding: var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
  display: grid;
  gap: var(--cs-space-3);
}
.cs-status__stamp {
  justify-self: start;
  margin: 0;
  padding: var(--cs-space-px-3) var(--cs-space-2);
  border-radius: var(--cs-radius-pill);
  font-family: var(--cs-font-mono);
  font-size: var(--cs-size-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.cs-status--none .cs-status__stamp, .cs-status--off .cs-status__stamp { background: var(--cs-color-brand-tint); color: var(--cs-color-brand-text); border: 1px solid var(--cs-color-brand-tint-border); }
.cs-status--sharing .cs-status__stamp { background: var(--cs-color-danger-tint); color: var(--cs-color-danger); border: 1px solid var(--cs-color-danger); }
.cs-status__heading { margin: 0; font-size: var(--cs-size-text-lg); }
.cs-status__body { margin: 0; }
.cs-status__note { margin: 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-status__form { margin: 0; }

/* ---- a conversation ---- */

.cs-thread { max-width: 48rem; }
.cs-bubbles { list-style: none; margin: 0 0 var(--cs-space-5); padding: 0; display: grid; gap: var(--cs-space-3); }
.cs-bubble {
  max-width: 85%;
  padding: var(--cs-space-3) var(--cs-space-4);
  border-radius: var(--cs-radius-lg);
  display: grid;
  gap: var(--cs-space-1);
}
.cs-bubble--shop { justify-self: start; background: var(--cs-color-surface-muted); border-bottom-left-radius: var(--cs-radius-sm); }
.cs-bubble--you { justify-self: end; background: var(--cs-color-brand-tint); border: 1px solid var(--cs-color-brand-tint-border); border-bottom-right-radius: var(--cs-radius-sm); }
.cs-bubble__who { margin: 0; display: flex; gap: var(--cs-space-2); align-items: baseline; font-size: var(--cs-size-text-sm); font-weight: 600; }
.cs-bubble__when { font-family: var(--cs-font-mono); font-size: var(--cs-size-text-xs); font-weight: 400; color: var(--cs-color-ink-muted); }
.cs-bubble__body { margin: 0; white-space: pre-line; overflow-wrap: anywhere; }
.cs-reply { display: grid; gap: var(--cs-space-3); padding: var(--cs-space-4); border-radius: var(--cs-radius-lg); background: var(--cs-color-surface-muted); }
.cs-reply .field { margin: 0; max-width: none; }
.cs-reply textarea { width: 100%; box-sizing: border-box; }
.cs-reply button { justify-self: start; }
.cs-thread__keep { margin: var(--cs-space-4) 0 0; font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }

/* ---- a note card, for the dead download link ---- */

.cs-note-page { display: grid; place-items: center; min-height: 40vh; padding: var(--cs-space-6) var(--cs-space-4); }
.cs-note-card {
  max-width: 34rem;
  padding: var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
  display: grid;
  gap: var(--cs-space-2);
}
.cs-note-card__title { margin: 0; font-size: var(--cs-size-px-26); }
.cs-note-card__reason { margin: 0; }
.cs-note-card__next { margin: 0; color: var(--cs-color-ink-muted); }
.cs-note-card__back { margin: var(--cs-space-2) 0 0; font-size: var(--cs-size-text-sm); }

/* R6. A pack offered on its items' pages -- the plant board's "Complete the
   bed": the items side by side, the one-by-one total struck beside the pack's
   own price, and one button that adds the pack. */
.cs-bundle {
  margin-top: var(--cs-space-6);
  padding: var(--cs-space-4) var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}
.cs-bundle__heading { margin: 0 0 var(--cs-space-1); font-size: var(--cs-size-text-lg); }
.cs-bundle__blurb { margin: 0 0 var(--cs-space-3); color: var(--cs-color-ink-muted); }
.cs-bundle__items {
  list-style: none;
  margin: 0 0 var(--cs-space-4);
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: var(--cs-space-3);
}
/* A grid item narrower than a long title, not wider than its column. */
.cs-bundle__item { min-width: 0; }
.cs-bundle__link { display: grid; gap: var(--cs-space-1); color: inherit; text-decoration: none; }
.cs-bundle__frame {
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface-sunken);
}
.cs-bundle__image { display: block; width: 100%; height: 100%; object-fit: cover; }
.cs-bundle__name { font-size: var(--cs-size-text-sm); }
.cs-bundle__price { font-size: var(--cs-size-text-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.cs-bundle__buy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--cs-space-3);
}
.cs-bundle__total { margin: 0; font-variant-numeric: tabular-nums; }
.cs-bundle__pack-price { font-size: var(--cs-size-text-lg); font-weight: 600; }
.cs-bundle__saving { display: block; font-size: var(--cs-size-text-sm); color: var(--cs-color-brand-text); }
.cs-bundle__submit { flex: none; }

/* R6. The sticky buy bar: the price and the button again, submitting the
   page's own form. On a phone it sits at the end of the page and sticks to
   the foot of the screen until then; on a wide screen it sits under the sheet
   and sticks to the top once the buy box has scrolled away. */
.cs-buybar {
  display: none;
  align-items: center;
  gap: var(--cs-space-3);
  padding: var(--cs-space-2) var(--cs-space-4);
  background: var(--cs-color-surface);
  z-index: 20;
}
.cs-buybar__title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.cs-buybar__price { font-weight: 600; font-variant-numeric: tabular-nums; }
.cs-buybar__button { flex: none; }
/* R8: the phone board's bar runs edge to edge on paper, lifted by a shadow,
   the price large and the button taking what is left. */
.cs-buybar--phone {
  display: flex;
  position: sticky;
  bottom: 0;
  margin-inline: calc(var(--cs-space-px-24) * -1);
  padding: var(--cs-space-px-12) var(--cs-space-px-16);
  gap: var(--cs-space-px-16);
  border-top: var(--cs-border-default);
  box-shadow: var(--cs-shadow-overlay);
}
.cs-buybar--phone .cs-buybar__button { flex: 1 1 60%; min-height: var(--cs-space-px-52); }
.cs-buybar--phone .cs-buybar__price { font-size: var(--cs-size-px-18); font-weight: 700; line-height: 1.2; }
/* On a phone the bar is the price and the button, as the board draws it:
   a title cut to "Japanes..." says nothing the page above does not. */
.cs-buybar--phone .cs-buybar__title { display: none; }
.cs-buybar--phone .cs-buybar__price { flex: 1 1 auto; }
@media (min-width: 52rem) {
  .cs-buybar--phone { display: none; }
  .cs-buybar--wide {
    display: flex;
    position: sticky;
    top: 0;
    max-width: none;
    margin: 0 0 var(--cs-space-5);
    border-bottom: var(--cs-border-default);
  }
}

/* R6. A listing's sort and filters: one row of controls, then each
   attribute's values as a wrapping row of choices. */
.cs-browse {
  max-width: none;
  margin: 0 0 var(--cs-space-5);
  padding-inline: 0;
  display: grid;
  gap: var(--cs-space-3);
}
.cs-browse__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-2) var(--cs-space-4);
  margin: 0;
}
.cs-browse__facet {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-1) var(--cs-space-3);
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.cs-browse__facet legend { font-weight: 600; margin-bottom: var(--cs-space-1); }
.cs-browse__check { display: inline-flex; align-items: center; gap: var(--cs-space-1); }
.cs-browse__count { color: var(--cs-color-ink-muted); font-size: var(--cs-size-text-sm); }

/* R6. How far off free delivery is: a sentence and a bar that fills, the
   browser's own <progress>, colored like the shop's buttons. */
.cs-freebar { margin: 0 0 var(--cs-space-4); }
.cs-freebar__words { margin: 0 0 var(--cs-space-1); font-size: var(--cs-size-text-sm); }
.cs-freebar__bar {
  display: block;
  width: 100%;
  height: var(--cs-space-2);
  accent-color: var(--cs-color-brand);
}

/* ---- R7. The scheduler: the approved board "Scheduler -- book a visit" ----
   What to book and who with on the left; on its own sheet, the month beside
   the chosen day's times, where, and -- once a time is picked -- the details
   and the dark summary bar with its Book button. Every square, time and chip
   is a link; the state they share is the page's URL. */
.cs-booking {
  display: grid;
  grid-template-columns: minmax(0, 26.25rem) minmax(0, 1fr);
  gap: var(--cs-space-6);
  align-items: start;
  /* Vertical only: `.site-main` already carries the shop's gutter. */
  padding: var(--cs-space-px-40) 0 var(--cs-space-px-56);
}
.cs-booking__what { min-width: 0; }
.cs-booking__title {
  margin: 0 0 var(--cs-space-5);
  font-family: var(--cs-font-heading);
  font-size: clamp(var(--cs-size-text-xl), 3.4vw, 2.75rem);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.02em;
}
.cs-booking__lede { margin: 0 0 var(--cs-space-5); color: var(--cs-color-ink-muted); }
.cs-booking__services { display: grid; gap: var(--cs-space-px-10); margin: 0 0 var(--cs-space-5); }

.cs-service {
  display: flex;
  gap: var(--cs-space-4);
  padding: var(--cs-space-px-18) var(--cs-space-px-20);
  border: 1px solid var(--cs-color-border-strong);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  text-decoration: none;
}
.cs-service:hover { border-color: var(--cs-color-ink); }
.cs-service--on { border-color: var(--cs-color-brand); box-shadow: inset 0 0 0 1px var(--cs-color-brand); }
.cs-service__icon {
  display: inline-grid;
  place-items: center;
  flex: 0 0 var(--cs-space-px-46);
  width: var(--cs-space-px-46);
  height: var(--cs-space-px-46);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand);
}
.cs-service--on .cs-service__icon { background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); }
.cs-service__glyph { display: block; }
.cs-service__words { flex: 1 1 auto; min-width: 0; }
.cs-service__head { display: flex; gap: var(--cs-space-3); margin-bottom: var(--cs-space-1); }
.cs-service__name { font-weight: 700; }
.cs-service__price { margin-left: auto; font-weight: 600; white-space: nowrap; }
.cs-service__line { display: block; font-size: var(--cs-size-text-sm); line-height: 1.45; color: var(--cs-color-ink-muted); }

.cs-booking__label { margin: 0 0 var(--cs-space-px-10); font-size: var(--cs-size-text-sm); font-weight: 700; }
.cs-people { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); margin: 0; padding: 0; list-style: none; }
.cs-person {
  display: inline-flex;
  align-items: center;
  gap: var(--cs-space-2);
  min-height: var(--cs-space-px-44);
  padding: 0 var(--cs-space-4);
  border: 1px solid var(--cs-color-border-strong);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-text-sm);
  font-weight: 500;
  text-decoration: none;
}
.cs-person:hover { border-color: var(--cs-color-ink); }
.cs-person--on {
  border-color: var(--cs-color-brand);
  box-shadow: inset 0 0 0 1px var(--cs-color-brand);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand-text);
  font-weight: 700;
}
.cs-person__mark {
  display: inline-grid;
  place-items: center;
  width: var(--cs-space-px-32);
  height: var(--cs-space-px-32);
  margin-left: calc(var(--cs-space-px-10) * -1);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-accent);
  color: var(--cs-color-accent-contrast);
  font-size: var(--cs-size-px-13);
  font-weight: 700;
}

.cs-booking__sheet {
  display: grid;
  grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
  gap: var(--cs-space-6);
  min-width: 0;
  padding: var(--cs-space-px-30) var(--cs-space-6);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}
.cs-booking__month, .cs-booking__day { min-width: 0; }
.cs-booking__bar { display: flex; align-items: center; margin-bottom: var(--cs-space-px-18); }
.cs-booking__month-title {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-24);
  font-weight: 400;
  letter-spacing: -0.01em;
}
.cs-booking__arrows { display: flex; gap: var(--cs-space-px-6); margin-left: auto; }
.cs-booking__arrow {
  display: inline-grid;
  place-items: center;
  width: var(--cs-space-px-38);
  height: var(--cs-space-px-38);
  border: 1px solid var(--cs-color-border-strong);
  border-radius: var(--cs-radius-circle);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-text-lg);
  line-height: 1;
  text-decoration: none;
}
.cs-booking__arrow:hover { border-color: var(--cs-color-ink); }
.cs-booking__arrow--off { color: var(--cs-color-ink-faint); border-color: var(--cs-color-border); }

.cs-daygrid { width: 100%; border-collapse: separate; border-spacing: var(--cs-space-px-6); table-layout: fixed; margin: calc(var(--cs-space-px-6) * -1); }
.cs-daygrid__dow { padding-bottom: var(--cs-space-px-6); font-size: var(--cs-size-px-12); font-weight: 600; color: var(--cs-color-ink-muted); text-align: center; }
.cs-daygrid__cell { padding: 0; text-align: center; }
.cs-daygrid__day {
  display: grid;
  place-items: center;
  height: var(--cs-space-px-48);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand-text);
  font-size: var(--cs-size-px-15);
  font-weight: 600;
  text-decoration: none;
}
.cs-daygrid__day:hover { box-shadow: inset 0 0 0 1px var(--cs-color-brand); }
.cs-daygrid__day--on { background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); font-weight: 700; }
.cs-daygrid__day--closed { background: transparent; color: var(--cs-color-ink-faint); font-weight: 400; }
.cs-daygrid__day--closed:hover { box-shadow: none; }

.cs-booking__legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cs-space-px-7); margin: var(--cs-space-4) 0 0; font-size: var(--cs-size-px-13); color: var(--cs-color-ink-muted); }
.cs-booking__key { display: inline-block; width: var(--cs-space-px-12); height: var(--cs-space-px-12); border-radius: var(--cs-radius-px-4); }
.cs-booking__key--open { background: var(--cs-color-brand-tint); }
.cs-booking__key--closed { margin-left: var(--cs-space-px-12); border: 1px solid var(--cs-color-border-strong); }

.cs-booking__day { display: flex; flex-direction: column; }
.cs-booking__finish {
  grid-column: 1 / -1;
  min-width: 0;
  padding-top: var(--cs-space-5);
  border-top: var(--cs-border-hairline);
}
.cs-booking__day-title { margin: 0 0 var(--cs-space-1); font-size: var(--cs-size-text-md); font-weight: 700; }
.cs-booking__zone { margin: 0 0 var(--cs-space-4); font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-booking__hint { margin: 0 0 var(--cs-space-4); color: var(--cs-color-ink-muted); }
.cs-slots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cs-space-2);
  margin: 0 0 var(--cs-space-4);
  padding: 0;
  list-style: none;
}
.cs-slot {
  display: grid;
  place-items: center;
  height: var(--cs-space-px-48);
  border: 1px solid var(--cs-color-border-strong);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-px-15);
  font-weight: 500;
  text-decoration: none;
}
.cs-slot:hover { border-color: var(--cs-color-ink); }
.cs-slot--on { border-color: var(--cs-color-brand); background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); font-weight: 700; }
.cs-slot--taken { border-style: dashed; background: transparent; color: var(--cs-color-ink-faint); }
.cs-slot--taken:hover { border-color: var(--cs-color-border-strong); }

.cs-booking__zone-change { margin: 0 0 var(--cs-space-5); font-size: var(--cs-size-text-sm); }
.cs-booking__zone-change summary { cursor: pointer; color: var(--cs-color-ink-muted); }
.cs-booking__inline { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); margin: var(--cs-space-2) 0; }
.cs-booking__inline select, .cs-booking__inline input {
  min-width: 0;
  flex: 1 1 12rem;
  min-height: var(--cs-space-px-44);
  padding: 0 var(--cs-space-3);
  border: 1px solid var(--cs-color-border-strong);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-muted);
  font: inherit;
}
.cs-booking__where { margin: 0 0 var(--cs-space-2); font-size: var(--cs-size-text-sm); color: var(--cs-color-ink-muted); }
.cs-booking__verdict { display: flex; align-items: center; gap: var(--cs-space-2); margin: 0 0 var(--cs-space-4); font-size: var(--cs-size-px-13); font-weight: 600; }
.cs-booking__verdict--inside { color: var(--cs-color-brand-text); }
.cs-booking__verdict--outside { color: var(--cs-color-danger); }

.cs-booking__form { display: grid; gap: var(--cs-space-4); margin-top: var(--cs-space-4); }
.cs-booking__details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--cs-space-2) var(--cs-space-4);
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
/* The shop's fields keep a 34rem measure; here the grid is the measure. */
.cs-booking__details .field { margin: 0; min-width: 0; max-width: none; }
.cs-booking__details legend { padding: 0; }
.cs-booking__details .field input, .cs-booking__details .field textarea { width: 100%; }
.cs-booking__wide { grid-column: 1 / -1; }
.cs-booking__summary {
  display: flex;
  align-items: center;
  gap: var(--cs-space-px-18);
  margin-top: var(--cs-space-4);
  padding: var(--cs-space-px-18) var(--cs-space-px-20);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
}
.cs-booking__summary-words { flex: 1 1 auto; min-width: 0; }
.cs-booking__summary-title { margin: 0 0 var(--cs-space-px-3); font-size: var(--cs-size-px-15); font-weight: 700; }
.cs-booking__summary-line { margin: 0; font-size: var(--cs-size-px-13); color: var(--cs-color-brand-tint); }
.cs-booking__book {
  flex: 0 0 auto;
  min-height: var(--cs-space-px-48);
  padding: 0 var(--cs-space-px-24);
  border: 0;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-muted);
  color: var(--cs-color-brand-text);
  font: inherit;
  font-size: var(--cs-size-px-15);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
.cs-booking__book:hover { background: var(--cs-color-surface); }
.cs-booking__book:focus-visible { outline: var(--cs-space-px-2) solid var(--cs-color-accent); outline-offset: var(--cs-space-px-2); }

/* A shopper's own visit: the booking page's sheet, holding one visit. */
.cs-visit {
  max-width: 40rem;
  margin: 0 auto;
  padding: var(--cs-space-px-40) var(--cs-space-4);
}
.cs-visit__state {
  display: inline-block;
  margin: 0 0 var(--cs-space-5);
  padding: var(--cs-space-1) var(--cs-space-3);
  border-radius: var(--cs-radius-pill);
  font-size: var(--cs-size-text-sm);
  font-weight: 700;
}
.cs-visit__state--confirmed { background: var(--cs-color-brand-tint); color: var(--cs-color-brand-text); }
.cs-visit__state--held { background: var(--cs-color-accent-tint); color: var(--cs-color-accent-deep); }
.cs-visit__state--completed { background: var(--cs-color-surface-muted); color: var(--cs-color-ink-muted); }
.cs-visit__state--no_show, .cs-visit__state--canceled { background: var(--cs-color-danger-tint); color: var(--cs-color-danger); }
.cs-visit__facts {
  display: grid;
  gap: 0;
  margin: 0 0 var(--cs-space-5);
  padding: var(--cs-space-1) var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
}
.cs-visit__fact {
  display: grid;
  grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
  gap: var(--cs-space-4);
  padding: var(--cs-space-3) 0;
  border-bottom: var(--cs-border-hairline);
}
.cs-visit__fact:last-child { border-bottom: 0; }
.cs-visit__fact dt { font-weight: 600; color: var(--cs-color-ink-muted); }
.cs-visit__fact dd { margin: 0; }
.cs-visit__actions { display: flex; flex-wrap: wrap; gap: var(--cs-space-3); margin: 0 0 var(--cs-space-4); }
.cs-visit__note { margin: 0 0 var(--cs-space-3); color: var(--cs-color-ink-muted); }
.cs-visit__cancel { margin: var(--cs-space-4) 0 0; }
.cs-visit__cancel summary { cursor: pointer; font-weight: 600; color: var(--cs-color-danger); }
.cs-visit__cancel form { margin-top: var(--cs-space-3); }

/* The board is two columns and a sheet of two. Narrower than a laptop the
   page stacks its columns; on a phone the sheet stacks its halves too. */
@media (max-width: 64rem) {
  .cs-booking { grid-template-columns: minmax(0, 1fr); padding-block: var(--cs-space-6); }
}
@media (max-width: 47.99rem) {
  .cs-booking { padding-block: var(--cs-space-5); }
  .cs-booking__sheet { grid-template-columns: minmax(0, 1fr); padding: var(--cs-space-5) var(--cs-space-4); }
  .cs-booking__details { grid-template-columns: minmax(0, 1fr); }
  .cs-booking__summary { flex-direction: column; align-items: stretch; }
  .cs-booking__book { width: 100%; }
  .cs-daygrid { border-spacing: var(--cs-space-px-3); margin: calc(var(--cs-space-px-3) * -1); }
  .cs-daygrid__day { height: var(--cs-space-px-40); }
}

/* ------------------------------------------------------------------ *
 * 11 · The approved boards (R8)
 *
 * The eight boards the owner approved on 2026-09-27 are the specification
 * for this section: Home, the product pages, the two phone boards and the
 * scheduler. Paper cards on a cream page, the deep green that does the
 * talking, a terracotta that marks what to notice, Fraunces over Instrument
 * Sans. Everything below reads tokens; `theme.yaml` holds the values.
 * ------------------------------------------------------------------ */

/* ---- the eyebrow, as the boards set it: spaced capitals in the body face ---- */

.cs-eyebrow,
.eyebrow {
  font-family: var(--cs-font-body);
  font-size: var(--cs-size-px-13);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cs-color-accent-text);
}

/* ---- the home page: its blocks, the last one closing on the footer's margin ---- */

.cs-home > .block:last-child { margin-bottom: var(--cs-space-px-40); }
.farm-hero--notice { padding-block: var(--cs-space-px-24) 0; }

/* ---- a section's head: eyebrow and heading on the left, "See all" on the right ---- */

.cs-block-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--cs-space-px-12) var(--cs-space-px-24);
  margin: 0 0 var(--cs-space-px-28);
}

.cs-block-head__words { min-width: 0; }
.cs-block-head__words .cs-eyebrow { margin: 0 0 var(--cs-space-px-10); }

.cs-block-head__title {
  font-family: var(--cs-font-heading);
  font-size: clamp(2rem, 3.6vw, 2.9rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0;
}

.cs-block-head__more {
  display: inline-flex;
  align-items: center;
  gap: var(--cs-space-px-8);
  padding-block: var(--cs-space-px-6);
  color: var(--cs-color-ink);
  font-weight: 600;
  font-size: var(--cs-size-px-15-5);
  text-decoration: none;
}

.cs-block-head__more:hover { color: var(--cs-color-brand-text); }

/* ---- promises: the strip under the hero ---- */

.cs-promises { margin: 0 0 var(--cs-space-px-72); }

.cs-promises__list {
  list-style: none;
  margin: 0;
  padding: 0 var(--cs-space-px-16);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--cs-space-px-24) var(--cs-space-px-40);
}

.cs-promise {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--cs-space-px-14);
}

.cs-promise__mark {
  display: grid;
  place-items: center;
  width: var(--cs-space-px-44);
  height: var(--cs-space-px-44);
  border-radius: var(--cs-radius-px-12);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand);
}

.cs-promise__words { display: grid; gap: var(--cs-space-px-2); }
.cs-promise__title { font-size: var(--cs-size-px-16); font-weight: 600; color: var(--cs-color-ink); }
.cs-promise__text { font-size: var(--cs-size-px-14-5); line-height: 1.45; color: var(--cs-color-ink-muted); }

/* ---- the featured product: a split paper card ---- */

.cs-featured {
  display: grid;
  margin: 0 0 var(--cs-space-px-80);
  background: var(--cs-color-surface);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-xl);
  overflow: hidden;
}

@media (min-width: 52rem) {
  .cs-featured { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); }
}

.cs-featured__frame {
  position: relative;
  display: block;
  min-height: 20rem;
  background: var(--cs-color-surface-sunken);
}

.cs-featured__image {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cs-featured__frame .cs-ph { position: absolute; inset: 0; height: 100%; aspect-ratio: auto; border-radius: 0; }

.cs-featured__chips-on-photo {
  position: absolute;
  top: var(--cs-space-px-20);
  left: var(--cs-space-px-20);
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-px-8);
}

.cs-featured__chips-on-photo .cs-tile__ribbon { position: static; }

.cs-featured__flag {
  display: inline-flex;
  align-items: center;
  gap: var(--cs-space-px-6);
  padding: var(--cs-space-px-6) var(--cs-space-px-14);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-px-13-5);
  font-weight: 600;
}

.cs-featured__flag .icon { color: var(--cs-color-accent); fill: currentColor; }

.cs-featured__words {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--cs-space-px-14);
  padding: clamp(var(--cs-space-px-24), 4.6vw, var(--cs-space-px-64));
}

.cs-featured__words .cs-eyebrow { margin: 0; }

.cs-featured__title {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: clamp(2rem, 3.6vw, 3rem);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.cs-featured__title a { color: inherit; text-decoration: none; }
.cs-featured__title a:hover { color: var(--cs-color-brand-text); }

.cs-featured__blurb {
  margin: 0;
  font-size: var(--cs-size-px-17);
  line-height: 1.6;
  color: var(--cs-color-ink-muted);
  max-width: 34rem;
}

.cs-featured__facts {
  list-style: none;
  margin: var(--cs-space-px-4) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-px-8);
}

.cs-featured__fact {
  display: inline-flex;
  align-items: baseline;
  gap: var(--cs-space-px-6);
  padding: var(--cs-space-px-6) var(--cs-space-px-14);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface-muted);
  font-size: var(--cs-size-px-14);
  font-weight: 500;
  color: var(--cs-color-ink);
}

.cs-featured__fact-label { color: var(--cs-color-ink-muted); font-weight: 400; }

/* The price, the button and the heart along the bottom, the stock sentence at
   the far end, as the board lays them out. */
.cs-featured__buy {
  margin-top: auto;
  padding-top: var(--cs-space-px-28);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-px-14) var(--cs-space-px-20);
  width: 100%;
}

.cs-featured__price {
  margin: 0;
  display: grid;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.cs-featured__amount { font-size: var(--cs-size-px-30); font-weight: 700; color: var(--cs-color-ink); }
.cs-featured__unit { font-size: var(--cs-size-px-13-5); color: var(--cs-color-ink-muted); margin-top: var(--cs-space-px-4); }
.cs-featured__add { margin: 0; }
.cs-featured__buy .button-primary { min-height: var(--cs-space-px-52); padding-inline: var(--cs-space-px-32); }
.cs-featured__stock { margin: 0 0 0 auto; font-size: var(--cs-size-px-14); color: var(--cs-color-ink-muted); }

/* ---- the home grid, drawn with the catalog's own tile ---- */

.cs-home-grid { margin-bottom: var(--cs-space-px-80); }

.cs-tiles--shelf {
  max-width: none;
  margin: 0;
  padding: 0;
  gap: var(--cs-space-px-24);
}

@media (min-width: 64rem) { .cs-tiles--shelf { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---- the events band: the deep green, events on the left, a visit on the right ---- */

.cs-band {
  display: grid;
  gap: var(--cs-space-px-40) var(--cs-space-px-48);
  margin: 0 0 var(--cs-space-px-80);
  padding: clamp(var(--cs-space-px-24), 4.6vw, var(--cs-space-px-64));
  border-radius: var(--cs-radius-xl);
  background: var(--cs-color-surface-inverse);
  color: var(--cs-color-ink-inverse);
}

@media (min-width: 60rem) {
  .cs-band { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); align-items: start; }
  .cs-band--events-only { grid-template-columns: minmax(0, 1fr); }
}

.cs-band__eyebrow {
  margin: 0 0 var(--cs-space-px-10);
  font-size: var(--cs-size-px-13);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cs-color-brand-on-inverse);
}

.cs-band__title {
  margin: 0 0 var(--cs-space-px-28);
  font-family: var(--cs-font-heading);
  font-size: clamp(2rem, 3.6vw, 2.9rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--cs-color-ink-inverse);
}

.cs-band__events { min-width: 0; }

.cs-band__lead {
  display: grid;
  gap: var(--cs-space-px-20);
  padding: var(--cs-space-px-16);
  border: 1px solid var(--cs-color-border-inverse);
  border-radius: var(--cs-radius-lg);
  background: color-mix(in srgb, var(--cs-color-ink-inverse) 6%, transparent);
}

@media (min-width: 36rem) {
  .cs-band__lead { grid-template-columns: minmax(0, 13.75rem) minmax(0, 1fr); align-items: stretch; }
}

.cs-band__photo {
  display: block;
  overflow: hidden;
  border-radius: var(--cs-radius-md);
  aspect-ratio: 4 / 3;
  background: var(--cs-color-border-inverse);
}

.cs-band__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cs-band__photo .cs-ph { height: 100%; aspect-ratio: auto; border-radius: 0; }

/* Beside the words the picture takes its column's width and the row's height.
 * The 4:3 above worked the other way round there -- the row stretched the
 * picture's height to the words' and the ratio sized its width from that -- so
 * the picture ran out of its column and under the event's name (F-265). After
 * the rule it undoes, which it has to be to win. */
@media (min-width: 36rem) {
  .cs-band__photo { aspect-ratio: auto; min-height: 10rem; }
}

.cs-band__lead-words { display: flex; flex-direction: column; gap: var(--cs-space-px-10); min-width: 0; }

.cs-band__chips { display: flex; flex-wrap: wrap; gap: var(--cs-space-px-8); margin: 0; }

.cs-band__chip {
  padding: var(--cs-space-px-4) var(--cs-space-px-10);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-px-12-5);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cs-band__chip--quiet { background: var(--cs-color-border-inverse); color: var(--cs-color-ink-inverse); }

.cs-band__lead-title {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-24);
  font-weight: 500;
  line-height: 1.2;
}

.cs-band__lead-title a { color: var(--cs-color-ink-inverse); text-decoration: none; }
.cs-band__lead-title a:hover { text-decoration: underline; }

.cs-band__summary { margin: 0; font-size: var(--cs-size-px-14-5); line-height: 1.5; color: var(--cs-color-ink-inverse-muted); }

.cs-band__lead-foot {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-px-8) var(--cs-space-px-14);
}

.cs-band__price { font-size: var(--cs-size-px-18); font-weight: 700; font-variant-numeric: tabular-nums; }
.cs-band__seats { font-size: var(--cs-size-px-13-5); font-weight: 700; color: var(--cs-color-accent-on-inverse); }

.cs-band__tickets {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--cs-space-px-40);
  padding: var(--cs-space-px-8) var(--cs-space-px-20);
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-px-14-5);
  font-weight: 600;
  text-decoration: none;
}

.cs-band__tickets:hover { background: var(--cs-color-brand-tint); }

.cs-band__list { list-style: none; margin: var(--cs-space-px-16) 0 0; padding: 0; }

.cs-band__row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--cs-space-px-16);
  padding: var(--cs-space-px-16) var(--cs-space-px-4);
  border-bottom: 1px solid var(--cs-color-border-inverse);
}

.cs-band__date {
  font-size: var(--cs-size-px-13);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-color-brand-on-inverse);
}

.cs-band__row-title { color: var(--cs-color-ink-inverse); font-weight: 600; text-decoration: none; }
.cs-band__row-title:hover { text-decoration: underline; }
.cs-band__row-price { font-size: var(--cs-size-px-14-5); color: var(--cs-color-ink-inverse-muted); }

/* The visit card: paper on the green, the scheduler drawn small. */
.cs-visit-card {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-10);
  padding: clamp(var(--cs-space-px-20), 3vw, var(--cs-space-px-36));
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
}

.cs-visit-card .cs-eyebrow { margin: 0; }

.cs-visit-card__title {
  margin: 0;
  font-family: var(--cs-font-heading);
  font-size: clamp(1.6rem, 2.4vw, 2rem);
  font-weight: 400;
  line-height: 1.15;
}

.cs-visit-card__title a { color: inherit; text-decoration: none; }
.cs-visit-card__title a:hover { color: var(--cs-color-brand-text); }
.cs-visit-card__summary,
.cs-visit-card__note { margin: 0; font-size: var(--cs-size-px-15); line-height: 1.5; color: var(--cs-color-ink-muted); }
.cs-visit-card__label { margin: var(--cs-space-px-10) 0 0; font-size: var(--cs-size-px-14); font-weight: 600; }

.cs-visit-card__days,
.cs-visit-card__times {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--cs-space-px-8);
}

.cs-visit-card__days { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.cs-visit-card__times { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.cs-visit-day {
  display: grid;
  justify-items: center;
  gap: var(--cs-space-px-2);
  padding: var(--cs-space-px-10) var(--cs-space-px-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  text-decoration: none;
}

a.cs-visit-day:hover { border-color: var(--cs-color-ink); }
.cs-visit-day__name { font-size: var(--cs-size-px-13); color: var(--cs-color-ink-muted); }
.cs-visit-day__number { font-size: var(--cs-size-px-19); font-weight: 700; font-variant-numeric: tabular-nums; }

.cs-visit-day--on { background: var(--cs-color-brand); border-color: var(--cs-color-brand); color: var(--cs-color-brand-contrast); }
.cs-visit-day--on .cs-visit-day__name { color: var(--cs-color-brand-contrast); }

.cs-visit-day--shut { border-style: dashed; background: transparent; color: var(--cs-color-ink-faint); }
.cs-visit-day--shut .cs-visit-day__name { color: var(--cs-color-ink-faint); }
.cs-visit-day--shut .cs-visit-day__number { text-decoration: line-through; font-weight: 500; }

.cs-visit-time {
  display: grid;
  place-items: center;
  min-height: var(--cs-space-px-44);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  color: var(--cs-color-ink);
  font-weight: 500;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

a.cs-visit-time:hover { border-color: var(--cs-color-ink); }
.cs-visit-time--on {
  background: var(--cs-color-brand-tint);
  border: var(--cs-space-px-2) solid var(--cs-color-brand);
  font-weight: 700;
}

.cs-visit-card__go {
  display: grid;
  place-items: center;
  min-height: var(--cs-space-px-52);
  margin-top: var(--cs-space-px-10);
  padding: var(--cs-space-px-10) var(--cs-space-px-20);
  text-align: center;
  line-height: 1.3;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
  font-weight: 700;
  text-decoration: none;
}

.cs-visit-card__go:hover { background: var(--cs-color-brand-hover); }

.cs-visit-day:focus-visible,
.cs-visit-time:focus-visible,
.cs-visit-card__go:focus-visible,
.cs-band__tickets:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

/* ---- the journal block: photograph-led cards (`cs-notes`; `cs-journal` is the
   journal page's own) ---- */

.cs-notes { margin-bottom: var(--cs-space-px-80); }

.cs-notes__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--cs-space-px-24);
}

.cs-notes__card { min-width: 0; }

.cs-notes__link {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-px-8);
  color: inherit;
  text-decoration: none;
}

.cs-notes__frame {
  display: block;
  overflow: hidden;
  border-radius: var(--cs-radius-lg);
  aspect-ratio: 3 / 2;
  background: var(--cs-color-surface-sunken);
  margin-bottom: var(--cs-space-px-6);
}

.cs-notes__image { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 200ms ease; }
.cs-notes__link:hover .cs-notes__image { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) { .cs-notes__image { transition: none; } }
.cs-notes__frame .cs-ph { height: 100%; aspect-ratio: auto; border-radius: 0; }

.cs-notes__category {
  font-size: var(--cs-size-px-12-5);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cs-color-accent-text);
}

.cs-notes__title {
  font-family: var(--cs-font-heading);
  font-size: var(--cs-size-px-23);
  font-weight: 450;
  line-height: 1.2;
  color: var(--cs-color-ink);
}

.cs-notes__link:hover .cs-notes__title { color: var(--cs-color-brand-text); }

.cs-notes__excerpt {
  font-size: var(--cs-size-px-15);
  line-height: 1.55;
  color: var(--cs-color-ink-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cs-notes__meta { font-size: var(--cs-size-px-13-5); color: var(--cs-color-ink-muted); }

.cs-notes__link:focus-visible,
.cs-block-head__more:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-4);
  border-radius: var(--cs-radius-sm);
}

/* ---- the tile, as every board draws its cards ---- */

/* No box: the photograph, rounded, then the words on the page's own ground. */
.cs-tile__frame {
  border: 0;
  border-radius: var(--cs-radius-lg);
  background: var(--cs-color-surface-sunken);
}

.cs-tile__image,
.cs-tile__frame .cs-ph { aspect-ratio: 6 / 5; }

.cs-tile__link { gap: var(--cs-space-px-4); }

.cs-tile__meta {
  margin-top: var(--cs-space-px-10);
  font-size: var(--cs-size-px-13);
  color: var(--cs-color-ink-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cs-tile__title {
  margin-top: 0;
  font-size: var(--cs-size-px-21);
  font-weight: 400;
  line-height: 1.2;
  color: var(--cs-color-ink);
}

.cs-tile__meta + .cs-tile__title { margin-top: 0; }
.cs-tile__frame + .cs-tile__title { margin-top: var(--cs-space-px-10); }
.cs-tile__link:hover .cs-tile__title { color: var(--cs-color-brand-text); }

.cs-tile__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--cs-space-px-4) var(--cs-space-px-10);
}

.cs-tile__price { font-size: var(--cs-size-px-17); font-weight: 700; color: var(--cs-color-ink); }
.cs-tile__rating { font-size: var(--cs-size-px-13-5); color: var(--cs-color-ink-muted); }
.cs-tile__star { color: var(--cs-color-ink-muted); }

/* The chip on the photograph, in the board's four voices: the accent for
   "only a few left", the green for a sale, paper for everything else. */
.cs-tile__ribbon {
  top: var(--cs-space-px-12);
  left: var(--cs-space-px-12);
  padding: var(--cs-space-px-4) var(--cs-space-px-10);
  font-family: var(--cs-font-body);
  font-size: var(--cs-size-px-12-5);
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  border: 0;
}

.cs-tile__ribbon--low { background: var(--cs-color-accent); color: var(--cs-color-accent-contrast); border: 0; }
.cs-tile__ribbon--sale { background: var(--cs-color-brand); color: var(--cs-color-brand-contrast); border: 0; }
.cs-tile__ribbon--sold-out { background: var(--cs-color-ink); color: var(--cs-color-ink-inverse); border: 0; }
.cs-tile__ribbon--out-of-season { background: var(--cs-color-surface); color: var(--cs-color-accent-deep); border: 0; }

@media (max-width: 47.99rem) {
  .cs-promises__list { grid-template-columns: minmax(0, 1fr); padding: 0; }
  .cs-featured__frame { min-height: 16rem; }
  .cs-featured__buy .button-primary { flex: 1 1 auto; }
  .cs-featured__stock { margin-left: 0; flex-basis: 100%; }
  .cs-band { border-radius: var(--cs-radius-lg); }
  .cs-band__row { grid-template-columns: 3.75rem minmax(0, 1fr) auto; gap: var(--cs-space-px-10); }
  .cs-tiles--shelf { gap: var(--cs-space-px-20) var(--cs-space-px-14); }
  .cs-tile__title { font-size: var(--cs-size-px-18); }
  .cs-notes__list { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------------ *
 * 12 · The account screens (F-372)
 *
 * A shopper's own pages: orders, messages, saved things, addresses, the
 * profile, devices, privacy. Until V0.6.80 the shipped theme drew none of
 * them -- the menu was a bulleted list of eleven links, the forms were the
 * browser's own, and the orders table ran off a phone -- because the
 * reference theme drew the whole area in templates of its own, and it does
 * not ship. The markup is core's (`app/templates/account/`); no board draws
 * an account page, so these are the theme's own pieces put to it: its pills,
 * its fields, its panels and its hairlines.
 * ------------------------------------------------------------------ */

/* The menu: the board's pills in a row that wraps; on a phone, one row that
 * scrolls sideways inside itself rather than eleven rows of links. The page
 * the shopper is on is the filled pill. */
.account-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  list-style: none;
  margin: 0 0 var(--cs-space-6);
  padding: 0;
}

.account-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--cs-space-px-40);
  padding: 0 var(--cs-space-4);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-text-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.account-nav a:hover { border-color: var(--cs-color-ink); }

.account-nav a[aria-current="page"] {
  background: var(--cs-color-brand);
  border-color: var(--cs-color-brand);
  color: var(--cs-color-brand-contrast);
}

.account-nav a:focus-visible {
  outline: var(--cs-space-px-2) solid var(--cs-color-accent);
  outline-offset: var(--cs-space-px-2);
}

.account-nav__status {
  display: inline-flex;
  align-items: center;
  min-height: var(--cs-space-px-40);
  padding: 0 var(--cs-space-3);
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
  white-space: nowrap;
}

@media (max-width: 47.99rem) {
  .account-nav ul {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: var(--cs-space-2);
    scrollbar-width: thin;
  }
}

/* "Your address is not confirmed": a notice with its own button. */
.account-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-3);
  margin: 0 0 var(--cs-space-5);
  padding: var(--cs-space-3) var(--cs-space-5);
  border: var(--cs-border-default);
  border-color: var(--cs-color-accent-tint-border);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-accent-tint);
}

.account-notice p { margin: 0; }

/* The tables: orders, messages, a return's lines and a share's boxes.
 * Hairlines and a quiet head on the paper surface; on a phone the table
 * scrolls inside itself instead of carrying the page off the screen. */
.account-orders,
.account-boxes {
  width: 100%;
  margin: 0 0 var(--cs-space-5);
  border-collapse: collapse;
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
  font-size: var(--cs-size-text-sm);
}

.account-orders th,
.account-orders td,
.account-boxes th,
.account-boxes td {
  padding: var(--cs-space-3) var(--cs-space-4);
  border-bottom: var(--cs-border-hairline);
  text-align: left;
  vertical-align: top;
}

.account-orders thead th,
.account-boxes thead th {
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-xs);
  font-weight: 600;
  text-transform: uppercase;
}

.account-orders tbody tr:last-child > *,
.account-boxes tbody tr:last-child > * { border-bottom: 0; }

.account-orders td a { margin-right: var(--cs-space-2); }

@media (max-width: 47.99rem) {
  .account-orders:not(.account-orders--stacked),
  .account-boxes {
    display: block;
    overflow-x: auto;
  }

  /* The orders, on a phone: each order a card of its own, every cell its
   * column's name beside its value -- eight columns in a 327px table were an
   * items column seven lines tall. */
  .account-orders--stacked,
  .account-orders--stacked tbody,
  .account-orders--stacked tr { display: block; }

  .account-orders--stacked thead { display: none; }

  .account-orders--stacked tr {
    padding: var(--cs-space-3) var(--cs-space-4);
    border-bottom: var(--cs-border-hairline);
  }

  .account-orders--stacked tbody tr:last-child { border-bottom: 0; }

  /* The value flows as it would in its cell -- the document column is three
   * links, the total a price and a line under it -- and the column's name sits
   * in the gutter beside it. */
  .account-orders--stacked td {
    position: relative;
    display: block;
    padding: var(--cs-space-1) 0 var(--cs-space-1) 7rem;
    border-bottom: 0;
  }

  .account-orders--stacked td::before {
    content: attr(data-label);
    position: absolute;
    top: var(--cs-space-1);
    left: 0;
    width: 6.5rem;
    color: var(--cs-color-ink-muted);
    font-size: var(--cs-size-text-xs);
    font-weight: 600;
    text-transform: uppercase;
  }
}

.account-fee {
  display: block;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-xs);
}

.account-return { white-space: nowrap; }

/* A small fact in a pill: "Parcels come here", a box's week. */
.pill {
  display: inline-flex;
  align-items: center;
  padding: var(--cs-space-px-2) var(--cs-space-3);
  border: var(--cs-border-default);
  border-color: var(--cs-color-brand-tint-border);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-brand-tint);
  color: var(--cs-color-brand-text);
  font-size: var(--cs-size-text-xs);
  font-weight: 600;
}

/* The address book: a card for each address, side by side where there is room. */
.address-book {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: var(--cs-space-4);
  list-style: none;
  margin: 0 0 var(--cs-space-5);
  padding: 0;
}

.address-book__item,
.account-share {
  padding: var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}

.account-share { margin: 0 0 var(--cs-space-5); }

.address-book__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cs-space-2);
  margin: 0 0 var(--cs-space-2);
}

.address-book__item address {
  margin: 0 0 var(--cs-space-4);
  font-style: normal;
}

.address-book__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cs-space-2);
  margin: 0;
}

.address-book__actions form { margin: 0; }

/* The forms that are not built from `.field`: labels above boxes, as every
 * other form in the theme draws them. */
.stacked-form,
.account-profile,
.message-form,
.return-form,
.review-form { max-width: 34rem; }

.account-profile p {
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-1);
  margin: 0 0 var(--cs-space-4);
}

/* The photograph form's three numbered steps, each a label over its control. */
form.account-share > p {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--cs-space-1);
  margin: 0 0 var(--cs-space-4);
}

form.account-share input[type="file"] { max-width: 100%; font: inherit; font-size: var(--cs-size-text-sm); }

.account-profile p:has(> input[type="checkbox"]) {
  flex-direction: row;
  align-items: center;
  gap: var(--cs-space-px-10);
}

.account-profile label { font-size: var(--cs-size-text-sm); font-weight: 600; }

.account-profile input[type="text"],
.account-profile input[type="email"],
.review-form select,
.review-form textarea,
.account-share input[type="text"],
.account-share select {
  min-height: var(--cs-space-px-44);
  max-width: 100%;
  padding: var(--cs-space-2) var(--cs-space-4);
  border: var(--cs-border-strong);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font: inherit;
  font-size: var(--cs-size-text-sm);
}

.review-form textarea { border-radius: var(--cs-radius-md); }

/* How many of a line to send back: a small box in its table cell. */
.return-form input[type="number"] {
  width: 5rem;
  min-height: var(--cs-space-px-40);
  padding: 0 var(--cs-space-3);
  border: var(--cs-border-strong);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface);
  color: var(--cs-color-ink);
  font: inherit;
  font-size: var(--cs-size-text-sm);
}

.account-profile input[type="checkbox"] {
  width: var(--cs-space-px-20);
  height: var(--cs-space-px-20);
  margin: 0;
  accent-color: var(--cs-color-brand);
}

.account-profile__email,
.account-hint,
.account-empty,
.empty-state,
.wholesale-note {
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

.site-main .error {
  color: var(--cs-color-danger);
  font-size: var(--cs-size-text-sm);
}

/* A choice among things bought, in a fieldset: the reviews and the photographs. */
.review-form fieldset,
.account-share fieldset {
  margin: 0 0 var(--cs-space-4);
  padding: var(--cs-space-3) var(--cs-space-5);
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
}

.review-choice {
  display: flex;
  align-items: center;
  gap: var(--cs-space-2);
  margin: var(--cs-space-2) 0;
}

.review-choice input { accent-color: var(--cs-color-brand); }

/* Lists of facts -- security, reviews, photographs sent, devices, the
 * photograph feed: rows on one panel, ruled by hairlines. */
.account-security,
.account-reviews,
.account-submissions,
.account-feed,
.device-list {
  margin: 0 0 var(--cs-space-5);
  padding: 0;
  list-style: none;
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}

.account-security li,
.account-reviews li,
.account-submissions li,
.account-feed li,
.device-list li {
  padding: var(--cs-space-3) var(--cs-space-4);
  border-bottom: var(--cs-border-hairline);
}

.account-security li:last-child,
.account-reviews li:last-child,
.account-submissions li:last-child,
.account-feed li:last-child,
.device-list li:last-child { border-bottom: 0; }

.account-review__what,
.account-submission__what,
.device-agent {
  display: block;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.account-review__state,
.account-submission__state,
.device-current {
  display: inline-flex;
  margin: 0 0 var(--cs-space-1);
  padding: var(--cs-space-px-2) var(--cs-space-3);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface-sunken);
  color: var(--cs-color-ink);
  font-size: var(--cs-size-text-xs);
  font-weight: 600;
}

.account-review__note,
.account-submission__note,
.account-feed__when,
.device-ip,
.device-seen {
  display: block;
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

/* A share: what it is, the next box, and the boxes as a table. */
.account-share__meta,
.account-share__tally {
  color: var(--cs-color-ink-muted);
  font-size: var(--cs-size-text-sm);
}

.account-share__next { font-weight: 600; }

/* The sign-out buttons under the device list, one above the other. */
.device-list ~ form { margin: 0 0 var(--cs-space-3); }

.account-boxes .is-next > * { font-weight: 600; }

/* Wholesale: the steps and what an account brings. */
.wholesale-steps,
.wholesale-benefits {
  margin: 0 0 var(--cs-space-5);
  padding-left: var(--cs-space-5);
}

.wholesale-steps li,
.wholesale-benefits li { margin-bottom: var(--cs-space-2); }

/* Two-factor: the secret and the link are long unbroken strings, and on a
 * phone they ran off the screen; the recovery codes are a grid of codes. */
.totp-secret code,
.totp-uri code,
.recovery-codes code {
  font-family: var(--cs-font-mono);
  overflow-wrap: anywhere;
}

.totp-uri { font-size: var(--cs-size-text-sm); }

.recovery-codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 10rem), 1fr));
  gap: var(--cs-space-2);
  margin: 0 0 var(--cs-space-5);
  padding: var(--cs-space-4);
  list-style: none;
  border: var(--cs-border-default);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface);
}

/* Privacy: the one thing on these pages that cannot be undone. */
.page-account-privacy section { margin: 0 0 var(--cs-space-6); }

.warning {
  padding: var(--cs-space-3) var(--cs-space-5);
  border: var(--cs-border-default);
  border-color: var(--cs-color-accent-tint-border);
  border-radius: var(--cs-radius-md);
  background: var(--cs-color-accent-tint);
}

.site-main form button.danger {
  min-height: var(--cs-space-px-48);
  padding: var(--cs-space-px-12) var(--cs-space-px-28);
  border: 1px solid var(--cs-color-danger);
  border-radius: var(--cs-radius-control);
  background: var(--cs-color-surface);
  color: var(--cs-color-danger);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.site-main form button.danger:hover {
  background: var(--cs-color-danger);
  color: var(--cs-color-surface);
}

/* --- Products side by side (docs/22 Later 8) ------------------------------
 *
 * The catalog's own voice: eyebrow and title, then a table whose columns are
 * headed by the products as framed pictures with their names, and whose
 * first column -- what each row is -- stays put while the rest scroll on a
 * phone. The picker under a category's grid is core's, drawn in the same tones. */
.cs-compare { display: grid; gap: var(--cs-space-5); }
.cs-compare__head { display: grid; gap: var(--cs-space-2); }
.cs-compare__title { margin: 0; }
.cs-compare__lede { margin: 0; color: var(--cs-color-ink-muted); }
.cs-compare__scroll { overflow-x: auto; border: var(--cs-border-default);
  border-radius: var(--cs-radius-md); background: var(--cs-color-surface); }
.cs-compare__table { border-collapse: collapse; min-width: 100%;
  font-size: var(--cs-size-text-sm); }
.cs-compare__table th, .cs-compare__table td { padding: var(--cs-space-3) var(--cs-space-4);
  text-align: left; vertical-align: top; border-bottom: var(--cs-border-default); }
.cs-compare__table tbody th { position: sticky; left: 0; background: var(--cs-color-surface);
  color: var(--cs-color-ink-muted); font-weight: 600; }
.cs-compare__corner { background: var(--cs-color-surface); }
.cs-compare__product { min-width: 11rem; }
.cs-compare__link { display: grid; gap: var(--cs-space-2); color: inherit; text-decoration: none; }
.cs-compare__frame { display: block; aspect-ratio: 1; overflow: hidden;
  border-radius: var(--cs-radius-md); background: var(--cs-color-surface-muted); }
.cs-compare__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cs-compare__name { font-weight: 600; }
.cs-compare__note p { margin: 0; color: var(--cs-color-ink-muted); }
.compare-picker { margin-block: var(--cs-space-5); padding: var(--cs-space-3) var(--cs-space-4);
  border: var(--cs-border-default); border-radius: var(--cs-radius-md);
  background: var(--cs-color-surface); }
