/* The style guide's tokens and components (docs/style-guides/style-guide.md), on every page: loaded right after app.css. The /style
   gallery draws each one (pages/StyleGuide.tsx); its own page layout is in style-guide.css. Colors are mixed from
   app.css's tokens, so dark mode follows. */
:root {
  /* Spacing: one 4px scale for padding and gaps */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px;
  /* Type: six sizes, three weights (400, 600, 700) */
  --text-xs: 12px; --text-sm: 14px; --text-base: 16px; --text-lg: 20px; --text-xl: 25px; --text-2xl: 31px;
  /* The highlighter as a line or mark on paper (a ring, an edge): the fill itself is too pale to see as a line */
  --highlighter-ink: #B07400;
  /* Not verified yet (an estimate, an unchecked allergen): calm gray, never amber */
  --unverified: var(--ink-soft);
  --cost-unknown: #C2620E;  /* no price known: should be rare */
  /* A price from an invoice past the 6-month limit: the invoice green, faded toward gray */
  --stale: #4E9A72;
  --link: var(--focus);
}
/* --stale on dark: dimmer than --done there (#5CC08D), as on light it's lighter */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --stale: #3F8F67; --cost-unknown: #E8954A; } }
:root[data-theme="dark"] { --stale: #3F8F67; --cost-unknown: #E8954A; }
/* --warn-fill / --warn-text: a warn pill. On dark the highlighter is too murky behind text, so it uses the lighter amber. */
:root { --warn-fill: var(--highlighter); --warn-text: #1D2B4F; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --highlighter-ink: #E6B55A; --warn-fill: #E6B55A; --warn-text: #12161F; } }
:root[data-theme="dark"] { --highlighter-ink: #E6B55A; --warn-fill: #E6B55A; --warn-text: #12161F; }

/* Type */
.text-xs { font-size: var(--text-xs); } .text-sm { font-size: var(--text-sm); } .text-lg { font-size: var(--text-lg); }
.money { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }


/* Concept icons: 16px, one 1.3 stroke in the text's own color. Status marks alone take a meaning color. */
.ico { display: inline-flex; align-items: center; gap: var(--space-1); vertical-align: -3px; color: inherit; }
.ico svg { width: 16px; height: 16px; flex: none; }
.ico.lg svg { width: 20px; height: 20px; }
.ico[data-tip] { cursor: help; }
/* An icon that opens something: a link or button, with a ring on hover and a 44px target on touch screens */
.ico-link { display: inline-grid; place-items: center; min-width: 28px; min-height: 28px; padding: 0; border: 1px solid transparent;
  border-radius: 999px; background: none; color: inherit; cursor: pointer; text-decoration: none; vertical-align: middle; }
.ico-link:hover { border-color: var(--edge); background: var(--walk-in); }
@media (pointer: coarse) { .ico-link { min-width: 44px; min-height: 44px; } }
.edit-button svg { width: 15px; height: 15px; color: var(--ink-soft); }
.edit-button:hover svg { color: var(--ink); }

/* Cost marks: where a price comes from */
.cost-mark { display: inline-flex; align-items: center; gap: 2px; vertical-align: -3px; }
.cost-mark svg { width: 16px; height: 16px; flex: none; }
.cost-mark.cost-invoice { color: var(--done); }
.cost-mark.cost-stale { color: var(--stale); }
.cost-mark.cost-estimate, .cost-mark.cost-ballpark, .cost-mark.cost-free { color: var(--unverified); }
.cost-mark.cost-missing { color: var(--cost-unknown); }
.cost-mark.cost-yours { color: var(--focus); }  /* blue, as today: navy is too close to the gray of an estimate */
.cost-mark .approx { font-weight: 700; font-size: var(--text-sm); }

/* Allergen marks: filled = confirmed, gray ring = not checked, thick amber ring = may contain; dashed halo = from a sub-recipe */
.allergen-dot { display: inline-grid; place-items: center; width: 16px; height: 16px; vertical-align: -3px; }
.allergen-dot svg { width: 16px; height: 16px; }
.allergen-dot.allergen-confirmed { color: var(--done); }
.allergen-dot.allergen-unchecked { color: var(--unverified); }
.allergen-dot.allergen-may { color: var(--highlighter-ink); }

/* A dish nobody has confirmed: a small gray ? beside its name. Printed too. */
.unconfirmed-mark { display: inline-grid; place-items: center; width: 16px; height: 16px; margin-left: var(--space-1); border: 1.5px solid var(--unverified);
  border-radius: 50%; color: var(--unverified); font-size: 11px; font-weight: 700; line-height: 1; vertical-align: 1px; cursor: help; }
/* Food cost at or under target: a small green check before the % */
.on-target { display: inline-flex; align-items: center; gap: var(--space-1); white-space: nowrap; cursor: help; }
.on-target svg { width: 14px; height: 14px; color: var(--done); flex: none; }

/* Phone tab bar: five destinations, words always, no counts; Add raised in the middle (an action, never "current") */
.tab-bar { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); align-items: end; background: var(--paper);
  border-top: 1px solid var(--edge); padding: var(--space-1) var(--space-1) calc(var(--space-1) + env(safe-area-inset-bottom)); }
.tab-bar a, .tab-bar button { display: grid; justify-items: center; gap: 2px; min-height: 44px; padding: var(--space-1) 0; border: 0; background: none;
  color: var(--ink-soft); font-size: var(--text-sm); text-decoration: none; cursor: pointer; }
.tab-bar svg { width: 20px; height: 20px; }
.tab-bar [aria-current="page"] { color: var(--ink); font-weight: 700; box-shadow: inset 0 3px 0 var(--ink); }
.tab-bar .tab-add .add-disc { display: grid; place-items: center; width: 44px; height: 44px; margin-top: -18px; border-radius: 50%;
  background: var(--ink); color: var(--paper); }
.tab-bar .tab-add { color: var(--ink); }

/* An allergen in a list: its mark, then its name, in a neutral pill (the mark carries the meaning) */
.allergen-pill { display: inline-flex; align-items: center; gap: 4px; padding: 0 8px 0 4px; border: 1px solid var(--edge); border-radius: 999px;
  font-size: var(--text-sm); color: var(--ink); background: var(--paper); white-space: nowrap; }
.check-mark { color: var(--done); vertical-align: -2px; flex: none; }

/* Status pills: a tint, a dot and a word, one per meaning. Tags: outlined and neutral, they say what a thing is. */
.pill-good, .pill-warn, .pill-bad, .pill-info, .pill-neutral {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 999px; border: 1px solid;
  font-size: var(--text-sm); font-weight: 600; white-space: nowrap; line-height: 1.5; }
.pill-good, .pill-warn, .pill-bad, .pill-info, .pill-neutral { --tone: var(--ink-soft); }
.pill-good { --tone: var(--done); } .pill-bad { --tone: var(--red-pen); } .pill-info { --tone: var(--focus); }
.pill-good, .pill-bad, .pill-info, .pill-neutral {
  color: color-mix(in srgb, var(--tone) 85%, var(--ink)); background: color-mix(in srgb, var(--tone) 12%, var(--paper));
  border-color: color-mix(in srgb, var(--tone) 40%, var(--paper)); }
.pill-warn { color: var(--warn-text); background: var(--warn-fill); border-color: var(--highlighter-ink); }
.pill-good::before, .pill-warn::before, .pill-bad::before, .pill-info::before, .pill-neutral::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.pill-warn.over::before { display: none; }  /* the ▲ is its mark */
.pill-good[data-tip], .pill-warn[data-tip], .pill-bad[data-tip], .pill-info[data-tip], .pill-neutral[data-tip] { cursor: help; }
.tag-pill { display: inline-flex; align-items: center; gap: var(--space-1); padding: 0 8px; border: 1px solid var(--edge); border-radius: 999px;
  font-size: var(--text-xs); font-weight: 600; color: var(--ink-soft); background: transparent; white-space: nowrap; vertical-align: 1px; }
.tag-pill.walk-in { border-style: dashed; border-color: var(--done); color: var(--done); }
/* Chips: filters you tap, each with its count; on when aria-pressed */
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip-row button { border-radius: 999px; min-height: 36px; padding: 4px 12px; font-size: var(--text-sm); }
.chip-row button[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); font-weight: 600; }
.chip-row .count { color: inherit; opacity: .75; font-variant-numeric: tabular-nums; }
/* A chosen chip's count (or tab's) is its own ink, not the gray hint that disappears on the navy fill (R1-C-10) */
.chips button.chosen .hint, .chips button[aria-pressed="true"] .hint, .chips button[aria-selected="true"] .hint,
.chip-row button[aria-pressed="true"] .hint { color: inherit; opacity: .85; }
@media (pointer: coarse) { .chip-row button { min-height: 44px; } }

/* Buttons. .small: compact and rounded: a page tool beside the search box, and the action on each row of a list (a to-do).
   A plain one has a light navy tint with an edge: its fill, border and hover say "button", not a status pill (pills are
   smaller, with a dot). A link that acts as one is a.button.small. .primary, .quiet and .danger keep their own colours at
   this size (only the plain one is tinted); a text link marked small (button.link.small) stays a link: no pill at all. */
button.small:not(.link), .button.small { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 2px 12px; border-radius: 999px;
  font-size: var(--text-sm); font-weight: 600; white-space: nowrap; }
:is(button, .button).small:not(.link):not(.primary):not(.quiet):not(.danger) { padding: 2px 14px; color: var(--ink);
  background: color-mix(in srgb, var(--ink) 9%, var(--paper)); border-color: color-mix(in srgb, var(--ink) 22%, var(--paper)); }
button.small:not(.link):hover { border-color: var(--ink); }
:is(button, .button).small:not(.link):not(.primary):not(.quiet):not(.danger):hover { background: color-mix(in srgb, var(--ink) 15%, var(--paper)); }
@media (pointer: coarse) { button.small:not(.link), .button.small { min-height: 44px; } }
/* Every Add button: + then the concept icon then the words */
.add-button { display: inline-flex; align-items: center; gap: 6px; }
.add-button .plus { font-weight: 700; font-size: var(--text-lg); line-height: 1; }
.add-button .ico { vertical-align: 0; }
.add-button.small { min-height: 32px; padding: 2px 12px; font-size: var(--text-sm); }
@media (pointer: coarse) { .add-button.small { min-height: 44px; } }
/* A disabled action link: gray, not underlined, still focusable so its tooltip says why. Never pink or red. */
button.link[aria-disabled="true"] { color: var(--ink-soft); opacity: .7; text-decoration: none; cursor: not-allowed; }

/* Concept colors: recipe, ingredient and menu item each have one, for the icon and a light tint behind the name. They
   say what a thing is, never how it stands, so none may read as a status (green, blue, gray, amber, red). Plum, teal and
   copper, chosen October 27; on dark each is lightened toward white. */
:root { --cr: #8A4B8F; --ci: #17777F; --cm: #8C5A26;
  --concept-recipe: var(--cr); --concept-ingredient: var(--ci); --concept-menu-item: var(--cm); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --concept-recipe: color-mix(in srgb, var(--cr) 55%, white); --concept-ingredient: color-mix(in srgb, var(--ci) 55%, white);
  --concept-menu-item: color-mix(in srgb, var(--cm) 55%, white); } }
:root[data-theme="dark"] { --concept-recipe: color-mix(in srgb, var(--cr) 55%, white);
  --concept-ingredient: color-mix(in srgb, var(--ci) 55%, white); --concept-menu-item: color-mix(in srgb, var(--cm) 55%, white); }
.concept-recipe { --concept: var(--concept-recipe); } .concept-ingredient { --concept: var(--concept-ingredient); }
.concept-menu_item { --concept: var(--concept-menu-item); }
/* A concept icon takes its color (ConceptIcon's class is the concept); in a button it stays the button's color */
.ico.recipe { color: var(--concept-recipe); } .ico.ingredient { color: var(--concept-ingredient); }
.ico.menu_item { color: var(--concept-menu-item); }
.name-bubble { display: inline-flex; align-items: center; gap: var(--space-1); padding: 1px 10px 1px 6px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--concept) 35%, var(--paper)); background: color-mix(in srgb, var(--concept) 10%, var(--paper));
  color: var(--ink); font-size: var(--text-sm); font-weight: 600; white-space: nowrap; }
.name-bubble .ico { color: var(--concept); vertical-align: 0; }
/* A line's bubble (menu-plate.tsx LineBubble): the same tint, whatever the price; padding even, as it has no icon inside */
.bubble.name-bubble { padding: 1px 10px; text-decoration: none; border-style: solid; }
a.bubble.name-bubble:hover { border-color: var(--concept); }
/* Used-in counts: a tooltip lists them; they open nothing */
.used-count { display: inline-flex; align-items: center; gap: 3px; padding: 0 6px; border-radius: 999px; font-size: var(--text-xs); font-weight: 600;
  color: var(--ink-soft); border: 1px solid var(--edge); cursor: help; }
.used-count .ico { color: var(--concept); vertical-align: 0; }
.used-count .ico svg { width: 14px; height: 14px; }
.used-list { display: grid; gap: var(--space-1); margin: var(--space-1) 0 0; }
.used-list .ico { color: var(--concept); }

/* Delete or remove: the red trash can, icon only in a row (its tooltip says what goes), or before the word on a button */
.trash-icon { display: inline-flex; color: var(--red-pen); vertical-align: -3px; }
.trash-icon svg, .trash-button svg { width: 16px; height: 16px; }
.trash-button { min-width: 32px; min-height: 32px; padding: 0; display: inline-grid; place-items: center; border: 1px solid transparent;
  border-radius: 999px; background: none; color: var(--red-pen); }
.trash-button:hover { border-color: var(--edge); background: color-mix(in srgb, var(--red-pen) 8%, var(--paper)); }
.trash-button[aria-disabled="true"] { color: var(--ink-soft); opacity: .6; cursor: not-allowed; }
.trash-button[aria-disabled="true"]:hover { background: none; border-color: transparent; }
@media (pointer: coarse) { .trash-button { min-width: 44px; min-height: 44px; } }
/* Enter a price: a blue $ with a pencil */
.price-button { min-width: 32px; min-height: 32px; padding: 0; display: inline-grid; place-items: center; border: 1px solid transparent;
  border-radius: 999px; background: none; color: var(--focus); }
.price-button:hover { border-color: var(--edge); }
.price-button svg { width: 18px; height: 18px; }
@media (pointer: coarse) { .price-button { min-width: 44px; min-height: 44px; } }
/* A confirming action: the green check before its words (green means confirmed); outlined, never navy */
button.confirm-button { color: var(--done); border-color: color-mix(in srgb, var(--done) 45%, var(--paper)); }
button.confirm-button .check-mark { color: var(--done); }
/* An Add button's + sits on the words' center line */
.add-button .plus { display: inline-grid; place-items: center; height: 1em; line-height: 1; }

/* A sheet's Close: "Close ×", the word and the X, in its top corner, always there; it stays put while the sheet scrolls */
.sheet { position: relative; }
.sheet.wide { width: min(880px, 100%); }
.sheet-close { position: sticky; top: 0; float: right; z-index: 2; min-height: 36px; padding: 0 8px; margin: -8px -8px 0 8px;
  display: inline-flex; align-items: center; gap: 4px; border: 1px solid transparent; border-radius: var(--radius); background: var(--paper);
  color: var(--ink-soft); font-size: var(--text-sm); font-weight: 400; }
.sheet-close:hover { border-color: var(--edge); color: var(--ink); }
.sheet-close svg { width: 16px; height: 16px; }
@media (pointer: coarse) { .sheet-close { min-height: 44px; } }

/* A sheet's buttons (SheetActions): Cancel first, the main action last; stacked on a phone, the main action on top */
@media (max-width: 760px) {
  .sheet .sheet-actions { flex-direction: column-reverse; align-items: stretch; }
  .sheet .sheet-actions > button, .sheet .sheet-actions > .button { justify-content: center; }
}

/* Cards by function. Data: .paper.panel. Configuration: .paper.panel.config (app.css). */
.kpi-card { display: grid; gap: var(--space-1); align-content: start; }
.kpi-card .kpi-label { font-size: var(--text-sm); color: var(--ink-soft); display: flex; align-items: center; gap: var(--space-2); }
.kpi-card .kpi-value { font-size: var(--text-2xl); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-card .kpi-trend { font-size: var(--text-sm); color: var(--ink-soft); }
.kpi-card .kpi-trend.up-bad { color: var(--highlighter-ink); }  /* worse, over target: look now, not broken */ .kpi-card .kpi-trend.down-good { color: var(--done); }
/* Notices: everything on the page that needs a person, in one card at the top, tinted lighter than the page (not white).
   One line each: its icon, what happened, and an action that names itself. Urgent lines get an amber edge, broken ones red
   and go first. Replaces the alert card. */
:root { --notice: color-mix(in srgb, var(--walk-in) 45%, var(--paper)); }
.notices-card { background: var(--notice); padding: var(--space-2) var(--space-5); }
.notice-line { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-3); align-items: center;
  padding: var(--space-3) 0 var(--space-3) var(--space-3); border-left: 3px solid transparent; }
.notice-line + .notice-line { border-top: 1px solid var(--edge); }
.notice-line.urgent { border-left-color: var(--highlighter-ink); }
.notice-line.broken { border-left-color: var(--red-pen); }
.notice-line.broken > .ico { color: var(--red-pen); }
.notice-line p { margin: 0; }
/* Notices that ask a decision with their choices sit in the same card as blocks, divided like its lines */
.notices-card:empty { display: none; }
.notices-card > .notice { background: none; border: 0; border-radius: 0; padding: var(--space-3) 0; margin: 0; }
.notices-card > .notice + .notice, .notices-card > .notice + .notice-line, .notices-card > .notice-line + .notice { border-top: 1px solid var(--edge); }
.notices-card > .notice[role="alert"], .notices-card > .notice.error { border-left: 3px solid var(--red-pen); padding-left: var(--space-3); }
.notices-card > .notice h2 { font-size: var(--text-base); margin: 0 0 var(--space-1); }
.notice-line .notice-detail, .notice-line p > .working { display: block; margin-top: 2px; }
/* Still the spinner, 8px, then its words (docs/style-guides/style-guide.md, Loading) */
.notice-line .working.notice-detail, .notice-line p > .working, table.list-table td .under.working { display: flex; }
@media (max-width: 760px) { .notice-line { grid-template-columns: auto minmax(0, 1fr); } .notice-line > button { grid-column: 2; justify-self: start; } }
.empty-card { display: grid; justify-items: center; text-align: center; gap: var(--space-2); padding: var(--space-8) var(--space-5); }
.empty-card .ico svg { width: 32px; height: 32px; color: var(--ink-soft); }
.empty-card h3 { font-size: var(--text-lg); }
.empty-card p { margin: 0; color: var(--ink-soft); max-width: 36em; }
.drop-card { display: grid; justify-items: center; gap: var(--space-2); text-align: center; padding: var(--space-6) var(--space-5);
  /* A border that carries meaning (drop here) needs 3:1 against the card, light and dark (R2-C-06): --ink-soft, not --edge. */
  border: 2px dashed var(--ink-soft); border-radius: var(--radius); background: var(--paper); }
/* An invoice's settled lines (C5-19): every row the same tracks, so amounts line up down a 45-line invoice. */
/* One grid for the whole list, every row a subgrid (R4-C-01): the name takes the room, the numbers what they need. */
.line-box { container-type: inline-size; }
.line-list { display: grid; grid-template-columns: 20px minmax(10rem, 1fr) auto max-content max-content max-content; column-gap: var(--space-3); }
.line-list > li { grid-column: 1 / -1; min-width: 0; }
.line-list > li.settled, .line-list > li.line-head, .line-list .settled-line.line-grid { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; }
.line-grid, .settled-line.line-grid { gap: var(--space-1) var(--space-3); align-items: baseline; text-align: left; }
.line-grid .amt { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.line-grid .line-name { font-weight: 600; overflow-wrap: anywhere; }
.line-head { color: var(--ink-soft); font-size: var(--text-sm); font-weight: 600; padding: 0 0 var(--space-1); }
/* A narrow list (a phone, or beside the invoice image on a laptop) stacks each line: name, what came, then the amounts. */
@container (max-width: 40rem) {
  .line-list { display: block; }
  .line-list > li.settled, .line-list .settled-line.line-grid { display: grid; grid-template-columns: 20px minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); }
  .line-grid .amt[data-label]:not(:empty)::before { content: attr(data-label) " "; color: var(--ink-soft); font-size: var(--text-sm); display: block; }
  .line-grid .line-name, .line-grid .line-came { grid-column: 2 / -1; }
  .line-grid .amt { grid-column: auto; text-align: left; white-space: normal; }
  .line-grid .amt:nth-of-type(4) { grid-column: 2; }
  .line-list > li.line-head { display: none; }  /* the amounts carry their own labels here (R5-C-01) */
}
.drop-card.over { border-color: var(--focus); background: color-mix(in srgb, var(--focus) 8%, var(--paper)); }
.drop-card p { margin: 0; }
/* drop-zone.tsx: every place files are added uses this box. Filling its container, at most a readable width. */
.drop-card { width: 100%; max-width: 40rem; box-sizing: border-box; margin: var(--space-3) 0; }
.drop-card .drop-icon { color: var(--ink-soft); }
.drop-card.disabled { opacity: .6; }
.drop-card .hint { max-width: 32em; }

/* Tables: every table stripes, in a tint unlike both the card and the page; .dense is tighter. Under 760px, .stack turns
   rows into cards. */
:root { --row-stripe: color-mix(in srgb, var(--focus) 5%, var(--paper)); }
table.list-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--text-sm); }
table.list-table th, table.list-table td { padding: var(--space-2) var(--space-3); text-align: left; border-bottom: 1px solid var(--edge); vertical-align: middle; }
table.list-table thead th { position: sticky; top: 0; z-index: 1; background: var(--paper); color: var(--ink-soft); font-weight: 600;
  font-size: var(--text-sm); border-bottom: 1px solid var(--ink-soft); }
table.list-table th.money, table.list-table td.money { text-align: right; }
/* Column names wrap (never run into the next one); amounts never break; names wrap anywhere they must (CJK has no spaces). */
table.list-table thead th { vertical-align: bottom; }
table.list-table td.name { overflow-wrap: anywhere; min-width: 12em; }
table.list-table tbody tr:nth-child(even) { background: var(--row-stripe); }
/* The app's other tables stripe the same way (docs/style-guides/style-guide.md, Tables): every real table, never the page's own color */
.model-table tbody tr:nth-child(even), .cost-table tbody tr:nth-child(even), table.sizes tbody tr:nth-child(even),
.mix-table tbody tr:nth-child(even), table.impact tbody tr:nth-child(even), .covers-table tbody tr:nth-child(even),
.people-table tbody tr:nth-child(even), table.small tbody tr:nth-child(even) { background: var(--row-stripe); }
table.list-table tbody tr:hover { background: color-mix(in srgb, var(--focus) 11%, var(--paper)); }
/* Names and units left, amounts right, row actions centered and stacked; headings take their column's alignment */
table.list-table th.actions, table.list-table td.actions { text-align: center; }
table.list-table td.actions .stacked { display: grid; justify-items: center; gap: 2px; }
table.list-table td .under { display: block; font-weight: 400; font-size: var(--text-xs); color: var(--ink-soft); }
table.list-table tbody tr:last-child td { border-bottom: 0; }
table.list-table td.name { font-weight: 600; }
table.list-table.dense th, table.list-table.dense td { padding: var(--space-1) var(--space-2); border-bottom: 0; }
.row-open { color: var(--ink-soft); text-decoration: none; }
@media (max-width: 760px) {
  table.list-table.stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.list-table.stack, table.list-table.stack tbody, table.list-table.stack tr, table.list-table.stack td { display: block; }
  table.list-table.stack tr { border: 1px solid var(--edge); border-radius: var(--radius); padding: var(--space-3); margin-bottom: var(--space-2);
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-1) var(--space-3); }
  table.list-table.stack tbody tr:nth-child(even) { background: var(--paper); }  /* a card per row: no stripes */
  table.list-table.stack td { border: 0; padding: 0; }
  table.list-table.stack td.name { grid-column: 1; }
  table.list-table.stack td.lead { grid-column: 2; grid-row: 1; text-align: right; font-weight: 700; }
  table.list-table.stack td:not(.name):not(.lead) { grid-column: 1 / -1; display: flex; justify-content: space-between; color: var(--ink-soft); }
  table.list-table.stack td:not(.name):not(.lead)::before { content: attr(data-label); }
  /* a group's heading ("Sauces & dips (7)") stays a plain line above its cards */
  table.list-table.stack tr.group-row { display: block; border: 0; padding: 0; margin: var(--space-2) 0; background: none; }
  table.list-table.stack tr.group-row th { display: block; }
}

/* "Optional" after a field's label, gray, on the same line (docs/style-guides/style-guide.md, Forms) */
.optional { color: var(--ink-soft); font-weight: 400; font-size: var(--text-sm); margin-left: 6px; }
.section-hint { display: block; margin: 2px 0 10px; color: var(--ink-soft); font-size: var(--text-sm); font-weight: 400; }
