/*
 * Recipe Tracker stylesheet.
 *

 */

/* ==========================================================================
   SELF-HOSTED FONTS  (public/fonts/*.woff2 -- served at /fonts/ because the app
   runs at the URL root with public_file_server enabled; kept offline like the
   rest of the app, no external CDN, no Sass/JS compiler needed). Figtree, Lora
   and Cormorant Garamond ship as single variable woff2 files covering their
   whole weight range; Caprasimo is a static 400.
   ========================================================================== */

@font-face { font-family:"Caprasimo";          font-style:normal; font-weight:400;     font-display:swap; src:url(/fonts/caprasimo.woff2) format("woff2"); }
@font-face { font-family:"Figtree";            font-style:normal; font-weight:300 800; font-display:swap; src:url(/fonts/figtree.woff2) format("woff2"); }
@font-face { font-family:"Cormorant Garamond"; font-style:normal; font-weight:300 700; font-display:swap; src:url(/fonts/cormorant-garamond.woff2) format("woff2"); }
@font-face { font-family:"Lora";               font-style:normal; font-weight:400 700; font-display:swap; src:url(/fonts/lora.woff2) format("woff2"); }
@font-face { font-family:"Lora";               font-style:italic; font-weight:400 700; font-display:swap; src:url(/fonts/lora-400i.woff2) format("woff2"); }

/* ==========================================================================
   THEME TOKENS  (2026 remodel -- Directions A "Organic" & B "Classical")
   Every colour, font, radius, shadow and the component-shape switches are CSS
   custom properties. :root holds the DEFAULT theme "organic" (light) -- both the
   colour palette AND the structural tokens (font families, pill radii, filled
   soft-shadow cards, solid-fill buttons). Each other theme is a [data-theme]
   block set on <body> from the user's profile (see User::THEMES):

     organic          -> :root (no block needed; <body data-theme="organic">)
     organic_dark     -> colour swaps only (inherits :root structure)
     classical        -> classical STRUCTURE (shared block) + light colours
     classical_dark   -> classical STRUCTURE (shared block) + dark colours

   Component rules elsewhere read these tokens, so most A/B differences are just
   token values -- only genuinely different shapes (e.g. the classical table's
   2px top rule + italic notes) are scoped by [data-theme] in the component CSS.
   ========================================================================== */

/* ---- Direction A -- Organic (light) : the app DEFAULT (also fills :root) ---- */
:root {
  /* Type */
  --font-heading:"Caprasimo", Georgia, "Times New Roman", serif;
  --font-body:"Figtree", "Segoe UI", Helvetica, Arial, sans-serif;
  --heading-weight:400; --heading-spacing:0;

  /* Shape / elevation */
  --radius-card:20px; --radius-btn:999px; --radius-chip:999px;
  --radius-input:999px; --radius-badge:999px;
  --shadow-sm:0 1px 2px rgba(46,43,37,.14);
  --shadow-md:0 3px 10px rgba(46,43,37,.16);
  --shadow-lg:0 12px 32px rgba(46,43,37,.22);
  --card-bg:var(--surface); --card-border:1px solid var(--border-soft);
  --card-shadow:var(--shadow-md);

  /* Buttons (primary) -- solid accent fill, pill */
  --btn-bg:var(--accent); --btn-fg:var(--accent-on); --btn-border:transparent;
  --btn-hover-bg:var(--accent-hover); --btn-hover-fg:var(--accent-on);

  /* Chips (category / protein / cook style) and tags -- filled tints */
  --chip-bg:#efe2ca; --chip-border:transparent; --chip-fg:#6b5a42;
  --tag-bg:#e9efd9; --tag-border:transparent; --tag-fg:#4c5a35;
  /* Recipes table: sort-header row = neutral-200 with muted neutral-700 labels;
     the filter row below is the lighter neutral-100 (matches the design). */
  --table-head-bg:#eee7db; --table-head-fg:#645c50; --table-filter-bg:#f9f4ed; --table-head-border:var(--border);
  --meal-dayhead-bg:#3d472b;   /* sage accent-2-800 -- the planner's green day headers */

  /* Palette */
  --page-bg:#f5ead8; --surface:#ebddc5; --surface-2:#e3d5bd; --surface-hover:#f0e6d3;
  --text:#201e1d; --text-2:#5c5344; --muted:#82796a; --heading:#2b2018;
  --recipe-name:#2b2018;
  --border:rgba(32,30,29,.16); --border-strong:rgba(32,30,29,.30); --border-soft:rgba(32,30,29,.10);
  --accent:#c67139; --accent-hover:#b2622d; --accent-on:#ffffff;
  --accent-2:#7a8a5e; --good-strong:#56633f;
  /* Bought / checked-off (shopping). Sage in Organic; the Classical blocks remap
     it to GOLD so no green ever appears there (bought is shown by check+strike). */
  --bought:#7a8a5e; --bought-tint:#e7efd8; --bought-ink:#425626;
  --masthead-bg:#643312; --masthead-border:#4a2610; --masthead-text:#ffffff;
  --masthead-link:#ffe1d0; --masthead-link-hover:#ffffff; --masthead-muted:#f0cbb4;
  --masthead-active:#ffc6a5; --nav-sep:rgba(255,255,255,.30);
  --btn-secondary:#6b6257; --btn-secondary-hover:#554d44;
  --btn-danger:#c15a3c; --btn-danger-on:#fff;
  /* Secondary buttons: a soft cream pill (Organic) -- see [data-theme] blocks. */
  --btn2-bg:#faf3e6; --btn2-fg:var(--text); --btn2-border:var(--border-strong); --btn2-hover-bg:#fffdf8;

  /* Status / opinions -- Organic-tuned traffic light (shared meaning) */
  --good:#6f8f4e; --warn:#cf9a3f; --warn-2:#c97a3a; --bad:#c15a3c; --neutral:#a99b86;
  --ok-bg:#e7efd8; --ok-border:#a9c489; --ok-text:#425626;
  --err-bg:#f6e0d6; --err-border:#dda286; --err-text:#7a3a24;
  --info-bg:#eef1e4; --info-border:#c4cbaa; --info-text:#56633f;

  /* Weather-icon accents (meal planner). Subtle so they don't fight the data.
     Organic palette; the Classical block below re-tints them. Shared across
     light/dark of a direction -- these mid-tones read on both. */
  --wx-sun:#e6a93c; --wx-partly:#d8b45a; --wx-cloud:#a7adb3; --wx-rain:#7098bd; --wx-snow:#9fb6c9;
}

/* ---- Direction A -- Organic (dark) : "after dark" (structure from :root) ---- */
[data-theme="organic_dark"] {
  --page-bg:#231e17; --surface:#332c22; --surface-2:#3d3529; --surface-hover:#3a3227;
  --text:#f3e8d6; --text-2:#ded1b8; --muted:#b9ab90; --heading:#f3e8d6;
  --recipe-name:#ffc6a5;
  --border:rgba(243,232,214,.14); --border-strong:rgba(243,232,214,.28); --border-soft:rgba(243,232,214,.09);
  --accent:#d98a54; --accent-hover:#e39a68; --accent-on:#231e17; --accent-2:#9fb07d;
  --bought:#9fb07d; --bought-tint:#26331f; --bought-ink:#c3e0aa;
  --masthead-bg:#3a1f12; --masthead-border:#2a160c; --masthead-text:#fdf1e6;
  --masthead-link:#ffd9c2; --masthead-link-hover:#ffffff; --masthead-muted:#e0b89e;
  --masthead-active:#ffc6a5; --nav-sep:rgba(255,255,255,.22);
  --btn-secondary:#4a4133; --btn-secondary-hover:#5a5040;
  --btn-danger:#c15a3c; --btn-danger-on:#fff;
  --btn2-bg:var(--surface-2); --btn2-fg:var(--text); --btn2-border:var(--border-strong); --btn2-hover-bg:var(--surface-hover);

  --chip-bg:#3d3529; --chip-border:transparent; --chip-fg:#ded1b8;
  --tag-bg:#39402c; --tag-border:transparent; --tag-fg:#cfe0a8;
  --table-head-bg:#2c2620; --table-head-fg:#cdbfa3; --table-filter-bg:#3a3227; --table-head-border:var(--border);
  --meal-dayhead-bg:#3d472b;
  --shadow-sm:0 1px 2px rgba(0,0,0,.35);
  --shadow-md:0 3px 12px rgba(0,0,0,.40);
  --shadow-lg:0 14px 34px rgba(0,0,0,.52);

  --good:#7fa15b; --warn:#d6a24b; --warn-2:#cf8548; --bad:#d1694a; --neutral:#b3a68f;
  --ok-bg:#26331f; --ok-border:#4c6b39; --ok-text:#c3e0aa;
  --err-bg:#3a201c; --err-border:#7a3a30; --err-text:#f0b3a6;
  --info-bg:#2b3122; --info-border:#4f5c3a; --info-text:#cfe0a8;
}

/* ---- Direction B -- Classical : shared STRUCTURE (both light & dark) ----------
   Editorial system: serif display type, hairline rules over fills, near-square
   radii, OUTLINED buttons/chips, elevation reduced to a whisper. Colours are
   layered on top by the two blocks that follow. */
[data-theme="classical"],
[data-theme="classical_dark"] {
  --font-heading:"Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-body:"Lora", Georgia, "Times New Roman", serif;
  --heading-weight:600; --heading-spacing:.005em;

  --radius-card:6px; --radius-btn:4px; --radius-chip:4px;
  --radius-input:4px; --radius-badge:3px;
  --shadow-sm:none;
  --shadow-md:0 1px 2px rgba(0,0,0,.06);
  --shadow-lg:0 2px 8px rgba(0,0,0,.10);
  --card-bg:transparent; --card-border:1px solid var(--border); --card-shadow:none;

  /* Outlined buttons: transparent fill, accent border + text */
  --btn-bg:transparent; --btn-fg:var(--accent); --btn-border:var(--accent);
  --btn-hover-bg:var(--accent-tint); --btn-hover-fg:var(--accent-hover);

  /* Outlined chips / tags */
  --chip-bg:transparent; --chip-border:var(--border-strong); --chip-fg:var(--text-2);
  --tag-bg:transparent; --tag-border:var(--accent); --tag-fg:var(--accent);

  /* Weather-icon accents -- Classical (muted, gold sun). Shared by both variants. */
  --wx-sun:#c79a3a; --wx-partly:#b8974a; --wx-cloud:#9a968d; --wx-rain:#6d8299; --wx-snow:#8ea3b0;

  /* Secondary buttons: outlined neutral (transparent + hairline). */
  --btn2-bg:transparent; --btn2-fg:var(--text); --btn2-border:var(--border-strong); --btn2-hover-bg:var(--surface-hover);
}

/* ---- Direction B -- Classical (light) : "the family cookbook" ---- */
[data-theme="classical"] {
  --page-bg:#f3f2f2; --surface:#eae9e9; --surface-2:#eae9e9; --surface-hover:#efefef;
  --text:#201f1d; --text-2:#4a4843; --muted:#7d7a73; --heading:#201f1d;
  --recipe-name:#201f1d;
  --border:rgba(32,31,29,.16); --border-strong:rgba(32,31,29,.50); --border-soft:rgba(32,31,29,.10);
  --accent:#b68235; --accent-hover:#a06f24; --accent-on:#ffffff;
  --accent-2:#7d7a73; --accent-tint:rgba(182,130,53,.12); --good-strong:#5c7a3f;
  /* Classical is mono-gold: bought = gold check + strike, never green. */
  --bought:#b68235; --bought-tint:rgba(182,130,53,.14); --bought-ink:#a06f24;
  --masthead-bg:#221f1b; --masthead-border:#b68235; --masthead-text:#efe9dc;
  --masthead-link:#efe9dc; --masthead-link-hover:#ffffff; --masthead-muted:#b8b1a3;
  --masthead-active:#b68235; --nav-sep:rgba(239,233,220,.30);
  --btn-secondary:#5a564e; --btn-secondary-hover:#46433c;
  --btn-danger:#a24a37; --btn-danger-on:#fff;
  --table-head-bg:transparent; --table-head-border:var(--text); --meal-dayhead-bg:var(--masthead-bg);

  --good:#5c7a3f; --warn:#b0842f; --warn-2:#a06f24; --bad:#a24a37; --neutral:#8a8378;
  --ok-bg:#e7ece0; --ok-border:#a9bb92; --ok-text:#42522e;
  --err-bg:#f2e2de; --err-border:#c99b8f; --err-text:#7a3327;
  --info-bg:#eceae4; --info-border:#c9c3b3; --info-text:#5a564e;
}

/* ---- Direction B -- Classical (dark) : "the colophon" ---- */
[data-theme="classical_dark"] {
  --page-bg:#1a1815; --surface:#262320; --surface-2:#262320; --surface-hover:#2e2a26;
  --text:#ece7dc; --text-2:#c7c0b1; --muted:#8a8378; --heading:#ece7dc;
  --recipe-name:#d8b06a;
  --border:rgba(236,231,220,.16); --border-strong:rgba(236,231,220,.42); --border-soft:rgba(236,231,220,.10);
  --accent:#c69a4f; --accent-hover:#d8b06a; --accent-on:#1a1815;
  --accent-2:#a49d90; --accent-tint:rgba(198,154,79,.15); --good-strong:#8fa06a;
  --bought:#c69a4f; --bought-tint:rgba(198,154,79,.18); --bought-ink:#d8b06a;
  --masthead-bg:#100e0c; --masthead-border:#b68235; --masthead-text:#ece7dc;
  --masthead-link:#ece7dc; --masthead-link-hover:#ffffff; --masthead-muted:#a49d90;
  --masthead-active:#d8b06a; --nav-sep:rgba(236,231,220,.24);
  --btn-secondary:#3a352f; --btn-secondary-hover:#48423a;
  --btn-danger:#a24a37; --btn-danger-on:#fff;
  --table-head-bg:transparent; --table-head-border:var(--text); --meal-dayhead-bg:var(--masthead-bg);

  --good:#7f9a5c; --warn:#c49a4a; --warn-2:#c09149; --bad:#c06a52; --neutral:#a49d90;
  --ok-bg:#242a1d; --ok-border:#4b5a36; --ok-text:#c3d3a4;
  --err-bg:#33211d; --err-border:#6f3a30; --err-text:#e6b0a4;
  --info-bg:#2a2823; --info-border:#4d4940; --info-text:#cdc6b6;
}

/* Fallback for the accent tint used by outlined-button hover, in case a theme
   forgets to set it (organic themes don't use it). */
:root { --accent-tint:rgba(198,113,57,.12); }

/* ---- Shared interaction states (all themes) ---- */
:where(a, button, input, select, textarea, [tabindex], .button, summary):focus-visible {
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:2px;
}
::selection { background:var(--accent); color:var(--accent-on); }
[disabled], .is-disabled { opacity:.45; cursor:default; }

/* Secondary buttons keep light text (their grey backgrounds stay dark in every
   theme). Danger buttons use --btn-danger-on so themes with a pale red can put
   dark text on it for legibility -- they never follow --accent-on. */
.button.danger, button.danger { color: var(--btn-danger-on); }

/* ---- Profile: live theme preview ---- */
.profile-theme .theme-preview {
  margin-top: 16px;
  max-width: 520px;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--page-bg);
  color: var(--text);
}
.theme-preview .tp-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--masthead-bg);
  color: var(--masthead-text);
  border-bottom: 3px solid var(--masthead-border);
}
.theme-preview .tp-brand { font-weight: bold; }
.theme-preview .tp-nav { font-size: 12px; color: var(--masthead-link); }
.theme-preview .tp-body {
  padding: 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.theme-preview .tp-card {
  flex: 1 1 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
}
.theme-preview .tp-title { font-weight: bold; color: var(--heading); }
.theme-preview .tp-chips,
.theme-preview .tp-kids { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }


/* ---------- Base ---------- */
* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background: var(--page-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a        { color: var(--accent); text-decoration: none; }
a:hover  { text-decoration: underline; }

.inner {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- Masthead ---------- */
#masthead {
  background: var(--masthead-bg);
  color: var(--masthead-text);
  padding: 14px 0;
  border-bottom: 4px solid var(--masthead-border);
}
#masthead .inner {
  display: flex;
  flex-wrap: nowrap;   /* keep title + nav + search + user on ONE line every page */
  align-items: center;
  gap: 6px 16px;
}
.site-title {
  margin: 0;
  font-size: 22px;
  flex: none;
}
.main-nav { flex: none; }
.user-box { flex: none; }
.site-title a, .site-title a:hover {
  color: var(--masthead-text);
  text-decoration: none;
}
.main-nav a {
  color: var(--masthead-link);
  margin-right: 12px;
  font-size: 14px;
}
.main-nav a:hover { color: var(--masthead-link-hover); }
.main-nav a.is-active {
  color: var(--masthead-link-hover);
  border-bottom: 2px solid var(--masthead-active);
  padding-bottom: 3px;
  text-decoration: none;
}
.main-nav .nav-sep { color: var(--nav-sep); margin-right: 8px; }
.site-title a { font-family: var(--font-heading); font-weight: var(--heading-weight); letter-spacing: .01em; }

/* ---------- Content ---------- */
#content { padding-top: 24px; padding-bottom: 40px; min-height: 60vh; }

h1, h2, h3, h4 {
  color: var(--heading);
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  letter-spacing: var(--heading-spacing);
  line-height: 1.15;
}
h1 { margin-top: 0; }
/* Classical display headings read bigger + lighter than Organic's chunky slab. */
[data-theme="classical"] h1, [data-theme="classical_dark"] h1 { font-size: 34px; letter-spacing: .01em; }
[data-theme="classical"] h2, [data-theme="classical_dark"] h2 { font-weight: 600; }

/* ---------- Flash ---------- */
.flash {
  padding: 10px 14px;
  border-radius: 4px;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.flash-notice { background: var(--ok-bg); border-color: var(--ok-border); color: var(--ok-text); }
.flash-alert  { background: var(--err-bg); border-color: var(--err-border); color: var(--err-text); }

/* ---------- Buttons ----------
   Token-driven so Organic renders solid accent-filled pills and Classical
   renders outlined 4px buttons -- same markup, shape switched by tokens. */
.button, button, input[type="submit"] {
  display: inline-block;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-border);
  padding: 8px 15px;
  border-radius: var(--radius-btn);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.button:hover, button:hover, input[type="submit"]:hover {
  background: var(--btn-hover-bg);
  color: var(--btn-hover-fg);
  border-color: var(--btn-hover-fg);
  text-decoration: none;
}
/* Secondary buttons: a quiet companion to the primary -- a soft cream pill in
   Organic, an outlined neutral in Classical (per-theme via --btn2-*). */
.button.secondary, button.secondary {
  background: var(--btn2-bg); color: var(--btn2-fg); border-color: var(--btn2-border);
}
.button.secondary:hover, button.secondary:hover {
  background: var(--btn2-hover-bg); color: var(--btn2-fg); border-color: var(--btn2-border);
}
/* Danger stays solid-filled in both directions (it carries meaning). */
.button.danger, button.danger {
  background: var(--btn-danger); border-color: var(--btn-danger);
}
.button.danger:hover, button.danger:hover { filter: brightness(.92); color: var(--btn-danger-on); }
.button.small { padding: 4px 11px; font-size: 12px; }

/* ---------- Tables ---------- */
table.list {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
}
table.list th, table.list td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-soft);
  text-align: left;
  vertical-align: middle;
}
table.list th {
  background: var(--table-head-bg);
  color: var(--table-head-fg, var(--heading));
  font-family: var(--font-body);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
table.list tr:hover td { background: var(--surface-hover); }
/* Recipes table: the filter row sits on the lighter neutral-100 tint, distinct
   from the sort-header row above it (design). */
#recipes-table .filter-row th { background: var(--table-filter-bg, var(--table-head-bg)); }
/* Sort-header row uses the sage green from the meal planner + cream text
   (Organic only; Classical keeps its hairline top-rule header). */
[data-theme="organic"] #recipes-table .head-row th,
[data-theme="organic_dark"] #recipes-table .head-row th {
  background: var(--meal-dayhead-bg);
  color: var(--masthead-text);
  border-bottom-color: rgba(255,255,255,.18);
}
[data-theme="organic"] #recipes-table .head-row th:hover,
[data-theme="organic_dark"] #recipes-table .head-row th:hover { background: #4a5636; }
/* Classical: no filled header -- a 2px top rule + hairline row rules instead. */
[data-theme="classical"] table.list,
[data-theme="classical_dark"] table.list { background: transparent; border: none; }
[data-theme="classical"] table.list th,
[data-theme="classical_dark"] table.list th {
  border-top: 2px solid var(--table-head-border);
  border-bottom: 1px solid var(--border);
}

/* Sortable table headers (see sortable_table.js). */
table.sortable th.sortable-col { cursor: pointer; -webkit-user-select: none; -moz-user-select: none; user-select: none; }
table.sortable th.sortable-col:hover { background: var(--surface-hover); }
table.sortable th.sortable-col:after { content: '\2195'; opacity: 0.35; margin-left: 6px; font-size: 11px; }
table.sortable th.sort-asc:after  { content: '\2191'; opacity: 0.9; }
table.sortable th.sort-desc:after { content: '\2193'; opacity: 0.9; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block;
  padding: 2px 9px;
  border: 1px solid transparent;
  border-radius: var(--radius-badge);
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  white-space: nowrap;
}
.opinion-yes      { background: var(--good); }
.opinion-meh      { background: var(--warn); }
.opinion-no       { background: var(--bad); }
.opinion-notsure  { background: var(--neutral); }
.opinion-blank    { background: var(--surface-2); color: var(--muted); }

.complexity-easy   { background: var(--good); }
.complexity-medium { background: var(--warn); }
.complexity-hard   { background: var(--warn-2); }
.complexity-expert { background: var(--bad); }
.complexity-blank  { background: var(--surface-2); color: var(--muted); }

/* "What the kids think" list on the recipe detail: coloured dot + name, with the
   verdict word pushed to the right (see opinion_dot helper). */
.kids-verdict { list-style: none; margin: 0; padding: 0; max-width: 440px; }
.kids-verdict li {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 2px; border-bottom: 1px solid var(--border-soft);
}
.kids-verdict li:last-child { border-bottom: none; }
.op-dot { width: 13px; height: 13px; border-radius: 50%; flex: none; display: inline-block; }
.op-dot.opinion-blank { background: transparent; box-shadow: inset 0 0 0 2px var(--border-strong); }
.kids-verdict .kv-name { font-weight: 600; }
.kids-verdict .kv-op { margin-left: auto; color: var(--text-2); }

/* Classical: complexity is an OUTLINED chip -- text + border in the status
   colour, transparent fill (kids' opinions stay filled dots, see below). */
[data-theme="classical"]  .badge[class*="complexity-"],
[data-theme="classical_dark"] .badge[class*="complexity-"] {
  background: transparent; font-weight: 600;
}
[data-theme="classical"]  .complexity-easy,   [data-theme="classical_dark"] .complexity-easy   { color: var(--good);  border-color: var(--good); }
[data-theme="classical"]  .complexity-medium, [data-theme="classical_dark"] .complexity-medium { color: var(--warn);  border-color: var(--warn); }
[data-theme="classical"]  .complexity-hard,   [data-theme="classical_dark"] .complexity-hard   { color: var(--warn-2);border-color: var(--warn-2); }
[data-theme="classical"]  .complexity-expert, [data-theme="classical_dark"] .complexity-expert { color: var(--bad);   border-color: var(--bad); }
[data-theme="classical"]  .complexity-blank,  [data-theme="classical_dark"] .complexity-blank  { color: var(--muted); border-color: var(--border-strong); }

/* Marks a "My Recipe" that was imported from a linked website (vs written by us). */
.origin-badge {
  display: inline-block;
  vertical-align: middle;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 10px;
  border: 1px solid var(--info-border);
  background: var(--info-bg);
  color: var(--info-text);
  font-size: 11px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
h1 .origin-badge { font-size: 13px; }

/* ---------- Forms ---------- */
.form-field { margin-bottom: 16px; }
.form-field label {
  display: block;
  font-weight: bold;
  margin-bottom: 4px;
  color: var(--heading);
}
input[type="text"], input[type="url"], input[type="email"], input[type="password"],
input[type="search"], input[type="number"], input[type="date"], input[type="file"],
textarea, select {
  width: 100%;
  max-width: 520px;
  padding: 7px 8px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 14px;
  background: var(--surface);
  color: var(--text);
}
/* Native <select> dropdown list items (and date/time controls) use OS defaults
   unless told otherwise -- without this the option text renders black on the
   dark themes' dark surface and is unreadable. */
select option, select optgroup { background: var(--surface); color: var(--text); }
input[type="date"] { color-scheme: light dark; }
textarea { min-height: 90px; }
.form-actions { margin-top: 20px; }
.field-hint { color: var(--muted); font-size: 12px; }

.errors {
  background: var(--err-bg);
  border: 1px solid var(--err-border);
  color: var(--err-text);
  padding: 10px 14px;
  border-radius: 4px;
  margin-bottom: 16px;
}
.errors ul { margin: 6px 0 0 18px; }

/* ---------- Ratings grid on the form ---------- */
.ratings-grid { display: table; border-spacing: 10px 0; }
.rating-cell  { display: inline-block; margin-right: 16px; }
.rating-cell label { display: block; }

/* ---------- Recipe show ---------- */
/* Two-column detail: meta + cooked log (+ notes) on the left, a sidebar with the
   kids' verdicts and recipe links on the right (collapses to one column on
   phones). */
.recipe-detail-grid { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.recipe-main { min-width: 0; display: flex; flex-direction: column; gap: 20px; }
.recipe-aside { display: flex; flex-direction: column; gap: 20px; }
/* Both columns' sections are cards (filled surface + soft shadow in Organic,
   hairline in Classical), matching the design. */
.recipe-detail-grid .section {
  margin: 0;
  background: var(--card-bg); border: var(--card-border);
  border-radius: var(--radius-card); box-shadow: var(--card-shadow);
  padding: 16px 18px;
}
.recipe-detail-grid .section h2 { margin-top: 0; }
@media (max-width: 760px) {
  .recipe-detail-grid { grid-template-columns: 1fr; gap: 14px; }
}

/* Meta: one row of chips (complexity pill + category/protein/cook + tags). */
.recipe-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin: 0 0 4px; }

/* Edit / Delete under the sidebar. */
.recipe-actions { display: flex; gap: 8px; }
.recipe-actions .inline-form { display: inline-flex; }

.section { margin-bottom: 28px; }
.section h2 {
  border-bottom: 2px solid var(--border);
  padding-bottom: 6px;
}

/* ---------- Pictures ---------- */
.gallery { list-style: none; margin: 0; padding: 0; }
.gallery li {
  display: inline-block;
  vertical-align: top;
  margin: 0 12px 12px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 6px;
  border-radius: 4px;
}
.gallery img {
  display: block;
  max-width: 220px;
  max-height: 220px;
  height: auto;
}
.gallery .caption { font-size: 12px; color: var(--muted); margin-top: 4px; max-width: 220px; }
.thumb-small img { max-width: 70px; max-height: 70px; }

/* Every page matches the recipes page: the masthead AND the content use the same
   (wider) width site-wide, so the brand, page heading, and content all align at
   the same left edge on every page -- not just on the recipes index. */
#masthead .inner, #content.inner { max-width: 1440px; }

/* ---------- Recipes index ---------- */
/* The table sizes to its content (not stretched) so it stays compact; if it
   needs more than the container, .table-scroll scrolls it horizontally. */
body.recipes-index table.sortable-table { width: auto; }

/* ---------- Sortable / filterable table ---------- */
.table-scroll { overflow-x: auto; }

/* Compact cells so all columns fit without horizontal scrolling. */
table.sortable-table { font-size: 13px; }
table.sortable-table th,
table.sortable-table td { padding: 5px 8px; }

/* Notes column: capped width, wraps instead of forcing the table wide. */
table.sortable-table td.note-cell { color: var(--muted); font-size: 12px; }
/* Classical sets notes in italic, editorial-style. */
[data-theme="classical"] table.sortable-table td.note-cell,
[data-theme="classical_dark"] table.sortable-table td.note-cell { font-style: italic; }
table.sortable-table td.note-cell .note-clip {
  max-width: 300px;
  white-space: normal;
  line-height: 1.35;
}

table.sortable-table th.sortable {
  cursor: pointer;
  white-space: nowrap;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
table.sortable-table th.sortable:hover { background: var(--surface-hover); }
table.sortable-table th.sorted { background: var(--surface-2); }
table.sortable-table th .sort-ind {
  font-size: 11px;
  color: var(--muted);
  margin-left: 3px;
}

table.sortable-table tr.filter-row th {
  background: var(--surface-2);
  padding: 4px 6px;
  border-bottom: 1px solid var(--border);
}
table.sortable-table tr.filter-row input,
table.sortable-table tr.filter-row select {
  width: 100%;
  min-width: 68px;
  max-width: none;
  padding: 3px 4px;
  font-size: 12px;
}

/* ---------- "Has a write-up" indicator ---------- */
.recipe-doc-icon,
.recipe-link-icon {
  text-decoration: none;
  margin-left: 5px;
  font-size: 13px;
  opacity: 0.8;
  cursor: pointer;
}
.recipe-doc-icon:hover,
.recipe-link-icon:hover { opacity: 1; text-decoration: none; }

/* ---------- Inline-editable cells ---------- */
table.sortable-table td.editable {
  cursor: pointer;
  position: relative;
}
table.sortable-table td.editable:hover {
  background: var(--surface-hover);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}
table.sortable-table td.editable:hover:after {
  content: "\270E"; /* pencil */
  position: absolute;
  top: 3px;
  right: 4px;
  font-size: 10px;
  color: var(--accent);
}
table.sortable-table td.editing,
table.sortable-table td.editing:hover { background: var(--surface); box-shadow: none; }
table.sortable-table td.editing:after { content: none; }
.inline-edit-select {
  width: 100%;
  min-width: 90px;
  max-width: none;
  padding: 3px 4px;
  font-size: 13px;
}
table.sortable-table td.saving { opacity: 0.5; }
table.sortable-table td.cell-saved { background: var(--ok-bg) !important; box-shadow: inset 0 0 0 1px var(--ok-border) !important; }
table.sortable-table td.cell-error { background: var(--err-bg) !important; box-shadow: inset 0 0 0 1px var(--err-border) !important; }

/* ---------- Filter bar ---------- */
.filter-bar {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 12px 14px;
  margin-bottom: 20px;
}
.filter-bar .filter-field {
  display: inline-block;
  vertical-align: bottom;
  margin: 0 12px 8px 0;
}
.filter-bar label { display: block; font-size: 12px; font-weight: bold; color: var(--heading); }
.filter-bar select, .filter-bar input[type="text"] { width: auto; min-width: 140px; }

/* ---------- Misc ---------- */
.toolbar { margin-bottom: 18px; }
/* Recipes index toolbar: "Add a recipe" stays left; Clear / Download / the
   Table-Tiles toggle / count are pushed to the right (design layout). The long
   hint drops to its own line. */
body.recipes-index .toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
body.recipes-index .toolbar #clear-filters { margin-left: auto; }
body.recipes-index .toolbar .field-hint { flex-basis: 100%; margin-top: 2px; }
/* Notes column hidden in the recipes table (kept in the DOM so recipes_table.js
   column indexing is unaffected; the data is still in the CSV export). */
.col-notes { display: none; }
.muted { color: var(--muted); }
.inline-form { display: inline; }
.stat-cards { margin: 0 0 24px 0; padding: 0; list-style: none; }
.stat-cards li {
  display: inline-block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 16px 22px;
  margin: 0 12px 12px 0;
  text-align: center;
}
.stat-cards .num { display: block; font-size: 30px; font-weight: bold; color: var(--accent); }
.stat-cards .lbl { color: var(--muted); font-size: 13px; }

/* ---------- View toggle (table / tiles) ---------- */
.view-toggle { display: inline-block; margin-left: 4px; vertical-align: middle; }
.view-toggle .view-btn { border-radius: 0; margin: 0; }
.view-toggle .view-btn:first-child { border-radius: 4px 0 0 4px; }
.view-toggle .view-btn:last-child  { border-radius: 0 4px 4px 0; }
.view-toggle .view-btn.is-active {
  background: var(--accent); color: var(--accent-on); border-color: var(--accent);
}
.view-toggle .view-btn.is-active:hover {
  background: var(--accent-hover); color: var(--accent-on); border-color: var(--accent-hover);
}

/* Show one container at a time. In tiles mode the table header stays visible
   so its sort + per-column filters still drive both views; only the tbody is
   hidden. */
#recipes-view.view-table #recipes-tiles { display: none; }
#recipes-view.view-tiles #recipes-table tbody { display: none; }
/* With the tbody hidden the header table would shrink to its own content width;
   stretch it to fill the container so the sort/filter header lines up with the
   full-width tiles grid below it. */
#recipes-view.view-tiles #recipes-table { width: 100%; }

/* ---------- Tiles / cards ---------- */
.tiles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.recipe-tile {
  position: relative;
  background: var(--card-bg);
  border: var(--card-border);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow .14s ease, transform .14s ease;
}
/* Complexity pill floated over the top-left of the tile photo. */
.tile-complexity { position: absolute; top: 10px; left: 10px; z-index: 2; }
.tile-complexity .badge { box-shadow: 0 1px 3px rgba(0,0,0,.28); }
[data-theme="classical"] .tile-complexity, [data-theme="classical_dark"] .tile-complexity { top: 14px; left: 14px; }
[data-theme="classical"] .tile-complexity .badge, [data-theme="classical_dark"] .tile-complexity .badge {
  background: var(--surface); box-shadow: none;
}
.recipe-tile:hover { box-shadow: var(--shadow-lg); }
/* Classical tiles: a matted "plate" -- surface mat + hairline, no lift. */
[data-theme="classical"] .recipe-tile:hover,
[data-theme="classical_dark"] .recipe-tile:hover { box-shadow: var(--shadow-md); transform: none; }
[data-theme="classical"] .tile-photo,
[data-theme="classical_dark"] .tile-photo { margin: 6px 6px 0; border: 1px solid var(--border); border-radius: 3px; height: 144px; }
.tile-photo {
  height: 150px;
  background: var(--surface-2);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tile-photo img {
  width: 100%;
  height: 150px;
  object-fit: cover;
  display: block;
}
.tile-photo:hover { text-decoration: none; }
.tile-noimg { color: var(--muted); font-size: 13px; }
.tile-body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tile-title { font-weight: bold; font-size: 17px; line-height: 1.2; }
.tile-title a, .tile-title a:hover { color: var(--recipe-name); font-family: var(--font-heading); font-weight: var(--heading-weight); text-decoration: none; }
/* Recipe name in the desktop table reads as a display link too. */
#recipes-table td[data-value] > a[href]:first-child { color: var(--recipe-name); font-weight: 700; }
.tile-meta { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.chip {
  display: inline-block;
  background: var(--chip-bg);
  color: var(--chip-fg);
  border: 1px solid var(--chip-border);
  border-radius: var(--radius-chip);
  padding: 2px 9px;
  font-size: 12px;
  white-space: nowrap;
}
.tile-ratings { display: flex; flex-wrap: wrap; gap: 8px; }
.tile-rating { display: inline-flex; align-items: center; gap: 4px; }
.tile-rating-name { font-size: 11px; color: var(--muted); }

/* Kids' verdict as a compact colour dot (recipes table + tiles). The opinion
   badge keeps its class/colour + JS hooks; we just render it as a circle and
   visually hide the word. Full-word badges elsewhere (recipe detail, profile
   preview) are untouched. */
.tile-ratings .badge,
#recipes-table td[data-field="rating"] .badge {
  width: 13px; height: 13px; padding: 0; border-radius: 50%;
  overflow: hidden; text-indent: -999px; vertical-align: middle;
}
.tile-ratings .opinion-blank,
#recipes-table td[data-field="rating"] .opinion-blank {
  background: transparent; box-shadow: inset 0 0 0 2px var(--border-strong);
}
#recipes-table td[data-field="rating"] { text-align: center; }

/* ---------- Recipe show: hero photo ---------- */
.recipe-hero {
  position: relative;
  margin: 0 0 20px 0;
  border-radius: var(--radius-card);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface-2);
  box-shadow: var(--card-shadow);
}
/* Classical: photographs as tipped-in plates -- surface mat + hairline. */
[data-theme="classical"] .recipe-hero,
[data-theme="classical_dark"] .recipe-hero { padding: 6px; box-shadow: none; }
[data-theme="classical"] .recipe-hero-img,
[data-theme="classical_dark"] .recipe-hero-img { border: 1px solid var(--border); }
[data-theme="classical"] .recipe-hero-title,
[data-theme="classical_dark"] .recipe-hero-title { font-family: var(--font-heading); font-weight: 600; }
.recipe-hero-img {
  display: block;
  width: 100%;
  max-height: 380px;
  object-fit: cover;
}
.recipe-hero-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 32px 20px 14px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.68), rgba(0, 0, 0, 0));
}
.recipe-hero-title {
  margin: 0;
  color: #fff;
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: 34px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

/* ---------- Meal planner ---------- */
.meal-week h2, .meal-history h2 { margin-bottom: 8px; }

/* The week header row: a Prev/Next stepper flanking the week title (Previous
   week / This week / Next week on the index; the dated stepper on the #week
   page). Prev grows left, Next is pushed right, the title sits between them. */
.week-nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.week-nav h2 { margin: 0; }
.week-nav-prev, .week-nav-next { flex: 1 1 auto; }
.week-nav-next { text-align: right; }
.week-range {
  font-size: 15px;
  font-weight: normal;
  color: var(--muted);
  margin-left: 8px;
}
.more-weeks { margin-top: 10px; }

/* Planner phone layout: vertical day cards (hidden on desktop; the table shows
   there). Toggled at the phone breakpoint below. */
.meal-daycards { display: none; flex-direction: column; gap: 12px; }
.daycard {
  background: var(--card-bg); border: var(--card-border);
  border-radius: var(--radius-card); box-shadow: var(--card-shadow); overflow: hidden;
}
.daycard-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 10px 14px 8px; border-bottom: 1px solid var(--border);
}
.daycard-name { font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 19px; color: var(--heading); }
.daycard-today {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  background: var(--meal-dayhead-bg); color: var(--masthead-text);
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
}
.daycard-date { margin-left: auto; font-size: 12px; color: var(--muted); }
[data-theme="classical"] .daycard-head, [data-theme="classical_dark"] .daycard-head { border-bottom: 2px solid var(--text); }
[data-theme="classical"] .daycard-date, [data-theme="classical_dark"] .daycard-date { font-style: italic; }
.daycard.is-trailing .daycard-head { background: var(--surface-2); }
.daycard-row { display: flex; gap: 10px; align-items: flex-start; padding: 9px 14px; border-top: 1px solid var(--border-soft); }
.daycard-row:first-of-type { border-top: none; }
/* Meal-type CHIP (was a fixed-width label column) -- frees item text to full
   width. Each meal type gets its own tint (Organic: filled; Classical: outlined
   in the same hue). Falls back to the neutral chip tokens. */
.daycard-meal {
  flex: 0 0 62px; align-self: flex-start; margin-top: 1px; text-align: center;
  display: inline-block; padding: 2px 8px; border-radius: var(--radius-chip);
  background: var(--chip-bg); color: var(--chip-fg); border: 1px solid transparent;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
/* Organic: filled tints (bg + darker text of the same hue). */
[data-theme="organic"] .mp-chip-breakfast, [data-theme="organic_dark"] .mp-chip-breakfast { background:#f4e4c4; color:#8a5a1e; }
[data-theme="organic"] .mp-chip-lunch,     [data-theme="organic_dark"] .mp-chip-lunch     { background:#e6efd6; color:#4c5a35; }
[data-theme="organic"] .mp-chip-dinner,    [data-theme="organic_dark"] .mp-chip-dinner    { background:#f5ddcb; color:#8c491a; }
[data-theme="organic"] .mp-chip-event,     [data-theme="organic_dark"] .mp-chip-event     { background:#e2ddf0; color:#514a72; }
/* Classical: outlined in the same hues (transparent fill, coloured text+border). */
[data-theme="classical"] .daycard-meal, [data-theme="classical_dark"] .daycard-meal { background: transparent; }
[data-theme="classical"] .mp-chip-breakfast, [data-theme="classical_dark"] .mp-chip-breakfast { color:#9a6a24; border-color:#9a6a24; }
[data-theme="classical"] .mp-chip-lunch,     [data-theme="classical_dark"] .mp-chip-lunch     { color:#5c7a3f; border-color:#5c7a3f; }
[data-theme="classical"] .mp-chip-dinner,    [data-theme="classical_dark"] .mp-chip-dinner    { color:#a06f24; border-color:#a06f24; }
[data-theme="classical"] .mp-chip-event,     [data-theme="classical_dark"] .mp-chip-event     { color:#6a6357; border-color:#6a6357; }

/* Per-row pencil affordance (signals inline edit; taps open the same editor). */
.mp-row-edit {
  flex: 0 0 auto; align-self: flex-start; margin-top: 1px;
  background: transparent; border: none; padding: 2px; cursor: pointer;
  color: var(--muted); line-height: 0; border-radius: 6px;
}
.mp-row-edit:hover { color: var(--accent); background: var(--surface-hover); }
.mp-row-edit .nav-icon { width: 15px; height: 15px; }
/* height:auto is essential -- the base .meal-cell rule sets height:44px, which on
   a table cell is a minimum but on these flex-item divs is a FIXED height, so a
   multi-item dinner would overflow down into the Events row. */
.daycard .meal-cell, .daycard .event-cell { flex: 1 1 auto; min-height: 24px; height: auto; }
.daycard .editable-cell, .daycard .editable-events { cursor: text; border-radius: 6px; margin: -2px -4px; padding: 2px 4px; }
.daycard .editable-cell:hover, .daycard .editable-events:hover { background: var(--surface-hover); }

/* "+ Add lunch/event" ghost for empty fields (mobile day-cards only; the desktop
   table keeps empty cells blank). */
.mp-add-ghost { color: var(--muted); font-size: 14px; }
[data-theme="classical"] .mp-add-ghost, [data-theme="classical_dark"] .mp-add-ghost { font-style: italic; }
.meal-table .mp-add-ghost { display: none; }

/* Recipe-matched item text = underlined accent link (distinct from the badge). */
.daycard .meal-item a {
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
}
/* "Recently made" = a themed badge (Lucide repeat), NOT a link. */
.mp-recent {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-left: 6px; border-radius: 50%; vertical-align: middle;
}
.mp-recent .nav-icon { width: 12px; height: 12px; }
[data-theme="organic"] .mp-recent, [data-theme="organic_dark"] .mp-recent { background: var(--tag-bg); color: var(--good-strong); }
[data-theme="classical"] .mp-recent, [data-theme="classical_dark"] .mp-recent { background: transparent; border: 1px solid var(--accent); color: var(--accent); }

/* ---- Meal planner: mobile compact header (title + overflow + stepper + day strip) ---- */
.mp-mobile-bar { display: none; }
.mp-mtop { display: flex; align-items: center; justify-content: space-between; }
.mp-title { margin: 0; font-size: 24px; }
.mp-overflow { position: relative; }
.mp-overflow-btn {
  width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--text); cursor: pointer; padding: 0; border-radius: 8px;
}
.mp-overflow-btn:hover { background: var(--surface-hover); }
.mp-overflow-menu {
  position: absolute; right: 0; top: 42px; z-index: 20; min-width: 190px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg); padding: 6px; display: flex; flex-direction: column;
}
.mp-overflow-menu[hidden] { display: none; }
.mp-overflow-menu a, .mp-overflow-menu button {
  text-align: left; background: transparent; border: none; color: var(--text);
  padding: 9px 10px; font: inherit; border-radius: 6px; cursor: pointer; text-decoration: none;
}
.mp-overflow-menu a:hover, .mp-overflow-menu button:hover { background: var(--surface-hover); }

.mp-stepper { display: flex; align-items: center; gap: 10px; margin: 8px 0 4px; }
.mp-step {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--accent);
}
.mp-step:hover { background: var(--surface-hover); text-decoration: none; }
.mp-week {
  flex: 1 1 auto; text-align: center; display: flex; flex-direction: column; line-height: 1.1;
  font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 18px; color: var(--heading);
}
.mp-week-range { font-family: var(--font-body); font-size: 12px; font-weight: 400; color: var(--muted); }

.mp-daystrip { display: flex; gap: 6px; overflow-x: auto; -webkit-overflow-scrolling: touch; padding: 4px 0 2px; }
.mp-day-pill {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; min-width: 40px;
  padding: 5px 6px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface);
  color: var(--text-2); text-decoration: none;
}
.mp-day-pill .mp-day-dow { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; }
.mp-day-pill .mp-day-num { font-size: 15px; font-weight: 700; color: var(--text); }
.mp-day-pill.is-today { background: var(--meal-dayhead-bg); border-color: var(--meal-dayhead-bg); }
.mp-day-pill.is-today .mp-day-dow, .mp-day-pill.is-today .mp-day-num { color: var(--masthead-text); }
.mp-day-pill.is-selected { outline: 2px solid var(--accent); outline-offset: 1px; }

.meal-grid-wrap { overflow-x: auto; }
.meal-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 900px;
  background: var(--surface);
}
.meal-table th, .meal-table td {
  border: 1px solid var(--border);
  vertical-align: top;
  padding: 4px 6px;
}
.meal-rowhead {
  width: 78px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 12px;
  text-align: right;
  white-space: nowrap;
}
.meal-dayhead {
  background: var(--meal-dayhead-bg);
  color: var(--masthead-text);
  font-size: 12px;
  text-align: center;
  line-height: 1.2;
}
.meal-dayname { display: block; font-weight: bold; }
.meal-daydate { display: block; font-size: 11px; opacity: 0.85; }

/* ---------- Weather marker (meal planner day headers, day cards, day strip) ----------
   An inline icon + temperature under each day. The temps inherit the surrounding
   text colour; only the icon is tinted, via its .wx-<sym> class -> --wx-* token
   (kept subtle so it doesn't fight the plan). Renders nothing when a day has no
   stored weather (weather_marker returns "" for a nil info). */
.wx { display: inline-flex; align-items: center; gap: 3px; margin-top: 2px; font-size: 11px; line-height: 1; }
.meal-dayhead .wx { display: flex; justify-content: center; }
.wx-icon { width: 15px; height: 15px; flex: 0 0 auto; }
.wx-sun    { color: var(--wx-sun); }
.wx-partly { color: var(--wx-partly); }
.wx-cloud  { color: var(--wx-cloud); }
.wx-rain   { color: var(--wx-rain); }
.wx-snow   { color: var(--wx-snow); }
.wx-temps { display: inline-flex; align-items: baseline; gap: 1px; }
.wx-hi { font-weight: 700; }
.wx-lo { opacity: .7; }
.wx-sep { opacity: .5; margin: 0 1px; }
/* The marker as a link to the full 10-day forecast: inherit the header colour,
   no underline until hover (on the temps only, so the tinted icon stays clean). */
a.wx-link { color: inherit; text-decoration: none; cursor: pointer; }
a.wx-link:hover .wx-temps { text-decoration: underline; }
a.wx-link:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 3px; }
/* Day cards: weather beside the date rather than centred below it. */
.daycard-head .wx { margin-top: 0; margin-left: 6px; }
/* Mobile day-strip pill: compact (icon + high only), stacked under the number.
   Temps follow the pill's foreground -- light on the dark "today" pill. */
.mp-day-pill .wx-compact { margin-top: 1px; font-size: 9px; gap: 2px; color: var(--text-2); }
.mp-day-pill .wx-compact .wx-icon { width: 12px; height: 12px; }
.mp-day-pill.is-today .wx-compact { color: var(--masthead-text); }

.meal-cell, .event-cell { height: 44px; }
.meal-cell .cell-items, .event-cell .cell-items { min-height: 20px; }
.editable-cell, .editable-events { cursor: text; }
.editable-cell:hover, .editable-events:hover { background: var(--surface-hover); }

/* The 8th "next Sunday" column in the Sunday-to-Sunday view belongs to next
   week; a left divider marks where this week ends and next week begins. */
.meal-table th.is-trailing, .meal-table td.is-trailing { border-left: 3px double var(--border); }
.meal-cell.is-trailing, .event-cell.is-trailing { background: var(--surface-2); }
.editable-cell.is-trailing:hover, .editable-events.is-trailing:hover { background: var(--surface-hover); }

.meal-item { font-size: 13px; line-height: 1.3; padding: 1px 0; }
.meal-item a { color: var(--accent); }
.meal-item.made-recently { color: var(--warn-2); }
.repeat-flag { font-size: 11px; }
/* Count badge when an item's name matches more than one recipe (click to pick) */
.meal-match-count {
  font-size: 11px;
  color: var(--muted);
  background: var(--surface-2);
  border-radius: 8px;
  padding: 0 5px;
  margin-left: 4px;
}

.events-row .meal-rowhead { background: var(--surface-2); }
.event-cell { background: var(--surface-hover); }
.event-item {
  font-size: 12px;
  color: var(--text-2);
  line-height: 1.3;
  padding: 1px 0;
}

.cell-editor {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 13px;
  border: 1px solid var(--accent);
  border-radius: 3px;
  padding: 3px 4px;
  resize: vertical;
}
.cell-saved { background: var(--ok-bg) !important; transition: background 0.3s; }
.cell-error { background: var(--err-bg) !important; transition: background 0.3s; }
.meal-cell.saving, .event-cell.saving { opacity: 0.6; }

/* Compact read-only history grids */
.history-week { margin-bottom: 22px; }
.history-week h3 { margin: 0 0 6px 0; font-size: 16px; }
.is-compact .meal-table { min-width: 760px; }
.is-compact .meal-table th, .is-compact .meal-table td { padding: 2px 5px; }
.is-compact .meal-cell, .is-compact .event-cell { height: auto; }
.is-compact .meal-item, .is-compact .event-item { font-size: 12px; }

/* Want-to-try list */
.wishlist { margin: 26px 0; }
.wishlist-add {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}
.wishlist-add input[type=text] {
  padding: 5px 7px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 14px;
}
.wishlist-add input[placeholder='Dish to try'] { flex: 1 1 200px; }
.wishlist-add input[placeholder='Link (optional)'] { flex: 1 1 220px; }
.wishlist-add input[placeholder='Notes (optional)'] { flex: 1 1 160px; }
.wishlist-list { list-style: none; margin: 0; padding: 0; }
.wishlist-list li {
  padding: 6px 0;
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.wishlist-main { flex: 1 1 200px; }
.wishlist-notes { font-size: 12px; color: var(--muted); margin-left: 6px; }
.wishlist-actions { font-size: 12px; }

/* Print the week: on the planner pages, strip everything but the week grid and
   print it landscape in ink-friendly black-on-white. Scoped to meal_plans pages
   (any meal_plans-* body class) so it never affects other pages' printing. The
   Print button lives in the toolbar, which is hidden below, so it never prints. */
@media print {
  body[class*="meal_plans-"] #masthead,
  body[class*="meal_plans-"] .flash,
  body[class*="meal_plans-"] .toolbar,
  body[class*="meal_plans-"] .field-hint,
  body[class*="meal_plans-"] .more-weeks,
  body[class*="meal_plans-"] .meal-history,
  body[class*="meal_plans-"] .next-week,
  body[class*="meal_plans-"] .wishlist,
  body[class*="meal_plans-"] .no-print { display: none !important; }

  /* Landscape is applied ONLY to the planner grid, via a NAMED page. A bare
     `@page { size: landscape }` CANNOT be scoped by a body selector, so the old
     rule forced EVERY printed page in the whole app to landscape — recipes and
     every other page came out sideways (rotated 90deg) when printed or saved to
     PDF. A named page is assigned to the planner's #content below, so only the
     week grid prints landscape; everything else keeps the browser default
     (portrait). Browsers without named-page support just print the grid portrait
     — a harmless fallback. */
  @page planner { size: landscape; margin: 0.5in; }

  body[class*="meal_plans-"] #content { margin: 0; padding: 0; page: planner; }

  /* Let the grid fill the page instead of scrolling in a fixed-min-width box. */
  body[class*="meal_plans-"] .meal-grid-wrap { overflow: visible; }
  body[class*="meal_plans-"] .meal-table { min-width: 0; width: 100%; }

  /* Ink-friendly headers: the on-screen dark masthead colour won't print, so
     force black-on-white with a solid border instead. */
  body[class*="meal_plans-"] .meal-dayhead {
    background: #fff; color: #000; border-bottom: 2px solid #000;
  }
  body[class*="meal_plans-"] .meal-daydate { opacity: 1; }
  body[class*="meal_plans-"] .meal-rowhead,
  body[class*="meal_plans-"] .event-cell { background: #fff; color: #000; }

  /* Room to read each cell; keep whole rows together across page breaks. */
  body[class*="meal_plans-"] .meal-cell,
  body[class*="meal_plans-"] .event-cell { height: auto; min-height: 0.55in; }
  body[class*="meal_plans-"] .meal-table tr { page-break-inside: avoid; }

  /* Crisp black borders + text on paper. */
  body[class*="meal_plans-"] .meal-table th,
  body[class*="meal_plans-"] .meal-table td { border: 1px solid #000; }
  body[class*="meal_plans-"] .meal-item,
  body[class*="meal_plans-"] .meal-item a,
  body[class*="meal_plans-"] .meal-item.made-recently,
  body[class*="meal_plans-"] .event-item { color: #000; }
}
.wishlist-actions a { margin-left: 8px; }

.wishlist-pull {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0;
}
.wishlist-pull select {
  font-size: 12px;
  padding: 2px 4px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--surface);
}
.button.btn-small { padding: 3px 9px; font-size: 12px; }

/* ---------- Photo lightbox ---------- */
img.has-lightbox { cursor: zoom-in; }

.lightbox-overlay {
  display: none;
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.85);
  /* center the figure and flank it with the nav arrows */
  text-align: center;
}
.lightbox-overlay.is-open { display: flex; align-items: center; justify-content: center; }

.lightbox-figure {
  margin: 0;
  max-width: 92%;
  max-height: 92%;
}
.lightbox-img {
  display: block;
  max-width: 100%;
  max-height: 84vh;
  height: auto;
  margin: 0 auto;
  border-radius: 4px;
  box-shadow: 0 6px 30px rgba(0, 0, 0, 0.6);
  cursor: default;
}
.lightbox-caption {
  margin-top: 10px;
  color: #f2ece0;
  font-size: 14px;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  border: none;
  cursor: pointer;
  line-height: 1;
  border-radius: 6px;
}
.lightbox-close {
  top: 14px; right: 18px;
  font-size: 30px;
  width: 44px; height: 44px;
}
.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  font-size: 44px;
  width: 54px; height: 74px;
}
.lightbox-prev { left: 14px; }
.lightbox-next { right: 14px; }
.lightbox-close:hover,
.lightbox-nav:hover { background: rgba(255, 255, 255, 0.2); }

/* Generic utility: hide an element (used by shopping_list.js to show/hide the
   per-store "Clear purchased" button live as items are checked off). */
.is-hidden { display: none !important; }

/* ---------- Print: a My Recipe as a clean recipe card ---------- */
/* Shown only when printing (see the @media print block below). */
.print-only { display: none; }

@media print {
  /* Scoped to the My Recipe show page (body class = "controller-action"), so
     every other page still prints with the browser default. Strip the site
     chrome and the picture-management UI, leaving title + ingredients +
     instructions + notes — plus one finished-dish photo. */
  body.own_recipes-show #masthead,
  body.own_recipes-show #site-footer,
  body.own_recipes-show .toolbar,
  body.own_recipes-show .flash,
  body.own_recipes-show .origin-badge,
  body.own_recipes-show .no-print {
    display: none !important;
  }

  body.own_recipes-show,
  body.own_recipes-show #page,
  body.own_recipes-show #content.inner {
    margin: 0;
    padding: 0;
    max-width: none;
    width: auto;
    background: var(--surface);
    color: #000;
    box-shadow: none;
  }

  body.own_recipes-show h1 { font-size: 22pt; margin: 0 0 8pt; }
  body.own_recipes-show h2 { font-size: 13pt; margin: 12pt 0 4pt; page-break-after: avoid; }
  body.own_recipes-show .section { margin: 0 0 8pt; }
  body.own_recipes-show p { orphans: 3; widows: 3; }
  body.own_recipes-show a { text-decoration: none; color: #000; }

  body.own_recipes-show .print-only { display: block; }
  body.own_recipes-show .recipe-print-photo { margin: 0 0 10pt; }
  body.own_recipes-show .recipe-print-photo img {
    max-width: 3.2in;
    max-height: 3.2in;
    height: auto;
  }
}

/* ---------- Cook mode ---------- */
/* Full-screen hands-free view. The [hidden] attribute hides it until opened, so
   display lives on :not([hidden]) (never unconditionally, or [hidden] loses). */
.cook-mode {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  z-index: 1100;
  flex-direction: column;
  background: var(--surface-hover);   /* warm, high-contrast for reading across a kitchen */
  color: var(--text);
}
.cook-mode:not([hidden]) { display: flex; }

.cook-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.cook-title { font-size: 20px; font-weight: bold; }
.cook-close { font-size: 15px; }

.cook-body { flex: 1; display: flex; min-height: 0; }

.cook-ingredients {
  width: 300px;
  flex: none;
  padding: 16px 20px;
  border-right: 1px solid var(--border);
  overflow-y: auto;
}
.cook-ingredients h2 { margin: 0 0 10px; font-size: 16px; }
.cook-ingredients ul { margin: 0; padding-left: 20px; }
.cook-ingredients li { margin: 0 0 8px; font-size: 17px; line-height: 1.35; }

.cook-steps {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 20px 28px;
  min-width: 0;
}
.cook-progress { color: var(--muted); font-size: 15px; margin-bottom: 12px; }
.cook-step-list {
  flex: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
}
.cook-step { display: none; }
.cook-step.is-active {
  display: block;
  font-size: 30px;
  line-height: 1.45;
  max-width: 22em;
}
.cook-nav { display: flex; gap: 14px; padding-top: 16px; }
.cook-nav .button { font-size: 18px; padding: 12px 22px; }
.cook-nav .button[disabled] { opacity: 0.4; cursor: default; }

@media (max-width: 700px) {
  .cook-body { flex-direction: column; }
  .cook-ingredients {
    width: auto;
    max-height: 30vh;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
  .cook-step.is-active { font-size: 24px; }
}

/* ---------- Global search ---------- */
/* Compact box in the masthead (present on every page). Pushed to the right so
   the title + nav sit on the left of the single-row header. */
/* Pushed to the right; shrinks (min-width:0) so the masthead stays one line. */
.site-search { margin: 0 0 0 auto; display: flex; align-items: center; gap: 6px; flex: 0 1 260px; min-width: 0; }
.site-search input[type="text"] {
  padding: 5px 8px;
  border: 1px solid var(--masthead-border);
  border-radius: var(--radius-input);
  font-size: 13px;
  width: 100%;
  min-width: 0;
  vertical-align: middle;
}
.site-search .button { padding: 5px 12px; font-size: 13px; vertical-align: middle; flex: none; }

/* Larger box on the search results page. */
.search-form-lg { margin: 0 0 18px; }
.search-form-lg input[type="text"] {
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  font-size: 16px;
  width: 420px;
  max-width: 70%;
  vertical-align: middle;
}

.search-own { list-style: none; margin: 0; padding: 0; }
.search-own li { margin: 0 0 12px; }
.search-own .origin-badge { margin-left: 6px; }

/* --- Authentication ------------------------------------------------------ */

/* Login state in the masthead. */
.user-box {
  display: inline-block;
  font-size: 13px;
  white-space: nowrap;
}
.user-box .user-name { color: var(--masthead-muted); margin-right: 8px; }
.user-box .user-logout { color: #fff; text-decoration: underline; }
.user-box .user-logout:hover { color: var(--masthead-link-hover); }

/* Login page. */
.login-page {
  max-width: 360px;
  margin: 48px auto;
  padding: 28px 30px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
}
.login-page h2 { margin: 0 0 6px; }
.login-page .login-intro { color: var(--text-2); margin: 0 0 20px; }
.login-form .field { margin: 0 0 16px; }
.login-form label { display: block; font-weight: bold; margin: 0 0 4px; font-size: 14px; }
.login-form input[type="text"],
.login-form input[type="password"] {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  font-size: 15px;
  box-sizing: border-box;
}
.login-form .actions { margin-top: 20px; }
.login-form .actions .button { width: 100%; padding: 10px; font-size: 15px; }

/* Role badge in the Accounts list. */
.role-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: bold;
  text-transform: capitalize;
}
.role-admin  { background: var(--ok-bg); color: var(--good-strong); }
.role-viewer { background: var(--surface-2); color: var(--text-2); }

/* Small helper text under form fields. */
.form-field .hint,
.hint { display: block; color: var(--muted); font-size: 12px; margin-top: 3px; }

/* Cooked log (recipe show page + index column). */
.cooked-log .cooked-summary { margin: 0 0 12px; font-size: 15px; }
.cooked-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin: 0 0 14px;
}
.cooked-backdate { display: flex; align-items: center; gap: 8px; margin: 0; }
.cooked-backdate label { font-size: 13px; color: var(--text-2); display: flex; align-items: center; gap: 6px; }
.cooked-backdate input[type="date"] {
  padding: 6px 8px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  font-size: 14px;
}
.cooked-history { list-style: none; margin: 0; padding: 0; }
.cooked-history li {
  padding: 5px 0;
  border-top: 1px solid var(--border-soft);
  font-size: 14px;
}
.cooked-history .cooked-row { display: flex; align-items: center; gap: 8px; }
.cooked-history .cooked-when { font-weight: bold; }
.cooked-history .cooked-row .button.small { margin-left: auto; }
.cooked-note {
  margin: 3px 0 0;
  font-style: italic;
  color: var(--text-2);
}
.cooked-note-edit { display: flex; align-items: center; gap: 6px; margin: 4px 0 0; }
.cooked-note-edit input[type="text"] { flex: 1 1 auto; max-width: 340px; }
.cooked-date { white-space: nowrap; }

/* Last-cooked line on a recipe tile. */
/* Kids' dots + last-cooked share one row: dots left, date pushed to the right. */
.tile-verdicts { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tile-cooked { font-size: 12px; color: var(--muted); white-space: nowrap; flex: none; }

/* ---- Shopping list + mode ----
   Reuse the remodel's card convention (see .dash): the card sits one step
   LIGHTER than the warm page with a soft shadow (Organic), a quiet hairline with
   NO shadow (Classical). Tokens live on the shopping <body> (which also carries
   data-theme), so the theme variants key off body[data-theme=...]. */
body.shopping_items-index,
body.shopping_items-shop {
  --sl-card-bg: color-mix(in srgb, var(--page-bg) 45%, #fff);
  --sl-card-shadow: var(--shadow-sm);
}
body.shopping_items-index[data-theme="organic_dark"],
body.shopping_items-shop[data-theme="organic_dark"] {
  --sl-card-bg: color-mix(in srgb, var(--page-bg) 82%, #fff);
}
body.shopping_items-index[data-theme="classical"],
body.shopping_items-shop[data-theme="classical"],
body.shopping_items-index[data-theme="classical_dark"],
body.shopping_items-shop[data-theme="classical_dark"] {
  --sl-card-bg: var(--surface);
  --sl-card-shadow: none;
}

/* ---- Shopping list (management view) ---- */
.shopping-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 4px;
}
.shopping-toolbar form { margin: 0; }        /* button_to renders a <form> -- keep it inline */
.shopping-toolbar .button { margin: 0; display: inline-flex; align-items: center; gap: 7px; }
.shopping-toolbar .button .nav-icon { width: 17px; height: 17px; }

/* The add-item panel is a card (the base .section is just margin). */
.section.shopping-add {
  background: var(--sl-card-bg);
  border: 1px solid var(--border);
  box-shadow: var(--sl-card-shadow);
  border-radius: var(--radius-card);
  padding: 16px 18px 18px;
}
.section.shopping-add h2 {
  border: 0;
  padding: 0;
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: 21px;
}
.shopping-add-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.shopping-add-fields input[type="text"],
.shopping-add-fields .si-store {
  padding: 8px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-input);
  font-size: 13px;
  background: var(--surface);
}
.shopping-add-fields .si-name  { flex: 2 1 160px; }
.shopping-add-fields .si-qty   { flex: 1 1 110px; }
.shopping-add-fields .si-note  { flex: 2 1 150px; }
.shopping-add-fields .si-store { flex: 1 1 150px; width: auto; }

/* Multi-column (masonry-style) flow: uncapped -- the browser uses as many columns
   as fit at >= 340px and balances the card heights, so a one-item store (e.g.
   Kohls) never reserves a whole empty column. Each card avoids splitting. */
.shopping-stores {
  column-width: 340px;
  column-gap: 16px;
}
.store-card {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  width: 100%;
  margin: 0 0 16px;
  background: var(--sl-card-bg);
  border: 1px solid var(--border);
  box-shadow: var(--sl-card-shadow);
  border-radius: var(--radius-card);
  padding: 14px 16px 10px;
}
.store-head {
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 8px;
  margin-bottom: 4px;
}
.store-head h2 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: 19px;
}
.store-count { color: var(--muted); font-size: 13px; }
.store-head .clear-purchased-form { margin-left: auto; }

/* "Clear purchased" -- a quiet ghost pill (shown only when a store has bought
   items; shopping_list.js toggles .is-hidden). Tints to the accent on hover. */
.button.small.ghost-pill {
  background: transparent;
  color: var(--muted);
  border-color: var(--border-strong);
  font-weight: 600;
}
.button.small.ghost-pill:hover {
  background: var(--accent-tint);
  color: var(--accent);
  border-color: var(--accent);
}

.shopping-list { list-style: none; margin: 0; padding: 0; }
.shopping-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 6px;
  border-radius: var(--radius-card);
}
/* Whole row is a hover target; actions fade in with it. */
.shopping-row:hover { background: var(--accent-tint); }

.si-toggle-form { margin: 0; flex: 0 0 auto; }
.si-toggle {
  cursor: pointer;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-badge);
  background: var(--sl-card-bg);
  color: var(--bought-ink);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.si-toggle:hover { border-color: var(--accent); }
.si-box { display: flex; align-items: center; justify-content: center; }
.si-box .nav-icon { width: 15px; height: 15px; display: none; }
/* Checked: sage box (gold in Classical) via the --bought tokens; the check shows. */
.shopping-row.is-purchased .si-toggle {
  background: var(--bought-tint);
  border-color: var(--bought);
  color: var(--bought-ink);
}
.shopping-row.is-purchased .si-box .nav-icon { display: block; }

.si-text { flex: 1 1 auto; min-width: 0; }
.si-item { font-size: 14px; font-weight: 600; color: var(--text); }
/* Qty = pill. Every other sub-label (note, model no.) = one muted style. */
.si-qty-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  background: var(--surface-2);
  border-radius: var(--radius-chip);
  font-size: 12px;
  color: var(--text-2);
}
.si-note-tag {
  color: var(--muted);
  font-size: 13px;
  margin-left: 6px;
}
.si-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 4px; }
.si-actions form { margin: 0; display: inline; }
/* Ghost icon buttons: faint until the row is hovered, then circular tint. */
.si-icon {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-btn);
  color: var(--muted);
  line-height: 1;
  text-decoration: none;
  opacity: .45;
  transition: opacity .12s ease, background-color .12s ease, color .12s ease;
}
.si-icon .nav-icon { width: 16px; height: 16px; }
.shopping-row:hover .si-icon { opacity: 1; }
.si-icon.js-edit:hover { background: var(--accent-tint); color: var(--accent); }
.si-icon.si-del:hover { background: var(--err-bg); color: var(--btn-danger); }

/* Drag-to-reorder handle (arrange items in the order you hit them in the store). */
.si-grip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  cursor: grab;
  color: var(--muted);
  line-height: 1;
  padding: 0;
  touch-action: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}
.si-grip .nav-icon { width: 16px; height: 16px; }
.si-grip:active { cursor: grabbing; }
.shopping-row.is-dragging { opacity: .55; background: var(--surface-hover); }

/* Inline edit: hidden until the row is being edited, then it takes the row. */
.si-edit { display: none; margin: 0; }
.shopping-row.is-editing { flex-wrap: wrap; }
.shopping-row.is-editing .si-text,
.shopping-row.is-editing .si-actions,
.shopping-row.is-editing .si-grip,
.shopping-row.is-editing .si-toggle-form { display: none; }
.shopping-row.is-editing .si-edit {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
}
.si-edit input[type="text"],
.si-edit select {
  padding: 4px 7px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 13px;
}
.si-edit .si-edit-name { flex: 2 1 130px; }
.si-edit .si-edit-qty  { flex: 1 1 80px; }
.si-edit .si-edit-note { flex: 2 1 110px; }
.si-edit .button.small { padding: 3px 9px; font-size: 12px; }

/* Purchased: struck through, muted, and it sinks to the bottom on reload.
   (The checked-box colour is set with the --bought tokens above.) */
.shopping-row.is-purchased .si-item,
.shopping-row.is-purchased .si-qty-tag { text-decoration: line-through; color: var(--muted); }
.shopping-row.is-purchased .si-note-tag { text-decoration: line-through; color: var(--muted); }

@media (max-width: 520px) {
  .shopping-add-fields .si-name,
  .shopping-add-fields .si-qty,
  .shopping-add-fields .si-note { flex: 1 1 100%; }
  .store-card { flex-basis: 100%; }
}

/* iOS auto-zooms when a focused input's font is < 16px. Bump the shopping-list
   edit + add-item fields to 16px on phones so tapping "edit" no longer zooms the
   page in (does NOT disable pinch-zoom). */
@media (max-width: 760px) {
  .si-edit input[type="text"], .si-edit select,
  .shopping-add-fields input[type="text"], .shopping-add-fields .si-store { font-size: 16px; }
}

/* ---- Shopping mode (in-store check-off) ----
   One responsive page: a centered column on wide screens, full-width on a phone. */
.shop-view { max-width: 640px; margin: 0 auto; }

.shop-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0 6px;
  background: var(--page-bg);
}
.shop-bar h1 { margin: 0; font-size: 18px; }
.shop-bar-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.shop-hidebought { font-size: 13px; color: var(--text-2); display: flex; align-items: center; gap: 5px; }
.shop-hidebought input { width: 15px; height: 15px; }

/* Store filter pills -- horizontally scrollable, stays put under the bar. */
.shop-filter {
  position: sticky;
  top: 34px;
  z-index: 4;
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 4px 0 6px;
  background: var(--page-bg);
  -webkit-overflow-scrolling: touch;
}
/* Selection is TERRACOTTA/accent, never green (green means bought only). */
.shop-pill {
  flex: 0 0 auto;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-2);
  border-radius: var(--radius-btn);
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.shop-pill:hover { background: var(--accent-tint); }
.shop-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}
.shop-pill-count {
  display: inline-block;
  min-width: 16px;
  margin-left: 4px;
  padding: 0 5px;
  border-radius: var(--radius-chip);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 11px;
  text-align: center;
}
.shop-pill.is-active .shop-pill-count { background: rgba(255,255,255,.28); color: #fff; }

/* Title case, matching the filter pills and the rest of the app (not ALL-CAPS). */
.shop-store-name {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: 16px;
  color: var(--text-2);
  margin: 10px 0 0;
}
.shop-list { list-style: none; margin: 0; padding: 0; }

.shop-row { border-bottom: 1px solid var(--border-soft); border-radius: var(--radius-md, 10px); }
.shop-row:hover { background: var(--accent-tint); }
.shop-toggle-form { margin: 0; }
.shop-toggle-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 30px;      /* dense list; still a usable tap target */
  padding: 2px 6px;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.shop-readonly { cursor: default; }
/* Larger, glove/thumb-friendly checkbox; sage (gold in Classical) when checked. */
.shop-check {
  flex: 0 0 auto;
  width: 23px;
  height: 23px;
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-badge);
  background: var(--sl-card-bg);
  color: var(--bought-ink);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.shop-check .nav-icon { width: 17px; height: 17px; display: none; }
.shop-item-text { flex: 1 1 auto; min-width: 0; }
/* Name + quantity/note flow on ONE line (shorter rows); a long note just wraps
   to the next line rather than overflowing the phone width. */
.shop-item-name { display: inline; font-size: 15px; font-weight: 600; }
.shop-item-sub { display: inline; }
.shop-item-qty {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  background: var(--surface-2);
  border-radius: var(--radius-chip);
  font-size: 12px;
  color: var(--text-2);
}
.shop-item-note { color: var(--muted); font-size: 14px; margin-left: 8px; }

/* Checked-off: sage check (gold in Classical, never green), struck through. */
.shop-row.is-purchased .shop-check {
  background: var(--bought-tint);
  border-color: var(--bought);
  color: var(--bought-ink);
}
.shop-row.is-purchased .shop-check .nav-icon { display: block; }
.shop-row.is-purchased .shop-item-name,
.shop-row.is-purchased .shop-item-qty,
.shop-row.is-purchased .shop-item-note { text-decoration: line-through; color: var(--muted); }

/* "Hide bought" removes checked rows from view. */
.shop-view.hide-bought .shop-row.is-purchased { display: none; }

.shop-empty { font-size: 14px; padding: 16px 0; }

/* Classical voice: no large solid fills. The active filter pill is an accent
   OUTLINE (gold border + text) rather than a filled pill; its count chip tints
   instead of going white-on-fill. (Organic keeps the solid accent fill above.) */
[data-theme="classical"] .shop-pill.is-active,
[data-theme="classical_dark"] .shop-pill.is-active {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
[data-theme="classical"] .shop-pill.is-active .shop-pill-count,
[data-theme="classical_dark"] .shop-pill.is-active .shop-pill-count {
  background: var(--accent-tint);
  color: var(--accent);
}

/* Undo toast (shopping list delete). Themed surface + shadow; "Undo" is accent. */
.sl-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translate(-50%, 16px);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: calc(100vw - 32px);
  padding: 10px 12px 10px 16px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  font-size: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s ease, transform .16s ease;
}
.sl-toast.is-shown { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.sl-toast-msg { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sl-toast-undo {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  padding: 4px 8px;
  color: var(--accent);
  font-weight: 700;
  cursor: pointer;
}
.sl-toast-undo:hover { background: var(--accent-tint); color: var(--accent); border-color: transparent; }

/* On phones the in-store view fills the width (gutters disappear). */
@media (max-width: 700px) {
  .shop-view { max-width: none; }
}

/* ---- Administration hub ---- */
.admin-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
  margin-top: 12px;
}
.admin-card {
  flex: 1 1 220px;
  max-width: 320px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 12px 18px 14px;
}
.admin-card h2 {
  margin: 0 0 6px;
  font-size: 16px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 6px;
}
.admin-card ul { list-style: none; margin: 0; padding: 0; }
.admin-card li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 0;
}
.admin-card li + li { border-top: 1px solid var(--border-soft); }
.admin-count {
  min-width: 26px;
  text-align: center;
  padding: 0 7px;
  background: var(--surface-2);
  border-radius: 10px;
  font-size: 12px;
  color: var(--text-2);
}
.admin-count-bad { background: var(--err-bg); color: var(--err-text); font-weight: bold; }

/* ---- Link health ---- */
.link-status {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  white-space: nowrap;
}
.link-status.ls-ok          { background: var(--good); }
.link-status.ls-gone        { background: var(--bad); }
.link-status.ls-paywall     { background: var(--warn-2); }
.link-status.ls-blocked     { background: var(--neutral); }
.link-status.ls-unreachable { background: var(--neutral); }
.link-status.ls-muted       { background: var(--neutral); }

.lc-badge {
  display: inline-block;
  min-width: 22px;
  text-align: center;
  padding: 0 7px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: bold;
  color: #fff;
}
.lc-badge-bad  { background: var(--bad); }
.lc-badge-warn { background: var(--warn-2); }

.lc-runs .lc-breakdown { font-size: 12px; }

.lc-list { list-style: none; margin: 0; padding: 0; }
.lc-row {
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.lc-row-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lc-row .lc-recipe { font-weight: bold; }
.lc-changed {
  font-size: 12px;
  color: var(--warn-2);
  background: var(--surface-2);
  border-radius: 8px;
  padding: 1px 7px;
}
.lc-row-url { font-size: 13px; margin: 2px 0 0; word-break: break-all; }
.lc-row-note { font-size: 12px; margin: 2px 0 0; }
.lc-row-actions { margin: 4px 0 0; }
.lc-group { margin: 6px 0; }
.lc-group summary { cursor: pointer; padding: 4px 0; }

/* ---- Home dashboard (2026 rebuild -- see docs/DASHBOARD-PLAN.md) --------------
   One markup + component layer, themed entirely by tokens. The only per-theme
   rules are the three deliberate divergences (card separation, primary button,
   second-accent / status hues). Everything else is shared. Dashboard-local
   helper tokens (--d-*) derive accent tints/borders via color-mix, since the
   base system carries no accent RAMP. */
.dash {
  /* Organic (light, the :root default): cards sit one step LIGHTER than the
     warm page, with a soft shadow -- this is the contrast fix (Plan §3, §7.1). */
  --d-card-bg: color-mix(in srgb, var(--page-bg) 45%, #fff);
  --d-card-shadow: var(--shadow-sm);
  --d-row-radius: 10px;
  --d-accent-tint:    color-mix(in srgb, var(--accent) 14%, var(--d-card-bg));
  --d-accent-border:  color-mix(in srgb, var(--accent) 42%, var(--d-card-bg));
  --d-accent2-tint:   color-mix(in srgb, var(--accent-2) 18%, var(--d-card-bg));
  --d-accent2-border: color-mix(in srgb, var(--accent-2) 46%, var(--d-card-bg));
  --d-accent2-ink:    var(--good-strong, var(--accent-2));
  --d-second-dot:     var(--accent-2);      /* non-dinner meal dot */
  --d-row-hover:      color-mix(in srgb, var(--accent) 10%, var(--d-card-bg));
}
[data-theme="organic_dark"] .dash {
  /* Dark: "lighter than the page" is a subtle lift toward white. */
  --d-card-bg: color-mix(in srgb, var(--page-bg) 82%, #fff);
}
/* Divergences §7.1 + §7.3: Classical keeps the surface quiet (hairline, NO
   shadow) and folds the second-accent role back onto the mono gold accent /
   neutral -- never green. */
[data-theme="classical"] .dash,
[data-theme="classical_dark"] .dash {
  --d-card-bg: var(--surface);
  --d-card-shadow: none;
  --d-row-radius: 4px;
  --d-accent2-tint:   var(--d-accent-tint);
  --d-accent2-border: var(--d-accent-border);
  --d-accent2-ink:    var(--accent);
  --d-second-dot:     var(--muted);
}

.dash-title {
  font-family: var(--font-heading); font-weight: var(--heading-weight);
  letter-spacing: var(--heading-spacing);
  font-size: 30px; margin: 0 0 16px; color: var(--heading);
}

/* ---- Shared card shell (Plan §3) ---- */
.dash-card {
  background: var(--d-card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--d-card-shadow);
  padding: 18px 20px;
}
.dash-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 0 0 10px;
}
.dash-card-head h2 {
  margin: 0; border: 0; padding: 0; line-height: 1.15;
  font-family: var(--font-heading); font-weight: var(--heading-weight);
  letter-spacing: var(--heading-spacing);
  font-size: 21px; color: var(--heading);
}
.dash-more { font-size: 13px; white-space: nowrap; color: var(--accent); text-decoration: none; }
.dash-more:hover { text-decoration: underline; }
.dash-cap { margin: -2px 0 10px; font-size: 12.5px; color: var(--muted); }
.dash-empty { font-size: 13px; padding: 6px 0; color: var(--muted); }

/* Links vs plain labels -- one consistent affordance (Plan §5). */
.dash a.dash-link { color: var(--accent); text-decoration: none; }
.dash a.dash-link:hover { text-decoration: underline; }
.dash .dash-meta { color: var(--muted); font-size: 13px; white-space: nowrap; }
.dash .dash-when { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* ---- Stat strip (Plan §4a) ---- */
.stat-strip {
  list-style: none; margin: 0 0 16px; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
}
.stat-tile {
  margin: 0; background: var(--d-card-bg); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--d-card-shadow);
}
/* The tile's inner row -- an <a> when the tile links somewhere (dashboard), or a
   plain .stat-inner span when it doesn't (some Insights tiles). Same layout either way. */
.stat-tile > a, .stat-tile > .stat-inner {
  display: flex; align-items: center; gap: 13px;
  padding: 15px 17px; text-decoration: none; color: inherit;
}
.stat-chip {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-card);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--d-accent-tint); color: var(--accent);
}
.stat-chip .nav-icon { width: 22px; height: 22px; }
/* Organic alternates accent / second-accent; Classical is mono (both fold to
   the accent tint via --d-accent2-* above). */
.stat-tile.st-b .stat-chip { background: var(--d-accent2-tint); color: var(--d-accent2-ink); }
.stat-body { display: flex; flex-direction: column; line-height: 1.1; }
.stat-num {
  font-family: var(--font-heading); font-weight: var(--heading-weight);
  font-size: 28px; color: var(--heading);
}
.stat-lbl { font-size: 13px; color: var(--muted); margin-top: 3px; }

/* ---- Action pills (Plan §4b -- reuses .button / .button.secondary so each
   theme's own primary/secondary styling applies, satisfying §7.2). ---- */
.dash-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.dash-actions .button { margin: 0; display: inline-flex; align-items: center; gap: 7px; }
.dash-actions .button .nav-icon { width: 17px; height: 17px; }

/* ---- Week at a glance (Plan §4c) ---- */
.week-card { margin: 0 0 16px; }
.week-strip { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.week-day {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
  padding: 10px 11px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-card);
}
.week-day.is-today {
  background: var(--d-accent-tint);
  border-color: var(--d-accent-border);
}
.week-day.is-today .wd-name { color: var(--accent); }
.wd-name { font-size: 12px; font-weight: 700; color: var(--heading); }
.wd-date { font-size: 11px; color: var(--muted); }
.wd-dinner { font-size: 13px; color: var(--text-2); margin-top: 3px; overflow-wrap: anywhere; }
.wd-empty { color: var(--muted); }

/* ---- 3-column card grid (Plan §2) ---- */
.dash-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; }
.dash-col { display: flex; flex-direction: column; gap: 16px; }

/* ---- Shared lists ---- */
.dash-list { list-style: none; margin: 0; padding: 0; }
.dash-list li {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 8px; border-radius: var(--d-row-radius);
}
.dash-list li:hover { background: var(--d-row-hover); }

/* ---- Today card (Plan §4d) ---- */
.dash-meals { list-style: none; margin: 0; padding: 0; }
.meal-row { display: flex; align-items: baseline; gap: 9px; padding: 6px 8px; border-radius: var(--d-row-radius); }
.meal-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 999px; align-self: flex-start; margin-top: 5px; }
.meal-dot.md-accent { background: var(--accent); }
.meal-dot.md-second { background: var(--d-second-dot); }
.meal-lbl { flex: 0 0 66px; font-size: 11px; letter-spacing: .05em; text-transform: uppercase; font-weight: 700; color: var(--muted); }
.meal-items { flex: 1 1 auto; color: var(--text-2); overflow-wrap: anywhere; }
.meal-items a, .foot-text a { color: var(--accent); text-decoration: none; }
.meal-items a:hover, .foot-text a:hover { text-decoration: underline; }
.dash-foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-soft); font-size: 13px; }
.foot-lbl { font-weight: 700; color: var(--heading); margin-right: 6px; }
.foot-text { color: var(--text-2); }

/* ---- Family favorites (Plan §4e) ---- */
.fav-list { list-style: none; margin: 0; padding: 0; }
.fav-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 8px; border-radius: var(--d-row-radius);
}
.fav-row:hover { background: var(--d-row-hover); }
.fav-verdicts { display: flex; gap: 9px; flex: 0 0 auto; }
.fav-kid { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; }
.fav-init { font-size: 10px; font-weight: 700; color: var(--muted); text-transform: uppercase; }
.dv-dot { width: 11px; height: 11px; border-radius: 999px; display: inline-block; box-sizing: border-box; }
/* Organic verdict hues: sage / amber / neutral (Plan §4e). */
.dv-yes  { background: var(--accent-2); }
.dv-meh  { background: #d69a3c; }
.dv-no   { background: var(--neutral); }
.dv-none { background: transparent; border: 1px dashed var(--border-strong); }
.fav-legend {
  display: flex; gap: 15px; margin-top: 10px; padding-top: 8px;
  border-top: 1px solid var(--border-soft); font-size: 12px; color: var(--muted);
}
.fav-legend span { display: inline-flex; align-items: center; gap: 5px; }
/* Divergence §7.3: Classical encodes verdict by SHAPE, mono gold, never green. */
[data-theme="classical"] .dash .dv-yes,
[data-theme="classical_dark"] .dash .dv-yes { background: var(--accent); border: 0; }
[data-theme="classical"] .dash .dv-meh,
[data-theme="classical_dark"] .dash .dv-meh { background: transparent; border: 2px solid var(--accent); }
[data-theme="classical"] .dash .dv-no,
[data-theme="classical_dark"] .dash .dv-no { background: transparent; border: 1px solid var(--border-strong); }

/* ---- Shopping card (Plan §4g) ---- */
.dash-big {
  font-family: var(--font-heading); font-weight: var(--heading-weight);
  font-size: 30px; color: var(--accent); margin: 2px 0 10px; line-height: 1;
}
.dash-big-lbl { font-family: var(--font-body); font-size: 14px; font-weight: normal; color: var(--muted); }
.dash-stores { list-style: none; margin: 0 0 12px; padding: 0; }
.dash-stores li {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 5px 8px; border-radius: var(--d-row-radius); font-size: 14px;
}
.dash-stores li:hover { background: var(--d-row-hover); }
.dash-badge {
  flex: 0 0 auto; background: var(--d-accent-tint); color: var(--accent);
  border-radius: 999px; padding: 1px 9px; font-size: 12px; font-weight: 700;
}
.button.dash-block {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; box-sizing: border-box; margin: 4px 0 0;
}
.button.dash-block .nav-icon { width: 17px; height: 17px; }

/* ---- Dining Out card (Plan §4h) ---- */
.dine-list { list-style: none; margin: 0 0 10px; padding: 0; }
.dine-row { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: var(--d-row-radius); }
.dine-row:hover { background: var(--d-row-hover); }
.dine-pin {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: var(--radius-card);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--d-accent2-tint); color: var(--d-accent2-ink);
}
.dine-pin .nav-icon { width: 17px; height: 17px; }
.dine-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.dine-meta { font-size: 12px; color: var(--muted); }
.dine-stars { flex: 0 0 auto; white-space: nowrap; }

/* ---- Recently cooked (thumbnails -- Plan §4j) ---- */
.cooked-list { list-style: none; margin: 0; padding: 0; }
.cooked-row { display: flex; align-items: center; gap: 11px; padding: 6px 8px; border-radius: var(--d-row-radius); }
.cooked-row:hover { background: var(--d-row-hover); }
.cooked-thumb {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: var(--d-row-radius);
  overflow: hidden; background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center;
}
.cooked-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cooked-thumb-ph { color: var(--muted); }
.cooked-thumb-ph .nav-icon { width: 20px; height: 20px; }
.cooked-main { flex: 1 1 auto; min-width: 0; }
/* Classical: wrap the thumbnail in a thin "plate" mat, square-ish. */
[data-theme="classical"] .dash .cooked-thumb,
[data-theme="classical_dark"] .dash .cooked-thumb {
  border: 1px solid var(--border-strong); padding: 2px; background: var(--surface);
}

/* ---- Want to try (second-voice card -- Plan §4k) ---- */
.want-card { background: var(--d-accent2-tint); border-color: var(--d-accent2-border); }
.want-card .dash-card-head h2 { color: var(--d-accent2-ink); }
.want-card a.dash-link { color: var(--d-accent2-ink); }
.want-card a.dash-link:hover { text-decoration: underline; }
/* Classical (mono): standard card set apart by a gold top-rule, no tinted fill. */
[data-theme="classical"] .dash .want-card,
[data-theme="classical_dark"] .dash .want-card {
  background: var(--d-card-bg); border-color: var(--border);
  border-top: 3px solid var(--accent);
}
[data-theme="classical"] .dash .want-card .dash-card-head h2,
[data-theme="classical_dark"] .dash .want-card .dash-card-head h2 { color: var(--heading); }
[data-theme="classical"] .dash .want-card a.dash-link,
[data-theme="classical_dark"] .dash .want-card a.dash-link { color: var(--accent); }

/* ---- Responsive (Plan §6) ---- */
@media (max-width: 1199px) {
  .dash-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .dash-title { font-size: 26px; }
  .dash-grid { grid-template-columns: 1fr; }
  .stat-strip { grid-template-columns: repeat(2, 1fr); }
  /* Week strip becomes a horizontal-scroll row of day chips. */
  .week-strip {
    grid-template-columns: none; grid-auto-flow: column;
    grid-auto-columns: minmax(120px, 1fr);
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding-bottom: 4px;
  }
}

/* ---------- Tags ---------- */
.tag-chip {
  display: inline-block;
  background: var(--tag-bg);
  color: var(--tag-fg);
  border: 1px solid var(--tag-border);
  border-radius: var(--radius-chip);
  padding: 1px 9px;
  margin: 1px 3px 1px 0;
  font-size: 12px;
  line-height: 1.5;
  white-space: nowrap;
  text-decoration: none;
}
a.tag-chip:hover { filter: brightness(.96); color: var(--tag-fg); text-decoration: none; }
.recipe-tags { margin: 0 0 14px; }
.tile-tags { margin-top: 6px; }
.tags-cell { max-width: 180px; }

.tag-checkboxes {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
}
.tag-check {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
  white-space: nowrap;
}

/* ---------- Freezer inventory ---------- */
.freezer-add-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.freezer-add-fields input[type="text"],
.freezer-add-fields input[type="date"] {
  padding: 5px 7px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 13px;
}
.freezer-add-fields .fi-name   { flex: 2 1 170px; }
.freezer-add-fields .fi-qty    { flex: 1 1 110px; }
.freezer-add-fields .fi-note   { flex: 2 1 150px; }
.freezer-add-fields .fi-loc,
.freezer-add-fields .fi-recipe {
  padding: 5px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 13px;
}
.fi-inline-label { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }

.freezer-locations {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
}
.freezer-card {
  flex: 1 1 320px;
  max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 8px 12px 4px;
}
.freezer-head {
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 4px;
  margin-bottom: 2px;
}
.freezer-head h2 { margin: 0; font-size: 15px; }
.freezer-count { color: var(--muted); font-size: 12px; }

.freezer-list { list-style: none; margin: 0; padding: 0; }
.freezer-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border-soft);
}
.freezer-row:first-child { border-top: 0; }
.fi-text { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.fi-item-name { font-size: 14px; color: var(--text); }
.fi-tag, .fi-note-tag, .fi-frozen {
  font-size: 12px;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: 9px;
  padding: 0 7px;
}
.fi-note-tag { color: var(--muted); background: transparent; font-style: italic; padding: 0; }
.fi-frozen { color: var(--muted); background: transparent; padding: 0; }
.fi-recipe-link { font-size: 12px; text-decoration: none; }
.fi-actions { flex: 0 0 auto; display: inline-flex; gap: 2px; }
.fi-icon {
  background: none;
  border: 0;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  text-decoration: none;
}
.fi-actions form { margin: 0; display: inline; }

/* ---------- Freezer-meal label ---------- */
.label-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 8px 0 16px;
}
.label-date-form { display: inline-flex; align-items: center; gap: 6px; margin: 0; }

.freezer-label {
  max-width: 460px;
  margin: 0 auto;
  padding: 18px 22px;
  background: #fff;
  color: #000;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
}
.fl-title {
  margin: 0 0 4px;
  font-size: 22px;
  font-weight: bold;
  text-decoration: underline;
  color: #000;
}
.fl-made { margin: 0 0 12px; font-size: 14px; color: #000; }
.fl-steps { margin: 0 0 14px; padding-left: 22px; }
.fl-steps li { margin: 4px 0; font-size: 14px; line-height: 1.35; color: #000; }
.fl-noinstructions { color: #444; margin: 0 0 14px; }
.fl-link {
  display: flex;
  align-items: center;
  gap: 12px;
  border-top: 1px solid #ccc;
  padding-top: 12px;
}
.fl-qr { flex: 0 0 auto; width: 120px; height: 120px; }
.fl-qr svg { width: 100%; height: 100%; display: block; }
.fl-url { font-size: 12px; word-break: break-all; color: #333; }

@media print {
  /* Print only the label card -- strip masthead, nav, flash and the on-screen
     controls. Body class is "<controller>-<action>" (see the layout). */
  body.recipes-freezer_label #masthead,
  body.recipes-freezer_label .toolbar,
  body.recipes-freezer_label .label-controls,
  body.recipes-freezer_label .flash,
  body.recipes-freezer_label .no-print { display: none !important; }
  body.recipes-freezer_label #content { margin: 0; padding: 0; }
  body.recipes-freezer_label .freezer-label {
    margin: 0;
    border: 1px solid #000;
    max-width: none;
    width: auto;
  }
}

/* ==========================================================================
   Opinion history (recipe show: how a child's opinion changed over time)
   ========================================================================== */
.opinion-history { margin-top: 18px; border-top: 1px solid var(--border); padding-top: 12px; }
.opinion-history h3 { margin: 0 0 8px; font-size: 15px; }
.opinion-history-list { list-style: none; margin: 0; padding: 0; }
.opinion-history-list li {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 4px 0;
}
.opinion-history-child { min-width: 70px; font-weight: bold; color: var(--text-2); }
.opinion-trail { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.opinion-step { display: inline-flex; align-items: center; gap: 5px; }
.opinion-step-date { font-size: 12px; color: var(--muted); }
.opinion-arrow { color: var(--muted); }

/* ==========================================================================
   Freezer panel on the meal planner (read-only snapshot)
   ========================================================================== */
.freezer-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.freezer-panel-head h2 { margin: 0; }
.freezer-panel-cols {
  display: flex; flex-wrap: wrap; gap: 18px; margin-top: 8px;
}
.freezer-panel-col { flex: 1 1 200px; min-width: 180px; }
.freezer-panel-col h3 { margin: 0 0 6px; font-size: 14px; color: var(--text-2); }
.freezer-panel-list { list-style: none; margin: 0; padding: 0; }
.freezer-panel-list li { padding: 3px 0; border-bottom: 1px solid var(--border-soft); }

/* ==========================================================================
   Kitchen insights (2026 rebuild -- see docs/INSIGHTS-PLAN.md)
   Reuses the dashboard shell (.dash / .dash-card / .stat-strip / .stat-tile /
   .dash-* tokens); this block only adds Insights-specific pieces. The charts are
   hand-authored inline SVG (see ApplicationHelper#insight_activity_chart /
   #insight_kids_chart) styled via the .insight-svg / .ic-* / .vseg-* classes
   below; the fixed verdict hues below are the four data-viz semantic colors (§6),
   identical in both themes.
   ========================================================================== */
.insights {
  --v-yes: #5c8a3a;              /* leaf green */
  --v-meh: #d69a3c;              /* gold */
  --v-no:  #b23a2e;              /* true red -- distinct from the terracotta accent */
  --v-notsure: var(--neutral);   /* neutral in every theme */
}
.insights .insights-subtitle { color: var(--muted); margin: -8px 0 18px; }
.insights > .dash-card,
.insights > .insight-two-col { margin-bottom: 16px; }

/* 5-up stat strip variant (dashboard tile is 4-up). */
.stat-strip-5 { grid-template-columns: repeat(5, 1fr); }

/* Nudge banner -- accent-tinted strip. */
.insight-nudge {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 16px; padding: 12px 16px;
  background: var(--d-accent-tint); border: 1px solid var(--d-accent-border);
  border-radius: var(--radius-card); color: var(--text);
}
.insight-nudge .nudge-icon { flex: 0 0 auto; color: var(--accent); display: inline-flex; }
.insight-nudge .nudge-icon .nav-icon { width: 20px; height: 20px; }
.insight-nudge .nudge-copy { flex: 1 1 220px; font-size: 14px; }
.insight-nudge .nudge-btn { flex: 0 0 auto; margin: 0; }

.insight-note { margin: -2px 0 12px; font-size: 12.5px; color: var(--muted); }

/* Inline SVG charts (no charting library). The <svg> scales to the card width
   (viewBox + width:100%); fills/strokes/text are themed via these classes so the
   charts inherit the active [data-theme] tokens with no JS. */
.insight-svg { display: block; width: 100%; height: auto; margin-top: 4px; }
.ic-grid { stroke: var(--border); stroke-width: 1; }
.ic-bar  { fill: var(--accent-2); }        /* sage (Organic) / neutral (Classical) */
.ic-axis { fill: var(--muted); font-family: var(--font-body); font-size: 11px; }
.ic-lbl  { fill: var(--muted); font-family: var(--font-body); font-size: 11px; }
.ic-val  { fill: var(--text-2); font-family: var(--font-body); font-size: 11px; font-weight: 700; }
.kx-name { font-weight: 700; fill: var(--heading); font-size: 12px; }
/* Kids' 100%-stacked segments -- the four fixed semantic hues (§6). */
.vseg-yes { fill: var(--v-yes); }
.vseg-meh { fill: var(--v-meh); }
.vseg-no  { fill: var(--v-no); }
.vseg-notsure { fill: var(--v-notsure); }

/* Two-column band (Most cooked | Make it again). */
.insight-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }

/* Horizontal bar list (Most cooked) -- sage fill, track a step darker than card. */
.insight-barlist { list-style: none; margin: 0; padding: 0; }
.insight-barlist li { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.insight-bar-label { flex: 0 0 42%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insight-bar-track {
  flex: 1 1 auto; height: 14px; border-radius: 7px;
  background: color-mix(in srgb, var(--text) 12%, var(--d-card-bg, var(--surface)));
}
.insight-bar-fill { display: block; height: 100%; background: var(--accent-2); border-radius: 7px; min-width: 2px; }
.insight-bar-value { flex: 0 0 auto; font-variant-numeric: tabular-nums; color: var(--text-2); min-width: 26px; text-align: right; }

/* Verdict chips + legend (fixed semantic hues). */
.vchip {
  display: inline-block; padding: 1px 8px; border-radius: var(--radius-badge);
  font-size: 12px; font-weight: 700; color: #fff; line-height: 1.5;
}
.vchip-yes { background: var(--v-yes); }
.vchip-meh { background: var(--v-meh); }
.vchip-no  { background: var(--v-no); }
.vchip-notsure { background: var(--v-notsure); }
.vchip-none { background: var(--neutral); }
.vchip-legend { display: flex; flex-wrap: wrap; gap: 15px; margin: 0 0 12px; font-size: 12px; color: var(--muted); }
.vk { display: inline-flex; align-items: center; gap: 6px; }
.vk-dot { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.vk-dot.vchip-yes { background: var(--v-yes); }
.vk-dot.vchip-meh { background: var(--v-meh); }
.vk-dot.vchip-no  { background: var(--v-no); }
.vk-dot.vchip-notsure { background: var(--v-notsure); }

.kids-summary { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 20px; }
.kids-summary li { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
.kids-summary .ks-name { font-weight: 700; color: var(--heading); }

/* Taste turnarounds -- grouped by recipe, two columns on desktop. */
.turnaround-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 22px; }
.turnaround-group { break-inside: avoid; padding: 4px 0 8px; }
.turnaround-recipe { margin: 0 0 4px; font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 16px; border: 0; }
.turnaround-list { list-style: none; margin: 0; padding: 0; }
.turnaround-list li { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 3px 0; font-size: 13px; }
.turnaround-child { font-weight: 700; color: var(--text); }
.opinion-arrow { color: var(--muted); }

@media (max-width: 900px) {
  .stat-strip-5 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 760px) {
  .insight-two-col { grid-template-columns: 1fr; }
  .turnaround-grid { grid-template-columns: 1fr; }
  .stat-strip-5 { grid-template-columns: repeat(2, 1fr); }
  .insight-bar-label { flex-basis: 50%; }
}

/* ==========================================================================
   RESPONSIVE + MOBILE NAVIGATION  (2026 remodel, work item 4)
   Desktop keeps the horizontal masthead. On phones the masthead is replaced by
   a compact top app bar + a slide-in menu (the plain-Safari chrome); when the
   app is installed to the Home Screen (standalone) a bottom tab bar appears.
   ========================================================================== */

/* The mobile chrome is hidden on desktop; the phone breakpoint reveals it. */
#mobile-topbar, .mobile-search, #mobile-menu, #menu-backdrop, #bottom-nav { display: none; }

.nav-icon { display: block; width: 24px; height: 24px; flex: none; }

/* ---- Mobile top app bar ---- */
#mobile-topbar {
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  padding-top: calc(8px + env(safe-area-inset-top));
  background: var(--masthead-bg);
  color: var(--masthead-text);
  border-bottom: 3px solid var(--masthead-border);
  position: sticky; top: 0; z-index: 900;
}
#mobile-topbar .mtb-brand { flex: 1 1 auto; font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 19px; }
#mobile-topbar .mtb-brand a, #mobile-topbar .mtb-brand a:hover { color: var(--masthead-text); text-decoration: none; }
.mtb-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  background: transparent; border: none; color: var(--masthead-text);
  border-radius: 8px; cursor: pointer;
}
.mtb-btn:hover { background: rgba(255,255,255,.12); color: var(--masthead-text); }

/* Top-bar search field: revealed by the search toggle. */
.mobile-search { padding: 8px 12px; background: var(--masthead-bg); border-bottom: 1px solid var(--masthead-border); }
.mobile-search input[type="text"] {
  width: 100%; padding: 9px 12px; font-size: 16px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-input);
  background: var(--surface); color: var(--text);
}

/* ---- Slide-in menu + backdrop ---- */
#menu-backdrop {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0,0,0,.45);
}
.mobile-menu {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 1001;
  width: 82%; max-width: 320px;
  background: var(--surface); color: var(--text);
  border-right: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  transform: translateX(-100%);   /* slides in from the LEFT (hamburger is left) */
  transition: transform .22s ease;
  display: flex; flex-direction: column;
  padding-bottom: env(safe-area-inset-bottom);
  overflow-y: auto;
}
body.menu-open .mobile-menu { transform: translateX(0); }
.mm-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px 10px 18px;
  background: var(--masthead-bg); color: var(--masthead-text);
  padding-top: calc(10px + env(safe-area-inset-top));
}
.mm-title { font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 20px; }
.mm-head .mtb-btn { color: var(--masthead-text); }
.mm-links { padding: 8px 0; }
.mm-secondary { border-top: 1px solid var(--border); margin-top: auto; }
.mm-link {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 18px; font-size: 16px;
  color: var(--text); text-decoration: none;
}
.mm-link:hover { background: var(--surface-hover); text-decoration: none; }
.mm-link .nav-icon { color: var(--muted); }
.mm-link.is-active { color: var(--accent); font-weight: 600; background: var(--surface-hover); }
.mm-link.is-active .nav-icon { color: var(--accent); }

/* ---- Bottom tab bar (installed / standalone only) ---- */
.bottom-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  align-items: stretch;
  background: var(--surface); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -2px 10px rgba(0,0,0,.10);
}
.bn-tab {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 8px 2px 7px;
  background: transparent; border: none; cursor: pointer;
  color: var(--muted); font-size: 11px; font-family: var(--font-body); text-decoration: none;
}
.bn-tab .nav-icon { width: 22px; height: 22px; }
.bn-tab:hover { color: var(--text); text-decoration: none; }
.bn-tab.is-active { color: var(--accent); }

/* ==========================================================================
   PHONE BREAKPOINT
   ========================================================================== */
@media (max-width: 760px) {
  /* Swap the desktop masthead for the mobile top bar + reveal the mobile
     chrome. The slide-in menu is present but transformed off-screen until
     body.menu-open; the backdrop + search field are driven by body classes. */
  #masthead { display: none; }
  #mobile-topbar { display: flex; }
  #mobile-menu { display: flex; }
  body.menu-open #menu-backdrop { display: block; }
  body.search-open .mobile-search { display: block; }

  #content { padding-top: 16px; }
  .inner { padding: 0 14px; }
  h1 { font-size: 26px; }
  [data-theme="classical"] h1, [data-theme="classical_dark"] h1 { font-size: 28px; }

  /* Recipes: force the card/tiles view on phones (the wide table doesn't fit).
     The sort/filter header still lives in the table and keeps driving both
     views via recipes_table.js. */
  #recipes-view .table-scroll { display: none; }
  #recipes-view #recipes-tiles { display: grid !important; }
  .view-toggle { display: none; }
  .tiles-grid { grid-template-columns: 1fr; gap: 14px; }

  /* Big, tap-friendly controls. */
  .toolbar .button, .toolbar button { padding: 10px 16px; }
  /* iOS Safari auto-zooms the page whenever a focused form control renders below
     16px. Pin every text-entry control to 16px sitewide on phones so focusing any
     field never zooms. `!important` is deliberate and required: component rules
     set smaller sizes with higher specificity (e.g. `.cell-editor` on the meal
     planner, `.si-edit input`/`select` on the shopping + freezer inline editors,
     the table filter boxes), and an element-only rule would lose to them. This
     covers every input/select/textarea in the app -- there are no contenteditable
     editors -- so the zoom is gone on every page. Pinch-to-zoom stays available
     (we don't touch the viewport). */
  input, select, textarea { font-size: 16px !important; }

  /* Planner: swap the wide week grid for the vertical day cards, and the desktop
     controls for the compact mobile header. */
  .meal-grid-wrap { overflow-x: visible; }
  .meal-table { display: none; }
  .meal-daycards { display: flex; }
  .mp-desktop-title, .mp-desktop-ctl { display: none; }
  .mp-mobile-bar { display: block; }

  /* Planner mobile header as a full-bleed coloured band. Terracotta
     (--masthead-bg) so it merges with the iOS status-bar / PWA theme-color band
     -- Dining Out keeps the sage --meal-dayhead-bg intentionally. Per-theme token
     (organic terracotta, classical near-black) with light text. */
  .mp-mobile-bar {
    background: var(--masthead-bg); color: var(--masthead-text);
    margin: -16px -14px 14px; padding: 12px 14px 14px;
    border-radius: 0; /* squared off at the bottom, matching the prototype */
  }
  .mp-mobile-bar .mp-title { color: var(--masthead-text); }
  /* Overflow (⋯) button + steppers: soft translucent-white chips, light icon. */
  .mp-mobile-bar .mp-overflow-btn { color: var(--masthead-text); border-radius: 999px; }
  .mp-mobile-bar .mp-overflow-btn:hover { background: rgba(255,255,255,.16); }
  .mp-mobile-bar .mp-step {
    border: none; background: rgba(255,255,255,.16); color: var(--masthead-text);
  }
  .mp-mobile-bar .mp-step:hover { background: rgba(255,255,255,.28); text-decoration: none; }
  .mp-mobile-bar .mp-step.is-disabled { opacity: .4; }
  /* Centered week label, light text. */
  .mp-mobile-bar .mp-week { color: var(--masthead-text); }
  .mp-mobile-bar .mp-week-range { color: rgba(255,255,255,.82); }
  /* Day strip: all 7 days at once, evenly spread across the width, no scroll. */
  .mp-mobile-bar .mp-daystrip { overflow: visible; gap: 5px; }
  .mp-mobile-bar .mp-day-pill {
    flex: 1 1 0; min-width: 0;
    background: rgba(255,255,255,.14); border-color: transparent; color: var(--masthead-text);
  }
  .mp-mobile-bar .mp-day-pill .mp-day-num { color: var(--masthead-text); }
  .mp-mobile-bar .mp-day-pill .mp-day-dow { color: rgba(255,255,255,.82); }
  .mp-mobile-bar .mp-day-pill .wx-compact { color: var(--masthead-text); }
  /* Today pill: inverted -- light fill with the band's colour as text so it pops. */
  .mp-mobile-bar .mp-day-pill.is-today {
    background: var(--masthead-text); border-color: var(--masthead-text);
  }
  .mp-mobile-bar .mp-day-pill.is-today .mp-day-num,
  .mp-mobile-bar .mp-day-pill.is-today .mp-day-dow,
  .mp-mobile-bar .mp-day-pill.is-today .wx-compact { color: var(--masthead-bg); }
}

/* Bottom tab bar appears only when installed to the Home Screen (standalone).
   Two detections: the CSS media query and the JS-set .pwa-standalone class
   (iOS Safari only reports standalone via navigator.standalone).
   NB: the show rules must use the #bottom-nav ID -- the base hide is
   `#bottom-nav{display:none}`, so a `.bottom-nav` class rule (lower specificity)
   would lose to it and the bar would never appear. */
@media (max-width: 760px) and (display-mode: standalone) {
  #bottom-nav { display: flex; }
  #content { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}
body.pwa-standalone #bottom-nav { display: flex; }
/* Fill the viewport on SHORT standalone pages (e.g. a short shopping-mode list).
   iOS mis-positions a fixed bottom bar when the document is shorter than the
   viewport, leaving a gap below the bar; forcing the shell to the full (dynamic)
   viewport height keeps the tab bar pinned to the true bottom. */
body.pwa-standalone { min-height: 100vh; min-height: 100dvh; }
body.pwa-standalone #page { min-height: 100vh; min-height: 100dvh; }
/* In standalone the bottom bar carries primary nav, so drop the redundant top
   app bar (and its search toggle) -- the "More" tab opens the same menu. */
body.pwa-standalone #mobile-topbar { display: none; }
/* With no top bar, reserve the translucent status-bar height at the top (and the
   bottom bar's height below) so the iOS clock/battery don't collide with the
   page heading. */
body.pwa-standalone #content {
  padding-top: calc(env(safe-area-inset-top) + 14px);
  padding-bottom: calc(76px + env(safe-area-inset-bottom));
}
/* Industry-standard status-bar treatment: a FIXED solid band filling the iOS
   safe-area at the top, in the app's dark header colour, so the clock/battery
   stay legible and page content scrolls BENEATH it (never behind the clock).
   White status-bar glyphs (black-translucent style) read fine on this. */
body.pwa-standalone::before {
  content: "";
  position: fixed; top: 0; left: 0; right: 0;
  height: env(safe-area-inset-top);
  background: var(--masthead-bg);
  z-index: 998;
  pointer-events: none;
}

/* Respect reduced-motion: no menu slide. */
@media (prefers-reduced-motion: reduce) {
  .mobile-menu { transition: none; }
  .recipe-tile { transition: none; }
}

/* ==========================================================================
   RECIPES: mobile search + filters (phones only, <=760px)
   A search bar + a "Filters" bottom sheet that replace the desktop table's
   per-column filters / Download CSV on a phone (the desktop table is unchanged).
   The band deliberately reuses the meal-planner mobile header colour
   (--meal-dayhead-bg) so the two primary mobile tools read as one family.
   Everything here drives the same show/hide engine as the desktop filters --
   see recipes_table.js (mobileMatches / mobileFilters).
   ========================================================================== */
/* Hidden on desktop; the desktop toolbar + table above stay in charge. */
.recipes-mobile-bar { display: none; }
.rm-sheet, .rm-sheet-backdrop { display: none; }
/* Lock background scroll while the sheet is open. */
body.rm-sheet-open { overflow: hidden; }

@media (max-width: 760px) {
  /* Hide the desktop heading + toolbar (Add / Clear filters / Download CSV /
     count / hint) on phones -- the green mobile bar replaces them. The toolbar
     needs the body.recipes-index prefix to outweigh the display:flex rule at
     `body.recipes-index .toolbar` (0-2-1); a bare class (0-1-0) would lose. */
  .recipes-desktop-head { display: none; }
  body.recipes-index .recipes-desktop-toolbar { display: none; }

  /* The only toolbar content kept on mobile: the icon legend, relocated into
     the green band (light text). */
  .rm-legend { margin: 12px 0 0; color: rgba(255,255,255,.82); font-size: 13px; line-height: 1.4; }
  .rm-legend span { font-size: 15px; }

  /* The coloured header band (full-bleed). Terracotta (--masthead-bg) so it
     merges with the iOS status-bar / PWA theme-color band -- Dining Out keeps the
     sage --meal-dayhead-bg intentionally. Per-theme token: organic terracotta,
     classical near-black, each with its dark variant. */
  .recipes-mobile-bar {
    display: block;
    background: var(--masthead-bg); color: var(--masthead-text);
    margin: -16px -14px 16px; padding: 12px 14px 14px;
  }
  .rm-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
  .rm-title { margin: 0; font-size: 24px; color: var(--masthead-text); }
  /* Add-a-recipe: the terracotta pop on the band (gold outline under Classical --
     both come straight from the --btn-* tokens). */
  .rm-add {
    flex: none; display: inline-flex; align-items: center; gap: 4px;
    background: var(--btn-bg); color: var(--btn-fg); border: 1px solid var(--btn-border);
    border-radius: var(--radius-btn); padding: 7px 14px; font-weight: 600; text-decoration: none;
  }
  .rm-add:hover { background: var(--btn-hover-bg); color: var(--btn-hover-fg); }

  /* Search field + Filters button: soft translucent-white chrome on the band. */
  .rm-search {
    display: flex; align-items: center; gap: 8px; margin-top: 10px;
    background: rgba(255,255,255,.15); border: 1px solid rgba(255,255,255,.22);
    border-radius: var(--radius-input); padding: 8px 12px; color: var(--masthead-text);
  }
  .rm-search .nav-icon { width: 18px; height: 18px; flex: none; opacity: .9; }
  .rm-search input {
    flex: 1 1 auto; min-width: 0; background: transparent; border: none; outline: none;
    color: var(--masthead-text); font: inherit; padding: 0;
    /* Keep >=16px so iOS Safari doesn't auto-zoom the page on focus (must come
       after `font: inherit`, which would otherwise reset the size below 16px). */
    font-size: 16px;
  }
  .rm-search input::placeholder { color: rgba(255,255,255,.75); }
  /* iOS adds a native clear "x" to type=search; keep it but nudge spacing. */
  .rm-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

  .rm-filterrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
  .rm-filters-btn {
    display: inline-flex; align-items: center; gap: 7px;
    background: rgba(255,255,255,.15); color: var(--masthead-text);
    border: 1px solid rgba(255,255,255,.22); border-radius: var(--radius-btn);
    padding: 8px 14px; font: inherit; font-weight: 600; cursor: pointer;
  }
  .rm-filters-btn:hover { background: rgba(255,255,255,.26); }
  .rm-filters-btn .nav-icon { width: 18px; height: 18px; }
  .rm-badge {
    display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px;
    padding: 0 6px; border-radius: 999px; background: var(--accent); color: var(--accent-on);
    font-size: 12px; font-weight: 700; line-height: 1;
  }
  .rm-count { color: rgba(255,255,255,.9); font-size: 14px; white-space: nowrap; }

  /* Active-filter chips: a horizontally scrolling row, each removable. */
  .rm-active {
    display: flex; flex-wrap: nowrap; gap: 8px; margin-top: 12px;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
  }
  .rm-active:empty { display: none; }
  .rm-chip-active {
    flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
    background: rgba(255,255,255,.14); color: var(--masthead-text);
    border: 1px solid rgba(255,255,255,.30); border-radius: 999px;
    padding: 5px 10px; font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
  }
  .rm-chip-active .rm-x { font-size: 11px; opacity: .85; }

  /* ---- Filters bottom sheet + dimmed backdrop ---- */
  .rm-sheet-backdrop { position: fixed; inset: 0; z-index: 1200; background: rgba(20,17,14,.5); }
  .rm-sheet-backdrop:not([hidden]) { display: block; }
  .rm-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1201;
    flex-direction: column; max-height: 88vh; max-height: 88dvh;
    background: var(--surface); color: var(--text);
    border-radius: 18px 18px 0 0; box-shadow: var(--shadow-lg);
  }
  .rm-sheet:not([hidden]) { display: flex; }
  .rm-sheet-head {
    display: flex; align-items: center; justify-content: space-between; flex: none;
    padding: 14px 16px; border-bottom: 1px solid var(--border);
    font-family: var(--font-heading); font-size: 18px;
  }
  .rm-sheet-close {
    width: 34px; height: 34px; border: none; background: transparent; color: var(--text-2);
    font-size: 17px; cursor: pointer; border-radius: 999px;
  }
  .rm-sheet-close:hover { background: var(--surface-hover); }
  .rm-sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 8px 16px 4px; }
  .rm-search-sheet {
    background: var(--page-bg); border: 1px solid var(--border); color: var(--text); margin: 8px 0 4px;
  }
  .rm-search-sheet .nav-icon { opacity: .7; }
  .rm-search-sheet input { color: var(--text); }
  .rm-search-sheet input::placeholder { color: var(--muted); }

  .rm-facet { padding: 12px 0; border-bottom: 1px solid var(--border-soft); }
  .rm-facet:last-child { border-bottom: none; }
  .rm-facet-title {
    margin: 0 0 10px; font-family: var(--font-body); font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
  }
  .rm-chipset { display: flex; flex-wrap: wrap; gap: 8px; }
  .rm-chip {
    background: var(--page-bg); color: var(--text); border: 1px solid var(--border-strong);
    border-radius: var(--radius-chip); padding: 8px 14px; font: inherit; font-size: 14px; cursor: pointer;
  }
  .rm-chip.is-selected { background: var(--accent-2); color: #fff; border-color: var(--accent-2); }

  .rm-kidrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 0; }
  .rm-kidname { font-weight: 600; }
  .rm-verdicts { display: inline-flex; gap: 6px; }
  .rm-verdict {
    background: transparent; border: 1px solid var(--border-strong); color: var(--text-2);
    border-radius: var(--radius-chip); padding: 7px 14px; font: inherit; font-size: 14px; cursor: pointer;
  }
  .rm-verdict-yes.is-selected { background: var(--good); color: #fff; border-color: var(--good); }
  .rm-verdict-meh.is-selected { background: var(--warn); color: #fff; border-color: var(--warn); }
  .rm-verdict-no.is-selected  { background: var(--bad);  color: #fff; border-color: var(--bad); }

  /* These chips/verdicts (and Reset / active-filter pills) are <button>s, so the
     global `button:hover` accent (~line 358) bleeds through -- and on touch that
     hover "sticks" after a tap until you tap elsewhere, showing as a stray brown.
     Neutralise it: interaction states never recolour a chip; only .is-selected
     does. (All mobile-only -- this whole block is inside @media max-width:760px.) */
  .rm-chip:hover, .rm-chip:focus, .rm-chip:active {
    background: var(--page-bg); color: var(--text); border-color: var(--border-strong);
  }
  .rm-chip.is-selected:hover, .rm-chip.is-selected:focus, .rm-chip.is-selected:active {
    background: var(--accent-2); color: #fff; border-color: var(--accent-2);
  }
  .rm-verdict:hover, .rm-verdict:focus, .rm-verdict:active {
    background: transparent; color: var(--text-2); border-color: var(--border-strong);
  }
  .rm-verdict-yes.is-selected:hover, .rm-verdict-yes.is-selected:focus, .rm-verdict-yes.is-selected:active { background: var(--good); color: #fff; border-color: var(--good); }
  .rm-verdict-meh.is-selected:hover, .rm-verdict-meh.is-selected:focus, .rm-verdict-meh.is-selected:active { background: var(--warn); color: #fff; border-color: var(--warn); }
  .rm-verdict-no.is-selected:hover,  .rm-verdict-no.is-selected:focus,  .rm-verdict-no.is-selected:active  { background: var(--bad);  color: #fff; border-color: var(--bad); }
  .rm-reset:hover, .rm-reset:focus, .rm-reset:active {
    background: transparent; color: var(--text-2); border-color: transparent;
  }
  .rm-chip-active:hover, .rm-chip-active:focus, .rm-chip-active:active {
    background: rgba(255,255,255,.14); color: var(--masthead-text); border-color: rgba(255,255,255,.30);
  }

  .rm-sheet-foot {
    display: flex; gap: 12px; align-items: center; flex: none;
    padding: 12px 16px calc(env(safe-area-inset-bottom, 0px) + 12px);
    border-top: 1px solid var(--border); background: var(--surface);
  }
  .rm-reset {
    flex: none; background: transparent; border: none; color: var(--text-2);
    font: inherit; font-weight: 600; padding: 10px 8px; cursor: pointer;
  }
  .rm-apply {
    flex: 1 1 auto; background: var(--btn-bg); color: var(--btn-fg); border: 1px solid var(--btn-border);
    border-radius: var(--radius-btn); padding: 12px 16px; font: inherit; font-weight: 700; cursor: pointer;
  }
  .rm-apply:hover { background: var(--btn-hover-bg); color: var(--btn-hover-fg); }
}

/* Classical: selected chips are gold-outlined over a faint tint, not a solid
   fill (stroke-forward, per the Classical system). */
[data-theme="classical"] .rm-chip.is-selected,
[data-theme="classical_dark"] .rm-chip.is-selected {
  background: var(--accent-tint); border-color: var(--accent); color: var(--accent);
}

/* ==========================================================================
   DINING OUT  (restaurants / wineries / breweries -- /dining)
   Token-driven so it themes automatically (Organic <-> Classical, light/dark).
   The green header band reuses --meal-dayhead-bg (the planner's sage/near-black).
   Many controls are bare <button>s, so their :hover is pinned to the resting
   look (the global button:hover accent would otherwise bleed through on tap).
   ========================================================================== */

/* ---- Shared bits: stars, status dots/pills, kid tag ---- */
.d-stars { white-space: nowrap; letter-spacing: 1px; font-size: 13px; }
.d-stars-full  { color: #c98a3a; }
.d-stars-empty { color: #cdbfae; }
[data-theme="organic_dark"] .d-stars-full  { color: #e0a54a; }
[data-theme="organic_dark"] .d-stars-empty { color: #5c5344; }
[data-theme="classical"] .d-stars-full,
[data-theme="classical_dark"] .d-stars-full { color: var(--accent); }
[data-theme="classical_dark"] .d-stars-empty { color: #5a5757; }

.d-dot { display: inline-block; width: 9px; height: 9px; border-radius: 999px; flex: none; vertical-align: middle; }
.dstat-good { background: var(--good); }
.dstat-warn { background: var(--warn); }
.dstat-bad  { background: var(--bad); }

.d-status-pill {
  display: inline-block; padding: 5px 12px; border-radius: var(--radius-chip);
  font-size: 12px; font-weight: 700; color: #fff; line-height: 1.2;
}
.d-status-pill.dstat-good { background: var(--good); }
.d-status-pill.dstat-warn { background: var(--warn); }
.d-status-pill.dstat-bad  { background: var(--bad); }

.d-kidtag {
  display: inline-block; background: var(--tag-bg); color: var(--tag-fg);
  border: 1px solid var(--tag-border); border-radius: var(--radius-chip);
  padding: 2px 10px; font-size: 12px; font-weight: 600; white-space: nowrap;
}
.d-kid-yes { color: var(--good); font-weight: 700; }
.d-totrytag {
  display: inline-block; background: transparent; color: var(--accent);
  border: 1px solid var(--accent); border-radius: var(--radius-chip);
  padding: 1px 9px; font-size: 12px; font-weight: 600; white-space: nowrap; line-height: 1.5;
}

/* ---- Green header band (list / map / decide) ---- */
.d-band {
  background: var(--meal-dayhead-bg); color: var(--masthead-text);
  border-radius: var(--radius-card); padding: 16px 20px 18px; margin-bottom: 18px;
}
.d-band-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.d-title { font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 30px; margin: 0; color: #fff; line-height: 1.1; }
.d-sub { font-size: 13px; opacity: .85; margin-top: 3px; }
.d-band-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.d-band .d-add { flex: none; }

/* segmented switcher */
.d-switch { display: inline-flex; gap: 4px; padding: 3px; border-radius: var(--radius-chip); background: rgba(255,255,255,.16); }
.d-switch-tab {
  padding: 7px 15px; border-radius: var(--radius-chip); font-size: 13px;
  color: #fff; text-decoration: none; line-height: 1.1;
}
.d-switch-tab:hover { color: #fff; text-decoration: none; }
.d-switch-tab.is-active { background: #fff; color: var(--meal-dayhead-bg); font-weight: 700; }
.d-switch-tab.is-active:hover { color: var(--meal-dayhead-bg); }

/* search */
.d-search-wrap {
  display: flex; align-items: center; gap: 9px; height: 44px; margin-top: 13px;
  border-radius: var(--radius-input); background: rgba(255,255,255,.16); padding: 0 15px;
}
.d-search-wrap .nav-icon { width: 18px; height: 18px; color: rgba(255,255,255,.85); flex: none; }
.d-search { flex: 1; border: 0; background: transparent; color: #fff; font-size: 15px; outline: none; padding: 0; }
.d-search::placeholder { color: rgba(255,255,255,.7); }

/* filter pills */
.d-filters { display: flex; flex-wrap: wrap; gap: 12px 22px; margin-top: 14px; }
.d-facet { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.d-facet-label { font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: rgba(255,255,255,.8); font-weight: 700; }
.d-filter {
  padding: 5px 12px; border-radius: var(--radius-chip); font-size: 13px; line-height: 1.2;
  border: 1px solid rgba(255,255,255,.35); background: rgba(255,255,255,.10); color: #fff;
  cursor: pointer; font-family: var(--font-body); font-weight: 500;
}
.d-filter:hover { background: rgba(255,255,255,.20); color: #fff; border-color: rgba(255,255,255,.5); }
.d-filter.is-active { background: #fff; color: var(--meal-dayhead-bg); border-color: #fff; font-weight: 700; }
.d-filter.is-active:hover { background: #fff; color: var(--meal-dayhead-bg); }

/* ---- List: desktop table ---- */
.d-table-wrap {
  overflow-x: auto; border-radius: var(--radius-card);
  border: 1px solid var(--border); background: var(--surface);
}
.d-table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 900px; }
.d-table thead th {
  text-align: left; padding: 12px 14px; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--table-head-fg); background: var(--table-head-bg);
  border-bottom: 1px solid var(--table-head-border); white-space: nowrap;
}
.d-table tbody td { padding: 11px 14px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
.d-table tbody tr:last-child td { border-bottom: 0; }
.d-table .d-center { text-align: center; }
.d-muted { color: var(--text-2); }
.d-name-link { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.d-name { font-weight: 700; color: var(--recipe-name); }
.d-name-link:hover .d-name { text-decoration: underline; }
.d-kid-yes { display: inline-block; }
.d-lastvisit { white-space: nowrap; }

/* ---- List: mobile cards ---- */
.d-cards { display: none; flex-direction: column; gap: 12px; }
.d-card {
  display: flex; gap: 12px; align-items: flex-start; text-decoration: none;
  background: var(--card-bg); border: var(--card-border); box-shadow: var(--card-shadow);
  border-radius: var(--radius-card); padding: 14px 15px; color: var(--text);
}
.d-card:hover { text-decoration: none; color: var(--text); }
.d-card-icon {
  width: 42px; height: 42px; border-radius: var(--radius-chip); flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--info-bg); color: var(--good-strong);
}
.d-card-icon .nav-icon { width: 20px; height: 20px; }
.d-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.d-card-head { display: flex; align-items: center; gap: 8px; }
.d-card-name { font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 18px; line-height: 1.15; }
.d-card-sub { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.d-card-foot { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.d-card-price { font-size: 12px; color: var(--muted); }
.d-card-foot .d-kidtag { margin-left: auto; }

.d-empty, .d-noresults { padding: 30px 10px; text-align: center; color: var(--muted); }
.d-noresults { padding: 20px 10px; }

/* ---- Place detail ---- */
.d-crumb { font-size: 13px; color: var(--muted); margin-bottom: 12px; }
.d-crumb-top { color: var(--accent); text-decoration: none; }
.d-crumb-top:hover { text-decoration: underline; }
.d-detail { display: grid; grid-template-columns: 1fr 380px; gap: 28px; align-items: start; }
.d-detail-main { min-width: 0; }
.d-photos { display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; gap: 8px; height: 340px; }
.d-photo {
  display: block; width: 100%; height: 100%; border-radius: var(--radius-card);
  overflow: hidden; background: var(--surface-2);
}
.d-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.d-photo-hero { grid-row: span 2; }
.d-photo-empty { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 13px; }
.d-photos .d-photo:nth-child(1):only-child { grid-column: 1 / -1; grid-row: 1 / -1; }

.d-notes-head { display: flex; align-items: center; justify-content: space-between; margin: 20px 0 12px; }
.d-notes-head h2 { font-family: var(--font-heading); font-size: 22px; margin: 0; }
.d-visit {
  padding: 14px 16px; border-radius: var(--radius-card); background: var(--card-bg);
  border: var(--card-border); box-shadow: var(--card-shadow); margin-bottom: 11px;
}
.d-visit-top { display: flex; align-items: center; gap: 12px; }
.d-visit-date { font-weight: 700; color: var(--accent); }
.d-visit-who { font-size: 12px; color: var(--muted); }
.d-visit-stars { margin-left: auto; }
.d-visit-note { font-size: 14.5px; line-height: 1.55; color: var(--text-2); margin: 8px 0 0; }
.d-visit-note p { margin: 0 0 6px; }
.d-visit-del { display: inline; margin: 0 0 0 auto; }

.d-log-form { margin-top: 18px; padding: 16px; border-radius: var(--radius-card); border: var(--card-border); background: var(--surface); }
.d-log-form h3 { margin: 0 0 10px; font-family: var(--font-heading); font-size: 18px; }

/* right rail */
.d-detail-rail { min-width: 0; }
.d-place-name { font-family: var(--font-heading); font-size: 32px; margin: 0; line-height: 1.05; }
.d-ident { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.d-ident-meta { font-size: 13px; color: var(--muted); }
.d-ratingrow { display: flex; align-items: center; gap: 14px; margin-top: 14px; flex-wrap: wrap; }
.d-ratingrow .d-stars { font-size: 19px; }
.d-price { font-size: 15px; color: var(--muted); }
.d-actions { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.d-actions .button { flex: 1; text-align: center; }
.d-map-frame { margin-top: 18px; border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border); }
.d-map-frame iframe { width: 100%; height: 220px; border: 0; display: block; }
.d-info { margin-top: 16px; font-size: 14px; color: var(--text-2); }
.d-info-row { display: flex; gap: 11px; padding: 9px 0; border-bottom: 1px solid var(--border-soft); align-items: flex-start; }
.d-info-row:last-child { border-bottom: 0; }
.d-info-row .nav-icon { width: 17px; height: 17px; flex: none; color: var(--muted); margin-top: 1px; }
.d-place-notes { margin-top: 14px; font-size: 14px; color: var(--text-2); }
.d-place-notes p { margin: 0 0 6px; }
.d-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }

.d-photos-manage { margin-top: 20px; }
.d-photos-manage h3 { font-family: var(--font-heading); font-size: 17px; margin: 0 0 10px; }
.d-thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin-bottom: 10px; }
.d-thumb { position: relative; }
.d-thumb img { width: 100%; height: 80px; object-fit: cover; border-radius: var(--radius-chip); display: block; }
.d-thumb-del {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; padding: 0;
  border-radius: 999px; background: rgba(0,0,0,.55); color: #fff; border: 0; font-size: 12px; line-height: 1; cursor: pointer;
}
.d-thumb-del:hover { background: rgba(0,0,0,.75); color: #fff; border-color: transparent; }
.d-upload { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.d-detail-admin { margin-top: 18px; }

.d-linkbtn { background: transparent; border: 0; color: var(--muted); cursor: pointer; padding: 2px 6px; font-size: 13px; line-height: 1; }
.d-linkbtn:hover { background: transparent; color: var(--bad); border-color: transparent; }

/* ---- Form ---- */
.d-form-title, .d-form-map summary { }
.d-form-title { font-family: var(--font-heading); font-size: 28px; margin: 4px 0 16px; }
.d-form label { display: block; font-size: 13px; color: var(--text-2); margin-bottom: 12px; }
.d-form input[type="text"], .d-form input[type="date"], .d-form input[type="search"],
.d-form select, .d-form textarea {
  display: block; width: 100%; margin-top: 4px; box-sizing: border-box;
}
.d-form-row { display: flex; gap: 14px; flex-wrap: wrap; }
.d-form-row > label { flex: 1 1 160px; }
.d-form-full { display: block; }
.d-form-check { display: flex; align-items: center; gap: 7px; flex: 0 0 auto; align-self: flex-end; }
.d-form-check input { width: auto; margin: 0; }
.d-form-map { margin: 4px 0 14px; }
.d-form-map summary { cursor: pointer; font-size: 13px; color: var(--text-2); margin-bottom: 8px; }
.d-form-actions { display: flex; gap: 10px; margin-top: 8px; }

/* ---- Map view ---- */
.d-maplayout { display: flex; height: 520px; border-radius: var(--radius-card); overflow: hidden; border: 1px solid var(--border); }
.d-maprail { flex: 0 0 320px; overflow-y: auto; background: var(--surface); border-right: 1px solid var(--border); }
.d-maprail-head { padding: 16px 18px; border-bottom: 1px solid var(--border); }
.d-maprail-head h2 { font-family: var(--font-heading); font-size: 20px; margin: 0; }
.d-legend { display: flex; gap: 14px; margin-top: 10px; font-size: 12px; color: var(--text-2); }
.d-legend span { display: inline-flex; align-items: center; gap: 6px; }
.d-maprail-item { display: flex; align-items: center; gap: 11px; padding: 12px 18px; border-bottom: 1px solid var(--border-soft); text-decoration: none; color: var(--text); }
.d-maprail-item:hover { background: var(--surface-hover); text-decoration: none; color: var(--text); }
.d-maprail-body { flex: 1; min-width: 0; }
.d-maprail-name { display: block; font-weight: 700; font-size: 14px; color: var(--recipe-name); }
.d-maprail-sub { display: block; font-size: 12px; color: var(--muted); }
.d-maprail-stars { white-space: nowrap; }
.d-mapframe { flex: 1; min-width: 0; }
.d-mapframe iframe { width: 100%; height: 100%; border: 0; display: block; }
.d-map-none { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; color: var(--muted); padding: 24px; }

/* ==========================================================================
   DINING · DECIDE  ("where should we eat tonight?" game)
   ========================================================================== */
#d-decide { max-width: 460px; }
.dg-head { background: var(--meal-dayhead-bg); color: #fff; border-radius: var(--radius-card); padding: 16px 18px; margin-bottom: 14px; }
.dg-head-title { font-family: var(--font-heading); font-size: 22px; }
.dg-players { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.dg-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px 5px 6px; border-radius: 999px; background: rgba(255,255,255,.16); font-size: 13px; }
.dg-cutsfirst { font-size: 12px; color: rgba(255,255,255,.85); margin-left: auto; }
.dg-firstlabel { font-size: 12px; color: rgba(255,255,255,.85); margin-right: 2px; }
.dg-pickfirst { cursor: pointer; color: #fff; border: 1px solid transparent; font-family: var(--font-body); }
.dg-pickfirst:hover { background: rgba(255,255,255,.26); color: #fff; border-color: transparent; }
.dg-pickfirst.is-active { background: #fff; color: var(--meal-dayhead-bg); }
.dg-pickfirst.is-active:hover { background: #fff; color: var(--meal-dayhead-bg); }
.dg-firstbadge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; opacity: .75; }
.dg-av { width: 26px; height: 26px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800; color: #fff; flex: none; }
.dg-av--big { width: 44px; height: 44px; font-size: 18px; }
.dg-av--0 { background: var(--accent); }
.dg-av--1 { background: var(--accent-2); }
/* Extra player colours (decorative avatars for 3+ players / the user list). */
.dg-av--2 { background: #b8894e; }
.dg-av--3 { background: #6a7f8f; }
.dg-av--4 { background: #9c6b8e; }
.dg-av--5 { background: #5f8a6a; }
.dg-av--6 { background: #a3623f; }
.dg-av--7 { background: #7a6ea8; }

/* ---- Decide: setup screen (pick players + first cutter + play mode) ---- */
.dg-setup-sub { font-weight: 700; font-size: 14px; color: var(--text-2); margin: 16px 0 8px; }
.dg-setup-hint { font-size: 13px; color: var(--muted); margin: -2px 0 8px; }
.dg-picks { display: flex; flex-wrap: wrap; gap: 8px; }
/* Unselected = dashed + muted; selected = solid accent + tint + a filled check.
   The clear off/on contrast is the fix for "I couldn't tell who was selected". */
.dg-playerpick {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px 7px 7px;
  border: 1.5px dashed var(--border-strong); border-radius: 999px;
  background: transparent; cursor: pointer; font-weight: 600; color: var(--muted);
}
.dg-playerpick.is-on { border-style: solid; border-color: var(--accent); background: var(--accent-tint); color: var(--text); }
.dg-playerpick input { position: absolute; opacity: 0; width: 0; height: 0; }
.dg-playerpick-name { font-size: 14px; }
.dg-playerpick-check {
  width: 20px; height: 20px; border-radius: 999px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--border-strong); color: #fff; font-size: 12px; font-weight: 800;
}
.dg-playerpick.is-on .dg-playerpick-check { background: var(--accent); border-color: var(--accent); }

/* "Start from a saved list" chips (setup) + the saved-lists bar (build). */
.dg-startlists, .dg-loadlists { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.dg-startlist-wrap { display: inline-flex; align-items: center; }
.dg-startlist, .dg-loadlist {
  cursor: pointer; border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text); border-radius: 999px; padding: 6px 12px; font-size: 13px; font-weight: 600;
  font-family: var(--font-body);
}
.dg-startlist:hover, .dg-loadlist:hover { background: var(--accent-tint); color: var(--text); border-color: var(--accent); }
.dg-startlist.is-active { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.dg-startlist.is-active:hover { background: var(--accent); color: var(--accent-on); }
.dg-listcount { opacity: .7; font-size: 12px; }
.dg-listdel {
  border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 13px;
  padding: 2px 6px; margin-left: 2px;
}
.dg-listdel:hover { color: var(--btn-danger); background: transparent; border-color: transparent; }
.dg-listsbar { margin: 12px 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--card-bg); }
.dg-listsbar-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; font-weight: 700; font-size: 14px; color: var(--text-2); }

/* Error flash on the setup screen. */
.dg-flash--err { background: var(--err-bg); color: var(--err-text); border-color: var(--err-border); }

/* Preview of the selected start-from list's places (setup screen). */
.dg-listpreview { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.dg-preview-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; font-size: 13px;
  background: var(--surface); border: 1px solid var(--border-soft); color: var(--text);
}
.dg-preview-kind { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; }
.dg-preview-kind.is-sit { color: var(--accent-2); }
.dg-preview-kind.is-takeout { color: var(--muted); }

/* Game-screen action row (start over / new game). */
.dg-gameactions { margin-top: 12px; font-size: 13px; color: var(--muted); }
.dg-startover { font-weight: 700; }

/* ---- Decide lists: admin management page (#dl-manage) ---- */
.dl-flash { background: var(--info-bg); color: var(--info-text); border: 1px solid var(--info-border); border-radius: var(--radius-card); padding: 9px 14px; margin-bottom: 12px; font-size: 14px; }
.dl-toolbar { margin: 8px 0 14px; }
.dl-list { display: flex; flex-direction: column; gap: 10px; }
.dl-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); padding: 14px 16px; }
.dl-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dl-card-title { font-family: var(--font-heading); font-weight: var(--heading-weight); font-size: 18px; }
.dl-card-actions { display: flex; gap: 8px; flex: none; }
.dl-card-actions .button { margin: 0; }
.dl-card-preview { margin-top: 6px; font-size: 13px; color: var(--text-2); }
.dl-card-preview.dl-muted { color: var(--muted); font-style: italic; }

.dl-editor { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); padding: 16px 18px; }
.dl-editor-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.dl-name { flex: 1 1 auto; font-size: 16px; font-family: var(--font-heading); }
.dl-rows { display: flex; flex-direction: column; gap: 6px; margin: 12px 0; }
.dl-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border-soft); border-radius: var(--radius-card); background: var(--surface); }
.dl-row-body { flex: 1 1 auto; min-width: 0; }
.dl-row-name { font-weight: 600; }
.dl-row-sub { font-size: 12px; color: var(--muted); }
/* Drag handle (same interaction as the shopping list). */
.dl-grip { flex: none; display: inline-flex; align-items: center; cursor: grab; color: var(--muted); touch-action: none; -webkit-user-select: none; user-select: none; }
.dl-grip:active { cursor: grabbing; }
.dl-row.is-dragging { opacity: .55; background: var(--surface-hover); }
.dl-editor-foot { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.dl-editor-foot .button { margin: 0; }
.dl-del-inline { color: var(--btn-danger); margin-left: auto; }
/* First-cutter chips + mode toggle sit on the light page (not the dark head), so
   they get light-surface styling rather than the translucent-on-dark chip. */
.dg-setup .dg-players { margin-top: 0; }
.dg-setup .dg-pickfirst {
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong);
}
.dg-setup .dg-pickfirst:hover { background: var(--accent-tint); color: var(--text); border-color: var(--accent); }
.dg-setup .dg-pickfirst.is-active { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.dg-setup .dg-pickfirst.is-active:hover { background: var(--accent); color: var(--accent-on); }
.dg-setup .dg-firstbadge { opacity: .9; }
.dg-modetoggle { flex-wrap: wrap; }

/* Roster chips shown on the build head (dark), first cutter highlighted. */
.dg-roster.is-active { background: #fff; color: var(--meal-dayhead-bg); }

/* Transient message (e.g. "It's not your turn"). */
.dg-flash {
  background: var(--info-bg); color: var(--info-text); border: 1px solid var(--info-border);
  border-radius: var(--radius-card); padding: 9px 14px; margin-bottom: 12px; font-size: 14px;
}
.dg-newgame { font-size: 13px; }
/* While it's someone else's turn, their candidate cards are read-only. */
.dg-list.is-waiting { opacity: .7; }

.dg-head--turn .dg-turnline { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: rgba(255,255,255,.85); }
.dg-turnrow { display: flex; align-items: center; gap: 11px; margin-top: 12px; }
.dg-turnhint { font-size: 12.5px; color: rgba(255,255,255,.85); margin-top: 2px; }

.dg-addbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.dg-addbar #dg-add { height: 42px; border-radius: var(--radius-input); border: 1px solid var(--border-strong); background: var(--surface); padding: 0 14px; font-size: 14px; color: var(--text); width: 100%; box-sizing: border-box; }
.dg-addfield { position: relative; flex: 1 1 180px; }
.dg-suggest {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  max-height: 320px; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 4px;
}
.dg-suggest-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; background: transparent; border: 0; border-radius: 8px;
  padding: 9px 11px; cursor: pointer; color: var(--text); font-family: var(--font-body); font-size: 14px;
}
.dg-suggest-item:hover { background: var(--surface-hover); color: var(--text); border-color: transparent; }
.dg-suggest-name { font-weight: 600; }
.dg-suggest-town { font-size: 12px; color: var(--muted); flex: none; }
.dg-suggest-more { padding: 7px 11px; font-size: 12px; color: var(--muted); }
.dg-kind-toggle { display: inline-flex; gap: 3px; padding: 3px; border-radius: var(--radius-chip); background: var(--surface-2); }
.dg-kt { padding: 6px 11px; border-radius: var(--radius-chip); font-size: 12px; border: 0; background: transparent; color: var(--text-2); cursor: pointer; font-weight: 600; }
.dg-kt:hover { background: transparent; color: var(--text); border-color: transparent; }
.dg-kt.is-active { background: var(--accent-2); color: #fff; }
.dg-kt.is-active:hover { background: var(--accent-2); color: #fff; }

.dg-count { font-size: 12px; color: var(--muted); font-weight: 700; margin-bottom: 8px; }
.dg-list { display: flex; flex-direction: column; gap: 9px; }
.dg-row { display: flex; align-items: center; gap: 11px; padding: 11px 13px; border-radius: var(--radius-card); background: var(--card-bg); border: var(--card-border); box-shadow: var(--card-shadow); }
.dg-row-body { flex: 1; min-width: 0; }
.dg-row-name { font-family: var(--font-heading); font-size: 16px; }
.dg-row-sub { font-size: 12px; color: var(--muted); }
.dg-kind { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 10.5px; font-weight: 700; white-space: nowrap; }
.dg-kind--sit { background: var(--tag-bg); color: var(--tag-fg); }
.dg-kind--takeout { background: var(--chip-bg); color: var(--chip-fg); }
.dg-kind-btn { padding: 0; border: 0; background: transparent; cursor: pointer; }
.dg-kind-btn:hover { background: transparent; border-color: transparent; }
.dg-x { width: 26px; height: 26px; padding: 0; border: 0; background: transparent; color: var(--muted); font-size: 14px; cursor: pointer; flex: none; }
.dg-x:hover { background: transparent; color: var(--bad); border-color: transparent; }
.dg-empty { padding: 20px 12px; text-align: center; color: var(--muted); font-size: 13px; }
.dg-foot { margin-top: 14px; }
.dg-start { width: 100%; background: var(--accent-2); border-color: var(--accent-2); }
.dg-start:hover:not([disabled]) { filter: brightness(.95); background: var(--accent-2); border-color: var(--accent-2); color: #fff; }
.dg-start[disabled] { opacity: .5; cursor: not-allowed; }
.dg-foot-note { text-align: center; font-size: 12px; color: var(--muted); margin-top: 9px; }
.dg-add-btn { flex: none; }

.dg-cutcard { display: flex; align-items: center; gap: 12px; padding: 14px 15px; border-radius: var(--radius-card); background: var(--card-bg); border: var(--card-border); box-shadow: var(--card-shadow); }
.dg-cutcard-body { flex: 1; min-width: 0; }
.dg-cut { display: inline-flex; align-items: center; gap: 5px; padding: 8px 13px; border-radius: var(--radius-btn); border: 1.5px solid var(--accent); background: transparent; color: var(--accent); font-size: 13px; font-weight: 700; cursor: pointer; flex: none; }
.dg-cut:hover { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.dg-cutdivider { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin: 14px 0 9px; }
.dg-cutlist { display: flex; flex-direction: column; gap: 7px; }
.dg-cutrow { display: flex; align-items: center; gap: 10px; padding: 9px 14px; border-radius: var(--radius-chip); background: var(--surface-2); }
.dg-cutrow-name { flex: 1; font-size: 14px; color: var(--muted); text-decoration: line-through; }

.dg-finalgrid { display: flex; flex-direction: column; gap: 14px; }
.dg-finalcard { border-radius: var(--radius-card); overflow: hidden; background: var(--card-bg); border: var(--card-border); box-shadow: var(--card-shadow); }
.dg-ph { display: block; width: 100%; height: 120px; background-size: cover; background-position: center; background-color: var(--surface-2); }
.dg-ph--empty { background-color: var(--surface-2); }
.dg-ph--big { height: 190px; border-radius: var(--radius-card); }
.dg-finalcard-body { padding: 14px 16px; }
.dg-pick { width: 100%; margin-top: 12px; background: var(--accent-2); border-color: var(--accent-2); }
.dg-pick:hover { filter: brightness(.95); background: var(--accent-2); border-color: var(--accent-2); color: #fff; }

.dg-winner-hero { background: var(--meal-dayhead-bg); color: #fff; border-radius: var(--radius-card); padding: 26px 22px; text-align: center; }
.dg-winner-kicker { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.85); }
.dg-winner-name { font-family: var(--font-heading); font-size: 32px; line-height: 1.05; margin-top: 10px; }
.dg-winner-sub { font-size: 14px; color: rgba(255,255,255,.85); margin-top: 8px; }
.dg-winner-card { padding: 16px 0; }
.dg-winner-meta { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.dg-winner-meta .d-stars { font-size: 18px; }
.dg-winner-actions { display: flex; gap: 8px; margin-top: 12px; }
.dg-winner-actions .button { flex: 1; text-align: center; }
.dg-playagain { text-align: center; font-size: 13px; color: var(--muted); margin-top: 8px; }
.dg-again { color: var(--accent-2); font-weight: 700; padding: 0 2px; }
.dg-again:hover { color: var(--accent); }

/* ---- Dining responsive (phone) ---- */
@media (max-width: 900px) {
  /* Single column: flatten the two column-wrappers (display:contents removes them
     from layout so their blocks become direct flex items of .d-detail) and order
     the blocks into the prototype's mobile sequence -- hero, name, actions, info,
     map, photos, visit log -- instead of "whole left column, then whole rail". */
  .d-detail { display: flex; flex-direction: column; gap: 18px; }
  .d-detail-main, .d-detail-rail { display: contents; }
  .d-photos         { order: 1; }
  .d-id-block       { order: 2; }
  .d-actions        { order: 3; }
  .d-log-form       { order: 4; }   /* opens right under the action row */
  .d-info           { order: 5; }
  .d-map-frame      { order: 6; }
  .d-place-notes    { order: 7; }
  .d-tags           { order: 8; }
  .d-photos-manage  { order: 9; }
  .d-visits-section { order: 10; }
  .d-detail-admin   { order: 11; }
  /* Their own top margins would stack on top of the flex gap -- zero them. */
  .d-id-block, .d-actions, .d-log-form, .d-info, .d-map-frame, .d-place-notes,
  .d-tags, .d-photos-manage, .d-visits-section, .d-detail-admin { margin-top: 0; }
  /* Log-a-visit trigger lives in the action row on phones; hide the duplicate
     one in the Visit-notes head. Two-up action buttons so 3–4 wrap cleanly. */
  .d-notes-head .d-log-toggle { display: none; }
  .d-actions .button { flex: 1 1 42%; }
}
/* On desktop the trigger lives in the Visit-notes head; hide the action-row one. */
@media (min-width: 901px) {
  .d-actions .d-log-toggle { display: none; }
}
@media (max-width: 760px) {
  .d-table-wrap { display: none; }
  .d-cards { display: flex; }
  .d-title { font-size: 24px; }
  .d-photos { height: auto; grid-template-columns: 1fr; grid-template-rows: none; }
  .d-photo { height: 210px; }
  .d-photo-hero { grid-row: auto; }
  /* Map view on phones: the map fills the space and the list is hidden entirely
     (pins + their popups do the navigating). The colour key lives on the map
     itself (see the legend control in public/dining-map.html). */
  .d-maplayout { flex-direction: column; height: auto; }
  .d-maprail { display: none; }
  .d-mapframe { height: 72vh; min-height: 360px; }
  #d-decide { max-width: 100%; }
  /* Keep each facet on one compact, horizontally-scrollable line so the header
     band doesn't grow tall on a phone. */
  .d-filters { gap: 10px; }
  .d-facet { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .d-facet-label { flex: none; }
  .d-filter { flex: none; }
}
