/* ==========================================================================
   COMPONENTS · shared across every page (Frontend Dev #1)
   Spec: _studio/DESIGN.md §7. Tokens only. Glass tiers come from glass.css;
   this file positions and sizes them. Section index:
     1  Lens/field glue        8  Product card (pocket / ledger / rail)
     2  Announcement bar       9  Badges, notes, roast meter, + Add pill
     3  Capsule header+island 10  Shipping tube
     4  Sheets (dialogs)      11  Cart drawer lines, stepper, nudge, toast
     5  Finder popover + menu 12  Forms: input, select, switch, errors
     6  Buttons + links       13  Paper: marker, margin note, slip
     7  Brewer chips + tiles  14  Shared sections (strip, tiles, reviews,
                                  guide cards, closing CTA)  15 Footer
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Lens / field glue (DESIGN §2.3 + GRAPHICS §6.3)
   Graphics' tile path reads --field-stroke / --field-alpha / --field-w from
   the <use>. NOTE: Graphics' --field-w is a STROKE width, while DESIGN's
   --field-w (set on :root by glass.js) is the field SVG width. We keep both
   by overriding the stroke value on the <use> only, so the <svg> above it
   still reads the root width.
   -------------------------------------------------------------------------- */
use[href="#field"],
.lens use, .field-win use {
  --field-stroke: var(--zone-line);
  --field-alpha: var(--zone-glass-a);
  --field-w: var(--zone-glass-w);
}
.glass--well > .lens use { --field-alpha: var(--zone-well-a); --field-w: var(--zone-well-w); }
/* Band lens (glass.js data-lens-band): the PDP slab's rim refracts the flood
   band's own contours (DESIGN §7.12) at the band's 20 % line colour. */
.lens > svg { max-inline-size: none; }  /* base.css clamps svg to 100 %; the field must keep its own size */
.lens--band { color: color-mix(in oklab, var(--band-line, var(--zone-line)) 20%, transparent); }

/* Fixed chrome follows scroll with a bounded, repeating scroll-driven
   animation: each iteration is one 1200 px tile, iterations = scrollMax/1200
   (glass.js writes --lens-iter). Equivalent to −(scrollY mod 1200). This
   replaces glass.css's unbounded lens-follow so the field symbol can stay
   2400 × 3600 (cheap) instead of document-sized. */
@keyframes lens-follow-tile { from { --fy-scroll: 0px; } to { --fy-scroll: -1200px; } }
@supports (animation-timeline: scroll()) {
  .lens--fixed > svg, .lens-follow {
    animation: lens-follow-tile linear both;
    animation-iteration-count: var(--lens-iter, 1);
    animation-timeline: scroll(root block);
  }
}
html.glass-lite :is(.lens--fixed > svg, .lens-follow) { animation: none; }
@media (prefers-reduced-motion: reduce) { .lens--fixed > svg, .lens-follow { animation: none; } }

.field-win {
  position: absolute; left: 0; top: 0;
  width: 2400px; height: 3600px;
  overflow: visible;
  transform: translateY(var(--fy-scroll));
}

/* Capsule lane: a fixed glass zone behind the capsule (Pine 18 %, feathered) */
.capsule-lane {
  position: fixed;
  inset: 0 0 auto 0;
  block-size: calc(var(--capsule-top) + var(--capsule-h) + var(--space-4));
  z-index: var(--z-field);
  pointer-events: none;
  overflow: hidden;
  -webkit-mask: linear-gradient(#000 55%, transparent);
          mask: linear-gradient(#000 55%, transparent);
}
:root:is([data-glass="off"], [data-transparency="reduced"]) .capsule-lane { display: none; }
@media (prefers-reduced-transparency: reduce), (forced-colors: active) { .capsule-lane { display: none; } }

/* A glass zone you can drop into any positioned box (hero panel, CTA band) */
.zone-field { position: absolute; inset: 0; overflow: hidden; pointer-events: none; border-radius: inherit; }
.zone-field > svg { position: absolute; left: 0; top: 0; width: 2400px; height: 3600px; overflow: visible; }
.zone-field--well use { --field-alpha: var(--zone-well-a); }


/* --------------------------------------------------------------------------
   2. Announcement bar (§7.1)  · static in each page, wired by shell.js
   -------------------------------------------------------------------------- */
.announce {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-block-size: var(--announce-h);
  padding: var(--space-2) var(--tap) var(--space-2) var(--space-4);
  background: var(--ink);
  color: var(--on-ink);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-weight: var(--fw-strong);
  text-align: center;
}
.announce__close {
  position: absolute; inset-block: 0; inset-inline-end: 0;
  display: grid; place-items: center;
  inline-size: var(--tap);
  min-block-size: var(--tap);
  color: var(--on-ink);
}
html:not(.js) .announce, html.announce-off .announce { display: none; }
.announce__short { display: none; }
@media (max-width: 479.98px) {
  .announce__long { display: none; }
  .announce__short { display: inline; }
}


/* --------------------------------------------------------------------------
   3. Capsule header (§7.2) + status island (§7.3)
   The header is a sticky, non-glass slot of fixed height; the capsule is
   absolutely placed inside it, so the island can grow without shifting
   the page.
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: var(--capsule-top);
  z-index: var(--z-chrome);
  block-size: var(--capsule-h);
  margin: var(--capsule-top) var(--capsule-x) 0;
}
@media (min-width: 1024px) {
  .site-header { margin-inline: max(var(--capsule-x), (100% - var(--container)) / 2); }
}
/* Short viewports (200 % zoom, landscape phones): the header scrolls away with
   the page so the announcement bar and its close button stay reachable. Not
   `static`: the absolutely placed capsule needs this box as its anchor (B-04). */
@media (max-height: 500px) { .site-header { position: relative; top: auto; } }

.capsule {
  --r: var(--r-pill);
  position: absolute;
  inset: 0 0 auto 0;
  min-block-size: var(--capsule-h);
  transition:
    transform var(--t-hide) var(--ease-in),
    --shell-a var(--t-zone) var(--ease-std), --plate-a var(--t-zone) var(--ease-std),
    --sat var(--t-zone) var(--ease-std), --bright var(--t-zone) var(--ease-std), --lens-o var(--t-zone) var(--ease-std);
}
.capsule.is-hidden:not(:focus-within) { transform: translateY(var(--hide-shift)); }
.capsule[data-compact] { box-shadow: var(--shadow-lift); }   /* motion hook: compaction (see REVIEWS) */

.capsule__bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-2);
}
.capsule__bar > :first-child { justify-self: start; }
.capsule__bar > :last-child { justify-self: end; }
.capsule .plate { min-block-size: var(--tap); }

.capsule__menu {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding-inline: var(--space-3) var(--space-4);
  border-radius: var(--r-pill);
  font-size: var(--fs-label); font-weight: var(--fw-strong); letter-spacing: var(--tr-label);
}
.capsule__logo {
  display: inline-flex; align-items: center;
  padding-inline: calc(var(--space-3) + 2px);
  border-radius: var(--r-pill);
  color: var(--ink);
}
.capsule__logo svg { block-size: var(--logo-h); inline-size: auto; }
.capsule__nav { display: none; border-radius: var(--r-pill); }
.capsule__nav ul { display: flex; gap: var(--space-4); padding-inline: var(--space-4); list-style: none; padding-block: 0; margin: 0; }
.capsule__link {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-block-size: var(--tap);
  margin-block: -1px;
  padding-inline: var(--space-1);
  font-size: var(--fs-ui); font-weight: var(--fw-ui);
  text-decoration: none; color: var(--ink);
  text-underline-offset: 6px; text-decoration-thickness: 2px; text-decoration-color: var(--pine);
}
.capsule__link[aria-current="page"] { text-decoration-line: underline; }
@media (hover: hover) and (pointer: fine) {
  .capsule__link:hover { text-decoration-line: underline; text-decoration-color: color-mix(in oklab, var(--pine) 50%, transparent); }
  .capsule__link[aria-current="page"]:hover { text-decoration-color: var(--pine); }
  .plate.squish:hover, .capsule__nav:hover { background-image: linear-gradient(color-mix(in oklab, var(--oat) 55%, transparent) 0 0); }
}
.capsule__finder[aria-expanded="true"] .icon { transform: rotate(180deg); }
.capsule__finder .icon { transition: transform var(--t-fast) var(--ease-std); }

.capsule__cart {
  position: relative;
  display: inline-grid; place-items: center;
  inline-size: var(--tap); block-size: var(--tap);
  border-radius: var(--r-pill);
  color: var(--ink);
}
.capsule__count {
  position: absolute; inset-block-start: 1px; inset-inline-end: 1px;
  display: grid; place-items: center;
  min-inline-size: var(--badge-dot); block-size: var(--badge-dot);
  padding-inline: var(--space-1);
  border-radius: var(--r-pill);
  background: var(--pine); color: var(--on-pine);
  font-size: var(--fs-mini); font-weight: var(--fw-strong); line-height: 1;
  font-variant-numeric: tabular-nums;
}
@keyframes cart-stretch { 45% { transform: scaleX(var(--stretch-scale)); } }
.capsule__cart.is-stretch { animation: cart-stretch var(--t-stretch) var(--ease-out); }

@media (min-width: 1024px) {
  .capsule__bar { grid-template-columns: auto 1fr auto; }
  .capsule__menu { display: none; }
  .capsule__logo { grid-column: 1; }
  .capsule__nav { display: block; grid-column: 2; justify-self: center; }
  .capsule__cart { grid-column: 3; }
}
/* static (no-JS) fallback header: same geometry */
.site-header:not(.is-enhanced) .capsule__bar > .capsule__nav { display: none; }
@media (min-width: 1024px) { .site-header:not(.is-enhanced) .capsule__bar > .capsule__nav { display: block; } }

/* Status island: the same element, second state (motion hook data-state) */
.capsule__island { display: none; }
.capsule[data-state="island"] { --r: var(--r-island); }
.capsule[data-state="island"] .capsule__bar { display: none; }

/* ---- Compact capsule (DESIGN §7.2): Menu (icon) · monogram · page tools · Cart.
   shell.js setCapsuleTools(html) + setCapsuleCompact(on). Used by Shop < 1024. */
.capsule__tools { display: flex; gap: var(--space-2); justify-self: end; }
.capsule__tools[hidden] { display: none; }
.capsule__tool {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-block-size: var(--tap); padding-inline: var(--space-3);
  border-radius: var(--r-pill);
  font-size: var(--fs-label); font-weight: var(--fw-strong); white-space: nowrap;
}
.capsule[data-tools="compact"] .capsule__bar { grid-template-columns: auto auto minmax(0, 1fr) auto; }
.capsule[data-tools="compact"] .capsule__menu-text { display: none; }
.capsule[data-tools="compact"] .capsule__menu { min-inline-size: var(--tap); padding-inline: 0; justify-content: center; }
.capsule[data-tools="compact"] .capsule__logo { inline-size: var(--tap); padding-inline: 0; display: inline-grid; place-items: center; }
.capsule[data-tools="compact"] .capsule__logo svg { inline-size: var(--logo-h); block-size: var(--logo-h); }
.capsule[data-state="island"] .capsule__island {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--plate-inset);
  align-items: center;
  animation: island-in var(--t-spring) var(--ease-spring);
}
@keyframes island-in { from { opacity: 0; transform: scale(.98); } }
.island__msg {
  display: grid; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  min-block-size: var(--tap);
  align-content: center;
}
.island__text { display: flex; align-items: center; gap: var(--space-2); min-inline-size: 0; font-size: var(--fs-ui); line-height: var(--lh-ui); font-weight: var(--fw-strong); }
.island__text .icon { color: var(--pine); flex: none; }
/* "Added {name} · {size} · {grind}": the name truncates first (B-15) */
.island__msg { min-inline-size: 0; }
.island__line { display: flex; gap: .3em; min-inline-size: 0; white-space: nowrap; }
.island__added, .island__meta { flex: none; }
.island__name { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; }
.island__actions { display: contents; }
/* < 768: the message takes the whole first row (so the name has room), the
   actions share row 2: Edit grind · View cart · Close (B-15) */
.island__msg { grid-column: 1 / -1; grid-row: 1; }
.island__edit {
  grid-column: 1; grid-row: 2; justify-self: end;
  min-block-size: var(--tap); padding-inline: var(--space-4);
  border-radius: var(--r-pill);
  font-size: var(--fs-ui); font-weight: var(--fw-strong);
}
.island__view { grid-column: 2; grid-row: 2; }
.island__actions [data-island-close] { grid-column: 3; grid-row: 2; justify-self: end; }
.capsule .island__view { min-block-size: var(--tap); }   /* 44, beats .btn--sm (B-15) */
@media (min-width: 768px) {
  .capsule[data-state="island"] { min-block-size: var(--island-h); }
  .capsule[data-state="island"] .capsule__island { grid-template-columns: minmax(0, 1fr) auto auto auto; min-block-size: calc(var(--island-h) - var(--plate-inset) * 2); }
  .island__msg, .island__edit, .island__view, .island__actions [data-island-close] { grid-row: 1; grid-column: auto; }
}


/* --------------------------------------------------------------------------
   4. Sheets (§2.2 T2, §7.4, §7.15, §7.11 quick-add)
   <dialog class="sheet sheet--right|--left|--bottom glass-sheet">
     .lens · .sheet__head (plate--solid) · [extra row] · .sheet__body (scrolls)
     · .sheet__toasts · .sheet__foot (plate--solid) · .sheet__live
   -------------------------------------------------------------------------- */
.sheet {
  position: fixed;
  margin: 0;
  max-inline-size: none;
  max-block-size: none;
  overflow: visible;
  color: var(--ink);
}
dialog.sheet[open] {
  display: flex;
  flex-direction: column;
  gap: var(--plate-inset);
  animation: sheet-in var(--t-sheet-in) var(--ease-sheet);
}
dialog.sheet[open]::backdrop { animation: scrim-in var(--t-scrim) var(--ease-std); }
dialog.sheet.is-closing { animation: sheet-out var(--t-sheet-out) var(--ease-in) forwards; }
dialog.sheet.is-closing::backdrop { animation: scrim-out var(--t-sheet-out) var(--ease-in) forwards; }
@keyframes sheet-in { from { transform: var(--sheet-from); opacity: 0; } }
@keyframes sheet-out { to { transform: var(--sheet-from); opacity: 0; } }
@keyframes scrim-in { from { opacity: 0; } }
@keyframes scrim-out { to { opacity: 0; } }
dialog.sheet:focus-visible { outline: none; }

.sheet--right {
  --sheet-from: translateX(var(--sheet-shift));
  inset: 0 0 0 auto;
  inline-size: 100vw;
  block-size: 100dvh;
  border-radius: 0;
}
@media (min-width: 600px) { .sheet--right { inline-size: var(--drawer-w); border-radius: var(--r-sheet) 0 0 var(--r-sheet); } }
.sheet--left {
  --sheet-from: translateX(calc(var(--sheet-shift) * -1));
  inset: 0 auto 0 0;
  inline-size: var(--menu-w);
  block-size: 100dvh;
  border-radius: 0 var(--r-sheet) var(--r-sheet) 0;
}
.sheet--bottom {
  --sheet-from: translateY(var(--sheet-shift));
  inset: auto 0 0 0;
  inline-size: 100%;
  max-block-size: 86dvh;
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  padding-block-end: calc(var(--plate-inset) + env(safe-area-inset-bottom));
}
@media (min-width: 768px) {
  .sheet--bottom { inline-size: min(560px, 100% - var(--space-6)); inset: auto 0 var(--space-4) 0; margin-inline: auto; border-radius: var(--r-sheet); }
}
.sheet__handle {
  position: absolute; inset-block-start: var(--space-2); inset-inline: 0; margin-inline: auto;
  inline-size: 36px; block-size: 4px; border-radius: var(--r-pill);
  background: color-mix(in oklab, var(--ink) 24%, transparent);
}
.sheet__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  min-block-size: calc(var(--tap) + var(--plate-inset) * 2);
  padding: var(--plate-inset) var(--plate-inset) var(--plate-inset) var(--space-4);
}
.sheet__title { font-size: var(--fs-h5); line-height: var(--lh-h4); font-weight: var(--fw-display-strong); }
.sheet__body {
  flex: 1 1 auto;
  min-block-size: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-1) 0 var(--space-2);
  scrollbar-width: thin;
}
.sheet__foot { padding: var(--space-3); display: grid; gap: var(--space-2); }
.sheet__head, .sheet__foot, .sheet__toasts, .drawer__keep { flex: none; }
.sheet__toasts:empty { display: none; }
.sheet__toasts { display: grid; gap: var(--space-2); justify-items: center; }
/* reduced transparency: sheet headers + pinned footers go Oat (§2.11) */
:root:is([data-glass="off"], [data-transparency="reduced"]) :is(.sheet__head, .sheet__foot) { background-color: var(--oat); }
@media (prefers-reduced-transparency: reduce) { :is(.sheet__head, .sheet__foot) { background-color: var(--oat); } }


/* --------------------------------------------------------------------------
   5. Finder popover (desktop, §7.5) + mobile menu (§7.4)
   -------------------------------------------------------------------------- */
.finder-pop {
  --r: var(--r-sheet);
  position: fixed;
  inset: auto;
  margin: 0;
  inline-size: min(var(--finder-w), 100vw - var(--space-6));
  display: grid; gap: var(--plate-inset);
  overflow: visible;
}
.finder-pop:popover-open { animation: pop-in var(--t-sheet-in) var(--ease-sheet); }
@keyframes pop-in { from { opacity: 0; transform: translateY(calc(var(--rise) * -1)); } }
.finder-pop:not(:popover-open):not(.is-open) { display: none; }
.finder-pop::backdrop { background: transparent; }   /* non-modal: no scrim (§7.5) */
@supports not selector(:popover-open) { .finder-pop { z-index: var(--z-sheet); } }
.finder-pop__head { padding: var(--space-4) var(--space-5); }
.finder-pop__title { font-size: var(--fs-h5); font-weight: var(--fw-display-strong); line-height: var(--lh-h4); }
.finder-pop__help { margin-block-start: var(--space-1); font-size: var(--fs-ui); line-height: var(--lh-ui); }
.finder-pop__foot { padding: var(--space-1) var(--space-5); }

.menu-sheet .sheet__body { padding-inline: 0; gap: var(--space-3); }
.menu-sheet__brew { padding: var(--space-4); display: grid; gap: var(--space-3); }
.menu-sheet__h { font-size: var(--fs-h5); line-height: var(--lh-h4); font-weight: var(--fw-display-strong); }
.menu-sheet__links { padding-inline: var(--space-4); }
.menu-sheet__links li + li { border-block-start: var(--edge-soft); }
.menu-sheet__links a {
  display: flex; align-items: center;
  min-block-size: var(--row-h);
  font-size: var(--fs-h5); font-family: var(--font-body); font-weight: var(--fw-ui);
  text-decoration: none;
}
.menu-sheet__links a:hover { text-decoration: underline; text-underline-offset: 4px; }
.menu-sheet__small { display: grid; gap: var(--space-2); padding-inline: var(--space-3); }
.menu-sheet .sheet__foot { padding-block: var(--space-1); }


/* --------------------------------------------------------------------------
   6. Buttons + text buttons (§7.6)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-block-size: var(--btn-h);
  padding-inline: calc(var(--space-6) - var(--space-1));
  border-radius: var(--r-pill);
  font-size: var(--fs-ui); line-height: var(--lh-ui); font-weight: var(--fw-strong);
  text-decoration: none;
  white-space: nowrap;
}
.btn--lg { min-block-size: var(--btn-h-lg); font-size: var(--fs-btn-lg); }
.btn--md { min-block-size: var(--btn-h-md); }
.btn--sm { min-block-size: var(--btn-h-sm); padding-inline: var(--space-4); }
.btn--block { inline-size: 100%; }
.btn--ghost {
  background: transparent;
  color: var(--ink);
  border: var(--edge-strong);
  transition: background-color var(--t-fast) var(--ease-std), transform var(--t-spring) var(--ease-spring);
}
@media (hover: hover) { .btn--ghost:hover { background-color: var(--oat); } }
/* a 40 px pill still gets a 44 px hit area */
.btn--sm { position: relative; }
.btn--sm::before { content: ""; position: absolute; inset: -2px 0; }
.text-btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-block-size: var(--tap);
  font-size: var(--fs-ui); font-weight: var(--fw-strong);
  color: var(--ink);
}
.text-btn:hover { text-decoration: underline; text-underline-offset: 3px; }
.text-btn--clay {
  color: var(--clay);
  font-size: var(--fs-label);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.text-btn--clay:hover { color: var(--clay-hover); text-decoration-thickness: 2px; }
.icon { inline-size: var(--icon-lg); block-size: var(--icon-lg); flex: none; color: inherit; }
.icon[width="16"] { inline-size: var(--icon-sm); block-size: var(--icon-sm); }
.icon[width="18"], .icon[width="20"] { inline-size: var(--icon-md); block-size: var(--icon-md); }
.icon[width="22"] { inline-size: 22px; block-size: 22px; }
.icon[width="28"] { inline-size: var(--icon-xl); block-size: var(--icon-xl); }
.icon[width="32"] { inline-size: var(--icon-xxl); block-size: var(--icon-xxl); }
.icon--flip { transform: scaleX(-1); }
.star { color: var(--saffron); }


/* --------------------------------------------------------------------------
   7. Brewer chips (§7.7) + chip tray (§7.8) + solid brewer tiles
   -------------------------------------------------------------------------- */
.brew-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-block-size: var(--chip-h);
  padding-inline: var(--space-3) var(--space-4);
  border-radius: var(--r-pill);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--fs-ui); font-weight: var(--fw-strong); line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}
.brew-chip--plate { border: var(--edge-soft); }
.brew-chip--paper { border: var(--edge-strong); }
@media (hover: hover) { .brew-chip:hover { background-color: var(--oat); } }
.brew-chip[aria-pressed="true"] { background: var(--pine); color: var(--on-pine); border-color: var(--pine); --icon-fill: .16; }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; padding: 0; }

.chip-tray { --r: var(--r-pill); position: relative; z-index: var(--z-raised); max-inline-size: 100%; }
.chip-tray__scroller {
  display: flex; gap: var(--space-2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--space-1);
  border-radius: calc(var(--r) - var(--plate-inset));
  scrollbar-width: none;
  list-style: none; padding: 0; margin: 0;
}
.chip-tray__scroller::-webkit-scrollbar { display: none; }
.chip-tray__scroller > li { scroll-snap-align: start; flex: none; }
@media (min-width: 1024px) {
  .chip-tray { --r: var(--r-sheet); }
  .chip-tray__scroller { flex-wrap: wrap; overflow: visible; }
}

.brew-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); list-style: none; padding: 0; margin: 0; }
.brew-tiles--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.brew-tile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: var(--space-3);
  align-content: center;
  min-block-size: var(--tile-h);
  block-size: 100%;
  padding: var(--space-3);
  border-radius: var(--r-tile);
  border: var(--edge-soft);
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
}
.brew-tile > .icon { grid-row: 1 / span 2; align-self: center; }
.brew-tile__label { font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-strong); }
.brew-tile__grind { font-size: var(--fs-mini); line-height: var(--lh-label); color: var(--muted); white-space: nowrap; }
/* menu tiles hold at 130 % text (B-18): rem height (--tile-h), a fixed 24 px
   icon, 12 px side padding and a subtitle that may wrap */
.menu-sheet .brew-tile { padding: var(--space-2) var(--space-3); column-gap: var(--space-2); }
.menu-sheet .brew-tile > .icon { flex: none; inline-size: var(--icon-lg); block-size: var(--icon-lg); }
.menu-sheet .brew-tile__grind { white-space: normal; overflow-wrap: anywhere; }
.sheet__brand { margin-inline-end: auto; color: var(--ink); }
.sheet__brand svg { block-size: 20px; inline-size: auto; }
@media (hover: hover) { .brew-tile:hover { background-color: var(--oat); } }
:root:is([data-glass="off"], [data-transparency="reduced"]) .brew-tile { border: var(--edge-strong); }


/* --------------------------------------------------------------------------
   7b. Bag (GRAPHICS §3.3): SVG pouch + live HTML label
   -------------------------------------------------------------------------- */
.bag { position: relative; margin: 0; aspect-ratio: 200 / 260; container-type: inline-size; }
.bag__art { display: block; inline-size: 100%; block-size: 100%; overflow: visible; }
.bag__topo { color: var(--bag-dark); }
.bag__label {
  position: absolute; inset-inline: 27%; inset-block: 65.4% 16.1%;
  display: grid; place-content: center; text-align: center;
  color: var(--ink); line-height: 1.05;
}
.bag__name {
  font-family: var(--font-display); font-weight: var(--fw-display-strong);
  font-size: clamp(9px, 7.4cqi, 22px); line-height: 1.05;
  font-variation-settings: "SOFT" var(--soft), "opsz" 24;
  text-wrap: balance;
}
.bag__roast { font-size: clamp(8px, 4.6cqi, 13px); line-height: 1.3; font-weight: var(--fw-strong); color: var(--muted); margin-block-start: .3em; }
@container (inline-size < 160px) { .bag__label { display: none; } }


/* --------------------------------------------------------------------------
   8. Product card (§7.9 pocket, §7.10 ledger, rails)
   .plist (container) > ul.pgrid > li.pcell > article.pcard.bag-scope
     a.pcard__well.glass-baked.glass--well  (glass only in ledger mode)
     div.pcard__pocket.glass-baked.glass--card (glass only in pocket mode)
       div.pcard__plate.plate > h3.pcard__name, .pcard__meta, ul.pcard__notes,
       p.roast, div.pcard__buy (price + add pill)
   Pocket is the default; lists narrower than 600 px become ledger rows.
   -------------------------------------------------------------------------- */
.plist { container: plist / inline-size; }
.pgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(13em, (100% - var(--gutter) * 3) / 4), 1fr));
  gap: var(--gutter);
  list-style: none; padding: 0; margin: 0;
}
.pcell { display: flex; min-inline-size: 0; }

.pcard {
  position: relative;
  display: flex; flex-direction: column;
  inline-size: 100%;
  background: var(--paper);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
.pcard:has(.pcard__link:focus-visible) { outline: var(--focus-w) solid var(--focus-ring); outline-offset: var(--focus-offset); }
.pcard__link:focus-visible { outline: none; box-shadow: none; }
.pcard__link { color: inherit; text-decoration: none; }
.pcard__link:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* well (pocket mode: plain Oat area, not glass) */
.pcard__well {
  --r: var(--r-card);
  position: relative;
  display: block;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: var(--r-card) var(--r-card) 0 0;
  box-shadow: none;
  background-color: var(--oat);
  background-image: radial-gradient(closest-side at 50% 58%, color-mix(in oklab, var(--bag-light) calc(var(--pool-max-a) * var(--pool-o)), transparent), transparent);
  color: inherit;
}
.pcard__well > .lens, .pcard__well::before, .pcard__well::after { display: none; }
/* pocket mode: feather the well's foot under the glass strip (B-24) */
.pcard__well {
  -webkit-mask-image: linear-gradient(#000 calc(100% - var(--well-fade)), transparent);
          mask-image: linear-gradient(#000 calc(100% - var(--well-fade)), transparent);
}
.pcard__topo {
  position: absolute; inset: 0;
  overflow: hidden;
  border-radius: inherit;
  color: color-mix(in oklab, var(--bag-dark) var(--zone-well-a), transparent);
}
.pcard__topo svg { inline-size: 100%; block-size: 100%; }
.pcard__bag {
  position: absolute;
  inset-block-end: 4%;
  inset-inline-start: 50%;
  block-size: 78%;
  inline-size: auto;
  translate: -50% 0;
  transition: transform var(--t-fast) var(--ease-out);
}
.pcard.is-sold .bag__art { opacity: .6; }

/* pocket (glass) */
.pcard__pocket {
  flex: 1;
  display: flex;
  margin-block-start: calc(var(--pocket-overlap) * -1);
  padding: var(--pocket-overlap) var(--plate-inset) var(--plate-inset);
  border-radius: var(--r-card);
  box-shadow: none;
}
.pcard__plate {
  flex: 1;
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-4);
}
.pcard__name {
  font-size: 1.25rem; line-height: 1.2; font-weight: var(--fw-display-strong);
  letter-spacing: 0;
  text-wrap: balance;
}
.pcard__meta { font-size: var(--fs-label); line-height: var(--lh-label); color: var(--muted); }
.pcard__notes { display: flex; flex-wrap: wrap; gap: var(--space-1); list-style: none; padding: 0; margin: 0; }
.pcard__buy {
  margin-block-start: auto;
  padding-block-start: var(--space-2);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
}
.pcard__price { font-size: var(--fs-body); font-weight: var(--fw-strong); font-variant-numeric: tabular-nums; line-height: 1.25; }
.pcard__per { font-size: var(--fs-label); font-weight: var(--fw-ui); color: var(--muted); white-space: nowrap; }
.pcard__sale { color: var(--clay); }
.pcard__price s { font-weight: var(--fw-ui); color: var(--muted); }
.pcard__badges { position: absolute; inset-block-start: var(--space-3); inset-inline-start: var(--space-3); display: flex; flex-wrap: wrap; gap: var(--space-1); z-index: var(--z-raised); }
.pcard > .ribbon { pointer-events: none; }  /* over the well link in pocket mode */
.pcard:has(> .ribbon) .pcard__badges { inset-block-start: calc(var(--space-3) + var(--ribbon-h) + var(--space-1)); }

@media (hover: hover) and (pointer: fine) {
  .pcard:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-lift); }
  .pcard:hover .pcard__bag { transform: translateY(-4px); }
}

/* rails: fixed 220 px pocket cards, snap */
.plist--rail .pgrid {
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: var(--rail-card-w);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: var(--space-2) var(--space-1) var(--space-4);
  scrollbar-width: thin;
}
.plist--rail .pcell { scroll-snap-align: start; }

/* ledger rows (< 600 px lists): notebook rows, glass moves to the well.
   R1 B-03: two columns (well | info) so the text column gets the full width
   (126 -> ~235 px at 375). The price sits bottom-left with the roast meter,
   "+ Add" bottom-right in the same buy row, spanning both lines. */
@container plist (inline-size < 600px) {
  .plist:not(.plist--rail) .pgrid { grid-template-columns: 1fr; gap: 0; border-block-start: var(--edge-soft); }
  .plist:not(.plist--rail) .pcard {
    display: grid;
    grid-template-columns: var(--ledger-well-w) minmax(0, 1fr) auto;
    grid-template-areas:
      "well name  name"
      "well meta  meta"
      "well notes notes"
      "well price add"
      "well roast add";
    grid-template-rows: auto auto auto auto 1fr;
    column-gap: var(--space-3);
    row-gap: 2px;
    align-items: start;
    min-block-size: var(--ledger-min-h);
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
    background: transparent;
    border-radius: 0;
    border-block-end: var(--edge-soft);
    box-shadow: inset var(--ledger-stripe) 0 0 var(--bag-dark);
    transform: none;
  }
  .plist:not(.plist--rail) .pcard:has(> .ribbon) {
    grid-template-areas:
      "well ribbon ribbon"
      "well name  name"
      "well meta  meta"
      "well notes notes"
      "well price add"
      "well roast add";
    grid-template-rows: auto auto auto auto auto 1fr;
  }
  .plist:not(.plist--rail) .pcard:hover { transform: none; box-shadow: inset var(--ledger-stripe) 0 0 var(--bag-dark); }
  .plist:not(.plist--rail) .pcard__well {
    --r: var(--r-well);
    grid-area: 1 / 1 / -1 / 2;
    inline-size: var(--ledger-well-w);
    aspect-ratio: 4 / 5;
    border-radius: var(--r-well);
    padding: var(--plate-inset);
    border: var(--edge);
    box-shadow: var(--shadow-1);
    background-color: color-mix(in oklab, var(--oat) 70%, var(--glass-base));
  }
  .plist:not(.plist--rail) .pcard__well > .lens { display: block; }
  .plist:not(.plist--rail) .pcard__well { -webkit-mask-image: none; mask-image: none; }
  .plist:not(.plist--rail) .pcard__well::before, .plist:not(.plist--rail) .pcard__well::after { display: block; }
  .plist:not(.plist--rail) .pcard__bag { block-size: 86%; inset-block-end: 7%; }
  .plist:not(.plist--rail) .pcard__badges { inset: auto auto -6px -4px; }
  .plist:not(.plist--rail) .pcard__badges .badge { block-size: 20px; font-size: var(--fs-micro); padding-inline: var(--space-2); }
  .plist:not(.plist--rail) .pcard__badges .badge + .badge { display: none; }
  /* ribbon: a one-line tag above the name (never over the well) */
  .plist:not(.plist--rail) .pcard > .ribbon {
    position: static; grid-area: ribbon; justify-self: start;
    min-block-size: 0; padding: 2px var(--space-2);
    font-size: var(--fs-micro); line-height: var(--lh-label);
    white-space: normal;
  }
  .plist:not(.plist--rail) .pcard:has(> .ribbon) .pcard__badges { inset-block-start: auto; }

  .plist:not(.plist--rail) :is(.pcard__pocket, .pcard__plate, .pcard__buy) { display: contents; }
  .plist:not(.plist--rail) .pcard__pocket > .lens,
  .plist:not(.plist--rail) .pcard__pocket::before,
  .plist:not(.plist--rail) .pcard__pocket::after { display: none; }
  .plist:not(.plist--rail) .pcard__name { grid-area: name; font-size: 1.125rem; line-height: 1.2222; font-variation-settings: "SOFT" var(--soft), "opsz" 24; }
  .plist:not(.plist--rail) .pcard__meta { grid-area: meta; }
  .plist:not(.plist--rail) .pcard__alt { display: none; }   /* altitude: >= 600 px containers only (B-25) */
  .plist:not(.plist--rail) .pcard__notes { grid-area: notes; display: block; font-size: var(--fs-label); line-height: var(--lh-label); }
  .plist:not(.plist--rail) .pcard__notes li { display: inline; background: none; border: 0; padding: 0; min-block-size: 0; font-weight: var(--fw-body); }
  .plist:not(.plist--rail) .pcard__notes li + li::before { content: " · "; }
  .plist:not(.plist--rail) .roast { grid-area: roast; align-self: start; }
  .plist:not(.plist--rail) .pcard__price { grid-area: price; align-self: end; margin-block-start: var(--space-1); line-height: var(--lh-label); }
  .plist:not(.plist--rail) .add-pill { grid-area: add; align-self: end; }
}
/* long or unbreakable names never push "+ Add" out of the card (B-03, I-5) */
.pcard__name { overflow-wrap: anywhere; hyphens: auto; }
:is(.pcard__plate, .pcard__link, .pcard__name) { min-inline-size: 0; }


/* --------------------------------------------------------------------------
   9. Badges, ribbon, note pills, roast meter, + Add pill (§7.7, §7.11)
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center;
  block-size: var(--badge-h);
  padding-inline: var(--space-2);
  border-radius: var(--r-pill);
  background: var(--paper);
  border: var(--edge-soft);
  color: var(--ink);
  font-size: var(--fs-mini); font-weight: var(--fw-strong); line-height: 1;
  white-space: nowrap;
}
.badge--new { background: var(--saffron); color: var(--on-saffron); border-color: transparent; }  /* every Saffron ground uses --on-saffron (B-07) */
.badge--sold { background: var(--ink); color: var(--paper); border-color: transparent; }
.ribbon {
  position: absolute; inset-block-start: var(--space-3); inset-inline-start: var(--space-3);
  z-index: var(--z-raised);
  display: inline-flex; align-items: center;
  min-block-size: var(--ribbon-h);
  padding-inline: var(--space-3);
  border-radius: var(--r-pill);
  background: var(--pine); color: var(--on-pine);
  font-size: var(--fs-mini); font-weight: var(--fw-strong);
  white-space: nowrap;
}
.note-pill {
  display: inline-flex; align-items: center;
  min-block-size: var(--pill-h);
  padding-inline: var(--space-3);
  border-radius: var(--r-pill);
  background: var(--paper);
  border: var(--edge-soft);
  font-size: var(--fs-label); font-weight: var(--fw-ui); line-height: 1.2;
}
.roast { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.roast__meter { display: inline-flex; flex: none; gap: 3px; }
.roast__meter > span { inline-size: 20px; block-size: 6px; border-radius: 2px; background: var(--track-empty); }
.roast__meter > .is-on { background: var(--ink); }
.roast__label { font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-strong); }

.add-pill {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
  flex: none;
  min-block-size: var(--btn-h);
  min-inline-size: 76px;
  padding-inline: var(--space-3) var(--space-4);
  border-radius: var(--r-pill);
  font-size: var(--fs-ui); font-weight: var(--fw-strong); line-height: 1;
}
.add-pill .icon { stroke-width: 2; }
.add-pill[aria-busy="true"] .icon { visibility: hidden; }
.add-pill[aria-busy="true"]::before {
  content: ""; position: absolute; margin-inline-start: -2px;
  inline-size: var(--icon-sm); block-size: var(--icon-sm);
  border-radius: 50%;
  border: 2px solid color-mix(in oklab, var(--on-pine) 35%, transparent);
  border-top-color: var(--on-pine);
  translate: calc(var(--icon-sm) * -0.95) 0;
  animation: spin 600ms linear infinite;
}
.add-pill { position: relative; }
@keyframes spin { to { rotate: 1turn; } }
@media (prefers-reduced-motion: reduce) { .add-pill[aria-busy="true"]::before { animation: none; } }
.add-pill--sold {
  background: var(--oat);
  color: var(--ink);
  border: var(--edge-strong);
  cursor: not-allowed;
}


/* --------------------------------------------------------------------------
   10. Shipping tube (§7.15, GRAPHICS §9)
   -------------------------------------------------------------------------- */
.tube { display: grid; gap: var(--space-2); }
.tube__text { font-size: var(--fs-ui); line-height: var(--lh-ui); font-weight: var(--fw-strong); }
.tube__text .icon { display: inline-block; vertical-align: -5px; margin-inline-end: var(--space-2); color: var(--pine); }
.tube__gap { font-family: var(--font-display); font-weight: var(--fw-display-strong); }
.tube__track {
  position: relative;
  block-size: var(--tube-h);
  border-radius: var(--r-pill);
  background: var(--oat);
  border: var(--edge-strong);
}
.tube__fill {
  position: absolute; inset: 0 auto 0 0;
  inline-size: max(var(--tube-h), var(--p, 0%));
  border-radius: var(--r-pill);
  /* liquid at rest (B-26): a rounded, lighter meniscus at the leading end and
     a 1 px Paper highlight along the top edge */
  background:
    radial-gradient(closest-side circle at calc(100% - var(--tube-h) / 2) 50%, color-mix(in oklab, var(--paper) 26%, transparent), transparent) right center / var(--tube-h) 100% no-repeat,
    var(--pine);
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--paper) 70%, transparent), inset -1px 0 0 color-mix(in oklab, var(--paper) 30%, transparent);
  overflow: hidden;
}
.tube__tick {
  position: absolute; inset-block: -4px; inset-inline-end: -1px;
  inline-size: 2px;
  background: var(--ink);
  border-radius: 1px;
}
.tube__goal { justify-self: end; margin-block-start: calc(var(--space-1) * -1); font-size: var(--fs-mini); font-weight: var(--fw-strong); font-variant-numeric: tabular-nums; }
.tube.is-full .tube__fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, color-mix(in oklab, white 30%, transparent) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: tube-sweep var(--t-sweep) var(--ease-out) 1 forwards;
}
.tube.is-full .tube__tick { animation: tick-flash var(--t-sweep) var(--ease-out) 1; }
@keyframes tube-sweep { to { transform: translateX(100%); } }
@keyframes tick-flash { 40% { background: var(--saffron); box-shadow: 0 0 0 1px var(--ink); } }
@media (prefers-reduced-motion: reduce) { .tube.is-full .tube__fill::after, .tube.is-full .tube__tick { animation: none; } }
.tube--mini .tube__track { block-size: var(--tube-h-mini); }
.tube--mini .tube__fill { inline-size: max(var(--tube-h-mini), var(--p, 0%)); }


/* --------------------------------------------------------------------------
   11. Cart drawer (§7.15): lines, stepper, nudge, empty, toast
   -------------------------------------------------------------------------- */
.drawer__keep { display: flex; padding-inline: var(--space-3); }
.drawer__body { padding-inline: 0; }
.drawer__ship { padding: var(--space-3) var(--space-4); }
.cart-lines { display: grid; gap: var(--space-2); list-style: none; padding: 0; margin: 0; }
.cart-line {
  display: grid;
  grid-template-columns: var(--thumb) minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--r-tile);
  background: var(--paper);
  border: var(--edge-soft);
}
.cart-line__thumb, .nudge__thumb {
  display: block;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-well);
  background: var(--oat);
  padding: var(--space-1) var(--space-2) 0;
  align-self: start;
}
.cart-line__thumb .bag, .nudge__thumb .bag { block-size: 100%; inline-size: auto; margin-inline: auto; }
.cart-line__body { display: grid; gap: var(--space-2); min-inline-size: 0; }
.cart-line__name { font-weight: var(--fw-strong); text-decoration: none; }
/* drawer: same type as the cart-page ledger, Fraunces 18/600 opsz 24 (B-20) */
.drawer .cart-line__name {
  font-family: var(--font-display); font-size: 1.125rem; line-height: 1.2222;
  font-weight: var(--fw-display-strong);
  font-variation-settings: "SOFT" var(--soft), "opsz" 24;
}
/* drawer card: thumb + body hug their content, no dead row under the stepper (B-13) */
.drawer .cart-line { align-items: start; }
.drawer .cart-line__body { align-content: start; gap: var(--space-2); }
.cart-line__name:hover { text-decoration: underline; text-underline-offset: 3px; }
.cart-line__opts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); font-size: var(--fs-label); }
.cart-line__fixed { font-size: var(--fs-label); font-weight: var(--fw-strong); }
.cart-line__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.cart-line__price { font-weight: var(--fw-strong); font-variant-numeric: tabular-nums; }
.cart-line__remove { justify-self: start; }
.cart-line__warn { font-size: var(--fs-label); color: var(--clay); }

.stepper {
  display: inline-flex; align-items: center;
  border: var(--edge-strong);
  border-radius: var(--r-pill);
  background: var(--paper);
}
.stepper__btn {
  display: grid; place-items: center;
  inline-size: var(--tap); block-size: var(--tap);   /* 44 × 44 one-thumb target (B-17) */
  border-radius: var(--r-pill);
  color: var(--ink);
}
.stepper__btn[aria-disabled="true"] { opacity: .4; cursor: not-allowed; }
@media (hover: hover) { .stepper__btn:not([aria-disabled="true"]):hover { background: var(--oat); } }
.stepper__value { min-inline-size: var(--space-6); text-align: center; font-weight: var(--fw-strong); font-variant-numeric: tabular-nums; }

.nudge {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--r-tile);
  background: var(--paper);
  border: var(--edge-soft);
}
.nudge__h { font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--fw-strong); letter-spacing: var(--tr-label); }
.nudge__name { font-size: var(--fs-ui); font-weight: var(--fw-strong); }
.nudge__name a { text-decoration: none; }
.nudge__name a:hover { text-decoration: underline; }
.nudge__meta, .nudge__line { font-size: var(--fs-label); font-weight: var(--fw-body); color: var(--muted); }

.drawer__foot { gap: var(--space-2); }
.drawer__sum { display: flex; align-items: baseline; justify-content: space-between; font-size: var(--fs-ui); font-weight: var(--fw-strong); }
.drawer__subtotal { font-family: var(--font-display); font-size: var(--fs-h5); font-weight: var(--fw-display); font-variant-numeric: tabular-nums; }
.drawer__small { font-size: var(--fs-label); color: var(--muted); }
.drawer__view { justify-self: center; display: inline-flex; align-items: center; min-block-size: var(--tap); }

.drawer__empty {
  display: grid; gap: var(--space-4); justify-items: start;
  padding: var(--space-6) var(--space-5);
  margin-inline: var(--space-1);
  border-radius: var(--r-tile);
  background: var(--paper);
}
.drawer__empty-h { font-size: var(--fs-h5); font-weight: var(--fw-display); }
.drawer__slip { justify-self: end; }

.notice {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-input);
  background: var(--saffron-tint);
  font-size: var(--fs-label); font-weight: var(--fw-strong);
}

.toasts {
  position: fixed;
  inset: auto 0 calc(var(--space-4) + env(safe-area-inset-bottom)) 0;
  z-index: var(--z-toast);
  display: grid; justify-items: center; gap: var(--space-2);
  pointer-events: none;
  padding-inline: var(--space-4);
}
.toast {
  pointer-events: auto;
  display: inline-flex; align-items: center; gap: var(--space-3);
  min-block-size: var(--btn-h-md);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-5);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow-float);
  font-size: var(--fs-ui); font-weight: var(--fw-strong);
  animation: toast-in var(--t-spring) var(--ease-spring);
}
.toast__action {
  min-block-size: var(--tap);
  padding-inline: var(--space-3);
  color: var(--paper);
  font-weight: var(--fw-strong);
  text-decoration: underline; text-underline-offset: 3px;
  border-radius: var(--r-pill);
}
.toast__action:focus-visible { outline-color: var(--paper); }
@keyframes toast-in { from { opacity: 0; transform: translateY(var(--rise)); } }


/* --------------------------------------------------------------------------
   12. Forms (§7.17): fields, inputs, selects, size cards, grind pills, switch
   -------------------------------------------------------------------------- */
.field { display: grid; gap: var(--space-2); }
.field + .field { margin-block-start: 20px; }
.field__label, .field-group__legend { font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-strong); color: var(--ink); }
.field__opt { font-weight: var(--fw-body); color: var(--muted); }
.field__help { font-size: var(--fs-label); line-height: var(--lh-label); color: var(--muted); }
.field-group__legend--display { font-family: var(--font-display); font-size: 1.25rem; font-weight: var(--fw-display-strong); margin-block-end: var(--space-3); }
.input, .select, .textarea {
  inline-size: 100%;
  min-block-size: var(--input-h);
  padding-inline: 14px;
  border-radius: var(--r-input);
  border: var(--edge-strong);
  background-color: var(--paper);
  color: var(--ink);
  font-size: 1rem;
  transition: border-color var(--t-fast) var(--ease-std);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink); }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible { border-color: var(--pine); }
.textarea { min-block-size: 140px; padding-block: var(--space-3); resize: vertical; }
.input:disabled, .select:disabled { background: var(--oat); color: var(--muted); }
.select {
  appearance: none;
  padding-inline-end: 36px;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.select--sm { inline-size: auto; min-block-size: var(--tap); font-size: var(--fs-label); font-weight: var(--fw-strong); padding-inline-start: var(--space-3); }
[aria-invalid="true"] { border: 2px solid var(--clay); }
.field-msg, .field__error {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--ink);
}
.field-msg .icon, .field__error .icon { color: var(--clay); }
.field--error { border-inline-start: 2px solid var(--clay); padding-inline-start: var(--space-3); }
.error-summary {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--r-input);
  background: var(--paper);
  box-shadow: inset 4px 0 0 var(--clay), var(--shadow-card);
}

/* size radio cards (quick add, PDP) */
.size-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: var(--space-2); }
.size-card {
  position: relative;
  display: grid; align-content: center; gap: 2px;
  min-block-size: 64px;
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border-radius: var(--r-input);
  border: var(--edge-strong);
  background: var(--paper);
  cursor: pointer;
}
.size-card input, .grind-pill input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.size-card__label { font-size: var(--fs-ui); font-weight: var(--fw-strong); }
.size-card__sub { font-size: var(--fs-mini); color: var(--muted); }
.size-card__tag { font-size: var(--fs-micro); font-weight: var(--fw-strong); color: var(--pine); }
.size-card:has(input:checked) { border: 2px solid var(--pine); background: var(--pine-tint); }
.size-card:has(input:focus-visible), .grind-pill:has(input:focus-visible) { outline: var(--focus-w) solid var(--focus-ring); outline-offset: var(--focus-offset); box-shadow: var(--focus-shadow); }

/* grind pills (quick add, PDP): radio group, one tab stop */
.grind-pills { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
@media (min-width: 1024px) { .grind-pills { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.grind-pill {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-2);
  align-items: center;
  min-block-size: 64px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-tile);
  border: var(--edge-strong);
  background: var(--paper);
  cursor: pointer;
}
.grind-pill > .icon { grid-row: 1 / span 2; }
.grind-pill__label { font-size: var(--fs-ui); font-weight: var(--fw-strong); line-height: 1.2; }
.grind-pill__grind { font-size: var(--fs-mini); color: var(--muted); }
.grind-pill__rec {
  grid-column: 1 / -1;
  justify-self: start;
  margin-block-start: var(--space-1);
  font-size: var(--fs-micro); font-weight: var(--fw-strong); color: var(--pine);
}
.grind-pill:has(input:checked) { background: var(--pine); border-color: var(--pine); color: var(--on-pine); --icon-fill: .16; }
.grind-pill:has(input:checked) :is(.grind-pill__grind, .grind-pill__rec) { color: var(--on-pine); }
.field-group + .field-group { margin-block-start: var(--space-5); }
.field-group > legend { float: inline-start; inline-size: 100%; padding: 0; margin-block-end: var(--space-3); }
.field-group > legend + * { clear: both; }

/* quick-add sheet */
.qa-sheet__body { padding-inline: var(--space-1); }
.qa-sheet__body > * { margin: 0; }
.qa-sheet__body .field-group { padding: var(--space-4); border-radius: var(--r-tile); background: var(--paper); }
.qa-sheet__product { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--r-tile); background: var(--paper); }
.qa-sheet__product .bag { inline-size: 44px; flex: none; }
.qa-sheet__product p { display: grid; font-size: var(--fs-label); color: var(--muted); }
.qa-sheet__product strong { font-family: var(--font-display); font-size: 1.25rem; color: var(--ink); }
.qa-sheet__more { justify-self: center; }

/* Reduce-transparency switch (§7.17, §7.20) */
.switch-row { display: grid; gap: var(--space-1); }
.switch {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  inline-size: 100%;
  min-block-size: var(--tap);
  padding-inline: var(--space-3) var(--space-1);
  border-radius: var(--r-pill);
  text-align: start;
}
.switch__label { font-size: var(--fs-ui); font-weight: var(--fw-strong); }
.switch__track {
  position: relative; flex: none;
  inline-size: var(--switch-w); block-size: var(--switch-h);
  border-radius: var(--r-pill);
  border: var(--edge-strong);
  background: var(--oat);
  transition: background-color var(--t-fast) var(--ease-std);
}
.switch__thumb {
  position: absolute; inset-block-start: 3px; inset-inline-start: 3px;
  inline-size: var(--switch-thumb); block-size: var(--switch-thumb);
  border-radius: 50%;
  background: var(--paper);
  box-shadow: var(--shadow-1), 0 0 0 1px color-mix(in oklab, var(--ink) 14%, transparent);
  transition: transform var(--t-fast) var(--ease-out);
}
.switch[aria-checked="true"] .switch__track { background: var(--pine); border-color: var(--pine); }
.switch[aria-checked="true"] .switch__thumb { transform: translateX(calc(var(--switch-w) - var(--switch-thumb) - 8px)); }
@media (prefers-reduced-motion: reduce) { .switch__thumb { transition: none; } }
.switch[aria-disabled="true"] { cursor: not-allowed; }
.switch__help { padding-inline: var(--space-3); font-size: var(--fs-label); color: var(--muted); }


/* --------------------------------------------------------------------------
   13. Paper devices: section marker, section head, margin note, slip
   -------------------------------------------------------------------------- */
.marker {
  display: flex; align-items: center; gap: var(--space-3);
  font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-strong); letter-spacing: var(--tr-label);
  color: var(--muted);
}
.marker::before { content: ""; inline-size: var(--rule-w); block-size: 1px; background: var(--rule); flex: none; }
.section-head { max-inline-size: 46rem; }
.section-head > h2, .section-head > .h2 { margin-block-start: var(--space-4); }
.section-head > .section-head__intro {
  margin-block-start: var(--space-4);
  max-inline-size: 52ch;
  font-size: var(--fs-lead); line-height: var(--lh-body); color: var(--muted);
}

.margin-note {
  max-inline-size: var(--measure-note);
  padding-inline-start: var(--space-3);
  border-inline-start: 2px solid var(--clay);
  font-size: var(--fs-label); line-height: var(--lh-label);
  color: var(--muted);
}
@media (min-width: 1024px) {
  .margin-note--aside {
    position: relative;
    border: 0;
    padding-inline-start: calc(var(--space-6) + var(--space-2));
  }
  .margin-note--aside::before {
    content: "";
    position: absolute; inset-inline-start: 0; inset-block-start: 0.7em;
    inline-size: var(--space-6); block-size: 1px;
    background: color-mix(in oklab, var(--ink) 40%, transparent);
  }
  .margin-note--aside::after {
    content: "";
    position: absolute; inset-inline-start: 0; inset-block-start: calc(0.7em - 3px);
    inline-size: 6px; block-size: 6px;
    border-inline-start: 1px solid color-mix(in oklab, var(--ink) 40%, transparent);
    border-block-end: 1px solid color-mix(in oklab, var(--ink) 40%, transparent);
    transform: rotate(45deg);
  }
}

.slip {
  display: inline-block;
  max-inline-size: 22ch;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-slip);
  border: var(--edge-soft);
  background: var(--oat);
  box-shadow: var(--shadow-slip);
  transform: rotate(var(--slip-rotate));
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-slip); line-height: 1.3333;
  font-variation-settings: "SOFT" var(--soft), "opsz" 14;
  color: var(--ink);
}


/* --------------------------------------------------------------------------
   14. Shared sections (§7.24)
   -------------------------------------------------------------------------- */
/* Freshness strip */
.fresh-strip { padding-block: var(--section-y-tight); }
.fresh-strip__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-5); list-style: none; padding: 0; margin: var(--space-6) 0 0; }
@media (min-width: 1024px) { .fresh-strip__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.fresh-strip__item { display: grid; gap: var(--space-2); align-content: start; }
.fresh-strip__item .icon { inline-size: var(--icon-xxl); block-size: var(--icon-xxl); }
.fresh-strip__item strong { font-size: var(--fs-body); line-height: 1.375; }
.fresh-strip__item p { font-size: var(--fs-ui); line-height: var(--lh-body); color: var(--muted); }

/* Taste tiles */
.taste-tiles { display: grid; gap: var(--gutter); grid-template-columns: 1fr; list-style: none; padding: 0; margin: 0; }
@media (min-width: 600px) { .taste-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.taste-tile {
  position: relative;
  display: grid;
  grid-template-rows: var(--swatch-h) auto;
  block-size: 100%;
  border-radius: var(--r-card);
  background: var(--paper);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--ink);
  transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
.taste-tile__swatch {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-card) var(--r-card) 0 0;
  background: var(--bag);
  color: color-mix(in oklab, var(--paper) 35%, transparent);
}
.taste-tile__swatch svg { position: absolute; inset: -4px; inline-size: calc(100% + 8px); block-size: calc(100% + 8px); transition: transform var(--t-fast) var(--ease-out); }
.taste-tile__body { padding: var(--space-5); display: grid; gap: var(--space-2); }
.taste-tile__title { font-family: var(--font-display); font-size: var(--fs-h5); font-weight: var(--fw-display); line-height: var(--lh-h4); font-variation-settings: "SOFT" var(--soft); }
.taste-tile__line { font-size: var(--fs-ui); line-height: var(--lh-body); color: var(--muted); }
@media (hover: hover) and (pointer: fine) {
  .taste-tile:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-lift); }
  .taste-tile:hover .taste-tile__swatch svg { transform: translate(4px, -4px); }
}

/* Reviews: snap row on mobile, 3-up on desktop */
.reviews__label { font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--muted); }
.reviews__row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 85%;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: var(--space-2) var(--space-1) var(--space-4);
  margin: 0 calc(var(--space-1) * -1);
  list-style: none;
  scrollbar-width: none;
}
.reviews__row::-webkit-scrollbar { display: none; }
.reviews__row > li { scroll-snap-align: start; display: flex; position: relative; }
.review {
  position: relative;          /* contains its visually-hidden text inside the scroller */
  display: grid; gap: var(--space-4); align-content: start;
  inline-size: 100%;
  padding: var(--space-6) var(--space-5);
  border-radius: var(--r-card);
  background: var(--paper);
  box-shadow: var(--shadow-card);
}
.review__stars { display: flex; gap: 2px; }
.review__stars .icon { inline-size: var(--icon-md); block-size: var(--icon-md); }
.review__stars .is-off { color: var(--track-empty); }
.review__quote {
  font-family: var(--font-display); font-style: italic;
  font-size: 1.25rem; line-height: 1.5;
  font-variation-settings: "SOFT" var(--soft), "opsz" 24;
}
.review__who { font-size: var(--fs-label); line-height: var(--lh-label); }
.review__who strong { display: block; }
.review__who span { color: var(--muted); }
.reviews__nav { display: flex; align-items: center; gap: var(--space-2); margin-block-start: var(--space-2); }
.reviews__pos { min-inline-size: 5ch; text-align: center; font-size: var(--fs-label); font-weight: var(--fw-strong); font-variant-numeric: tabular-nums; }
@media (min-width: 1024px) {
  .reviews__row { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); overflow: visible; margin: 0; padding: 0; }
  .reviews__nav { display: none; }
}
.icon-btn {
  display: inline-grid; place-items: center;
  inline-size: var(--tap); block-size: var(--tap);
  border-radius: var(--r-pill);
  border: var(--edge-strong);
  background: var(--paper);
  color: var(--ink);
}
.icon-btn[aria-disabled="true"] { opacity: .4; cursor: not-allowed; }

/* Guide teaser cards */
.guide-cards { display: grid; gap: var(--space-6) var(--gutter); list-style: none; padding: 0; margin: 0; }
@media (min-width: 768px) { .guide-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.guide-card { display: grid; gap: var(--space-3); align-content: start; }
.guide-card__media {
  display: block;
  aspect-ratio: 3 / 2;
  border-radius: var(--r-card);
  overflow: hidden;            /* a plain image wrapper, not glass */
  background: var(--oat);
}
.guide-card__media img { inline-size: 100%; block-size: 100%; object-fit: cover; transition: transform var(--t-spring) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .guide-card:hover .guide-card__media img { transform: scale(1.02); } }
.guide-card__meta { font-size: var(--fs-label); font-weight: var(--fw-strong); color: var(--muted); }
.guide-card__title { font-size: var(--fs-h5); font-size: 1.5rem; line-height: var(--lh-h4); font-weight: var(--fw-display); }
.guide-card__title a { text-decoration: none; }
.guide-card__title a:hover { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.guide-card__line { color: var(--muted); max-inline-size: 44ch; }

/* Closing CTA band */
.cta-band { position: relative; isolation: isolate; overflow: clip; }
.cta-band > .zone-field { z-index: -1; }
.cta-band > .zone-field use { --field-alpha: var(--zone-well-a); }
.cta-band__inner { display: grid; gap: var(--space-5); }
.cta-band__line { font-size: var(--fs-lead); color: var(--muted); }
.cta-band .chip-row { max-inline-size: 100%; }


/* --------------------------------------------------------------------------
   15. Footer (§7.18) · Ink dark zone
   -------------------------------------------------------------------------- */
.footer {
  position: relative;
  margin-block-start: var(--section-y);
  background: var(--ink);
  color: var(--on-ink);
  padding-block: 0 var(--section-y-tight);
  border-block-start: 1px solid color-mix(in oklab, var(--paper) 12%, transparent);
}
.footer a { color: var(--on-ink-muted); text-decoration: none; }
.footer a:hover { color: var(--on-ink); text-decoration: underline; text-underline-offset: 3px; }
.footer__band {
  position: relative; block-size: var(--band-contour-h); overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 30%, transparent);   /* no hard edge into the footer (B-19) */
          mask-image: linear-gradient(#000 30%, transparent);
}
.footer__field { position: absolute; left: 0; top: 0; width: 2400px; height: 1200px; overflow: visible; }
.footer__field use { --field-stroke: var(--paper); --field-alpha: .08; --field-w: 1px; }
.footer__grid { display: grid; gap: var(--space-6); padding-block-start: var(--space-6); }
.footer__logo { display: inline-block; color: var(--on-ink); }
.footer__logo svg { block-size: 28px; inline-size: auto; }
.footer__blurb { margin-block-start: var(--space-4); max-inline-size: 32ch; font-size: var(--fs-ui); line-height: var(--lh-body); color: var(--on-ink-muted); }
.footer__note {
  margin-block-start: var(--space-4);
  padding-inline-start: var(--space-3);
  border-inline-start: 2px solid var(--clay);
  font-size: var(--fs-label); color: var(--on-ink-muted);
}
.footer__groups { display: grid; }
.footer__group { border-block-end: 1px solid color-mix(in oklab, var(--paper) 12%, transparent); }
.footer__summary {
  display: flex; align-items: center; justify-content: space-between;
  min-block-size: max(var(--row-h), var(--tap));   /* mobile accordion: >= 44 (B-23) */
  font-size: var(--fs-ui); font-weight: var(--fw-strong);
  cursor: pointer;
  list-style: none;
}
.footer__summary::-webkit-details-marker { display: none; }
.footer__summary .icon { transition: transform var(--t-fast) var(--ease-std); }
.footer__group[open] .footer__summary .icon { transform: rotate(180deg); }
.footer__group ul { list-style: none; padding: 0 0 var(--space-3); margin: 0; }
.footer__group a { display: inline-flex; align-items: center; min-block-size: var(--tap); font-size: var(--fs-ui); }
.footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid color-mix(in oklab, var(--paper) 12%, transparent);
  font-size: var(--fs-label); color: var(--on-ink-muted);
}
.footer__bottom a { display: inline-flex; align-items: center; min-block-size: var(--tap); }
.social { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); list-style: none; padding: 0; margin: 0; }
.social a { display: inline-flex; align-items: center; min-block-size: var(--tap); font-size: var(--fs-label); font-weight: var(--fw-strong); }
.footer .switch-row { margin-inline-start: auto; }
.footer .switch { inline-size: auto; }
.switch__label { white-space: nowrap; }
.footer .switch__label { color: var(--on-ink); }
.footer .switch__track { border-color: color-mix(in oklab, var(--paper) 60%, transparent); }
.footer .switch__help { color: var(--on-ink-muted); }
.footer :focus-visible { outline-color: var(--pine); box-shadow: 0 0 0 2px var(--paper); }
@media (min-width: 1024px) {
  .footer__grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); }
  .footer__brand { grid-column: 1 / span 4; }
  .footer__groups { grid-column: 5 / -1; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gutter); }
  .footer__group { border: 0; }
  .footer__summary { min-block-size: var(--space-5); margin-block-end: var(--space-2); cursor: default; font-size: var(--fs-label); color: var(--on-ink); }  /* 24 px house minimum */
  .footer__summary .icon { display: none; }
  .footer__group a { min-block-size: 30px; }
  .footer__bottom { grid-column: 1 / -1; }
}
/* static (no-JS) footer */
.footer__static { display: grid; gap: var(--space-4); padding-block-start: var(--space-6); }
.footer__static nav ul { display: flex; flex-wrap: wrap; gap: 0 var(--space-5); list-style: none; padding: 0; }
.footer__static a { display: inline-flex; min-block-size: var(--tap); align-items: center; }
