/* =============================================================================
   airfryer-app — single stylesheet.

   Sections:
     1. Design tokens        (copied verbatim from docs/designs/design-system.md)
     2. Reset + base
     3. Layout shell         (top bar, bottom tab bar, page wrap, footer)
     4. Type scale
     5. Shared components    (chip, badge, button, card, pill row, form field,
                              notice, empty state, quick links)
     6. Hover / motion       (hover behind @media (hover:hover))
     7. PAGE-SPECIFIC SECTIONS — appended by later tasks below the banner

   Portal (Chromium ~70) hard rules — do not break them:
     no flexbox `gap` (grid `gap` is fine), no `aspect-ratio`, no `:is()`/
     `:where()`, no container queries, no `dvh`, no CSS nesting. Touch targets
     >= 48px (>= 64px in Cook Mode). Hover only inside @media (hover: hover);
     every control gets a visible `:active` state.
   ============================================================================= */

/* ============================ 1. design tokens ============================ */

:root {
  /* palette */
  --flour: #FBF7F0;        /* page background — warm white */
  --card: #FFFFFF;
  --crumb: #EBE2D6;        /* borders, dividers */
  --char: #221A14;         /* primary ink — warm charcoal */
  --smoke: #6B5F55;        /* muted ink — 4.6:1 on flour */
  --crisp: #E85D04;        /* brand orange — big elements, fills, accents */
  /* Text-level orange. Was #B84A03, which measures 4.40:1 on --crisp-soft —
     under this system's own 4.5:1 floor, and --crisp-soft is the background of
     every selected pill, segmented control and turn badge (persistent states,
     not transient ones). One notch darker at the same hue clears it everywhere:
     4.88:1 on --crisp-soft, 5.42:1 on --flour, 5.79:1 on --card. */
  --crisp-deep: #AD4503;
  --crisp-soft: #FDE8D7;   /* orange tint — selected states, banners */
  --herb: #3F6C51;         /* success / done / veg accent */
  --herb-soft: #E4EEE7;
  /* Alarm ink. Was #D92D20 = 4.01:1 on --alarm-soft, under the floor — and
     alarm-on-alarm-soft is live: .sl-remove:active (shopping list) paints it as
     text, .warn-head svg as an icon on a .tip-warn card. Same hue darkened:
     4.73:1 on --alarm-soft, 5.34:1 on --flour, 5.70:1 on --card, and
     white-on-alarm fills improve to 5.70:1 too. */
  --alarm: #C4291D;
  --alarm-soft: #FEE4E2;
  /* appliance panel (Cook Mode + readout chips) */
  --basket: #191310;       /* panel black — warm, not pure black */
  --panel-edge: #2E241D;
  --ember: #FFB454;        /* LED amber — digits on panel */
  /* LED amber at rest / label TEXT on the panel. Was #8A6A45, which measures
     3.70:1 on --basket — below this design system's own 4.5:1 text floor, and
     two pages had already patched around it locally. Same hue one notch up:
     5.81:1 on --basket, 4.79:1 on --panel-edge. One value, no local overrides. */
  --ember-dim: #B08A5C;
  /* type */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-digits: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  /* shape + space */
  --r-card: 14px;
  --r-chip: 999px;
  --space: 8px;            /* base unit; use multiples */
  --shadow-card: 0 1px 2px rgba(34,26,20,.06), 0 4px 12px rgba(34,26,20,.05);
}

/* ============================= 2. reset + base ============================ */

* { margin: 0; padding: 0; box-sizing: border-box; }

/* `overflow-x: hidden` here propagates to the viewport, so the page can never
   scroll sideways. Do NOT repeat it on `body`: a second overflow-x makes body
   its own scroll container, and every `position: sticky` descendant (top bar,
   cheat-sheet jump nav) then sticks to a box that never scrolls — i.e. stops
   sticking. Overflowing content is still clipped by this rule alone. */
html {
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

body {
  background: var(--flour);
  color: var(--char);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.55;
  padding-bottom: 76px; /* clearance for the fixed phone tab bar */
}

svg { display: block; }
img { max-width: 100%; height: auto; border: 0; }
a { color: inherit; }
b, strong { font-weight: 700; }
ul, ol { list-style-position: outside; padding-left: 20px; }

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

table { border-collapse: collapse; }

/* Visible focus for old Chromium: :focus, not only :focus-visible. */
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus,
summary:focus {
  outline: 3px solid var(--crisp);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--card);
  color: var(--crisp-deep);
  font-weight: 700;
  padding: 14px 18px;
  border-radius: 0 0 var(--r-card) 0;
}
.skip-link:focus { left: 0; }

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

/* ============================ 3. layout shell ============================ */

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 16px 48px;
}

/* top bar — hidden on phones, shown from 960px (Portal landscape / desktop) */
.topbar { display: none; }

.wordmark {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding-right: 8px;
  text-decoration: none;
  color: var(--char);
}
.led {
  width: 26px;
  height: 26px;
  border-radius: var(--r-chip);
  background: radial-gradient(circle at 50% 50%, var(--ember) 0, var(--ember) 4px, var(--basket) 5px);
}
.wordmark-text {
  margin-left: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
}
/* The wordmark is a link to Today, so it needs press feedback like every other
   control — it had a hover rule and nothing for touch. */
.wordmark:active { color: var(--crisp-deep); }

.topnav { margin-left: auto; display: flex; flex-wrap: wrap; justify-content: flex-end; }
.topnav a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0 14px;
  margin-left: 2px;
  text-decoration: none;
  color: var(--smoke);
  font-size: 16px;
  font-weight: 600;
}
.topnav a:active { color: var(--crisp-deep); background: var(--flour); }
.topnav .nav-active { color: var(--crisp-deep); box-shadow: inset 0 -3px 0 var(--crisp-deep); }

/* bottom tab bar — phone only */
.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  height: 56px;
  background: var(--card);
  border-top: 1px solid var(--crumb);
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}
.tab {
  display: grid;
  gap: 2px;
  justify-items: center;
  align-content: center;
  height: 56px;
  text-decoration: none;
  color: var(--smoke);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
}
.tab svg { width: 24px; height: 24px; }
.tab:active { background: var(--crisp-soft); color: var(--crisp-deep); }
.tab-active { color: var(--crisp-deep); box-shadow: inset 0 3px 0 var(--crisp-deep); }

@media (min-width: 960px) {
  body { padding-bottom: 0; }
  .tabbar { display: none; }
  .topbar {
    display: flex;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 50;
    min-height: 64px;
    background: var(--card);
    border-bottom: 1px solid var(--crumb);
    padding: 0 24px;
  }
  .wrap { padding: 0 32px 64px; }
}

/* footer */
.site-footer {
  border-top: 1px solid var(--crumb);
  margin-top: 40px;
  padding: 24px 16px 32px;
  max-width: 1120px;
  margin-left: auto;
  margin-right: auto;
  color: var(--smoke);
  font-size: 15px;
}
.footer-line { max-width: 78ch; margin-bottom: 8px; }
.footer-meta { margin-top: 4px; font-size: 14px; }
/* Inline footer links still have to clear the 48px touch floor. */
.site-footer a {
  display: inline-block;
  padding: 16px 8px;
  color: var(--crisp-deep);
  font-weight: 600;
}
.site-footer a:active { color: var(--crisp); background: var(--crisp-soft); border-radius: 8px; }
@media (min-width: 960px) {
  .site-footer { padding: 28px 32px 40px; }
}

/* ============================== 4. type scale ============================ */

.eyebrow {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--smoke);
}
.page-head { margin: 8px 0 20px; }
.page-title {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
  margin-top: 4px;
}
.section-title { font-size: 24px; font-weight: 800; letter-spacing: -.01em; }
.card-title { font-size: 20px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
.lede { color: var(--smoke); font-size: 17px; max-width: 60ch; margin-top: 8px; }
.section { margin-top: 32px; }
.section .section-title { margin-bottom: 14px; }
.muted { color: var(--smoke); }
.code {
  font-family: var(--font-digits);
  font-size: 15px;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: 6px;
  padding: 1px 6px;
}
@media (min-width: 960px) {
  .page-title { font-size: 34px; }
}

/* ========================== 5. shared components ========================= */

/* --- readout chip: the brand mark. Never restyle it per page. --- */
.chip {
  display: inline-block;
  background: var(--basket);
  color: var(--ember);
  font-family: var(--font-digits);
  font-size: 16px;
  font-weight: 600;
  border-radius: var(--r-chip);
  padding: 6px 14px;
  white-space: nowrap;
}
.chip .safe { color: #A9D18E; }
.chip-lg { font-size: 22px; padding: 10px 20px; }
.chip-row { margin-top: 10px; text-align: right; }

/* --- badges --- */
.badge {
  display: inline-block;
  background: var(--basket);
  color: var(--ember);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: var(--r-chip);
  padding: 3px 10px;
  margin-left: 8px;
}
.badge-safe {
  background: var(--herb-soft);
  color: var(--herb);
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
}

/* --- buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 10px 22px;
  border: 0;
  border-radius: var(--r-card);
  font-family: var(--font-ui);
  font-weight: 700;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}
.btn svg { width: 20px; height: 20px; margin-right: 8px; }
.btn-primary { background: var(--crisp); color: #FFFFFF; font-size: 19px; }
.btn-primary:active { background: var(--crisp-deep); transform: translateY(1px); }
.btn-secondary {
  background: var(--card);
  color: var(--char);
  border: 2px solid var(--crumb);
  font-size: 17px;
}
.btn-secondary:active { background: var(--flour); border-color: var(--smoke); transform: translateY(1px); }
.btn-danger { background: var(--card); color: var(--alarm); border: 2px solid var(--alarm-soft); font-size: 17px; }
.btn-danger:active { background: var(--alarm-soft); transform: translateY(1px); }
.btn-block { display: flex; width: 100%; }
.btn-row { margin-top: 16px; }
.btn-row .btn { margin: 0 8px 8px 0; }

/* inline-FLEX, not inline-block: `min-height` on an inline-block is advisory
   against a line box, and this link measured 46.8px against the 48px floor.
   Same fix (and the same 48px) as .link-plain below. */
.text-link {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 11px 4px;
  color: var(--crisp-deep);
  font-weight: 600;
  text-decoration: underline;
}
.text-link:active { color: var(--crisp); }
.link-plain {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 14px;
  color: var(--crisp-deep);
  font-size: 17px;
  font-weight: 600;
  text-decoration: underline;
}
.link-plain:active { background: var(--crisp-soft); border-radius: var(--r-card); }

/* --- cards --- */
.card {
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 16px;
}
.card + .card { margin-top: 16px; }

.card-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

/* emoji art square — no photos in v1 */
.art {
  width: 84px;
  height: 84px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--crisp-soft), var(--flour));
  display: grid;
  place-items: center;
  font-size: 44px;
  line-height: 1;
}

/* recipe card — the whole card is the tap target */
.rcard {
  position: relative;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.rcard-link {
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 14px;
  align-items: start;
  min-height: 88px;
  padding: 16px;
  border-radius: var(--r-card);
  text-decoration: none;
  color: inherit;
}
.rcard-link:active { background: var(--crisp-soft); }
.rcard-body { min-width: 0; padding-right: 40px; }
.rcard-meta { color: var(--smoke); font-size: 16px; margin-top: 2px; }

.fav {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--r-chip);
  color: var(--smoke);
  cursor: pointer;
}
.fav svg { width: 24px; height: 24px; }
.fav:active { background: var(--crisp-soft); color: var(--crisp-deep); }
.fav-on { color: var(--crisp); }

/* --- pill filter row --- */
.filter-group { margin-top: 18px; }
.filter-label { margin-bottom: 8px; }
.pill-row {
  display: flex;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2px 0 8px;
}
.pill {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 18px;
  margin-right: 8px;
  border-radius: var(--r-chip);
  background: var(--card);
  border: 2px solid var(--crumb);
  color: var(--char);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.pill:active { background: var(--crisp-soft); transform: translateY(1px); }
.pill-on { background: var(--crisp-soft); border-color: var(--crisp); color: var(--crisp-deep); }

/* --- form fields --- */
.field { margin-bottom: 18px; }
.field-label { display: block; font-size: 16px; font-weight: 600; margin-bottom: 6px; }
.input {
  width: 100%;
  height: 52px;
  padding: 0 14px;
  font-size: 17px;
  color: var(--char);
  background: var(--card);
  border: 2px solid var(--crumb);
  border-radius: 10px;
}
textarea.input { height: auto; min-height: 104px; padding: 12px 14px; line-height: 1.5; }
select.input { height: 52px; }
.input:focus { outline: 3px solid var(--crisp-soft); border-color: var(--crisp); }
.input::placeholder { color: var(--smoke); }
.helper { font-size: 16px; color: var(--smoke); margin-top: 6px; }

/* radio / segmented control */
.seg-group { display: flex; align-items: center; flex-wrap: wrap; }
.seg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 72px;
  padding: 0 20px;
  margin: 0 8px 8px 0;
  border-radius: var(--r-chip);
  border: 2px solid var(--crumb);
  background: var(--card);
  color: var(--char);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.seg-btn:active { background: var(--crisp-soft); }
.seg-selected { background: var(--crisp-soft); border-color: var(--crisp); color: var(--crisp-deep); font-weight: 700; }

/* --- notices --- */
.notice {
  background: var(--crisp-soft);
  border-left: 4px solid var(--crisp);
  border-radius: var(--r-card);
  padding: 16px 18px 18px;
  margin-bottom: 18px;
}
.notice-title { font-size: 18px; font-weight: 800; }
.notice p { margin-top: 4px; max-width: 62ch; }
.notice .btn { margin-top: 14px; }
.notice-error { background: var(--alarm-soft); border-left-color: var(--alarm); }
.notice-success { background: var(--herb-soft); border-left-color: var(--herb); }
.notice-warn { background: var(--alarm-soft); border-left-color: var(--alarm); }

/* --- empty state --- */
.empty {
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 40px 24px;
  text-align: center;
  margin-top: 20px;
}
.empty-art {
  width: 84px;
  height: 84px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--crisp-soft), var(--flour));
  display: grid;
  place-items: center;
  margin: 0 auto 16px;
  color: var(--crisp-deep);
}
.empty-art svg { width: 40px; height: 40px; }
.empty-title { font-size: 24px; font-weight: 800; letter-spacing: -.01em; }
.empty p { color: var(--smoke); max-width: 46ch; margin: 8px auto 20px; }

/* --- quick links grid (404, More, guest hero) --- */
.quick-links {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  max-width: 720px;
  margin: 24px 0 0;
}
.quick-link {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 8px 12px;
  background: var(--card);
  border: 2px solid var(--crumb);
  border-radius: var(--r-card);
  text-decoration: none;
  color: var(--char);
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}
.quick-link svg { width: 20px; height: 20px; margin-right: 8px; color: var(--crisp-deep); }
.quick-link:active { background: var(--flour); transform: translateY(1px); }

.logout-row { margin-top: 22px; }

/* ========================== 6. hover + motion ============================ */

/* Decorative only — never required to reach functionality (Portal is touch). */
@media (hover: hover) {
  .btn-primary:hover { background: var(--crisp-deep); }
  .btn-secondary:hover { border-color: var(--smoke); }
  .btn-danger:hover { background: var(--alarm-soft); }
  .topnav a:hover { color: var(--char); }
  .tab:hover { color: var(--char); }
  .rcard:hover { box-shadow: 0 2px 4px rgba(34,26,20,.08), 0 8px 20px rgba(34,26,20,.09); }
  .fav:hover { background: var(--flour); }
  .quick-link:hover { border-color: var(--smoke); }
  .pill:hover { border-color: var(--smoke); }
  .wordmark:hover .wordmark-text { color: var(--crisp-deep); }
  .site-footer a:hover { color: var(--crisp); }
}

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

/* =============================================================================
   ===========  PAGE-SPECIFIC SECTIONS BELOW — APPEND ONLY  ====================
   Later tasks add their page styles here, each under its own banner comment
   (e.g. "--- recipe detail ---"). Do not edit sections 1-6 above without
   checking every page that uses them.
   ============================================================================= */

/* --- auth + settings (login, register, settings, 429) ------------------- */

.auth-card {
  max-width: 440px;
  margin: 24px auto 0;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 24px;
}
.auth-title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -.01em;
  line-height: 1.25;
  margin-bottom: 16px;
}
.card-sub {
  font-size: 17px;
  color: var(--smoke);
  margin: -12px 0 16px;
}
.switch-line {
  margin-top: 16px;
  font-size: 16px;
  color: var(--smoke);
  text-align: center;
}
.house-note {
  margin-top: 14px;
  font-size: 16px;
  color: var(--smoke);
  text-align: center;
}
/* mockup treatment for the single-line auth notices (docs/designs/auth.html) */
.auth-card .notice { padding: 14px 16px; font-size: 17px; }
.auth-card .notice-success { color: var(--herb); font-weight: 600; }

/* settings */
.settings-card { max-width: 560px; }
.setting-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  padding: 14px 0;
  border-bottom: 1px solid var(--crumb);
}
.setting-name {
  font-size: 17px;
  font-weight: 600;
  margin-right: 16px;
  padding: 10px 0;
}
/* the segmented control is a form here (one tap = one POST, no JS needed) */
.setting-row .seg-group { margin-bottom: -8px; }
.setting-row .seg-btn { margin: 0 0 8px 8px; }
.account-line { margin-top: 18px; color: var(--smoke); font-size: 16px; }
.account-email { color: var(--char); font-weight: 600; }

/* rate-limited (429) */
.limit-card { text-align: center; padding: 40px 24px; }
.limit-icon { margin: 0 auto 10px; color: var(--smoke); }
.limit-title { font-size: 24px; font-weight: 800; margin-bottom: 6px; }
.limit-copy { margin-bottom: 6px; }
.limit-fine { font-size: 16px; color: var(--smoke); margin-bottom: 22px; }

/* --- converter (oven -> air fryer) ------------------------------------- */

.conv-card { max-width: 560px; padding: 22px; margin-top: 20px; }
.conv-card .field { margin-bottom: 22px; }
.conv-number { font-family: var(--font-digits); font-size: 18px; }

/* temperature input + its unit pills — grid gap, never flex gap (Portal) */
.conv-temp-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
}
.unit-radios { white-space: nowrap; }

/* real radios, visually hidden over their own pill: one tap, zero JS */
.rpill { position: relative; display: inline-block; }
.rpill + .rpill { margin-left: 8px; }
.rpill input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.rpill span {
  display: inline-block;
  min-width: 64px;
  min-height: 52px;
  padding: 13px 18px;
  border: 2px solid var(--crumb);
  border-radius: var(--r-chip);
  background: var(--card);
  color: var(--char);
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}
.rpill input:checked + span { background: var(--crisp-soft); border-color: var(--crisp); }
.rpill input:focus + span { border-color: var(--crisp); box-shadow: 0 0 0 3px var(--crisp-soft); }
.rpill input:active + span { background: var(--crisp-soft); }

/* conventional / fan segmented control */
.conv-seg {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 2px solid var(--crumb);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--card);
}
.conv-seg-opt { position: relative; display: block; }
.conv-seg-opt:first-child { border-right: 2px solid var(--crumb); }
.conv-seg-opt input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.conv-seg-opt span {
  display: block;
  min-height: 52px;
  padding: 14px 8px;
  color: var(--smoke);
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}
.conv-seg-opt input:checked + span {
  background: var(--crisp-soft);
  color: var(--char);
  box-shadow: inset 0 -3px 0 var(--crisp);
}
.conv-seg-opt input:focus + span {
  box-shadow: inset 0 -3px 0 var(--crisp), inset 0 0 0 3px var(--crisp-soft);
}
.conv-seg-opt input:active + span { background: var(--crisp-soft); }

/* result */
/* The converter is a single narrow column (720px in the mockup), not the full
   1120px shell — the answer is two numbers, it should not span a desktop. */
.conv-summary { color: var(--smoke); font-size: 18px; margin-top: 6px; }
.result-card {
  max-width: 720px;
  padding: 30px 20px;
  margin-top: 20px;
  text-align: center;
}
.result-label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--smoke);
  margin-bottom: 14px;
}
/* the readout chip at converter scale — same chip, bigger digits */
.chip-huge { font-size: 40px; line-height: 1; padding: 18px 32px; }
.conv-both { margin-top: 16px; font-size: 18px; font-weight: 600; }
.fan-note { margin-top: 10px; color: var(--crisp-deep); font-weight: 600; }

.conv-notice { max-width: 720px; margin: 16px 0 0; text-align: left; }
.conv-errors { margin-top: 6px; }
.conv-errors li { margin-top: 4px; }

.conv-fine { margin-top: 18px; padding-left: 0; list-style: none; color: var(--smoke); }
.conv-fine li { margin-top: 6px; }

.conv-again { margin-top: 20px; }

@media (min-width: 960px) {
  .chip-huge { font-size: 52px; padding: 22px 40px; }
}

/* --- cheat sheet (/cheatsheet) ------------------------------------------ */

/* head row: title + disclaimer left, °C/°F toggle right (wraps on phones) */
.cheat-head { display: flex; flex-wrap: wrap; align-items: flex-start; margin: 8px 0 0; }
.cheat-head-text { flex: 1 1 260px; margin-right: 16px; }
.cs-disclaimer { color: var(--smoke); font-size: 17px; max-width: 62ch; margin-top: 8px; }
.cs-units { margin-top: 10px; white-space: nowrap; }
.cs-units .seg-btn { min-width: 64px; font-size: 17px; }

/* sticky jump nav — bleeds to the viewport edges so the pills can scroll
   past them; `top` clears the sticky top bar once it appears at 960px. */
.cs-jumpnav {
  position: sticky;
  top: 0;
  z-index: 30;
  margin: 16px -16px 0;
  padding: 10px 16px;
  background: var(--flour);
  border-bottom: 1px solid var(--crumb);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  white-space: nowrap;
}

/* groups + the chart tables */
.cs-group { margin-top: 32px; scroll-margin-top: 84px; }
.cs-group .section-title { margin-bottom: 12px; }
.cs-tablewrap {
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
/* min-width forces the h-scroll INSIDE .cs-tablewrap on narrow screens,
   which is what keeps the page body from scrolling sideways. */
.cs-table { width: 100%; min-width: 780px; }
.cs-table th {
  text-align: left;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--smoke);
  padding: 14px 16px 10px;
  border-bottom: 2px solid var(--crumb);
  white-space: nowrap;
}
.cs-table td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--crumb);
  vertical-align: top;
  font-size: 16px;
}
.cs-table tr:last-child td { border-bottom: 0; }
.cs-food { font-weight: 700; min-width: 190px; }
.cs-time { font-family: var(--font-digits); font-size: 15px; font-weight: 600; white-space: nowrap; }
.cs-note { color: var(--smoke); min-width: 240px; }
.cs-turn-cell { white-space: nowrap; }
.cs-turn {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--smoke);
  border: 1px solid var(--crumb);
  border-radius: var(--r-chip);
  padding: 4px 10px;
  white-space: nowrap;
}
.cs-turn-detail {
  display: block;
  margin-top: 6px;
  color: var(--smoke);
  font-size: 14px;
  white-space: normal;
  max-width: 220px;
}
/* USDA badge sits on its own line under the food name (mockup) */
.cs-safe { display: table; margin: 6px 0 0; font-size: 12px; white-space: nowrap; }

.cs-footnote { margin-top: 28px; color: var(--smoke); font-size: 16px; max-width: 70ch; }

@media (min-width: 960px) {
  .cs-jumpnav { top: 64px; margin: 20px -32px 0; padding: 10px 32px; }
  .cs-group { margin-top: 40px; scroll-margin-top: 150px; }
  .cs-table td { font-size: 18px; }
  .cs-time { font-size: 16px; }
  .cs-disclaimer, .cs-footnote { font-size: 18px; }
}

/* --- tips (/tips) -------------------------------------------------------- */
/* docs/designs/tips.html — one column on the phone, two from 960px. */
.tips-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 960px) {
  .tips-grid { grid-template-columns: 1fr 1fr; }
}
.tip {
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 18px 20px;
}
.tip-title { font-size: 20px; font-weight: 700; letter-spacing: -.01em; line-height: 1.3; }
.tip-body { color: var(--smoke); margin-top: 6px; }

/* safety-critical tips (aerosol sprays, parchment liners, wet batter) */
.tip-warn {
  background: var(--alarm-soft);
  border-color: var(--alarm-soft);
  border-left: 4px solid var(--alarm);
}
.warn-head { display: flex; align-items: center; margin-bottom: 8px; }
.warn-head svg {
  width: 24px;
  height: 24px;
  color: var(--alarm);
  margin-right: 10px;   /* no flex gap — Portal Chromium */
  flex-shrink: 0;
}
.safety-chip {
  display: inline-block;
  background: var(--alarm);
  color: #FFFFFF;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: var(--r-chip);
  padding: 3px 10px;
}
@media (hover: hover) {
  .tip:hover { box-shadow: 0 2px 4px rgba(34, 26, 20, .08), 0 8px 20px rgba(34, 26, 20, .09); }
}

/* --- recipe library (/recipes) ------------------------------------------ */

/* The category pills carry their result count so a filter never promises
   recipes it cannot deliver (spec Feature 2). */
.pill-count {
  margin-left: 8px;
  color: var(--smoke);
  font-family: var(--font-digits);
  font-size: 14px;
  font-weight: 600;
}
.pill-on .pill-count { color: var(--crisp-deep); }

/* Search: a GET form, so results live in the URL and work with JS disabled.
   grid (not flex) because Portal Chromium has no flexbox `gap`. */
.search-form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  margin: 20px 0 8px;
}
.search-label { grid-column: 1 / -1; margin-bottom: -2px; }
.search-input { border-radius: var(--r-card); }

.results-line {
  margin-top: 18px;
  color: var(--smoke);
  font-size: 16px;
}

.recipe-grid { margin-top: 16px; }

/* Heart slot: the card link fills the card, so the favorite control sits in
   its own positioned box on top of it (a link for guests, a one-button PRG
   form once logged in). */
.fav-slot {
  position: absolute;
  top: 10px;
  right: 10px;
}
.fav-slot .fav { position: static; }

.empty .btn { margin-bottom: 8px; }
.empty .link-plain { margin-left: 4px; }

/* --- import from URL (/import) ------------------------------------------ */

/* URL + button on one line where there's room, stacked on a phone. No flex
   gap (Portal): the spacing is margins on the children. */
.url-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  margin-top: 4px;
}
.url-row .input {
  flex: 1 1 260px;
  min-width: 0;
  width: auto;
  margin: 0 12px 12px 0;
}
.url-row .btn { margin-bottom: 12px; }

.fine {
  font-size: 16px;
  color: var(--smoke);
  max-width: 68ch;
  margin-top: 12px;
}
.notice .fine { margin-top: 6px; }

/* preview card */
.preview { padding: 20px; margin-top: 8px; }
.preview-head { display: flex; align-items: flex-start; }
.preview-art {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--crisp-soft), var(--flour));
  font-size: 26px;
  line-height: 44px;
  text-align: center;
  margin-right: 12px;
}
.preview-headings { min-width: 0; }
.preview-title { font-size: 24px; font-weight: 800; line-height: 1.25; }
.preview-src {
  font-size: 16px;
  color: var(--smoke);
  margin-top: 2px;
  overflow-wrap: anywhere;
  word-wrap: break-word;
}
/* inline-FLEX, not inline-block, and 48px not 44px — same fix as .text-link
   above: `min-height` on an inline-block is only advisory against the line box,
   so this source link measured 44.8px against the 48px floor on a short URL. It
   is a real tap target — it opens the original recipe page in a new tab. */
.preview-link {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 10px 0;
  color: var(--crisp-deep);
  font-weight: 600;
}
.preview-desc { margin-top: 12px; max-width: 62ch; }

/* the "converted from an oven recipe" band */
.notice-convert { padding: 14px 16px; margin: 16px 0 4px; }

.meta-row { margin: 14px 0 4px; }
.meta-line { display: inline-block; font-size: 16px; color: var(--smoke); margin-left: 10px; }
.chip-small { font-size: 15px; padding: 4px 12px; }
.badge-turn { background: var(--crisp-soft); color: var(--crisp-deep); }

.section-block { margin-top: 22px; }
.section-block .eyebrow { display: block; margin-bottom: 4px; }

.ing-list { list-style: none; padding-left: 0; }
.ing-list li { padding: 9px 0; border-top: 1px solid var(--crumb); }
.ing-qty { font-weight: 600; }

.step-list { list-style: none; padding-left: 0; }
.step { display: flex; align-items: flex-start; padding: 10px 0; border-top: 1px solid var(--crumb); }
.step-num {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: var(--r-chip);
  background: var(--crisp-soft);
  color: var(--char);
  font-weight: 700;
  font-size: 16px;
  line-height: 32px;
  text-align: center;
  margin-right: 12px;
  margin-top: 1px;
}
.step-text { flex: 1 1 auto; min-width: 0; }

/* saved confirmation */
.import-saved { margin-bottom: 20px; border-left: 4px solid var(--herb); }
.import-saved-head { margin-bottom: 2px; }
.import-saved-head .badge { margin-left: 8px; }
.import-saved-note { color: var(--smoke); font-size: 16px; margin-top: 4px; }

/* --- recipe detail (/recipes/:slug) ------------------------------------- */
/* docs/designs/recipe-detail.html — full detail + the AI-recipe variant.
   Everything here is `rd-` prefixed: the shared chip/badge/button/notice
   components are reused as-is, and the page-specific pieces (banner art,
   servings segmented control, ingredient and step rows, sticky start bar) get
   their own names so no other page can inherit them by accident. */

.rd-eyebrow { color: var(--crisp-deep); font-size: 13px; margin-top: 10px; }

.rd-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-top: 4px;
}
.rd-title {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.12;
  min-width: 0;
}
.rd-badge { vertical-align: 4px; font-size: 12px; padding: 5px 12px; margin-left: 12px; }

.rd-fav-slot { flex: 0 0 48px; margin-left: 16px; }
.rd-fav {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-chip);
  color: var(--smoke);
  cursor: pointer;
}
.rd-fav svg { width: 24px; height: 24px; }
.rd-fav:active { background: var(--crisp-soft); color: var(--crisp-deep); transform: translateY(1px); }
.rd-fav-on { color: var(--crisp); }

/* AI / imported provenance band — the "check doneness" reminder */
.rd-source-notice {
  display: flex;
  align-items: center;
  max-width: 640px;
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--crisp-soft);
  border-radius: var(--r-card);
  font-size: 16px;
  font-weight: 600;
}
.rd-source-notice svg { flex: 0 0 24px; width: 24px; height: 24px; margin-right: 12px; color: var(--crisp-deep); }

/* emoji banner strip — no photos in v1 */
.rd-art {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  margin-top: 16px;
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  background: linear-gradient(135deg, var(--crisp-soft), var(--flour));
  overflow: hidden;
}
.rd-art-main { font-size: 60px; line-height: 1; }
.rd-art-side { font-size: 32px; line-height: 1; margin: 0 22px; opacity: .85; }

.rd-desc { margin-top: 16px; max-width: 62ch; font-size: 17px; }
.rd-meta { margin-top: 12px; color: var(--smoke); font-size: 16px; font-weight: 600; }
.rd-meta b { color: var(--char); }

.rd-readout { margin-top: 16px; }
.rd-temp-both {
  display: inline-block;
  margin-left: 12px;
  color: var(--smoke);
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
}

.rd-cols { margin-top: 8px; }
.rd-section-title { font-size: 24px; font-weight: 800; margin: 32px 0 8px; }
.rd-sub-h { font-size: 16px; font-weight: 700; margin: 28px 0 8px; }

/* servings scaler — four links, state lives in ?scale= (zero JS) */
.rd-seg {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  max-width: 420px;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  overflow: hidden;
}
.rd-seg-item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  border-left: 1px solid var(--crumb);
  color: var(--char);
  font-size: 17px;
  font-weight: 700;
  text-decoration: none;
}
.rd-seg-first { border-left: 0; }
.rd-seg-item:active { background: var(--crisp-soft); }
.rd-seg-on { background: var(--crisp-soft); color: var(--crisp-deep); box-shadow: inset 0 0 0 2px var(--crisp); }
.rd-seg-hint { margin-top: 8px; color: var(--smoke); font-size: 15px; }

/* USDA safe internal temperature — thermometer reading, not a dial setting */
.rd-safety {
  display: inline-flex;
  align-items: center;
  margin-top: 20px;
  padding: 10px 18px;
  background: var(--herb-soft);
  border-radius: var(--r-chip);
  color: var(--herb);
  font-size: 16px;
  font-weight: 700;
}

/* personal note card (the form posts to the notes endpoint) */
.rd-note {
  margin-top: 24px;
  padding: 16px;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.rd-note-body { margin-top: 6px; font-size: 17px; }
.rd-note-empty { color: var(--smoke); }
.rd-note-btn { margin-top: 12px; list-style: none; }
.rd-note-btn::-webkit-details-marker { display: none; }
.rd-note-form { margin-top: 14px; }
.rd-note-input {
  height: auto;
  min-height: 96px;
  padding: 10px 14px;
  line-height: 1.5;
  resize: vertical;
}
.rd-note-form .btn { margin-top: 12px; }

/* ingredients */
.rd-ing-list { list-style: none; padding-left: 0; }
.rd-ing { display: flex; align-items: baseline; padding: 12px 0; border-bottom: 1px solid var(--crumb); }
.rd-ing-qty { flex: 0 0 96px; padding-right: 10px; font-weight: 700; }
.rd-ing-name { flex: 1 1 auto; min-width: 0; }

/* steps */
.rd-steps { list-style: none; padding-left: 0; }
.rd-step { display: flex; align-items: flex-start; padding: 16px 0; border-bottom: 1px solid var(--crumb); }
.rd-step-num {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  margin-right: 14px;
  margin-top: 2px;
  border-radius: var(--r-chip);
  background: var(--char);
  color: #FFFFFF;
  font-size: 16px;
  font-weight: 800;
  line-height: 36px;
  text-align: center;
}
.rd-step-body { flex: 1 1 auto; min-width: 0; }
.rd-step-text { font-size: 17px; }
.rd-step-meta { margin-top: 8px; }
.rd-step-chip { font-size: 15px; padding: 4px 12px; }
.rd-turn-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 7px 14px;
  border-radius: var(--r-chip);
  background: var(--crisp-soft);
  color: var(--crisp-deep);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* batch warning + cook history */
.rd-band {
  display: flex;
  align-items: center;
  margin-top: 24px;
  padding: 14px 16px;
  background: var(--crisp-soft);
  border-radius: var(--r-card);
  font-weight: 600;
}
.rd-band svg { flex: 0 0 24px; width: 24px; height: 24px; margin-right: 12px; color: var(--crisp-deep); }
.rd-cooked { margin-top: 16px; color: var(--smoke); font-size: 15px; font-weight: 600; }

/* "Start cooking" rides the bottom of the screen the whole way down the page,
   clearing the fixed phone tab bar (56px) — the one control a cook reaches for
   with greasy hands must never be a scroll away. */
.rd-start-bar {
  position: sticky;
  bottom: 56px;
  z-index: 20;
  margin-top: 32px;
  padding: 12px 0 10px;
  background: linear-gradient(to top, var(--flour) 72%, rgba(251, 247, 240, 0));
}
.rd-start-bar .btn { min-height: 60px; font-size: 20px; }

@media (min-width: 960px) {
  .rd-title { font-size: 34px; }
  .rd-art { height: 140px; }
  .rd-art-main { font-size: 72px; }
  .rd-art-side { font-size: 38px; }
  .rd-cols { display: grid; grid-template-columns: 360px 1fr; gap: 48px; align-items: start; }
  .rd-start-bar { bottom: 0; }
}

@media (hover: hover) {
  .rd-fav:hover { border-color: var(--crisp); }
  .rd-seg-item:hover { background: var(--flour); }
  .rd-seg-on:hover { background: var(--crisp-soft); }
}

/* --- AI natural-language search (/search) -------------------------------- */

/* The two sections lead with a one-line summary right under their heading
   (docs/designs/search.html), so the heading's default 14px gap closes up. */
.search-sec .section-title { margin-bottom: 4px; }
.search-sub {
  color: var(--smoke);
  max-width: 62ch;
  margin-bottom: 14px;
}
.search-more { margin-top: 12px; }
.search-fine {
  margin-top: 18px;
  color: var(--smoke);
  font-size: 16px;
  max-width: 62ch;
}

/* No heart on this page (the library page owns favoriting), so the card body
   reclaims the space the heart slot reserves. */
.lib-card .rcard-body { padding-right: 0; }

/* idea cards: one column on a phone, two on the Portal / desktop. Grid gap is
   allowed (flex gap is not), and the button is pushed to the bottom so a row of
   cards with different amounts of text still lines its buttons up. */
.idea-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 16px;
}
@media (min-width: 960px) {
  .idea-grid { grid-template-columns: 1fr 1fr; }
}
.idea {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 18px;
}
.idea-title { margin-top: 4px; }
.idea-line { color: var(--smoke); margin-top: 6px; }
.idea-meta { margin: 12px 0 14px; min-height: 32px; }
.idea-form { margin-top: auto; }

/* mid-generation state — set by src/public/search.js, and only ever reached
   when client JS is running; with JS off the browser just waits on the POST. */
.btn-busy { background: var(--crumb); color: var(--char); cursor: default; }
.btn-busy:active { background: var(--crumb); transform: none; }
.btn-quiet { opacity: .55; }
.busy-note {
  color: var(--smoke);
  font-size: 16px;
  text-align: center;
  margin-top: 8px;
}

@media (hover: hover) {
  .idea:hover { box-shadow: 0 2px 4px rgba(34,26,20,.08), 0 8px 20px rgba(34,26,20,.09); }
  .btn-busy:hover { background: var(--crumb); }
}

/* Library matches sit two-up next to the two-up idea cards below them
   (docs/designs/search.html), rather than inheriting the library page's
   three-up auto-fill grid — one page, one rhythm. */
.search-sec .card-grid { grid-template-columns: 1fr; }
@media (min-width: 960px) {
  .search-sec .card-grid { grid-template-columns: 1fr 1fr; }
}

/* --- cook mode (/recipes/:slug/cook) ------------------------------------ */
/* docs/designs/cook-mode.html — the dark appliance panel. Zero-JS core only:
   the countdown/alarm (Task 8) and the extra-timer drawer (Task 9) restyle and
   reveal seams that already exist here. Kitchen sizes are correctness, not
   polish: instruction >= 28px, step zones >= 64px, countdown >= 96px. */
/* COOK-MODE-CSS:START */

.cook-body {
  background: var(--basket);
  color: #f5efe8;
  padding-bottom: 0; /* no phone tab bar in Cook Mode */
}
.cook-body a:focus,
.cook-body button:focus,
.cook-body summary:focus,
.cook-body textarea:focus {
  outline: 3px solid var(--ember);
  outline-offset: 2px;
}

/* JS-only controls stay hidden until src/public/cook.js (Task 8) un-hides them.
   The explicit [hidden] rule is required: an author `display` declaration on
   the element itself would otherwise beat the UA stylesheet's [hidden] rule. */
.cook-js[hidden] { display: none; }

.cook-panel {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* progress hairline — the only step cue readable from across the kitchen */
.cook-progress { height: 4px; background: var(--panel-edge); }
.cook-progress-fill { display: block; height: 100%; background: var(--ember); }

/* --- top row: exit, dial temperature, seam for extra-timer chips --- */

.cook-top {
  position: relative;
  z-index: 5;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px 16px;
}
.cook-top-left,
.cook-top-right {
  display: flex;
  align-items: center;
  min-height: 64px;
}
/* 64px, not the 48px global floor: this is a Cook Mode PRIMARY control (spec
   Feature 3 / "Look & feel" — 64-80px), and it is the only way out of a
   full-screen route that has no browser chrome, tapped with greasy hands. */
.cook-exit {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--panel-edge);
  border-radius: 14px;
  color: #f5efe8;
  text-decoration: none;
}
.cook-exit svg { width: 28px; height: 28px; }
.cook-exit:active { background: var(--panel-edge); transform: translateY(1px); }

.cook-chip {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  margin-left: 12px;
  padding: 10px 18px;
  background: #1f1812;
  border: 1px solid var(--panel-edge);
  font-size: 17px;
}
.cook-recipe-title {
  display: none;
  margin-left: 14px;
  font-size: 17px;
  font-weight: 600;
  color: var(--ember-dim);
}
@media (min-width: 720px) {
  .cook-recipe-title { display: block; }
}

/* --- SHAKE / FLIP banner --- */

.cook-banner {
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--ember);
  color: var(--basket);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: .12em;
  line-height: 1.2;
  text-transform: uppercase;
  text-align: center;
}
.cook-banner svg {
  width: 32px;
  height: 32px;
  margin-right: 16px;
  flex: 0 0 32px;
}
@media (min-width: 960px) {
  .cook-banner { padding: 20px 16px; font-size: 26px; }
}

/* --- centre stack --- */

.cook-center {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px 16px 24px;
  text-align: center;
}
@media (min-width: 960px) {
  /* clear of the 20%-wide edge zones */
  .cook-center { padding-left: 22%; padding-right: 22%; }
}

.cook-eyebrow {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ember-dim);
}
.cook-instruction {
  margin-top: 14px;
  max-width: 22ch;
  font-size: 30px;
  font-weight: 600;
  line-height: 1.25;
}
@media (min-width: 700px) {
  .cook-instruction { font-size: 34px; }
}
@media (min-width: 960px) {
  .cook-instruction { font-size: 36px; }
}

.cook-timer-label {
  margin-top: 16px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ember-dim);
}
/* min-height reserves the slot at the size Task 8's live countdown will need,
   so switching from the static duration to a running clock moves nothing. */
.cook-countdown {
  margin-top: 4px;
  min-height: 104px;
  font-family: var(--font-digits);
  font-size: 96px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: .01em;
  color: var(--ember);
}
@media (min-width: 960px) {
  .cook-countdown { min-height: 150px; font-size: 140px; }
}

.cook-start {
  margin-top: 20px;
  min-height: 64px;
  min-width: 240px;
  padding: 0 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ember);
  color: var(--basket);
  border: 0;
  border-radius: var(--r-card);
  font-size: 20px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-start:active { background: #e09838; transform: translateY(1px); }

.cook-sub-label {
  margin-top: 18px;
  font-family: var(--font-digits);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ember);
}

/* --- personal note (step 1) --- */

.cook-note {
  width: 100%;
  max-width: 620px;
  margin-top: 22px;
  padding: 14px 18px;
  background: #1f1812;
  border: 1px solid var(--panel-edge);
  border-radius: var(--r-card);
  text-align: left;
}
.cook-note-label {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ember-dim);
}
.cook-note-body { margin-top: 6px; font-size: 21px; line-height: 1.4; }

/* --- ingredients quick reference (native <details>, no script) --- */

.cook-ref {
  width: 100%;
  max-width: 620px;
  margin-top: 16px;
  text-align: left;
}
.cook-ref-summary {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: 0 18px;
  background: #1f1812;
  border: 1px solid var(--panel-edge);
  border-radius: var(--r-chip);
  color: var(--ember-dim);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  list-style: none;
  cursor: pointer;
}
.cook-ref-summary::-webkit-details-marker { display: none; }
.cook-ref-summary:active { border-color: var(--ember); color: var(--ember); }
.cook-ref-count {
  margin-left: 10px;
  font-family: var(--font-digits);
  letter-spacing: 0;
  color: var(--ember);
}
.cook-ref-chev { width: 22px; height: 22px; margin-left: auto; }
.cook-ref[open] .cook-ref-chev { transform: rotate(180deg); }
.cook-ref-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px 24px;
  margin: 12px 0 0;
  padding: 0 4px;
  list-style: none;
}
@media (min-width: 700px) {
  .cook-ref-list { grid-template-columns: 1fr 1fr; }
}
.cook-ref-item { font-size: 18px; line-height: 1.4; color: #e7ded4; }
.cook-ref-qty {
  margin-right: 8px;
  font-family: var(--font-digits);
  color: var(--ember);
}

/* --- step controls: one markup, two layouts (see src/views/cook.ejs) ---
   Phone: two half-width buttons across the bottom edge.
   Portal / landscape: 20%-wide full-height zones pinned to the panel edges. */

.cook-nav {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--panel-edge);
  border-top: 1px solid var(--panel-edge);
}
.cook-zone {
  display: flex;
  min-height: 76px;
  margin: 0;
  padding: 0;
  background: #1f1812;
  border: 0;
  color: var(--ember-dim);
  /* on the anchor itself: text-decoration cannot be switched off further down */
  text-decoration: none;
}
.cook-zone-inner {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  background: transparent;
  border: 0;
  color: inherit;
  font-family: inherit;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.cook-zone-inner svg { width: 30px; height: 30px; margin: 0 10px; }
/* chevron trails the word on the forward control, as it reads on the phone bar */
.cook-zone-next .cook-zone-inner { flex-direction: row-reverse; }
.cook-zone:active { background: var(--panel-edge); color: var(--ember); }

@media (min-width: 960px) {
  .cook-nav {
    position: static;
    display: block;
    background: transparent;
    border-top: 0;
  }
  .cook-zone {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 2;
    width: 20%;
    background: rgba(245, 239, 232, .02);
  }
  .cook-zone-back { left: 0; border-right: 1px solid var(--panel-edge); }
  .cook-zone-next { right: 0; border-left: 1px solid var(--panel-edge); }
  .cook-zone-inner,
  .cook-zone-next .cook-zone-inner {
    flex-direction: column;
    font-size: 18px;
    letter-spacing: .16em;
  }
  .cook-zone-inner svg { width: 56px; height: 56px; margin: 0 0 10px; }
}

/* --- finish screen --- */

.cook-check {
  width: 96px;
  height: 96px;
  margin-bottom: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--herb);
  border-radius: 50%;
}
.cook-check svg { width: 48px; height: 48px; }
.cook-finish-eyebrow {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #8fc7a0;
}
.cook-finish-title {
  margin-top: 10px;
  font-size: 38px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
}
@media (min-width: 960px) {
  .cook-finish-title { font-size: 44px; }
}
.cook-finish-sub { margin-top: 12px; font-size: 21px; color: #cfc6bc; }
.cook-finish-guest {
  max-width: 34ch;
  margin-top: 24px;
  font-size: 19px;
  color: #cfc6bc;
}
.cook-finish-form {
  width: 100%;
  max-width: 560px;
  margin-top: 26px;
  text-align: left;
}
.cook-finish-label {
  display: block;
  margin-bottom: 8px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #8fc7a0;
}
.cook-finish-input {
  width: 100%;
  min-height: 110px;
  padding: 12px 16px;
  background: #1f1812;
  border: 2px solid var(--panel-edge);
  border-radius: 12px;
  color: #f5efe8;
  font-family: var(--font-ui);
  font-size: 18px;
  line-height: 1.5;
  resize: vertical;
}
.cook-finish-input::placeholder { color: var(--ember-dim); opacity: 1; }
.cook-save {
  width: 100%;
  min-height: 64px;
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--herb);
  color: #ffffff;
  border: 0;
  border-radius: var(--r-card);
  font-size: 19px;
  font-weight: 800;
  text-decoration: none;
  cursor: pointer;
}
.cook-save:active { background: #315641; transform: translateY(1px); }
.cook-save-link { max-width: 320px; margin-top: 4px; }
.cook-back-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  margin-top: 18px;
  padding: 0 18px;
  color: var(--ember);
  font-size: 18px;
  font-weight: 700;
  text-decoration: underline;
}
.cook-back-link:active { color: #e09838; }

@media (hover: hover) {
  .cook-exit:hover { background: #241c15; }
  .cook-zone:hover { background: #241c15; }
  .cook-start:hover { background: #f0a845; }
  .cook-ref-summary:hover { border-color: var(--ember-dim); }
  .cook-save:hover { background: #476f58; }
  .cook-back-link:hover { color: #ffc77e; }
}

/* COOK-MODE-CSS:END */

/* --- offline fallback page (/offline, served from the SW cache) ----------- */

/* One appliance panel, dark like Cook Mode, so "no signal" reads as a state of
   the machine rather than a browser error. Everything else on the page uses the
   shared page-head / quick-links components. */
.offline-panel {
  background: var(--basket);
  border: 1px solid var(--panel-edge);
  border-radius: var(--r-card);
  padding: 26px 20px 24px;
  margin-top: 24px;
  text-align: center;
}
.offline-led {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--alarm);
  box-shadow: 0 0 0 4px rgba(196, 41, 29, .22);
}
.offline-readout {
  margin-top: 14px;
  font-family: var(--font-digits);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: .14em;
  color: var(--ember);
}
.offline-panel-note {
  margin-top: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ember-dim);
}

@media (min-width: 960px) {
  .offline-readout { font-size: 34px; }
}

/* --- shopping list (/shopping-list) -------------------------------------- */
/* docs/designs/shopping-list.html — main (recipe groups + Misc + checked) and
   empty. Everything is `sl-` prefixed; the card, button, input, notice and
   empty-state components are the shared ones.

   Check-off is the primary kitchen interaction, so the whole item row (ring +
   label) is one submit button rather than a 48px circle floating next to the
   text: a wet hand aiming roughly at the line still checks the right item. The
   remove ✕ keeps its own 48px target on the right. */

.sl-notice { margin-top: 4px; }

/* Add-item row: input and button side by side where there is room, stacked on a
   phone. No flex `gap` (Portal) — the spacing is margins on the children. */
.sl-add {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  margin: 4px 0 24px;
}
.sl-add .input {
  flex: 1 1 220px;
  min-width: 0;
  width: auto;
  margin: 0 12px 12px 0;
}
.sl-add .btn { margin-bottom: 12px; }

/* Group card: the header keeps the card's padding, the item rows run edge to
   edge so their tap targets reach the card border. */
.sl-group { padding: 0; margin-bottom: 16px; overflow: hidden; }
.sl-group + .sl-group { margin-top: 0; }
.sl-group-head { display: flex; align-items: center; padding: 14px 16px 10px; }
.sl-group-art {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--crisp-soft), var(--flour));
  font-size: 26px;
  line-height: 44px;
  text-align: center;
  margin-right: 12px;
}
.sl-group-headings { min-width: 0; }
.sl-group-title { font-size: 20px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
.sl-group-link { color: inherit; text-decoration: none; }
.sl-group-link:active { color: var(--crisp-deep); }
.sl-group-count { font-size: 16px; color: var(--smoke); }

.sl-items { list-style: none; padding-left: 0; margin: 0; }
.sl-item { display: flex; align-items: center; border-top: 1px solid var(--crumb); }

.sl-check-form { flex: 1 1 auto; min-width: 0; }
.sl-check {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 56px;
  padding: 4px 4px 4px 6px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
}
.sl-ring {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  margin: 0 10px;
  border: 2px solid var(--smoke);
  border-radius: 50%;
  background: var(--card);
  color: #FFFFFF;
  display: grid;
  place-items: center;
}
.sl-ring svg { width: 16px; height: 16px; }
.sl-ring-done { border-color: var(--herb); background: var(--herb); }
.sl-check:active { background: var(--flour); }
.sl-check:active .sl-ring { border-color: var(--crisp); background: var(--crisp-soft); }
.sl-check:active .sl-ring-done { border-color: var(--herb); background: var(--herb); }

/* `min-width: 0` lets the flex item shrink, but an unbroken 100-character
   label has no break opportunity to shrink AT, so it painted straight across
   the remove control. `anywhere` gives it one. */
.sl-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 17px;
  line-height: 1.35;
  /* Fallback FIRST: `anywhere` is Chromium 80+, so the Portal keeps the legacy
     alias while modern browsers land on `anywhere` (the later declaration of
     the same property wins). */
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.sl-qty { font-weight: 600; }
.sl-item-done .sl-label { color: var(--smoke); text-decoration: line-through; }

.sl-remove-form { flex: 0 0 48px; }
.sl-remove {
  width: 48px;
  height: 48px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: var(--smoke);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.sl-remove svg { width: 20px; height: 20px; }
.sl-remove:active { color: var(--alarm); background: var(--alarm-soft); }

/* Checked section: its own heading outside the card, struck-through rows in it. */
.sl-checked-head { display: flex; align-items: baseline; margin: 28px 0 10px; }
.sl-checked-title { font-size: 20px; font-weight: 700; margin-right: 10px; }
.sl-checked-count { font-size: 16px; color: var(--smoke); }
.sl-clear { margin-top: 16px; }

/* The recipe detail's "Add to shopping list" button, under its ingredients. */
.rd-shop-btn { margin-top: 16px; }

@media (hover: hover) {
  .sl-check:hover { background: var(--flour); }
  .sl-check:hover .sl-ring { border-color: var(--crisp); }
  .sl-check:hover .sl-ring-done { border-color: var(--herb); }
  .sl-remove:hover { color: var(--alarm); background: var(--alarm-soft); }
  .sl-group-link:hover { color: var(--crisp-deep); }
}

/* --- today (/) ---------------------------------------------------------- */
/* docs/designs/today.html — the AI idea card, and the guest welcome hero.
   Recipe cards, notices and quick links are the shared components above; only
   these two shapes are new. */

.icard {
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 14px;
  align-items: start;
  background: var(--card);
  border: 1px solid var(--crumb);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 16px;
}
.icard-body { min-width: 0; }
.icard-body .card-title { margin-top: 2px; }
.icard-desc { color: var(--smoke); font-size: 16px; margin-top: 4px; }
/* The button spans both columns so it stays a full-width 52px target under the
   art square, on a 390px phone as well as on the Portal. */
.icard-btnrow { grid-column: 1 / -1; }

.today-fine {
  margin-top: 16px;
  color: var(--smoke);
  font-size: 16px;
  max-width: 70ch;
}

/* guest welcome hero */
.hero { text-align: center; padding: 32px 8px 8px; }
.hero-chip {
  display: inline-block;
  background: var(--basket);
  color: var(--ember);
  font-family: var(--font-digits);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: .14em;
  padding: 16px 28px;
  border-radius: var(--r-chip);
}
.hero-pitch { font-size: 18px; color: var(--smoke); max-width: 46ch; margin: 18px auto 0; }
.hero-actions { margin-top: 24px; }
.hero-actions .btn { display: flex; width: 100%; max-width: 420px; margin: 10px auto 0; }
.hero-note { color: var(--smoke); font-size: 16px; margin-top: 16px; }
.hero-links { margin-left: auto; margin-right: auto; }

@media (min-width: 700px) {
  .hero-actions .btn { display: inline-flex; width: auto; margin: 0 6px; }
}

@media (hover: hover) {
  .icard:hover { box-shadow: 0 2px 4px rgba(34,26,20,.08), 0 8px 20px rgba(34,26,20,.09); }
}

/* --- cook mode enhancement layer (src/public/cook.js) -------------------- */
/* Everything here is JS-only: nothing below is reachable with client JS off.
   Chromium ~70 rules still apply — no flexbox `gap`, no `inset` shorthand, no
   `:is()`, no `aspect-ratio`, no `dvh`. */
/* COOK-MODE-JS-CSS:START */

/* Keep-awake video + blessed alarm audio. 1x1 and invisible but STILL RENDERED:
   some Chromium builds ignore a display:none video when deciding whether to
   suppress the screen timeout (docs/research/portal-browser-compat.md §3), so
   this rule must never become `display: none`. */
.cook-media {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  border: 0;
  pointer-events: none;
}

/* running timer: the same button, now the way out of it */
.cook-start-stop {
  background: var(--alarm);
  color: #ffffff;
}
.cook-start-stop:active {
  background: #b42318;
  transform: translateY(1px);
}

/* last rung of the keep-awake ladder: neither the API nor the video worked */
.cook-hint {
  max-width: 620px;
  margin-top: 20px;
  padding: 12px 16px;
  background: #241c15;
  border: 1px solid var(--panel-edge);
  border-radius: var(--r-card);
  color: #e7ded4;
  font-size: 17px;
  line-height: 1.45;
}

/* --- alarm: full screen, one giant dismiss target --- */
/* The visual half never depends on sound: a Portal with its volume down is the
   normal case, so this is what has to carry the alert across the kitchen. */
.cook-alarm {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--basket);
  color: #f5efe8;
  border: 0;
  border-radius: 0;
  font-family: var(--font-ui);
  text-align: center;
  cursor: pointer;
  box-shadow:
    inset 0 0 0 12px var(--ember),
    inset 0 0 0 22px var(--alarm);
  animation: cook-alarm-flash 1s steps(1, end) infinite;
}
/* `.cook-body button:focus` above is (0,2,1); this has to out-specify it or the
   alarm gets a focus ring drawn inside its own flashing one. */
.cook-body .cook-alarm:focus {
  outline: none; /* the whole screen is the control; a ring adds nothing */
}
@keyframes cook-alarm-flash {
  50% {
    background: #2b1310;
    box-shadow:
      inset 0 0 0 12px var(--alarm),
      inset 0 0 0 22px var(--ember);
  }
}
.cook-alarm-eyebrow {
  display: block;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ember-dim);
}
.cook-alarm-zero {
  display: block;
  margin-top: 14px;
  font-family: var(--font-digits);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ember);
}
.cook-alarm-word {
  display: block;
  margin-top: 12px;
  font-family: var(--font-digits);
  font-size: 96px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--ember);
}
.cook-alarm-sub {
  display: block;
  margin-top: 22px;
  font-size: 24px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #f5efe8;
}
@media (min-width: 960px) {
  .cook-alarm-word { font-size: 150px; }
  .cook-alarm-sub { font-size: 30px; }
}
/* Flashing is a real problem for some people; the alarm still has to be
   impossible to miss, so the flash becomes a solid ring, not nothing. */
@media (prefers-reduced-motion: reduce) {
  .cook-alarm {
    animation: none;
    box-shadow:
      inset 0 0 0 12px var(--ember),
      inset 0 0 0 22px var(--alarm);
  }
}

/* --- ?debug=1 capability overlay (src/public/cook-debug.js) --- */
.cook-debug {
  position: fixed;
  left: 12px;
  bottom: 12px;
  z-index: 70;
  max-width: 92%;
  max-height: 40%;
  overflow: auto;
  padding: 6px 10px;
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid var(--panel-edge);
  border-radius: 8px;
  font-family: var(--font-digits);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ember-dim);
  pointer-events: none;
}
.cook-debug-caps {
  color: var(--ember-dim);
  white-space: nowrap;
}
.cook-debug-lines {
  margin: 0;
  padding: 0;
  list-style: none;
}
.cook-debug-line {
  margin-top: 2px;
  word-break: break-all;
}
.cook-debug-bad { color: #ff9a8a; }

@media (hover: hover) {
  .cook-start-stop:hover { background: #c62a1d; }
}

/* COOK-MODE-JS-CSS:END */

/* --- cook mode extra timers: drawer + chips (src/public/cook.js) ---------- */
/* Continues the JS-only layer above (spec Feature 16, docs/designs/cook-mode.html
   state "timer drawer open"). Nothing here is reachable with client JS off: the
   "+ TIMER" tab, the drawer and the chips are all created in script, and the
   server-rendered [data-cook-timers] slot stays empty and invisible.
   Chromium ~70 rules still apply — no flexbox `gap`, no `inset`, no `:is()`. */
/* COOK-MODE-TIMERS-CSS:START */

/* Running extra timers stack DOWN the top-right corner as readout chips — the
   one place on the panel that is never covered by the drawer or the step
   zones. Restyling the empty slot costs nothing when no script runs. */
.cook-top-right {
  flex-direction: column;
  align-items: flex-end;
}
.cook-timer-chip {
  max-width: 44vw;
  margin-left: 0;
  margin-bottom: 8px;
  padding: 8px 16px;
}
.cook-timer-chip-label {
  overflow: hidden;
  margin-right: 10px;
  color: var(--ember-dim);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .1em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* "+ TIMER": a full-width strip above the phone step buttons, the bottom-edge
   tab from the mockup once the panel is wide enough for the side zones. */
.cook-timer-tab {
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 56px;
  padding: 0 24px;
  background: #1f1812;
  border: 0;
  border-top: 1px solid var(--panel-edge);
  color: var(--ember-dim);
  font-family: inherit;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-timer-tab:active {
  background: var(--panel-edge);
  color: var(--ember);
}
@media (min-width: 960px) {
  .cook-timer-tab {
    position: fixed;
    left: 50%;
    bottom: 0;
    width: auto;
    min-height: 48px;
    border: 1px solid var(--panel-edge);
    border-bottom: 0;
    border-radius: 12px 12px 0 0;
    transform: translateX(-50%);
  }
}

/* The drawer is `fixed`, not absolute like the mockup: a step with the
   ingredients list open makes the panel taller than the viewport, and a drawer
   parked at the bottom of the DOCUMENT would then need scrolling to reach. */
.cook-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  max-height: 88vh;
  overflow-y: auto;
  padding: 14px 16px 20px;
  background: #211913;
  border-top: 1px solid var(--panel-edge);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -12px 28px rgba(0, 0, 0, .45);
}
/* Portal / landscape: the drawer stops at the inside edges of the two 20%
   step zones instead of spanning the panel. Full width put a sheet over the
   lower ~60% of both Back and Next while it was open, so the "the step zones
   stay tappable" promise below was only true for the top of the zone. Now the
   drawer and the navigation never share a pixel. */
@media (min-width: 960px) {
  .cook-drawer {
    left: 20%;
    right: 20%;
    padding: 18px 32px 26px;
    border-radius: 18px 18px 0 0;
  }
}
.cook-drawer-grip {
  display: block;
  width: 56px;
  height: 5px;
  margin: 0 auto 14px;
  background: var(--ember-dim);
  border-radius: 3px;
  opacity: .6;
}
.cook-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.cook-drawer-title {
  color: var(--ember-dim);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
}
/* The way out of the drawer, and on a phone the drawer covers the step
   buttons — so it is a Cook Mode primary control and takes the 64px floor. */
.cook-drawer-close {
  min-width: 120px;
  min-height: 64px;
  padding: 0 18px;
  background: transparent;
  border: 1px solid var(--panel-edge);
  border-radius: 12px;
  color: #f5efe8;
  font-family: inherit;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-drawer-close:active {
  background: var(--panel-edge);
  transform: translateY(1px);
}

/* One tap = one running timer. Grid gap only (flexbox gap is Chromium 84+). */
.cook-presets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
@media (min-width: 700px) {
  .cook-presets { grid-template-columns: repeat(4, 1fr); }
}
.cook-preset {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 0 12px;
  background: var(--basket);
  border: 1px solid var(--panel-edge);
  border-radius: var(--r-chip);
  color: var(--ember);
  font-family: var(--font-digits);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-preset:active {
  background: var(--panel-edge);
  border-color: var(--ember);
}

.cook-drawer-field { margin-top: 16px; }
.cook-drawer-label {
  display: block;
  margin-bottom: 8px;
  color: var(--ember-dim);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.cook-drawer-input {
  width: 100%;
  min-height: 52px;
  padding: 0 16px;
  background: var(--basket);
  border: 2px solid var(--panel-edge);
  border-radius: 12px;
  color: #f5efe8;
  font-family: var(--font-ui);
  font-size: 18px;
}
.cook-drawer-input::placeholder { color: var(--ember-dim); opacity: 1; }
/* The border + ring IS the focus state here (the panel's global 3px outline is
   for a/button/summary/textarea) — never remove one without the other. */
.cook-drawer-input:focus {
  border-color: var(--ember);
  box-shadow: 0 0 0 3px rgba(255, 180, 84, .25);
  outline: none;
}
.cook-drawer-custom-row {
  display: flex;
  align-items: center;
}
.cook-drawer-custom-row .cook-drawer-input { flex: 1; }
.cook-drawer-start {
  flex: 0 0 auto;
  min-width: 104px;
  min-height: 52px;
  margin-left: 12px;
  padding: 0 18px;
  background: var(--ember);
  border: 0;
  border-radius: 12px;
  color: var(--basket);
  font-family: inherit;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-drawer-start:active {
  background: #e09838;
  transform: translateY(1px);
}

.cook-running { margin-top: 6px; }
.cook-running-empty {
  margin-top: 16px;
  color: var(--ember-dim);
  font-size: 16px;
}
.cook-running-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--panel-edge);
}
.cook-running-info {
  display: flex;
  align-items: baseline;
  min-width: 0;
}
.cook-running-label {
  overflow: hidden;
  max-width: 38vw;
  margin-right: 16px;
  color: var(--ember-dim);
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .12em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}
.cook-running-time {
  color: var(--ember);
  font-family: var(--font-digits);
  font-size: 30px;
  font-weight: 700;
}
@media (min-width: 700px) {
  .cook-running-time { font-size: 32px; }
}
/* Stopping a timer mid-cook is a wet-handed, one-thumb action: 64px tall and
   wide enough to hit without looking, per spec Feature 16. */
.cook-stop {
  flex: 0 0 auto;
  min-width: 108px;
  min-height: 64px;
  margin-left: 16px;
  background: var(--alarm);
  border: 0;
  border-radius: var(--r-card);
  color: #ffffff;
  font-family: inherit;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}
.cook-stop:active {
  background: #b42318;
  transform: translateY(1px);
}
.cook-drawer-note {
  margin-top: 14px;
  color: var(--ember-dim);
  font-size: 15px;
  line-height: 1.4;
}

/* Author `display` on these beats the UA [hidden] rule, so say it explicitly. */
.cook-drawer[hidden],
.cook-drawer-field[hidden],
.cook-drawer-note[hidden],
.cook-running-empty[hidden] { display: none; }

/* Drawer open: the step behind it dims to the mockup's .3 so the running
   timers and their Stop buttons are unmistakably what the panel is asking
   about. The step zones stay tappable — a cook can still walk on. */
.cook-drawer-open .cook-top,
.cook-drawer-open .cook-center,
.cook-drawer-open .cook-zone { opacity: .3; }

/* ...and once the drawer is inset between them (see above), Back and Next are
   fully uncovered, so they hold their normal contrast rather than reading as
   disabled controls the cook cannot use. On a phone the drawer IS a bottom
   sheet over the step buttons — there it stays dimmed and Close is the way
   out. Declared after the .3 rule so it wins on equal specificity. */
@media (min-width: 960px) {
  .cook-drawer-open .cook-zone { opacity: 1; }
}

/* Debug-only: the ?debug=1 readout is fixed bottom-left at z-index 70, which
   on a phone put it across a running-timer row inside the open drawer. It
   moves to the top-left for as long as the drawer is up — narrow enough to
   stay clear of the right-hand timer chips, and `pointer-events: none`
   (declared with the base rule) means it never intercepts a tap on the exit
   underneath it either. A SIBLING combinator, not a descendant one:
   cook-debug.js appends the box to <body>, next to .cook-panel, not inside it.
   Wide screens do not need this — the drawer is inset between the step zones
   there and the bottom-left corner is already free. */
@media (max-width: 959px) {
  /* At 88% the sheet reached y=101 on a 844px phone — over the panel header,
     with no clear band left anywhere. 70% keeps the top bar (exit, temp chip,
     running-timer chips) visible for the whole time the drawer is up; the
     drawer already scrolls internally, so nothing becomes unreachable. */
  .cook-drawer { max-height: 70%; }
  .cook-drawer-open ~ .cook-debug {
    top: 148px;   /* under the panel header, above the sheet */
    bottom: auto;
    max-width: 52%;   /* clear of the right-hand timer chips */
    max-height: 96px;
  }
}

.cook-drawer-problem { color: #ff9a8a; }
/* The open drawer sits on top of the tab at every width, so the tab goes away
   rather than staying as a control you can see and cannot press. `visibility`,
   not `display`: on a phone the tab is in flow above the step buttons and
   removing it would shuffle the panel every time the drawer opens. */
.cook-drawer-open .cook-timer-tab { visibility: hidden; }

@media (hover: hover) {
  .cook-timer-tab:hover { color: var(--ember); }
  .cook-preset:hover { border-color: var(--ember); }
  .cook-drawer-close:hover { background: var(--panel-edge); }
  .cook-drawer-start:hover { background: #f0a845; }
  .cook-stop:hover { background: #c62a1d; }
}

/* COOK-MODE-TIMERS-CSS:END */

/* --- imported recipe: link back to the source page (spec Feature 15) ----- */

.rd-source-link {
  display: inline-block;
  min-height: 48px;
  padding: 12px 0;
  margin-left: 6px;
  color: var(--crisp-deep);
  font-weight: 600;
  text-decoration: underline;
  overflow-wrap: anywhere;
  word-wrap: break-word;
}
.rd-source-link:active { color: var(--crisp); }
@media (hover: hover) {
  .rd-source-link:hover { color: var(--char); }
}
