/* ============================================================
   DABBA — components.css : every shared component
   ============================================================ */

/* ===== Button (Ch.5.15) ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--min-touch); padding: 0.65rem 1.25rem;
  border-radius: var(--radius-input); border: 1px solid transparent;
  font-family: var(--font-body); font-weight: 600; font-size: 1rem; line-height: 1.2;
  text-decoration: none; cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast), opacity var(--dur-fast);
  white-space: nowrap;
}
.btn:disabled { cursor: not-allowed; opacity: 0.5; }
.btn-lg { min-height: 52px; padding: 0.8rem 1.75rem; font-size: 1.0625rem; }
.btn-full { width: 100%; }
.btn-primary { background: var(--accent); color: var(--white); }
.btn-primary:hover:not(:disabled) { background: var(--accent-strong); }
.btn-secondary { background: var(--cream-50); border-color: var(--cream-300); color: var(--ink-900); }
.btn-secondary:hover:not(:disabled) { border-color: var(--ink-500); }
.btn-ghost { background: transparent; color: var(--accent-strong); }
.btn-ghost:hover:not(:disabled) { background: var(--accent-soft); }
.btn-danger { background: var(--paprika-600); color: var(--white); }
.btn-danger:hover:not(:disabled) { filter: brightness(0.92); }
.btn.loading { opacity: 0.7; pointer-events: none; }
.spinner {
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ===== Mode toggle (Ch.5.14 / 6.14) ===== */
.mode-toggle {
  position: relative; display: inline-flex; border-radius: var(--radius-pill);
  background: var(--cream-300); padding: 3px;
}
/* Sliding thumb: POSITION is a primary state cue (the selected radio sits on the
   accent pill). Colour is reinforcement only. Springy overshoot on desktop;
   reduced-motion (base.css) collapses the transition to an instant snap. */
.mode-toggle-thumb {
  position: absolute; top: 3px; bottom: 3px; left: 3px; width: 0; z-index: 0;
  border-radius: var(--radius-pill); background: var(--accent); box-shadow: var(--shadow-sm);
  opacity: 0;
  transition: left var(--dur-base) cubic-bezier(0.34, 1.56, 0.64, 1), width var(--dur-base) cubic-bezier(0.34, 1.56, 0.64, 1);
}
.mode-toggle.thumb-ready .mode-toggle-thumb { opacity: 1; }
.mode-toggle-btn {
  position: relative; z-index: 1; border: none; background: transparent; color: var(--ink-700);
  min-height: 38px; padding: 0 var(--space-4); border-radius: var(--radius-pill);
  font-size: 0.875rem; font-weight: 600; transition: color var(--dur-fast);
}
/* Selected label is the primary cue (white, bold) — never colour alone. */
.mode-toggle-btn.active { color: var(--white); font-weight: 700; }
.mode-toggle-btn:not(.active):hover { color: var(--ink-900); }
/* Fallback so a selection is never colour-less even for the frame before the
   thumb is measured (and if measurement ever fails). */
.mode-toggle:not(.thumb-ready) .mode-toggle-btn.active { background: var(--accent); color: var(--white); box-shadow: var(--shadow-sm); }
.account-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--mode-chrome); color: var(--white); font-weight: 700; font-size: 0.9rem;
  text-decoration: none;
}
.account-avatar:hover { text-decoration: none; opacity: 0.9; }

/* ===== Toast (Ch.5.17) ===== */
.toast-root {
  position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-2);
  width: min(92vw, 420px); pointer-events: none;
}
.toast {
  background: var(--cream-50); border: 1px solid var(--cream-200); border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg); padding: var(--space-3) var(--space-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  opacity: 0; transform: translateY(-12px); transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
  pointer-events: auto;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-success { border-left: 4px solid var(--forest-500); }
.toast-error { border-left: 4px solid var(--paprika-600); }
/* tier-drop shared-win toast — positive, polite */
.toast-win { border-left: 4px solid var(--terra-600); background: var(--accent-soft); }
.toast-close {
  background: none; border: none; cursor: pointer;
  font-size: 1.2rem; line-height: 1; color: var(--ink-500);
  min-width: var(--min-touch); min-height: var(--min-touch);
  border-radius: var(--radius-input);
  display: inline-flex; align-items: center; justify-content: center;
  transition: color var(--dur-fast), background var(--dur-fast);
}
.toast-close:hover { color: var(--ink-900); background: var(--cream-200); }
.toast-close:focus-visible { outline: none; box-shadow: var(--ring-focus); }
.toast-msg { font-size: var(--fs-body-sm); }

/* ===== EmptyState (Ch.5.16) ===== */
.empty-state { text-align: center; padding: var(--space-12) var(--space-6); max-width: 34rem; margin: 0 auto; }
.empty-glyph { width: 64px; height: 64px; margin: 0 auto var(--space-4); display: flex; align-items: center; justify-content: center; color: var(--ink-500); background: var(--cream-200); border-radius: 50%; }
.empty-title { margin-bottom: var(--space-3); }
.empty-body { color: var(--ink-700); margin-bottom: var(--space-6); }
.empty-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }
.sparse-banner {
  display: flex; align-items: center; gap: var(--space-4);
  background: var(--terra-100); border: 1px solid var(--cream-200);
  border-radius: var(--radius-card); padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-6); flex-wrap: wrap;
}
.sparse-banner-icon { color: var(--terra-700); flex: none; }
.sparse-banner-copy { flex: 1; min-width: 200px; }
.sparse-banner-copy h3 { margin-bottom: var(--space-1); }

/* ===== FillMeter (Ch.5.2) ===== */
.fillmeter { width: 100%; }
.fillmeter-track {
  width: 100%; height: var(--space-2); border-radius: var(--radius-pill);
  background: var(--cream-300); overflow: hidden;
}
.fillmeter-fill {
  height: 100%; border-radius: var(--radius-pill); background: var(--accent);
  transition: width var(--fill-meter-dur) var(--ease-out);
}
.fillmeter-fill.animated { }
.fillmeter-fill.nearly-full { background: var(--turmeric-500); }
.fillmeter-tipzone { position: relative; height: 22px; margin-top: 2px; }
.fillmeter-tip {
  position: absolute; top: 0; width: 2px; height: 10px; transform: translateX(-1px);
  background: var(--ink-700); border-radius: 1px;
}
.fillmeter-tiplabel {
  /* Root-cause overflow fix: the label ("minimum") was absolutely centered on the
     tip with translateX(-50%) and unclamped, so when the tip sat near 0% or 100%
     of the meter the word bled outside the tipzone/meter edges on every FillMeter
     (chef dashboard, chef batch detail, composer preview, order cards). Clamp the
     label's center to a safe inner inset — 4.5ch exceeds half the widest caption
     run, so the word stays fully inside the meter on its own line at any tip
     position. nowrap keeps the single word from ever folding onto a second line. */
  position: absolute; top: 10px;
  left: clamp(5ch, var(--tip-x, 0%), calc(100% - 5ch));
  transform: translateX(-50%);
  white-space: nowrap;
  color: var(--ink-700);
}
.fillmeter-readout { display: flex; align-items: baseline; gap: var(--space-3); margin-top: var(--space-2); }
.fillmeter-hint { font-size: var(--fs-body-sm); color: var(--ink-700); }
/* A live claim must settle, not pop (catalog §6.2): the count crossfades in on
   an in-place digit change (triggered from fillMeter.js). Tabular figures already
   pin the column width, so the fade never shifts layout. Reduced motion
   (base.css) collapses the animation to an instant show. */
.fillmeter-count-in { animation: fillmeter-in var(--dur-base) var(--ease-out); }
@keyframes fillmeter-in { from { opacity: 0; } to { opacity: 1; } }
.accent-forest .fillmeter-fill { background: var(--forest-500); }
.accent-terra .fillmeter-fill { background: var(--terra-600); }

/* ===== Countdown (Ch.5.3) ===== */
.countdown {
  display: inline-flex; align-items: center; font-variant-numeric: tabular-nums;
  font-size: var(--fs-num); font-weight: 600; border-radius: var(--radius-pill);
  padding: 0.35rem 0.85rem; white-space: nowrap;
  transition: background var(--dur-base) var(--ease-out), color var(--dur-base);
}
.countdown-tone-ink { background: var(--cream-100); color: var(--ink-700); }
.countdown-tone-turmeric { background: var(--turmeric-100); color: var(--ink-900); }
.countdown-tone-paprika { background: var(--paprika-100); color: var(--paprika-600); }
/* Urgency is not colour-only (catalog §8, senior/colour-weak): the hotter tones
   also step the numeral weight above the calm ink tone (600 -> 700) so urgency
   escalates on a second channel. Static font-weight (not animation/transform),
   so it survives prefers-reduced-motion — urgency is never animation-gated. */
.countdown-tone-turmeric, .countdown-tone-paprika { font-weight: 700; }
.countdown.compact { font-size: var(--fs-body-sm); padding: 0.25rem 0.6rem; }
.countdown-over { background: var(--cream-200); color: var(--ink-500); }

/* ===== PriceLadder (Ch.5.4) ===== */
.priceladder { min-width: 0; }
.priceladder-cells { display: flex; align-items: stretch; min-width: 0; max-width: 100%; }
.priceladder-cell {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--space-2) var(--space-1); border: 1px solid var(--cream-200);
  background: var(--white); border-radius: var(--radius-input); min-width: 0;
  overflow: hidden;
}
.priceladder-cell.earned { background: var(--accent-soft); border-color: transparent; }
.priceladder-cell.current { background: var(--accent); border-color: var(--accent); }
.priceladder-cell.current .priceladder-cell-price { color: var(--white); }
.priceladder-cell.current .priceladder-cell-threshold { color: rgba(255,255,255,0.85); }
/* The earned run reads as ONE connected under-fill (catalog §6.4): earned cells
   share the soft fill and drop their individual accent box (no per-cell "locked
   box"); the current cell stays the lone solid focal point. The accent connectors
   between two earned cells continue the run, so the whole left side reads as one
   group the community earned. */
.priceladder-step.earned { border-top-color: var(--accent); opacity: 0.55; }
/* prices keep a reserved tabular digit width so digit changes never reflow the row;
   if a translated price outgrows the cell it ellipsizes gracefully instead of breaking the row */
.priceladder-cell-price { font-size: 0.95rem; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; min-width: 0; }
.priceladder-cell-threshold { font-size: 0.72rem; color: var(--ink-500); max-width: 100%; overflow-wrap: anywhere; }
.priceladder-cell.base .priceladder-cell-threshold { color: var(--ink-500); }
.priceladder-step { width: 8px; flex: none; border-top: 1px solid var(--cream-200); align-self: center; }
.priceladder-caption { margin-top: var(--space-2); color: var(--ink-700); overflow-wrap: anywhere; }
.priceladder-flat { display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; flex-wrap: wrap; }
.priceladder-flat-txt { color: var(--ink-700); min-width: 0; }
.priceladder-compact .priceladder-cell { padding: var(--space-1); }
.accent-forest .priceladder-cell.current { background: var(--forest-500); border-color: var(--forest-500); }
.accent-forest .priceladder-cell.earned { background: var(--forest-100); border-color: transparent; }
.accent-forest .priceladder-step.earned { border-top-color: var(--forest-500); }

/* ===== ChefStrip (Ch.5.5) ===== */
.chefstrip {
  display: inline-flex; align-items: center; gap: var(--space-3); text-align: left;
  background: none; border: none; padding: 0; min-width: 0; cursor: pointer; border-radius: var(--radius-input);
  max-width: 100%;
}
/* Avatar ring: the ChefStrip sits on white cards (feed tile, rails). cream-200
   was near-invisible there, so use cream-300 plus a hairline shadow to lift the
   circle off white (catalog §6.5). ChefStrip on cream context still reads fine. */
.chefstrip-avatar { border-radius: 50%; object-fit: cover; border: 1px solid var(--cream-300); box-shadow: 0 0 0 1px rgba(28,25,23,0.05); flex: none; }
.chefstrip-sm .chefstrip-avatar { width: 32px; height: 32px; }
.chefstrip-md .chefstrip-avatar { width: 48px; height: 48px; }
.chefstrip-lg .chefstrip-avatar { width: 88px; height: 88px; }
.chefstrip-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.chefstrip-name { font-weight: 600; font-size: var(--fs-body-sm); display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.chefstrip-lg .chefstrip-name { font-size: var(--fs-h3); }
.chefstrip-meta { font-size: 0.8rem; color: var(--ink-500); }
.chefstrip-badge { color: var(--terra-700); background: var(--terra-100); border-radius: var(--radius-pill); padding: 1px 8px; font-size: 0.68rem; }
.chefstrip-cert { color: var(--forest-700); background: var(--forest-100); border-radius: var(--radius-pill); padding: 1px 8px; font-size: 0.68rem; }

/* ===== AllergenChips (Ch.5.6) ===== */
.allergen-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.allergen-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--cream-200); color: var(--ink-700);
  border-radius: var(--radius-pill); padding: 0.3rem 0.85rem; font-size: var(--fs-body-sm);
  background: var(--white); min-height: var(--min-touch);
}
.allergen-chip.interactive { cursor: pointer; }
.allergen-chip.interactive:hover { border-color: var(--ink-500); }
.allergen-chip.checked { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.allergen-chip.conflict { background: var(--paprika-100); border-color: var(--paprika-600); color: var(--paprika-600); font-weight: 600; }

/* ===== FulfilmentPicker (Ch.5.8) ===== */
.fulfilment-picker { display: flex; flex-direction: column; gap: var(--space-2); }
.fulfilment-option {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  min-height: 52px; padding: var(--space-3) var(--space-4);
  border: 1px solid var(--cream-200); border-radius: var(--radius-input);
  background: var(--white); text-align: left; cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.fulfilment-option:hover:not(:disabled) { border-color: var(--ink-500); }
.fulfilment-option.selected { border-color: var(--accent); background: var(--accent-soft); }
.fulfilment-option.locked { opacity: 0.55; cursor: not-allowed; }
.fulfilment-radio {
  width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--cream-300); flex: none;
}
.fulfilment-option.selected .fulfilment-radio { border-color: var(--accent); background: var(--accent); }
.fulfilment-info { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.fulfilment-name { font-weight: 600; }
.fulfilment-detail { color: var(--ink-500); font-size: 0.85rem; }
.fulfilment-fee { font-size: var(--fs-body-sm); color: var(--ink-700); }

/* ===== QuantityStepper (Ch.5.9) ===== */
.qty-row { display: inline-flex; align-items: center; border: 1px solid var(--cream-300); border-radius: var(--radius-input); overflow: hidden; background: var(--cream-50); }
.qty-btn {
  width: var(--min-touch); height: var(--min-touch); border: none; background: transparent;
  font-size: 1.4rem; color: var(--ink-900); cursor: pointer;
}
.qty-btn:hover:not(:disabled) { background: var(--cream-200); }
.qty-btn:disabled { color: var(--cream-300); cursor: not-allowed; }
.qty-value { min-width: 52px; text-align: center; font-size: var(--fs-num); font-weight: 700; }
.qty-bulk { color: var(--forest-700); font-weight: 600; margin-top: var(--space-2); }
.qty-hint { color: var(--ink-500); margin-top: var(--space-2); }

/* ===== StatusTimeline (Ch.5.10) ===== */
.status-timeline { display: flex; flex-direction: column; gap: 0; margin: var(--space-4) 0; min-width: 0; }
.status-step { display: flex; align-items: flex-start; gap: var(--space-3); position: relative; padding-bottom: var(--space-4); min-width: 0; }
.status-step::before {
  content: ''; position: absolute; left: 9px; top: 20px; bottom: 0;
  width: 2px; background: var(--cream-300);
}
.status-step:last-child::before { display: none; }
.status-dot { width: 20px; height: 20px; border-radius: 50%; background: var(--cream-300); border: 2px solid var(--cream-100); flex: none; z-index: 1; margin-top: 1px; }
.status-step.done .status-dot { background: var(--accent); }
.status-step.current .status-dot { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.status-step.current .status-label { color: var(--ink-900); font-weight: 600; }
/* labels reserve room and wrap gracefully at 200% zoom / in long locales instead of
   overflowing; text-transform stays uppercase (caption) but never hard-truncates */
.status-label { color: var(--ink-500); min-width: 0; overflow-wrap: anywhere; line-height: 1.3; }

/* ===== ShareCard (Ch.5.11) ===== */
.sharecard {
  background: var(--cream-100); border: 1px solid var(--cream-200); border-radius: var(--radius-card);
  overflow: hidden; box-shadow: var(--shadow-md); max-width: 420px;
}
.sharecard-photo { width: 100%; height: 140px; object-fit: cover; }
.sharecard-body { padding: var(--space-5); }
.sharecard-dish { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h2); margin-bottom: var(--space-1); }
.sharecard-chef { color: var(--ink-700); margin-bottom: var(--space-4); }
.sharecard-meter { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.sharecard-track { flex: 1; height: var(--space-2); border-radius: var(--radius-pill); background: var(--cream-300); overflow: hidden; }
.sharecard-fill { height: 100%; background: var(--accent); border-radius: var(--radius-pill); }
.sharecard-count { font-size: var(--fs-body-sm); }
/* The incentive line is the loudest text on the canvas — bigger than the dish
   name (fs-h2 1.375rem) so the reward reads first. Price stays tabular. */
.sharecard-incentive {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.8rem; line-height: 1.15; color: var(--accent-strong);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.sharecard-foot { display: flex; justify-content: space-between; align-items: center; padding: var(--space-3) var(--space-5); border-top: 1px solid var(--cream-200); }
.sharecard-wordmark { font-family: var(--font-display); font-weight: 700; }
.sharecard-claim { color: var(--ink-500); font-size: 0.78rem; }

/* ===== RatingStars + ReviewCard (Ch.5.12) ===== */
.rating-stars { display: inline-flex; gap: 2px; color: var(--cream-300); }
.rating-stars .star.filled { color: var(--turmeric-500); }
.review-card { padding: var(--space-5); margin-bottom: var(--space-4); }
.review-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.review-avatar { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; }
.review-meta { flex: 1; display: flex; flex-direction: column; }
.review-date { color: var(--ink-500); }
.review-body { margin-bottom: var(--space-3); }
.review-reply { border-left: 3px solid var(--forest-500); padding-left: var(--space-4); margin-top: var(--space-3); }
.review-reply-head { color: var(--forest-700); margin-bottom: var(--space-1); }
.review-reply-body { color: var(--ink-700); }

/* ===== DietaryFilterBar (Ch.5.13) ===== */
.filter-bar {
  position: sticky; top: 60px; z-index: var(--z-sticky);
  background: var(--cream-100); padding: var(--space-3) 0; margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--cream-200);
}
.filter-row { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: var(--space-2); scrollbar-width: none; }
.filter-row::-webkit-scrollbar { display: none; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--cream-200); background: var(--white); color: var(--ink-700);
  border-radius: var(--radius-pill); padding: 0.35rem 0.9rem; font-size: var(--fs-body-sm);
  min-height: var(--min-touch); cursor: pointer; white-space: nowrap;
}
.filter-chip:hover { border-color: var(--ink-500); }
.filter-chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); font-weight: 600; }
.filter-count { font-size: 0.8rem; color: var(--ink-500); }
.filter-dates { margin-top: var(--space-1); }
.filter-clear-row { margin-top: var(--space-2); }
.filter-clear { background: none; border: none; color: var(--accent-strong); font-weight: 600; padding: var(--space-2); cursor: pointer; font-size: var(--fs-body-sm); }

/* ===== Overlay / modal ===== */
.overlay-backdrop {
  position: fixed; inset: 0; background: rgba(28,25,23,0.4); z-index: var(--z-overlay);
  opacity: 0; transition: opacity var(--dur-base); display: flex; align-items: flex-end; justify-content: center;
}
.overlay-backdrop.show { opacity: 1; }
.overlay-panel {
  background: var(--cream-50); border-radius: var(--radius-sheet); z-index: var(--z-modal);
  max-width: min(92vw, 34rem); width: 100%; max-height: 90vh; overflow-y: auto;
  transform: translateY(100%); transition: transform var(--dur-base) var(--ease-out);
  box-shadow: var(--shadow-lg);
}
.overlay-panel.show { transform: translateY(0); }
@media (min-width: 768px) {
  .overlay-backdrop { align-items: center; }
  .overlay-panel { border-radius: var(--radius-card); }
}

/* ===== AllergyWarningSheet (Ch.5.7) ===== */
.allergy-sheet { position: relative; }
.allergy-sheet-band { position: absolute; top: 0; left: 0; right: 0; height: 6px; background: var(--paprika-600); }
.allergy-sheet-head { display: flex; gap: var(--space-3); align-items: center; padding: var(--space-6) var(--space-6) 0; }
.allergy-sheet-heading h2 { margin-bottom: var(--space-1); }
.allergy-sheet-body { padding: var(--space-5) var(--space-6); }
.allergy-conflict-list { margin: var(--space-3) 0; display: flex; flex-direction: column; gap: var(--space-2); }
.allergy-conflict-item { display: flex; align-items: center; gap: var(--space-3); justify-content: space-between; }
.allergy-conflict-sev { }
.sev-tag { font-size: 0.78rem; padding: 2px 8px; border-radius: var(--radius-pill); }
.sev-anaphylactic { background: var(--paprika-600); color: var(--white); font-weight: 700; }
.sev-intolerant { background: var(--paprika-100); color: var(--paprika-600); }
.sev-avoid { background: var(--cream-200); color: var(--ink-700); }
.allergy-ack {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-4) var(--space-6); border-top: 1px solid var(--cream-200);
  cursor: pointer;
}
.allergy-ack input { margin-top: 4px; width: 20px; height: 20px; accent-color: var(--paprika-600); }
.allergy-consequence {
  margin: 0; padding: 0 var(--space-6) var(--space-4);
  color: var(--ink-700); font-weight: 500;
}
.allergy-actions { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 var(--space-6) var(--space-6); }

/* ===== Inline error / race block (C3) ===== */
.error-inline {
  background: var(--paprika-100); border: 1px solid var(--paprika-600); color: var(--paprika-600);
  border-radius: var(--radius-card); padding: var(--space-5); margin: var(--space-6) 0;
}
.error-inline[hidden] { display: none; }
.race-block h3 { margin-bottom: var(--space-2); }
.race-block p { margin-bottom: var(--space-4); }
.race-actions { display: flex; flex-direction: column; gap: var(--space-2); }

/* ===== Inputs ===== */
.input {
  width: 100%; min-height: var(--min-touch); padding: 0.6rem 0.85rem;
  border: 1px solid var(--cream-300); border-radius: var(--radius-input);
  background: var(--cream-50); color: var(--ink-900); font-size: var(--fs-body-sm);
}
.input:focus { outline: none; box-shadow: var(--ring-focus); border-color: var(--accent); }
textarea.input { resize: vertical; min-height: 60px; }
.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
.field-hint { color: var(--ink-500); }

/* ===== Allergen warning icon (Ch.5.6) — second channel, not colour alone ===== */
.allergen-warn-icon { flex: none; color: var(--paprika-600); }
.allergen-step-chips { gap: var(--space-2); }
.allergen-none-row { margin-top: var(--space-3); }

/* ===== Accessible keyboard focus rings =====
   base.css already puts var(--ring-focus) (a 3px ring) on :focus-visible for every
   element. These rules exist to (a) make the ring win on elements whose resting
   box-shadow would otherwise mask it (e.g. the active mode segment), and (b) cover
   every interactive component explicitly so the 3px ring is always visible. */
.mode-toggle-btn:focus-visible { outline: none; box-shadow: var(--ring-focus) !important; }
.btn:focus-visible,
.filter-chip:focus-visible,
.filter-clear:focus-visible,
.qty-btn:focus-visible,
.fulfilment-option:focus-visible,
.allergen-chip.interactive:focus-visible,
.chip-toggle:focus-visible,
.dish-opt:focus-visible,
.spice-opt:focus-visible,
.tier-del:focus-visible,
.mode-toggle-btn:focus-visible { outline: none; box-shadow: var(--ring-focus); border-radius: var(--radius-input); }

