/* ══════════════════════════════════════
   CART FAB (stacks above WhatsApp FAB)
══════════════════════════════════════ */
.cart-fab {
  position: fixed;
  bottom: var(--sp-6);
  right: var(--sp-6);
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background: var(--color-coral);
  color: var(--color-white);
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-fab);
  box-shadow: 0 4px 16px rgba(255,107,53,0.45);
  transition: transform var(--t-fast), box-shadow var(--t-fast);
}

.cart-fab:hover {
  transform: translateY(-2px) scale(1.06);
  box-shadow: 0 6px 24px rgba(255,107,53,0.55);
}
.cart-fab:active { transform: scale(0.96); }

.cart-fab__badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  background: var(--color-navy);
  color: var(--color-white);
  font-size: 0.65rem;
  font-weight: 700;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--color-coral);
  line-height: 1;
}
.cart-fab__badge[data-count="0"] { display: none; }

/* ══════════════════════════════════════
   QUICK-ADD POPUP
══════════════════════════════════════ */
.quick-add {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-cart) + 10);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}
.quick-add.is-open { opacity: 1; pointer-events: auto; }

.quick-add__overlay {
  position: absolute;
  inset: 0;
  background: rgba(13,31,60,0.55);
  backdrop-filter: blur(2px);
}

/* Header (photo/name) is NOT here — the card itself no longer scrolls. It's a flex
   column of a scrolling body (.quick-add__body, Side/Extras/Combo) and a sticky footer
   (.quick-add__footer, price + Add/View) — the same split the full cart modal already
   uses (.cart-modal__content / .cart-modal__footer), so the price and the Add button
   stay on screen instead of scrolling out of view with everything else. */
.quick-add__card {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  background: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: scale(0.92) translateY(8px);
  transition: transform 0.22s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.quick-add.is-open .quick-add__card { transform: scale(1) translateY(0); }
.quick-add__body {
  position: relative; /* offset root for scrollQuickAddToCombo() in cart.js */
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch; /* momentum scroll on older iOS Safari */
  padding: var(--sp-6);
}
/* No visible scrollbar on any scrolling area inside the popup (the main body, the box
   builder's selected-rolls list, and its roll-search dropdown) — same treatment as
   .pw-track elsewhere in this file. Chrome on Windows draws up/down arrow chevrons at
   the ends of the native track; customizing width/track/thumb/button still left them in
   place (measured live, at several scroll positions, in both the regular popup and the
   box builder — a real Chrome/Windows quirk, not a caching or coordinate mistake). Only
   fully hiding the scrollbar removes them; content stays scrollable by wheel/trackpad/
   touch/drag same as .pw-track already relies on. */
.quick-add__body, .qa-box-rolls, .qa-roll-options { scrollbar-width: none; }
.quick-add__body::-webkit-scrollbar,
.qa-box-rolls::-webkit-scrollbar,
.qa-roll-options::-webkit-scrollbar { display: none; }
/* A fully custom scroll indicator for the main body — see updateScrollIndicator() in
   cart.js, which sizes/positions and shows/hides this. Plain divs, not a styled native
   scrollbar, so they can never grow the arrow buttons above — but without ANY affordance
   at all, a scrolled-mid popup looked finished when Side/Extras/Combo were still below
   the fold, so this replaces the hidden native bar rather than leaving nothing. */
.qa-scroll-track {
  position: absolute;
  right: var(--sp-2);
  width: 4px;
  display: none;
  pointer-events: none;
  z-index: 1;
}
.qa-scroll-thumb {
  position: absolute;
  left: 0;
  right: 0;
  border-radius: var(--radius-full);
  background: var(--color-border);
}
.quick-add__footer {
  flex-shrink: 0;
  padding: var(--sp-4) var(--sp-6);
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
}
/* The subtotal row's own top border/padding would double up against the footer's;
   drop them here since the footer's border-top already separates it from the body. */
.quick-add__footer .quick-add__subtotal-row { border-top: none; padding-top: 0; }
/* Build-your-own box has many controls — give it more room. */
.quick-add.is-box .quick-add__card { max-width: 680px; }
.quick-add.is-box .qa-roll-options { max-height: 360px; }

/* Sits over the bled hero photo now (see .quick-add__head below), so it needs its own
   legibility — same frosted-scrim recipe as the .fish-card__status badges over a photo. */
.quick-add__close {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(4px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
  border: none;
  cursor: pointer;
  font-size: var(--fs-base);
  color: var(--color-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast), color var(--t-fast);
  z-index: 1;
}
.quick-add__close:hover { background: var(--color-white); color: var(--color-text); }

/* The hero photo bleeds to the card's own top/left/right edges (negative-margins the
   card's padding) instead of a small 72×72 corner thumbnail — a bigger, more appetizing
   product photo. .quick-add__thumb KEEPS its class name: flyToCart() (js/cart.js) reads
   it by that exact selector for the existing fly-to-cart-FAB animation. */
.quick-add__head {
  margin: calc(var(--sp-6) * -1) calc(var(--sp-6) * -1) var(--sp-5);
}

.quick-add__thumb {
  width: 100%;
  height: 180px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  overflow: hidden;
  background: linear-gradient(135deg, #0d4f6e 0%, #115f78 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.quick-add__thumb { position: relative; } /* anchors the free-gift badge on a box header */
.quick-add__thumb img { width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; display: block; }
.quick-add__emoji { font-size: 3rem; }

.quick-add__info { padding: var(--sp-4) var(--sp-6) 0; }

.quick-add__name {
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  color: var(--color-navy);
  line-height: 1.2;
}
.quick-add__price {
  font-size: var(--fs-lg);
  font-weight: 800;
  color: var(--color-teal);
  margin-top: 2px;
}
.quick-add__price span { font-size: var(--fs-sm); font-weight: 400; color: var(--color-muted); }

.quick-add__field-label {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin-bottom: var(--sp-2);
}
.quick-add__opt-hint {
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--color-teal);
}

/* ── Info block (description / allergens / weight / fish attrs) ── */
.quick-add__desc {
  font-size: var(--fs-sm);
  color: var(--color-text);
  line-height: 1.5;
  margin-bottom: var(--sp-4);
}
.quick-add__attrs {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--color-cream);
  border-radius: var(--radius-md);
}
.qa-attr {
  display: flex;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--color-text);
}
.qa-attr__label {
  flex-shrink: 0;
  min-width: 70px;
  font-weight: 700;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-teal);
  align-self: center;
}
.quick-add__allergens { margin-bottom: var(--sp-4); }
.qa-allergen-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.qa-allergen {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--status-limited);
  background: var(--status-limited-bg);
  border-radius: var(--radius-full);
  padding: 3px var(--sp-3);
  text-transform: capitalize;
}
.qa-allergen--gf { color: var(--color-white); background: var(--color-teal); }
.quick-add__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-sm);
  color: var(--color-text);
  margin-bottom: var(--sp-4);
}
.quick-add__meta .quick-add__field-label { margin-bottom: 0; }

.quick-add__weights { margin-bottom: var(--sp-4); }
.quick-add__weight-btns { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* Variant / choice option pills (reuse the weight-pill look) */
.quick-add__opt { margin-bottom: var(--sp-4); }
.qa-opt-btns { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.qa-opt {
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  color: var(--color-text);
  transition: all var(--t-fast);
}
.qa-opt:hover { border-color: var(--color-teal); }
.qa-opt.is-active {
  background: var(--color-teal);
  border-color: var(--color-teal);
  color: var(--color-white);
}

/* Side + Extras chunked into one cream card so they read as "one system" — customizing
   the dish — clearly apart from the combo card below. Reuses the same cream/radius/
   padding recipe as .quick-add__attrs; each child .quick-add__opt just adds its own
   field-label + pills inside, unstyled otherwise. */
.qa-customize-card {
  padding: var(--sp-3) var(--sp-4);
  background: var(--color-cream);
  border-radius: var(--radius-md);
  margin-bottom: var(--sp-4);
}
.qa-customize-card .quick-add__opt:last-child { margin-bottom: 0; }

/* ── Meal-combo feature card ──
   Coral is reserved for exactly this one job in the popup — everywhere else in the
   popup stays teal — so it reads as a genuine upsell moment, not another pill row.
   Reuses the coral wash+border recipe already established by .qa-whole-note. */
.qa-combo-card {
  margin-bottom: var(--sp-4);
  border-radius: var(--radius-md);
  background: rgba(255, 107, 53, 0.08);
  border: 1px solid rgba(255, 107, 53, 0.25);
  overflow: hidden;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.qa-combo-card.is-active {
  background: rgba(255, 107, 53, 0.14);
  border-color: var(--color-coral);
}
.qa-combo-card__toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3);
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
}
.qa-combo-card__photo {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-md);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-cream);
  display: flex;
  align-items: center;
  justify-content: center;
}
.qa-combo-card__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.qa-combo-card__emoji { font-size: 1.5rem; }
.qa-combo-card__copy {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.qa-combo-card__headline {
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  color: var(--color-navy);
  line-height: 1.2;
}
.qa-combo-card__sub {
  font-size: var(--fs-sm);
  color: var(--color-muted);
}
.qa-combo-card__price {
  font-weight: 800;
  font-size: var(--fs-base);
  color: var(--color-coral);
  white-space: nowrap;
  flex-shrink: 0;
}
.qa-combo-card__chevron {
  font-size: var(--fs-xl);
  color: var(--color-coral);
  line-height: 1;
  flex-shrink: 0;
  transition: transform var(--t-fast);
}
.qa-combo-card.is-active .qa-combo-card__chevron { transform: rotate(90deg); }
/* The cookie/drink steps render inside the same card as the toggle (not as bare
   siblings below it), separated by a light divider that matches the card's own tint. */
.qa-combo-card .qa-combo-card__step {
  margin: 0;
  padding: var(--sp-3);
  border-top: 1px solid rgba(255, 107, 53, 0.2);
}
/* One-time pop-in when the card first appears — reuses the site's existing overshoot
   "liveliness" shape (qa-leaf-pop / num-pop) rather than inventing a new easing curve. */
@keyframes qa-combo-pop {
  0%   { transform: scale(0.92); opacity: 0; }
  55%  { transform: scale(1.02); }
  100% { transform: scale(1); opacity: 1; }
}
.qa-combo-card--intro { animation: qa-combo-pop 320ms ease; }
@media (prefers-reduced-motion: reduce) {
  .qa-combo-card--intro { animation: none; }
}

/* ── Meal-combo screen (renderComboScreen in cart.js) ──
   Same window as the dish, content swapped with a slide — a stacked second modal would
   put two dialogs on a phone screen. ← back takes the close button's top-left spot and
   the ✕ moves to the right, so both stay reachable without covering the title. */
.quick-add__back {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  border: none;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
  color: var(--color-text);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 2;
}
.quick-add.is-combo .quick-add__back { display: flex; }
.quick-add.is-combo .quick-add__close { left: auto; right: var(--sp-3); }

.qa-combo-hero { position: relative; margin: calc(var(--sp-6) * -1) calc(var(--sp-6) * -1) 0; }
.qa-combo-hero__photo { height: 240px; }
/* On the dish screen .quick-add__info sits inside the edge-to-edge head and pads itself
   back in; here it follows the hero directly inside #qa-body's own padding. */
.qa-combo-hero + .quick-add__info { padding: var(--sp-4) 0 0; }
.qa-combo-hero__badge {
  position: absolute;
  right: var(--sp-4);
  bottom: var(--sp-3);
  padding: 4px 12px;
  border-radius: var(--radius-full);
  background: var(--color-coral);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.12em;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
.qa-combo-hero__includes {
  margin-top: 4px;
  font-size: var(--fs-sm);
  color: var(--color-muted);
}
.qa-combo-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px var(--sp-2);
  margin: var(--sp-2) 0 var(--sp-4);
}
.qa-combo-price__now { font-size: var(--fs-2xl); font-weight: 800; color: var(--color-teal); }
.qa-combo-price__was { font-size: var(--fs-base); color: var(--color-muted); text-decoration: line-through; }
.qa-combo-price__save {
  align-self: center;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  background: rgba(255, 107, 53, 0.14);
  border: 1px solid rgba(255, 107, 53, 0.38);
  color: #b8420f;
  font-size: var(--fs-sm);
  font-weight: 800;
}
html[data-theme="dark"] .qa-combo-price__save { color: #ffab85; }

/* Extras are optional on a combo, so they fold away under their own heading. */
.qa-combo-extras {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-md);
  background: var(--color-cream);
}
.qa-combo-extras summary {
  cursor: pointer;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  list-style: none;
}
.qa-combo-extras summary::-webkit-details-marker { display: none; }
.qa-combo-extras summary::after { content: ' ›'; display: inline-block; transition: transform var(--t-fast); }
.qa-combo-extras[open] summary::after { transform: rotate(90deg); }
.qa-combo-extras[open] summary { margin-bottom: var(--sp-3); }
.qa-combo-extras .quick-add__opt:last-child { margin-bottom: 0; }
/* The summary already names the group; the group's own label inside would say it twice. */
.qa-combo-extras .quick-add__opt > .quick-add__field-label { display: none; }
.qa-combo-extras summary::after { margin-left: 4px; }

/* Screen change: forward slides in from the right, back from the left (transform +
   opacity only). Exit is not animated — the old screen is simply replaced. */
@keyframes qa-slide-fwd  { from { transform: translateX(28px);  opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes qa-slide-back { from { transform: translateX(-28px); opacity: 0; } to { transform: none; opacity: 1; } }
.quick-add__body.qa-slide-fwd  > * { animation: qa-slide-fwd 260ms cubic-bezier(0.2, 0.8, 0.2, 1); }
.quick-add__body.qa-slide-back > * { animation: qa-slide-back 260ms cubic-bezier(0.2, 0.8, 0.2, 1); }
@media (prefers-reduced-motion: reduce) {
  .quick-add__body.qa-slide-fwd > *, .quick-add__body.qa-slide-back > * { animation: none; }
}

/* Build-your-own box builder */
.qa-box { margin-bottom: var(--sp-4); }
.qa-box-extras-label { margin-top: var(--sp-4); }
.qa-box-rolls {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  max-height: 320px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* Required per-roll choices (veg-roll fillings, tempura/california cheese) */
.qa-box-roll-wrap { border-bottom: 1px solid rgba(0,0,0,0.06); }
.qa-box-roll-wrap:last-child { border-bottom: 0; }
.qa-box-roll-opts { padding: 0 var(--sp-1) var(--sp-2) 52px; display: flex; flex-direction: column; gap: var(--sp-2); }
.qa-box-roll-opt__label { display: block; font-size: var(--fs-sm); font-weight: 600; margin-bottom: 4px; }
.qa-box-roll {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--color-border);
}
.qa-box-roll__name { flex: 1; font-size: var(--fs-sm); font-weight: 600; }
.qa-box-roll__price { font-size: var(--fs-sm); color: var(--color-muted); }
.qa-box-stepper {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.qa-box-step {
  width: 28px;
  height: 28px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  font-size: var(--fs-base);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  color: var(--color-teal);
}
.qa-box-step:hover:not([disabled]) { border-color: var(--color-teal); }
.qa-box-step[disabled] { opacity: 0.4; cursor: not-allowed; }
.qa-box-count { min-width: 18px; text-align: center; font-weight: 700; }
.qa-box-roll__thumb {
  width: 40px; height: 40px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--color-cream);
}
.qa-box-roll__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
/* Made-to-order prep-time notice on build-your-own boxes (popup + cart line) */
.qa-box-prep { font-size: var(--fs-sm); font-weight: 600; color: var(--color-coral); margin-bottom: var(--sp-3); }
.cart-line__prep { font-size: var(--fs-xs); font-weight: 600; color: var(--color-coral); margin-top: 2px; }
.qa-box-roll__emoji { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; font-size: 22px; }
.qa-box-empty { font-size: var(--fs-sm); color: var(--color-muted); padding: var(--sp-2) 0; }

/* "Add a roll" searchable dropdown */
.qa-roll-dropdown { margin-top: var(--sp-3); }
.qa-roll-toggle {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--color-teal);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-teal);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
}
.qa-roll-toggle[disabled] { opacity: 0.5; cursor: not-allowed; border-color: var(--color-border); color: var(--color-muted); }
.qa-roll-toggle__chev { transition: transform var(--t-fast); }
.qa-roll-dropdown.is-open .qa-roll-toggle__chev { transform: rotate(180deg); }
.qa-roll-panel {
  margin-top: var(--sp-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.qa-roll-search {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: none;
  border-bottom: 1px solid var(--color-border);
  outline: none;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  background: var(--color-cream);
}
.qa-roll-options { max-height: 240px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.qa-roll-option {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: none;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-white);
  cursor: pointer;
  text-align: left;
}
.qa-roll-option:last-child { border-bottom: none; }
.qa-roll-option:hover { background: var(--color-cream); }
.qa-roll-option__name { flex: 1; font-size: var(--fs-sm); font-weight: 600; color: var(--color-text); }
.qa-roll-option__price { font-size: var(--fs-sm); font-weight: 700; color: var(--color-teal); }

/* Weighted box add-ons: a toggle row that reveals a weight stepper when active */
.qa-box-addons { display: flex; flex-direction: column; gap: var(--sp-2); }
.qa-box-addon {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.qa-box-addon.is-active { border-color: var(--color-teal); }
.qa-box-addon__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  background: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  color: var(--color-text);
  transition: all var(--t-fast);
}
.qa-box-addon.is-active .qa-box-addon__toggle { background: var(--color-teal); color: var(--color-white); }
.qa-box-addon__price { font-weight: 700; white-space: nowrap; }
/* "(add)" / "(remove)" — a clear, link-styled cue for the tappable add-on row */
.qa-box-addon__action {
  color: var(--color-coral);
  font-weight: 700;
  font-size: var(--fs-xs);
  text-decoration: underline;
}
.qa-box-addon.is-active .qa-box-addon__toggle .qa-box-addon__action { color: var(--color-white); }
.qa-box-addon__wt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--color-cream);
}
.qa-box-addon-step {
  width: 26px;
  height: 26px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  color: var(--color-teal);
}
.qa-box-addon-step:hover:not([disabled]) { border-color: var(--color-teal); }
.qa-box-addon-step[disabled] { opacity: 0.4; cursor: not-allowed; }
.qa-box-addon__g { min-width: 52px; text-align: center; font-weight: 700; font-size: var(--fs-sm); }
.qa-box-addon__line { margin-left: auto; font-weight: 700; color: var(--color-teal); }

/* One-time add-on nudge shown above the Add button */
.qa-box-suggest {
  margin: var(--sp-3) 0;
  padding: var(--sp-3);
  border: 1px dashed var(--color-teal);
  border-radius: var(--radius-md);
  background: var(--color-cream);
}
.qa-box-suggest__label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 700;
  margin-bottom: var(--sp-2);
}
.qa-box-suggest__row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.qa-box-suggest__yes {
  flex: 1;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--color-teal);
  border-radius: var(--radius-full);
  background: var(--color-teal);
  color: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
}
.qa-box-suggest__no {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  color: var(--color-text);
}
/* Full-card combo offer (renderComboOffer). Covers the whole popup, card and footer, with
   the card's own shape; opaque so nothing of the dish screen competes with it. */
.qa-offer {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  background: var(--color-white);
  border-radius: inherit;
  overflow: hidden;
  animation: qa-offer-in 300ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.qa-offer[hidden] { display: none; }
@keyframes qa-offer-in { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
.qa-offer__photo {
  position: relative;
  flex: 1 1 auto;
  min-height: 180px;
  background: linear-gradient(135deg, #0d4f6e 0%, #115f78 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.qa-offer__photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.qa-offer__body { flex: 0 0 auto; padding: var(--sp-5) var(--sp-6) var(--sp-6); }
.qa-offer__title {
  font-family: var(--font-heading);
  font-size: var(--fs-3xl, 1.9rem);
  line-height: 1.15;
  color: var(--color-navy);
}
.qa-offer__includes { margin-top: 4px; color: var(--color-muted); }
.qa-offer__price { margin: var(--sp-3) 0 var(--sp-5); }
.qa-offer__actions { display: flex; flex-direction: column; gap: var(--sp-2); }
.qa-btn.qa-offer__yes { width: 100%; padding: var(--sp-4); font-size: var(--fs-lg); } /* .qa-btn is declared later in this file */
.qa-offer__no {
  width: 100%;
  padding: var(--sp-3);
  border: none;
  background: none;
  color: var(--color-muted);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
@media (prefers-reduced-motion: reduce) { .qa-offer { animation: none; } }

.qa-weight {
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  color: var(--color-text);
  transition: all var(--t-fast);
}
.qa-weight:hover { border-color: var(--color-teal); }
.qa-weight.is-active {
  background: var(--color-teal);
  border-color: var(--color-teal);
  color: var(--color-white);
}

/* Fine weight slider (sits below the preset chips) */
.qa-weight-slider-wrap {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-3);
}
.qa-weight-slider {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--color-border);
  cursor: pointer;
}
.qa-weight-slider:focus { outline: none; }
.qa-weight-slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px rgba(10, 122, 143, 0.25); }
.qa-weight-slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px rgba(10, 122, 143, 0.25); }
.qa-weight-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--color-teal);
  border: 2px solid var(--color-white);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  transition: transform var(--t-fast);
}
.qa-weight-slider::-webkit-slider-thumb:active { transform: scale(1.15); }
.qa-weight-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--color-teal);
  border: 2px solid var(--color-white);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.qa-weight-value-wrap {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  flex-shrink: 0;
}
.qa-weight-value {
  width: 3.2em;
  text-align: right;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--color-teal);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 2px 4px;
  -moz-appearance: textfield;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.qa-weight-value:hover { border-color: var(--color-border); }
.qa-weight-value:focus {
  outline: none;
  border-color: var(--color-teal);
  background: var(--color-white);
}
.qa-weight-value::-webkit-outer-spin-button,
.qa-weight-value::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qa-weight-value__unit {
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--color-teal);
}

/* ── Vegan toggle ── */
.quick-add__vegan { margin-bottom: var(--sp-4); }
.qa-vegan {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--color-vegan);
  border-radius: var(--radius-full);
  background: var(--color-white);
  color: var(--color-vegan);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.qa-vegan:hover { box-shadow: 0 0 0 3px rgba(58, 157, 93, 0.15); }
.qa-vegan__icon {
  display: inline-flex;
  transition: transform var(--t-fast);
}
.qa-vegan.is-on {
  background: var(--color-vegan);
  color: var(--color-white);
}
.qa-vegan.is-on .qa-vegan__icon {
  transform: rotate(-12deg) scale(1.15);
  animation: qa-leaf-pop 320ms ease;
}
@keyframes qa-leaf-pop {
  0%   { transform: rotate(0) scale(0.8); }
  55%  { transform: rotate(-18deg) scale(1.3); }
  100% { transform: rotate(-12deg) scale(1.15); }
}

/* Vegan badge on a cart line */
.cart-line__vegan {
  display: inline-block;
  vertical-align: middle;
  margin-left: var(--sp-2);
  padding: 1px var(--sp-2);
  border-radius: var(--radius-full);
  background: var(--color-vegan);
  color: var(--color-white);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

@media (prefers-reduced-motion: reduce) {
  .qa-vegan.is-on .qa-vegan__icon { animation: none; }
}

.quick-add__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--sp-4);
}
.quick-add__row .quick-add__field-label { margin-bottom: 0; }

.quick-add__stepper,
.cart-line__qty {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: 4px var(--sp-3);
}
.qa-step,
.cart-line__qty-btn {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-full);
  background: var(--color-cream);
  border: 1px solid var(--color-border);
  cursor: pointer;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--color-text);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  transition: background var(--t-fast);
}
.qa-step:hover,
.cart-line__qty-btn:hover { background: var(--color-border); }
.qa-qty,
.cart-line__qty-num {
  font-weight: 700;
  font-size: var(--fs-base);
  min-width: 20px;
  text-align: center;
  color: var(--color-text);
}

.quick-add__subtotal-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--color-border);
  margin-bottom: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--color-muted);
}
.quick-add__subtotal-row strong {
  font-size: var(--fs-xl);
  font-weight: 800;
  color: var(--color-teal);
}

.quick-add__actions { display: flex; gap: var(--sp-3); }
.qa-btn {
  flex: 1;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-full);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  border: none;
  transition: transform var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.qa-btn:active { transform: scale(0.98); }
.qa-btn--add {
  background: linear-gradient(135deg, var(--color-teal), var(--teal-br));
  color: var(--color-white);
  box-shadow: 0 3px 12px rgba(10,122,143,0.32);
}
.qa-btn--add:hover:not([disabled]):not(.is-incomplete) { filter: brightness(1.06); }
/* .is-incomplete looks like [disabled] but stays tappable: a tap points at what is missing
   (flagMissing() in cart.js) instead of doing nothing. */
.qa-btn--add.is-incomplete,
.qa-btn--add[disabled] {
  background: var(--color-border);
  color: var(--color-muted);
  box-shadow: none;
  cursor: not-allowed;
}
.qa-btn--add.is-incomplete { cursor: pointer; }
.qa-btn--view {
  background: var(--color-cream);
  color: var(--color-navy);
  border: 1px solid var(--color-border);
}
.qa-btn--view:hover { background: var(--color-border); }

/* ══════════════════════════════════════
   FULL-WINDOW CART
══════════════════════════════════════ */
.cart-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-cart);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s ease;
}
.cart-modal.is-open { opacity: 1; pointer-events: auto; }

.cart-modal__overlay {
  position: absolute;
  inset: 0;
  background: rgba(13,31,60,0.6);
  backdrop-filter: blur(3px);
}

.cart-modal__window {
  position: relative;
  width: 100%;
  /* Widened for the two-column checkout below. The window is deliberately not stretched to
     fill a desktop screen: a form whose inputs run the width of a monitor is harder to read,
     not easier, so the extra room buys a second column instead of longer lines. */
  max-width: 920px;
  max-height: 92vh;
  background: var(--color-white);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateY(16px) scale(0.98);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.cart-modal.is-open .cart-modal__window { transform: translateY(0) scale(1); }

.cart-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-5) var(--sp-6);
  background: var(--color-navy);
  color: var(--color-white);
  flex-shrink: 0;
}
.cart-modal__title {
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  font-weight: 700;
}
.cart-modal__close {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-full);
  background: rgba(255,255,255,0.1);
  border: none;
  color: var(--color-white);
  cursor: pointer;
  font-size: var(--fs-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast);
}
.cart-modal__close:hover { background: rgba(255,255,255,0.22); }
.cart-modal__clear {
  margin-left: auto;
  margin-right: var(--sp-3);
  background: rgba(255,255,255,0.12);
  border: none;
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-full);
  cursor: pointer;
}
.cart-modal__clear:hover { background: rgba(255,255,255,0.24); }
.cart-modal__clear[hidden] { display: none; }

.cart-modal__content {
  display: block;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  min-height: 0;
}

.cart-modal__main {
  overflow: visible;
  min-width: 0;
  padding: var(--sp-5) var(--sp-6);
}

/* ── Checkout layout ──
   One flow on a phone, two columns once there is room: the text fields on the left, the
   pickup picker — the only control here rather than a text box — on the right. Stacking a
   month calendar under everything else is what turned the checkout into a long scroll
   through a narrow strip. */
.cart-summary__cols { display: grid; gap: var(--sp-4); }
.cart-summary__col { min-width: 0; }

@media (min-width: 860px) {
  .cart-summary__cols {
    grid-template-columns: minmax(0, 1fr) minmax(330px, 380px);
    gap: var(--sp-6);
    align-items: start;
  }
  /* The item list is rows of name-and-price. Left to run the full 920px it would be mostly
     dead space in the middle, so only the checkout spends the new width. */
  .cart-modal__main { max-width: 620px; margin-inline: auto; }
}

/* Fresh-fish availability notice */
.cart-fish-notice {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-md);
  background: rgba(255, 107, 53, 0.08);
  border: 1px solid rgba(255, 107, 53, 0.25);
  font-size: var(--fs-sm);
  color: var(--color-text);
}
.cart-happy-notice {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-md);
  background: var(--color-coral);
  color: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.cart-line__was { color: var(--color-muted); font-weight: 400; margin-right: 4px; }

/* Weight/price disclaimer — shown under the total and in the weighed quick-add popup */
.cart-weight-notice {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--color-muted);
}
.quick-add__weight-note {
  margin: calc(var(--sp-5) * -1) 0 var(--sp-5);
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: var(--color-muted);
}

/* "Add more items" — jump back to the menu to keep shopping */
.cart-addmore-row { display: flex; justify-content: flex-end; margin-top: var(--sp-4); }
.cart-addmore-row[hidden] { display: none; }
.cart-addmore {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-white);
  color: var(--color-teal);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.cart-addmore:hover { border-color: var(--color-teal); background: rgba(10,122,143,0.06); }
.cart-addmore:active { transform: scale(0.98); }

/* "You might also like" upsell grid */
.cart-modal__suggestion:empty { display: none; }
.cart-suggest {
  margin-top: var(--sp-5);
  padding-top: var(--sp-5);
  border-top: 1px dashed var(--color-border);
}
.cart-suggest__label {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin-bottom: var(--sp-3);
}
/* Rows, not tiles. As tiles the 16:10 photo alone stood ~180px tall, so two suggestions were
   taller than the room left under the cart: the customer saw the tops of two pictures and the
   add buttons never came into view. A row is the same shape as the cart lines directly above
   — thumbnail, name, control — so the section reads as part of the same list, and both fit
   whole without scrolling. auto-fit rather than a media query: the cart is 620px on a desktop
   and full-bleed on a phone, and the rows should pair up or stack on their own measurements. */
.cart-suggest__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-2);
}
.cart-suggest__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-cream);
}
.cart-suggest__item-thumb {
  position: relative;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: linear-gradient(135deg, #0d4f6e 0%, #115f78 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cart-suggest__item-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-suggest__emoji { font-size: 1.5rem; }
.cart-suggest__item-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.cart-suggest__name {
  font-family: var(--font-heading);
  font-size: var(--fs-sm);
  color: var(--color-navy);
  line-height: 1.2;
  /* Two lines at most: a long special should not be able to make one row taller than its
     neighbour and reintroduce the ragged block this replaced. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cart-suggest__price { font-size: var(--fs-sm); font-weight: 700; color: var(--color-teal); }
.cart-suggest__add {
  flex: none;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--color-teal), var(--teal-br));
  color: var(--color-white);
  font-size: var(--fs-lg);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(10,122,143,0.4);
  transition: transform var(--t-fast), filter var(--t-fast);
}
.cart-suggest__add:hover { filter: brightness(1.06); transform: scale(1.08); }
.cart-suggest__add:active { transform: scale(0.94); }

/* Empty state */
.cart-empty {
  text-align: center;
  color: var(--color-muted);
  padding: var(--sp-12) var(--sp-4);
}
.cart-empty svg { margin-bottom: var(--sp-4); opacity: 0.35; }
.cart-empty__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
  padding: var(--sp-3) var(--sp-5);
  border: none;
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--color-teal), var(--teal-br));
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 12px rgba(10,122,143,0.32);
  transition: transform var(--t-fast), filter var(--t-fast);
}
.cart-empty__cta svg { margin-bottom: 0; opacity: 1; }
.cart-empty__cta:hover { filter: brightness(1.06); transform: translateY(-1px); }
.cart-empty__cta:active { transform: scale(0.98); }

/* Cart line */
.cart-line {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.cart-line:last-child { border-bottom: none; }

.cart-line__thumb {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-md);
  overflow: hidden;
  flex-shrink: 0;
  background: linear-gradient(135deg, #0d4f6e 0%, #115f78 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cart-line__thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-thumb__emoji { font-size: 1.8rem; }

.cart-line__info { flex: 1; min-width: 0; }
.cart-line__name {
  font-weight: 600;
  color: var(--color-text);
  font-size: var(--fs-base);
}
.cart-line__detail {
  font-size: var(--fs-sm);
  color: var(--color-muted);
  margin: 2px 0 var(--sp-2);
}

.cart-line__end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
  flex-shrink: 0;
}
.cart-line__subtotal {
  font-weight: 800;
  color: var(--color-teal);
  font-size: var(--fs-base);
  white-space: nowrap;
}
.cart-line__remove {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-muted);
  padding: var(--sp-1);
  display: flex;
  transition: color var(--t-fast);
}
.cart-line__remove:hover { color: #ef4444; }

/* Summary sidebar */
.cart-modal__summary {
  background: var(--color-cream);
  padding: var(--sp-5) var(--sp-6);
  overflow: visible;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.cart-summary__title {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  color: var(--color-navy);
}

.cart-field { display: flex; flex-direction: column; }
.cart-field__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin-bottom: var(--sp-2);
}
.cart-field__input {
  padding: var(--sp-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--color-text);
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.cart-field__input:focus { outline: 2px solid var(--color-teal); outline-offset: 1px; }
.cart-field__textarea { resize: vertical; min-height: 64px; }

/* ── Phone: country select + national number ──
   The country code is mandatory because the cashier panel's WhatsApp button is wa.me/<digits>
   — a number saved without one is a dead link. Carrying the code in a select means a local
   still just types their seven digits and a visitor picks their country instead of guessing
   at a format. The select is deliberately allowed to clip: every option label starts with the
   dial code, so the useful half survives. */
.cart-phone-row { display: flex; gap: var(--sp-1); align-items: stretch; }
.cart-phone__num { flex: 1 1 auto; min-width: 0; }

/* The country combobox. A native <select> put an operating-system list in the middle of the
   glass and gave no way to reach country 180 except scrolling, so this is the cart's own
   search-over-list panel — the one the box builder already uses for rolls. */
.cc { position: relative; flex: 0 0 42%; max-width: 42%; min-width: 0; }
.cc-trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  width: 100%;
  text-align: left;
  cursor: pointer;
  font-weight: 600;
}
/* The dial code is the part that must never be clipped — it is what the customer is choosing.
   The country name yields first and takes the ellipsis. */
.cc-trigger__dial { flex: none; color: var(--color-teal); font-variant-numeric: tabular-nums; }
.cc-trigger__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-weight: 500;
  color: var(--color-muted);
}
.cc-caret { flex: none; color: var(--color-muted); transition: transform var(--t-fast); }
.cc-trigger[aria-expanded="true"] .cc-caret { transform: rotate(180deg); }

.cc-panel {
  position: absolute;
  z-index: 5;
  top: calc(100% + 6px);
  left: 0;
  /* Wider than the trigger: the trigger can afford to clip a country name, a list you are
     reading cannot. Clamped so it never leaves the cart on a narrow phone. */
  width: max(100%, 296px);
  max-width: min(86vw, 360px);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.18);
}
.cc-search {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: none;
  border-bottom: 1px solid var(--color-border);
  outline: none;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  background: var(--color-cream);
  color: var(--color-text);
}
.cc-options {
  max-height: 260px;
  overflow-y: auto;
  overscroll-behavior: contain;
  margin: 0;
  padding: 0;
  list-style: none;
}
.cc-option {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  font-size: var(--fs-sm);
}
/* Marks where the shop's own neighbours stop and the alphabet starts. Only drawn on the
   unfiltered list — over search results the same rule would claim an order that isn't there. */
.cc-option--first-rest { border-top: 1px solid var(--color-border); }
.cc-option__dial {
  flex: none;
  min-width: 3.4em;
  font-weight: 700;
  color: var(--color-teal);
  font-variant-numeric: tabular-nums;
}
.cc-option__name { flex: 1 1 auto; color: var(--color-text); }
.cc-option.is-active { background: var(--color-cream); }
.cc-option.is-selected .cc-option__name { font-weight: 700; }
.cc-empty {
  padding: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--color-muted);
  list-style: none;
}
.cart-field__hint {
  font-size: var(--fs-xs);
  color: var(--color-muted);
  margin-top: var(--sp-1);
}

/* ── Pickup mode selector (ASAP / Later today / Schedule) ── */
.pickup-modes {
  display: flex;
  gap: var(--sp-1);
  padding: 3px;
  background: var(--color-cream);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.pickup-mode {
  flex: 1;
  padding: var(--sp-2) var(--sp-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}
.pickup-mode.is-active {
  background: var(--color-teal);
  color: var(--color-white);
}
/* Unavailable, not merely unselected. In a segmented control the unselected half is already
   grey, so a 0.4 opacity nudge read as "the other tab" rather than "you cannot pick this" —
   customers tapped ASAP on a Sunday, nothing happened, and the toggle looked broken. A phone
   has no cursor either, so `not-allowed` alone communicated nothing. The line through the
   label is the part that survives on a small screen. */
.pickup-mode:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  font-weight: 500;
}
.pickup-closed-now {
  margin-top: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--field-error, #dc2626);
}

.pickup-body { margin-top: var(--sp-3); }
.pickup-body .cart-field__input { width: 100%; }

/* ── Scheduled pickup: day chips + time chips ──
   Replaces <input type="datetime-local">, whose popup is browser chrome that no CSS can
   reach — it always looked foreign inside the cart, and it let a customer pick an hour the
   shop is shut. Only collectable slots are rendered, so there is nothing invalid to choose. */
.pickup-slots { display: flex; flex-direction: column; gap: var(--sp-1); }
.pickup-slots__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-top: var(--sp-1);
}
/* ── The pickup calendar ──
   A month grid, because people hold "next Thursday" as a position in a month rather than as
   an offset from today. Days the kitchen cannot honour stay in place and go grey, so the
   month reads as a month instead of as a ragged list of the few dates that are free. */
.pc { margin-bottom: var(--sp-3); }
.pc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}
.pc-month {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--color-text);
  text-transform: capitalize;   /* several locales lower-case their month names */
}
.pc-nav { display: flex; gap: var(--sp-1); }
.pc-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-teal);
  cursor: pointer;
}
.pc-arrow:hover:not(:disabled) { background: color-mix(in srgb, var(--color-teal) 14%, transparent); }
/* The booking window is four weeks wide, so an arrow pointing at an entirely grey month is
   the normal case, not an edge one. It goes quiet rather than disappearing, which would make
   the header jump. */
.pc-arrow:disabled { color: var(--color-muted); opacity: 0.35; cursor: default; }

.pc-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  justify-items: center;
}
.pc-dow {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--color-muted);
  padding-bottom: var(--sp-1);
}
.pc-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--pc-cell, 34px);
  height: var(--pc-cell, 34px);
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.pc-day { cursor: pointer; }
.pc-day:hover:not(.is-selected):not(.is-off) { background: color-mix(in srgb, var(--color-teal) 14%, transparent); }
.pc-day.is-off { color: var(--color-muted); opacity: 0.32; cursor: default; }
/* Today is named in the accent colour; the chosen day is the one filled disc on the grid.
   A shut Sunday keeps the marker but stays dimmed — it says "you are here", not "book me". */
.pc-day.is-today { color: var(--color-teal); font-weight: 700; }
.pc-day.is-off.is-today { opacity: 0.55; }
.pc-day.is-selected {
  background: var(--color-teal);
  color: var(--color-white);
  font-weight: 700;
}
.pc-day:focus-visible { outline: 2px solid var(--color-teal); outline-offset: 2px; }

/* ── The pickup wheels ──
   An iOS-style picker. A week of days plus eighteen half-hour slots is a lot of buttons to
   put in a checkout, and a short scrolling column reads as "choose one" far more directly
   than a wrapped field of pills. The motion is CSS scroll-snap, not a drag library: the
   browser already knows how a flick should decelerate, and inheriting that is what makes it
   feel native under a thumb. */
.pw-set {
  --pw-row: 38px;
  /* Odd, so exactly one row sits under the band. Three rather than the five a full-screen
     iOS sheet uses: the wheel opens on its first entry, so the rows above it are empty, and
     at five that is a 76px hole in the middle of a checkout the first time anyone sees it. */
  --pw-rows: 3;
}
/* The band spans both columns, so it is positioned against the lanes and NOT against the
   whole control — otherwise its offset would have to compensate for the height of the labels
   above, and that arithmetic breaks the moment the type scale moves. */
.pw-lanes {
  position: relative;
  display: flex;
  gap: var(--sp-2);
  perspective: 700px;   /* what turns the tilt below into a barrel rather than a squash */
}
.pw-heads { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-1); }
.pw-heads .pw__label { flex: 1 1 0; min-width: 0; }
.pw__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.pw-viewport {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: calc(var(--pw-row) * var(--pw-rows));
  /* Fade the ends instead of drawing a frame — the rows should look like they are turning
     out of view, not being clipped by a box. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}
.pw-track {
  height: 100%;
  margin: 0;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;      /* a flick on the wheel must not scroll the cart behind it */
  scroll-snap-type: y mandatory;
  /* Half the viewport, less half a row: what lets the first and last rows reach the centre. */
  padding: calc((var(--pw-rows) - 1) / 2 * var(--pw-row)) 0;
  scrollbar-width: none;
  outline: none;
  transform-style: preserve-3d;
}
.pw-track::-webkit-scrollbar { display: none; }
.pw-track:focus-visible { border-radius: var(--radius-md); box-shadow: 0 0 0 2px var(--color-teal); }
.pw-item {
  height: var(--pw-row);
  line-height: var(--pw-row);
  scroll-snap-align: center;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  /* --d (signed distance from the centre row) and --ad (its absolute value) are written by
     bindWheel() on every scroll frame. CSS abs() is still too new to rely on here. */
  transform: rotateX(calc(var(--d, 0) * 19deg)) scale(calc(1 - var(--ad, 0) * 0.06));
  opacity: calc(1 - var(--ad, 0) * 0.26);
  transition: color var(--t-fast);
}
.pw-item.is-active { color: var(--color-teal); font-weight: 700; }

/* The selection band, drawn once across both wheels so they read as one control. It sits
   behind the rows and ignores the pointer, or it would eat the scroll. */
.pw-band {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--pw-row) * (var(--pw-rows) - 1) / 2);
  height: var(--pw-row);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--color-teal) 12%, transparent);
  pointer-events: none;
  z-index: 0;
}

.pw-chosen {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-teal);
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .pw-item { transform: none; }
}

/* Once the picker has a column of its own, both grids can breathe — the cramped feel came
   from 34px discs packed into a narrow strip, not from the calendar itself. This has to sit
   AFTER the base rules: a media query adds no specificity, so declared earlier it would lose
   to the plain `.pw-set { --pw-row: 38px }` above and silently do nothing. */
@media (min-width: 860px) {
  .pc { --pc-cell: 40px; }
  .pw-set { --pw-row: 42px; }
}

.pickup-note {
  font-size: var(--fs-sm);
  color: var(--color-muted);
  background: rgba(10, 122, 143, 0.06);
  border-radius: var(--radius-md);
  padding: var(--sp-3);
  margin: 0;
}

/* "Later today" stepper */
.pickup-stepper {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.pickup-step {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-white);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--color-teal);
  cursor: pointer;
  transition: all var(--t-fast);
}
.pickup-step:hover:not(:disabled) { border-color: var(--color-teal); background: rgba(10,122,143,0.06); }
.pickup-step:disabled { opacity: 0.35; cursor: not-allowed; }
.pickup-step__value {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.2;
}
.pickup-step__dur {
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--color-text);
}
.pickup-time {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-teal);
}

/* Payment radios */
.cart-pay-note { font-size: var(--fs-base); font-weight: 700; color: var(--color-navy); }
.cart-pickup-required, .cart-name-required { color: var(--field-error, #ef4444); font-weight: 700; }
/* Required field left empty: red ring + outline so it can't be missed */
.cart-field__input.is-invalid {
  border-color: var(--field-error, #ef4444);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--field-error, #ef4444) 40%, transparent);
}
.cart-field__input.is-invalid:focus { outline-color: var(--field-error, #ef4444); }
.cart-warning {
  margin-bottom: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-md);
  background: rgba(255,107,53,0.10);
  border: 1px solid rgba(255,107,53,0.35);
  color: var(--color-coral);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.35;
}
/* Pulse when the customer taps Place Order but a box is too late to prepare. */
.cart-warning--flash { animation: cart-warn-pulse 0.9s ease-in-out 2; }
/* Same pulse on the pickup picker when the customer steps back from the closed-store
   confirmation to change the time: the picker is usually scrolled off a phone screen, so a
   dialog that simply vanished looked like the button had done nothing. */
.pickup-field--flash { animation: cart-warn-pulse 0.9s ease-in-out 2; border-radius: var(--radius-md); }
@keyframes cart-warn-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,107,53,0); }
  35% { box-shadow: 0 0 0 4px rgba(255,107,53,0.40); background: rgba(255,107,53,0.20); }
}

.cart-summary__total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: var(--sp-4);
  border-top: 2px solid var(--color-border);
}
.cart-summary__total span { font-weight: 600; color: var(--color-text); }
.cart-summary__total strong {
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  font-weight: 900;
  color: var(--color-teal);
}

/* ── Promo code field + discount line ── */
.cart-promo { display: flex; gap: var(--sp-2); align-items: stretch; }
.cart-promo .cart-field__input { flex: 1 1 auto; text-transform: uppercase; }
.cart-promo__apply {
  flex: 0 0 auto;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--fs-sm);
  padding: 0 var(--sp-4);
  border: 1px solid var(--color-teal);
  border-radius: var(--radius-md);
  background: var(--color-teal);
  color: var(--color-white);
}
.cart-promo__apply:disabled { opacity: 0.5; cursor: default; }
.cart-promo--ok  { color: var(--color-teal); }
.cart-promo--err { color: var(--status-unavail, #c0392b); }
/* A valid code that covers nothing in this cart is neither success nor error. */
.cart-promo--warn { color: var(--status-limited); }
.cart-summary__discount {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--fs-sm);
  color: var(--color-teal);
  padding-top: var(--sp-3);
}
.cart-summary__discount strong { font-weight: 700; }

.cart-place {
  width: 100%;
  padding: var(--sp-4);
  border-radius: var(--radius-full);
  background: #25d366;
  color: var(--color-white);
  border: none;
  font-size: var(--fs-base);
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  box-shadow: 0 3px 12px rgba(37,211,102,0.35);
  transition: transform var(--t-fast), box-shadow var(--t-fast), opacity var(--t-fast);
}
.cart-place:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 5px 20px rgba(37,211,102,0.5); }
.cart-place:active:not(:disabled) { transform: scale(0.99); }
.cart-place:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: none; }

/* ── Per-item "special requests" note (quick-add popup) ── */
.qa-note { margin-top: var(--sp-4); }
.qa-note__toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
}
.qa-note__toggle input {
  width: 16px;
  height: 16px;
  accent-color: var(--color-teal);
  cursor: pointer;
}
.qa-note__field {
  margin-top: var(--sp-2);
  width: 100%;
  box-sizing: border-box;
  padding: var(--sp-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  resize: vertical;
  min-height: 56px;
}
.qa-note__field:focus { outline: 2px solid var(--color-teal); outline-offset: 1px; }

/* Per-item note shown on a cart line */
.cart-line__note {
  margin-top: 4px;
  font-size: var(--fs-xs);
  color: var(--color-muted);
  font-style: italic;
}

/* Whole-fish "priced in-store" note (quick-add popup) */
.qa-whole-note {
  margin-top: var(--sp-4);
  padding: var(--sp-3);
  border-radius: var(--radius-md);
  background: rgba(255, 107, 53, 0.08);
  border: 1px solid rgba(255, 107, 53, 0.25);
}
.qa-whole-note p {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--color-text);
}
.qa-whole-note p + p { margin-top: var(--sp-2); }
.qa-whole-note__weight { font-weight: 700; }
/* "Priced in-store" shown in place of a cart-line total */
.cart-line__instore {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--color-coral);
  text-align: right;
}

/* ══════════════════════════════════════
   TWO-STEP FLOW (cart view ↔ checkout view) + sticky footer
══════════════════════════════════════ */
.cart-modal__back {
  width: 40px;
  height: 40px;
  margin-right: var(--sp-2);
  border-radius: var(--radius-full);
  background: rgba(255,255,255,0.1);
  border: none;
  color: var(--color-white);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background var(--t-fast);
}
.cart-modal__back:hover { background: rgba(255,255,255,0.22); }

/* Swap the two panes by the step recorded on #cart-panel */
.cart-modal[data-view="cart"]     .cart-modal__summary { display: none; }
.cart-modal[data-view="checkout"] .cart-modal__main    { display: none; }
.cart-modal[data-view="cart"]     #cart-place,
.cart-modal[data-view="cart"]     #cart-box-warning,
.cart-modal[data-view="cart"]     .cart-modal__back     { display: none; }
.cart-modal[data-view="checkout"] #cart-go-checkout,
.cart-modal[data-view="checkout"] #cart-clear           { display: none; }

/* Sticky footer shared by both steps */
.cart-modal__footer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-6);
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
}
.cart-modal__footer .cart-summary__total { padding-top: 0; border-top: none; }

/* "Go to checkout" button (cart step) */
.cart-go-checkout {
  width: 100%;
  padding: var(--sp-4);
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--color-teal), var(--teal-br));
  color: var(--color-white);
  border: none;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 12px rgba(10,122,143,0.35);
  transition: transform var(--t-fast), box-shadow var(--t-fast), opacity var(--t-fast);
}
.cart-go-checkout:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 5px 20px rgba(10,122,143,0.5); }
.cart-go-checkout:active:not(:disabled) { transform: scale(0.99); }
.cart-go-checkout:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: none; }

/* ══════════════════════════════════════
   STICKY "GO TO CART" BAR (mobile — replaces the FAB there)
══════════════════════════════════════ */
.cart-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-fab);
  display: none;                 /* shown only on mobile (see media query) */
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -4px 20px rgba(13,31,60,0.12);
}
.cart-bar__total {
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  font-weight: 900;
  color: var(--color-teal);
  white-space: nowrap;
}
.cart-bar__btn {
  flex: 1;
  padding: var(--sp-4);
  border: none;
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--color-teal), var(--teal-br));
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 3px 12px rgba(10,122,143,0.35);
  transition: transform var(--t-fast);
}
.cart-bar__btn:active { transform: scale(0.98); }

/* ══════════════════════════════════════
   RESPONSIVE
   Full-screen cart on narrow screens AND short ones (phones in landscape,
   where width > 767px would otherwise fall back to the centered desktop card).
══════════════════════════════════════ */
@media (max-width: 767px), (max-height: 600px) {
  .cart-modal { padding: 0; }
  .cart-modal__window {
    max-width: 100%;
    max-height: 100%;
    height: 100%;
    border-radius: 0;
  }
  /* Scroll the items + summary together as one column instead of two separate
     scroll panes (which also let the summary scroll sideways and "wobble"). */
  .cart-modal__content {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .cart-modal__main,
  .cart-modal__summary { overflow: visible; min-width: 0; }
  .cart-modal__summary { border-left: none; border-top: 1px solid var(--color-border); }
  /* Keep inputs (esp. datetime-local) from forcing horizontal overflow. */
  .cart-field__input { max-width: 100%; min-width: 0; }
}

/* On phones: drop the cart FAB, use the sticky "go to cart" bar instead. */
@media (max-width: 767px) {
  .cart-fab { display: none; }
  .cart-bar:not([hidden]) { display: flex; }
  body.has-cart-bar { padding-bottom: 76px; }
  body.has-cart-bar .cart-toast { bottom: calc(var(--sp-8) + 64px); }
}

/* ── Clickable product cards ── */
.fish-card,
.menu-card { cursor: pointer; }
.fish-card[data-status="unavailable"] { cursor: default; }

/* ── Added-to-cart toast ── */
.cart-toast {
  position: fixed;
  left: 50%;
  bottom: var(--sp-8);
  transform: translate(-50%, calc(100% + var(--sp-8)));
  z-index: calc(var(--z-cart) + 1);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  max-width: calc(100vw - var(--sp-8));
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--radius-full);
  background: var(--color-vegan);
  color: var(--color-white);
  font-size: var(--fs-sm);
  font-weight: 600;
  box-shadow: 0 6px 20px rgba(0,0,0,0.25);
  opacity: 0;
  pointer-events: none;
  transition: transform var(--t-fast), opacity var(--t-fast);
}
.cart-toast.is-visible {
  transform: translate(-50%, 0);
  opacity: 1;
}
.cart-toast__icon { flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  .cart-toast { transition: opacity var(--t-fast); }
}

/* ══════════════════════════════════════
   LIVELINESS ANIMATIONS
══════════════════════════════════════ */
@keyframes badge-bump { 0% { transform: scale(1); } 40% { transform: scale(1.45); } 100% { transform: scale(1); } }
.cart-fab__badge.is-bump { animation: badge-bump 320ms ease; }

@keyframes num-pop { 0% { transform: scale(1); } 45% { transform: scale(1.25); } 100% { transform: scale(1); } }
.is-pop { animation: num-pop 260ms ease; display: inline-block; }

@keyframes fab-pulse {
  0%, 100% { box-shadow: 0 4px 14px rgba(0,0,0,0.25); }
  50%      { box-shadow: 0 4px 22px rgba(255,107,53,0.55); }
}
.cart-fab.has-items { animation: fab-pulse 2.8s ease-in-out infinite; }

@keyframes line-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.cart-line--in { animation: line-in 280ms ease both; }

@keyframes line-out {
  to { opacity: 0; transform: translateX(24px); height: 0; margin: 0; padding-top: 0; padding-bottom: 0; }
}
.cart-line.is-removing { animation: line-out 240ms ease forwards; overflow: hidden; }

/* Fly-to-cart clone */
.fly-clone {
  position: fixed;
  z-index: calc(var(--z-cart) + 2);
  border-radius: var(--radius-md);
  overflow: hidden;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(0,0,0,0.3);
  background: linear-gradient(135deg, #0d4f6e 0%, #115f78 100%);
}
.fly-clone img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fly-clone__emoji {
  width: 100%; height: 100%;
  align-items: center; justify-content: center;
  font-size: 2rem;
}

@media (prefers-reduced-motion: reduce) {
  .cart-fab__badge.is-bump,
  .is-pop,
  .cart-fab.has-items,
  .cart-line--in,
  .cart-line.is-removing { animation: none; }
}

@media print {
  .cart-fab,
  .cart-modal,
  .cart-toast,
  .quick-add { display: none !important; }
}

/* ── Featured-promo banner (above the promo field) ── */
.cart-promo-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px dashed var(--color-teal);
  border-radius: var(--radius-md);
  background: rgba(10, 122, 143, 0.08);
  font-size: var(--fs-sm);
}
.cart-promo-banner[hidden] { display: none; }
.cart-promo-banner__apply {
  flex: 0 0 auto;
  border: none;
  border-radius: var(--radius-sm);
  padding: var(--sp-2) var(--sp-4);
  background: var(--color-teal);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
}
.cart-promo-banner__apply:hover { filter: brightness(1.05); }
.cart-promo-banner__apply:disabled { opacity: 0.5; cursor: default; }

/* A required group the guest was pointed at (flagMissing): red ring, hint underneath,
   one shake so the eye finds it after the scroll. The ring goes the moment it is filled. */
[data-missing] {
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 2px var(--field-error, #dc2626);
  padding: var(--sp-2);
  margin-left: calc(var(--sp-2) * -1);
  margin-right: calc(var(--sp-2) * -1);
}
.qa-missing-hint {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--field-error, #dc2626);
}
.qa-box-req > .qa-missing-hint { margin: 0 0 var(--sp-2); }
@keyframes qa-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(3px); }
}
.qa-shake { animation: qa-shake 420ms ease-out; }
@media (prefers-reduced-motion: reduce) { .qa-shake { animation: none; } }

/* The box's free gift row: "FREE" in the combo coral where a price would be. */
.qa-box-addon--gift .qa-box-addon__price { color: var(--color-coral); font-weight: 800; letter-spacing: 0.04em; }
