/* ============================================================
   Screen 2 — Menu
   ============================================================ */
:root { --app-bar-h: 62px; }

/* App bar: fixed height so the category nav can stick right below it */
.app-bar { height: var(--app-bar-h); }
.app-bar-inner { height: 100%; padding: 0 16px; gap: 10px; }

.app-logo { display: flex; align-items: center; min-width: 0; }
.app-logo img { max-height: 42px; max-width: 160px; width: auto; height: auto; object-fit: contain; }
.app-logo .brand-name { font-weight: 700; font-size: var(--fz-lg); }

.nav-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.nav-links { display: flex; align-items: center; gap: 2px; }
.nav-link { padding: 8px 12px; border-radius: var(--r-pill); font-size: var(--fz-sm); font-weight: 600; color: var(--text-muted); white-space: nowrap; transition: all var(--dur) var(--ease); }
.nav-link:hover { color: var(--text); background: var(--surface-2); }
.nav-burger { display: none; width: 44px; height: 44px; border-radius: 50%; place-items: center; color: var(--text); background: var(--surface-2); border: 1px solid var(--border); }
.nav-burger svg { width: 22px; height: 22px; }

/* Cart button */
.cart-btn { position: relative; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; color: var(--on-brand); background: var(--brand); flex-shrink: 0; box-shadow: 0 6px 16px -6px color-mix(in srgb, var(--brand) 70%, transparent); transition: transform var(--dur) var(--ease); }
.cart-btn:hover { transform: translateY(-1px); }
.cart-btn svg { width: 20px; height: 20px; }
.cart-count { position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: var(--r-pill); background: var(--text); color: var(--bg); font-size: 11px; font-weight: 800; display: grid; place-items: center; border: 2px solid var(--surface); }

/* Mobile nav dropdown */
@media (max-width: 820px) {
  .nav-links {
    position: absolute; top: calc(var(--app-bar-h) + 4px); right: 12px;
    flex-direction: column; align-items: stretch; gap: 2px; min-width: 210px; padding: 8px;
    /* Frosted, near-opaque so the nav labels stay readable over busy menu content. */
    background: color-mix(in srgb, var(--surface) 96%, transparent);
    -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
    border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
    display: none; z-index: 50;
  }
  .nav-open .nav-links { display: flex; }
  .nav-link { padding: 12px 14px; }
  .nav-burger { display: grid; }
}

/* Context bar */
.ctx-bar { max-width: 1100px; margin: 0 auto; padding: 10px 16px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--fz-sm); color: var(--text-muted); }
.ctx-bar strong { color: var(--text); }
.ctx-bar-change { color: var(--brand); font-weight: 600; }
.nav-link.active { color: var(--brand); background: var(--brand-softer); }
.ctx-bar-dot { opacity: .5; }

/* Banners carousel */
.banners { position: relative; max-width: 1100px; margin: 10px auto 0; padding: 0 16px; }
.banners-viewport { overflow: hidden; border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.banners-track { display: flex; transition: transform .45s var(--ease); }
.banner-slide { flex: 0 0 100%; display: block; }
/* Show the WHOLE banner at its true ratio (no cover-crop) so it fits any screen,
   incl. narrow mobile, even when the uploaded image isn't exactly 1200×360. */
.banner-slide img { width: 100%; height: auto; display: block; }
.banners-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; font-size: 24px; line-height: 1; color: var(--text); background: var(--glass-bg); border: 1px solid var(--glass-bd); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); z-index: 2; }
.banners-arrow.prev { left: 24px; }
.banners-arrow.next { right: 24px; }
.banners-dots { position: absolute; left: 0; right: 0; bottom: 12px; display: flex; justify-content: center; gap: 6px; z-index: 2; }
.banner-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, .55); border: 0; cursor: pointer; transition: all var(--dur) var(--ease); }
.banner-dot.active { background: #fff; width: 22px; border-radius: var(--r-pill); }
/* Banners render at their natural ratio (see .banner-slide img). Hide the arrows on small screens. */
@media (max-width: 560px) { .banners-arrow { display: none; } }

/* Sticky category nav (below the app bar) */
.cat-nav {
  position: sticky; top: var(--app-bar-h); z-index: 30;
  border: 0;
  background: var(--bg); /* matches the page — no distinct band */
}
.cat-nav-row {
  max-width: 1100px; margin: 0 auto; padding: 12px 16px;
  display: flex; flex-wrap: nowrap; gap: 8px;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; scroll-behavior: smooth;
  cursor: grab;
}
.cat-nav-row.dragging { cursor: grabbing; scroll-behavior: auto; user-select: none; }
.cat-nav-row::-webkit-scrollbar { display: none; }
/* Fade the edges to signal there's more to scroll (toggled by JS) */
.cat-nav-row.is-scrollable { -webkit-mask: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent); mask: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
.cat-nav-row.is-scrollable.at-start { -webkit-mask: linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask: linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
.cat-nav-row.is-scrollable.at-end { -webkit-mask: linear-gradient(90deg, transparent, #000 28px, #000); mask: linear-gradient(90deg, transparent, #000 28px, #000); }
.cat-pill {
  flex: 0 0 auto; padding: 9px 18px; border-radius: var(--r-pill);
  font-size: var(--fz-sm); font-weight: 600; color: var(--text-muted);
  background: var(--surface-2); border: 1px solid var(--border);
  white-space: nowrap; cursor: pointer; user-select: none;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.cat-pill:hover { color: var(--text); border-color: var(--border-strong); }
.cat-pill.active { color: var(--on-brand); background: var(--brand); border-color: var(--brand); box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--brand) 65%, transparent); }

/* Automatic-offer promo strip (under the category bar) */
.menu-offers { max-width: 1100px; margin: 12px auto 0; padding: 0 16px; display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; }
.menu-offers::-webkit-scrollbar { display: none; }
.moffer { flex: 0 0 auto; max-width: 340px; display: flex; align-items: center; gap: 11px; padding: 10px 14px; border-radius: var(--r-md); background: var(--brand-softer); border: 1px solid color-mix(in srgb, var(--brand) 24%, transparent); }
.moffer-ic { font-size: 18px; flex-shrink: 0; }
.moffer-text { display: flex; flex-direction: column; min-width: 0; }
.moffer-name { font-weight: 700; font-size: var(--fz-sm); color: var(--on-brand-soft); white-space: nowrap; }
.moffer-desc { font-size: var(--fz-xs); color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Menu body */
.menu-wrap { max-width: 1100px; margin: 0 auto; padding: 8px 16px 120px; }
.cat-section { scroll-margin-top: 130px; padding-top: 16px; }
.cat-head { margin: 6px 2px 14px; }
.cat-title { margin: 0; font-size: var(--fz-xl); font-weight: 800; letter-spacing: -.01em; }
.cat-banner { position: relative; aspect-ratio: 4 / 1; border-radius: var(--r-lg); background-size: cover; background-position: center; background-color: var(--surface-2); margin: 6px 2px 14px; overflow: hidden; }
/* On wider screens 4:1 makes the banner far too tall — cap it to a slim band. */
@media (min-width: 768px) { .cat-banner { aspect-ratio: auto; height: 170px; } }
.cat-banner::after { content: ''; position: absolute; inset: 0; background: linear-gradient(transparent 40%, rgba(0, 0, 0, .6)); }
.cat-banner-title { position: relative; z-index: 1; color: #fff; font-size: var(--fz-xl); font-weight: 800; text-shadow: 0 2px 10px rgba(0, 0, 0, .5); }

.product-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 170px), 1fr)); }

/* Product card */
.p-card { position: relative; display: flex; flex-direction: column; text-align: left; overflow: hidden; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.p-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.p-card:focus-within { border-color: var(--border-strong); }
/* Full-card "open customiser" control: a real button stretched over the card so the
   whole card is tappable/keyboard-activatable WITHOUT nesting it inside another control.
   The "+" button sits above it (higher z-index) as an independent action. */
.p-open { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; border-radius: var(--r-lg); }
.p-open:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.p-thumb { position: relative; aspect-ratio: 16 / 9; background-size: contain; background-repeat: no-repeat; background-position: center; background-color: var(--surface-2); }
.p-thumb--empty { background-image: linear-gradient(135deg, color-mix(in srgb, var(--brand) 14%, var(--surface)), var(--surface-2)); }

/* Placeholder icon for products with no image (when images are enabled). */
.p-thumb--empty::after,
.pm-thumb.is-empty::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 38px; height: 38px; opacity: .42;
  background-color: color-mix(in srgb, var(--brand) 60%, var(--text-muted));
  -webkit-mask: var(--img-placeholder) center / contain no-repeat;
          mask: var(--img-placeholder) center / contain no-repeat;
}
.pm-thumb.is-empty::after { width: 52px; height: 52px; }
:root {
  --img-placeholder: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='2'/%3E%3Ccircle cx='8.5' cy='8.5' r='1.6'/%3E%3Cpath d='m21 15-4.5-4.5L6 21'/%3E%3C/svg%3E");
}
.p-tag { position: absolute; top: 8px; left: 8px; padding: 3px 9px; border-radius: var(--r-pill); font-size: 10px; font-weight: 700; color: var(--on-brand); background: color-mix(in srgb, var(--brand) 88%, black); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.p-body { padding: 11px 13px 12px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
.p-name { margin: 0; font-size: var(--fz-md); font-weight: 700; }
.p-desc { margin: 0; font-size: var(--fz-sm); color: var(--text-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.p-foot { margin-top: auto; padding-top: 8px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.p-foot-l { display: flex; align-items: center; gap: 8px; min-width: 0; }
.p-price { font-weight: 800; font-size: var(--fz-md); }
.p-tag-inline { align-self: flex-start; margin: 2px 0; font-size: 10px; font-weight: 700; color: var(--on-brand-soft); background: var(--brand-soft); padding: 3px 8px; border-radius: var(--r-pill); white-space: nowrap; }
.p-add { position: relative; z-index: 2; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--brand-soft); color: var(--on-brand-soft); font-size: 20px; font-weight: 600; line-height: 1; flex-shrink: 0; border: 0; cursor: pointer; transition: all var(--dur) var(--ease); }
/* Keep the 32px visual, but expand the touch/click hit area to ≥44px. */
.p-add::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 44px; height: 44px; }
.p-add:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.p-card:hover .p-add, .p-add:hover { background: var(--brand); color: var(--on-brand); }
.p-card--noimg .p-body { padding-top: 14px; }

/* Empty states */
.menu-empty { max-width: 560px; margin: 0 auto; padding: 16vh 18px; }
.empty-card { border-radius: var(--r-xl); padding: 40px 32px; text-align: center; box-shadow: var(--shadow-md); }
.empty-card h2 { margin: 0 0 6px; }
.empty-card p { margin: 0; color: var(--text-muted); }

/* Product detail modal */
.modal-overlay { position: fixed; inset: 0; z-index: 90; background: rgba(8, 10, 14, .5); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: fade-in .2s var(--ease); }
@keyframes fade-in { from { opacity: 0; } }
/* Bottom sheet on mobile; becomes a centred dialog on desktop (media query below). */
.prod-modal {
  position: fixed; z-index: 100; left: 0; right: 0; bottom: 0;
  width: 100%; max-height: 92dvh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); color: var(--text);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--shadow-lg);
  animation: sheet-up .42s cubic-bezier(.22, 1.1, .36, 1) both;   /* spring-in */
}
@keyframes sheet-up { from { transform: translateY(100%); } }
@keyframes modal-in { from { opacity: 0; transform: translate(-50%, calc(-50% + 20px)); } }
.pm-grip { position: absolute; top: 9px; left: 50%; transform: translateX(-50%); z-index: 4; width: 40px; height: 4px; border-radius: 999px; background: rgba(255, 255, 255, .75); }

/* Photo-forward hero: the dish photo (or a warm gradient when there's none) with the title overlaid. */
.pm-hero { position: relative; flex: none; height: 200px; overflow: hidden;
  background: linear-gradient(150deg, #F7B733 0%, #EA5A2B 58%, #C2410C 100%); }
.pm-hero-img { position: absolute; inset: 0; --thumb-grad: linear-gradient(150deg, #F7B733, #C2410C);
  background-size: contain; background-position: center; background-repeat: no-repeat; }
.pm-hero-img.is-hidden { display: none; }
/* Title sits below the image (in the body) so a contained photo is never covered. */
.pm-name { margin: 0 0 4px; font-size: var(--fz-xl); font-weight: 800; line-height: 1.15; color: var(--text); }
.pm-from { margin: 0 0 8px; font-size: var(--fz-md); font-weight: 700; color: var(--text); }
.pm-from:empty { display: none; }
.pm-from .pm-was { color: var(--text-muted); text-decoration: line-through; font-weight: 600; margin-right: 6px; }
/* Base close button — themed, works on any light/dark surface
   (cart drawer, welcome modal, and the imageless product sheet). */
.modal-close { position: absolute; top: 14px; right: 14px; z-index: 5; width: 40px; height: 40px; border-radius: 50%; font-size: 22px; line-height: 1; display: grid; place-items: center; color: var(--text); background: var(--surface-2); border: 1px solid var(--border); cursor: pointer; transition: background .18s var(--ease), border-color .18s var(--ease); }
.modal-close:hover { background: var(--surface); border-color: var(--border-strong); }
.modal-close:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
/* Only when the product hero PHOTO is showing does the close overlay it → white/frosted. */
.prod-modal:not(.no-hero) .modal-close { color: #fff; background: rgba(255, 255, 255, .22); border: 0; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.prod-modal:not(.no-hero) .modal-close:hover { background: rgba(255, 255, 255, .34); }
.prod-modal:not(.no-hero) .modal-close:focus-visible { outline-color: #fff; }

/* No image to show (admin-disabled OR the product has none): drop the hero band; the base
   (themed) close applies, and the body gets top room for the grip + close. */
.prod-modal.no-hero .pm-hero { display: none; }
.prod-modal.no-hero .pm-body { padding-top: 46px; }
.prod-modal.no-hero .pm-grip { background: var(--border-strong); }

/* Only the body scrolls — hero + action bar stay put. */
.pm-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 14px 18px 10px; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
.pm-body::-webkit-scrollbar { width: 10px; }
.pm-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; border: 3px solid transparent; background-clip: padding-box; }
.pm-head { margin-bottom: 2px; }
.pm-desc { margin: 0; color: var(--text-muted); font-size: var(--fz-sm); line-height: 1.5; }
.pm-desc:empty { display: none; }
.pm-allergens { display: inline-block; margin-top: 10px; font-size: var(--fz-xs); color: var(--text-muted); background: var(--surface-2); border: 1px solid var(--border); padding: 6px 10px; border-radius: var(--r-pill); }
.pm-allergens strong { color: var(--text); }

/* "Required N of M chosen" progress — scrolls with the content (not sticky, so it
   can never overlap a modifier's title as you scroll). */
.pm-progress { display: flex; align-items: center; gap: 10px; margin: 12px 0 2px; padding: 8px 0; font-size: var(--fz-xs); font-weight: 600; color: var(--text-muted); }
.pm-progress[hidden] { display: none; }
.pm-progress strong { color: var(--text); font-weight: 700; }
.pm-progress-track { flex: 1; height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.pm-progress-fill { height: 100%; width: 0; border-radius: 999px; background: var(--brand); transition: width .45s cubic-bezier(.22, 1, .36, 1); }
.pm-progress-fill.done { animation: pm-glow .6s ease; }
@keyframes pm-glow { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 55%, transparent); } 100% { box-shadow: 0 0 0 7px transparent; } }

#pmTotal, .pm-was, .pm-opt-price { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
/* currentColor = the button's own text (--on-brand), NOT the muted grey that the generic
   .pm-was rule would otherwise hand it — grey-on-brand made the struck price invisible
   on the very button that advertises the saving. */
.pm-add .pm-was { color: currentColor; text-decoration: line-through; opacity: .72; font-weight: 600; margin-right: 5px; }

/* Cart drawer */
.drawer-overlay { position: fixed; inset: 0; z-index: 100; background: rgba(8, 10, 14, .5); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: fade-in .2s var(--ease); }
.cart-drawer { position: fixed; z-index: 110; top: 0; right: 0; height: 100dvh; width: min(400px, 100vw); transform: translateX(100%); transition: transform .32s var(--ease); display: flex; flex-direction: column; border-radius: 0; }
.cart-drawer.open { transform: translateX(0); }
.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--border); font-weight: 700; font-size: var(--fz-lg); }
.drawer-body { flex: 1; overflow-y: auto; padding: 20px; }
.cart-empty { text-align: center; color: var(--text-muted); padding: 18vh 12px; }
.cart-empty-ic { font-size: 40px; margin-bottom: 10px; }
.cart-empty p { margin: 0 0 4px; font-weight: 600; color: var(--text); }
.cart-empty span { font-size: var(--fz-sm); }

/* Customiser: modifier groups — all expanded (calm scroll, no accordion) */
.pm-groups { margin-top: 12px; display: flex; flex-direction: column; gap: 12px; }
.pm-group { border: 1.5px solid var(--border); border-radius: var(--r-md); padding: 14px; background: var(--surface); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.pm-group.invalid { border-color: #e5484d; box-shadow: 0 0 0 3px color-mix(in srgb, #e5484d 16%, transparent); }
.pm-group-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.pm-group-title { font-weight: 700; font-size: var(--fz-md); }
.pm-group.invalid .pm-group-title { color: #e5484d; }
/* Rule pill: "Required · choose 1" (amber) / "Optional · up to N" (neutral). */
.pm-rule { flex: none; font-size: var(--fz-xs); font-weight: 600; padding: 3px 10px; border-radius: var(--r-pill); white-space: nowrap; color: var(--text-muted); background: var(--surface-2); }
.pm-rule.req { color: #9a6212; background: color-mix(in srgb, #f5a524 18%, var(--surface)); }
[data-theme="dark"] .pm-rule.req { color: #f5c451; background: color-mix(in srgb, #f5a524 24%, var(--surface)); }
/* Live "chosen" summary under the head. */
.pm-chosen { margin: 4px 0 0; font-size: var(--fz-xs); font-weight: 600; color: var(--brand); }
.pm-chosen.is-empty { display: none; }
/* Visible validation error for an invalid modifier group. */
.pm-group-alert { display: none; align-items: center; gap: 6px; margin-top: 10px; font-size: var(--fz-sm); font-weight: 600; color: #e5484d; }
.pm-group.invalid .pm-group-alert { display: flex; }
.pm-group-alert .os-ic { color: #e5484d; }
[data-theme="dark"] .pm-group.invalid .pm-group-title, [data-theme="dark"] .pm-group-alert { color: #ff8a8a; }
/* Inline "couldn't load options" retry control. */
.pm-options-error { display: flex; align-items: center; gap: 8px; width: 100%; padding: 14px; border-radius: var(--r-md); font: inherit; font-size: var(--fz-sm); font-weight: 600; color: #e5484d; background: color-mix(in srgb, #e5484d 8%, var(--surface)); border: 1.5px solid color-mix(in srgb, #e5484d 40%, var(--border)); cursor: pointer; text-align: left; }
.pm-options-error:hover { background: color-mix(in srgb, #e5484d 14%, var(--surface)); }

/* Full-width option rows */
.pm-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.pm-opt { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface); border: 1.5px solid var(--border); cursor: pointer; text-align: left; font: inherit; transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), transform .08s var(--ease); }
.pm-opt:active { transform: scale(.99); }
.pm-opt.selected { border-color: var(--brand); background: var(--brand-softer); }
.pm-opt:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
@media (hover: hover) { .pm-opt:hover { border-color: var(--border-strong); } }
.pm-ind { flex: none; width: 22px; height: 22px; border: 2px solid var(--border-strong); display: grid; place-items: center; transition: all var(--dur) var(--ease); }
.pm-ind.radio { border-radius: 50%; }
.pm-ind.check { border-radius: 6px; }
.pm-opt.selected .pm-ind { border-color: var(--brand); background: var(--brand); }
.pm-opt.selected .pm-ind.radio::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--on-brand); }
.pm-opt.selected .pm-ind.check::after { content: '✓'; color: var(--on-brand); font-size: 13px; font-weight: 800; line-height: 1; }
.pm-opt-name { flex: 1; min-width: 0; overflow-wrap: break-word; font-size: var(--fz-md); }
.pm-opt-price { flex: none; white-space: nowrap; font-size: var(--fz-sm); font-weight: 700; color: var(--on-brand-soft); }
.pm-opt.selected .pm-opt-price { color: var(--brand); }
/* A capped option shows what it WAS beside what it costs now. The struck figure is
   deliberately muted+lighter so the price you'll actually pay still reads first. */
.pm-opt-price .pm-was { color: var(--text-muted); text-decoration: line-through; font-weight: 600; font-size: var(--fz-xs, 0.75rem); margin-right: 5px; }
/* Allow-multiple: per-value quantity steppers */
.pm-opt--step { cursor: default; }
.pm-step { flex: none; display: flex; align-items: center; gap: 10px; }
.pm-step-btn { width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid var(--border-strong); background: var(--surface); color: var(--text); font-size: 18px; font-weight: 700; line-height: 1; display: grid; place-items: center; cursor: pointer; transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), opacity var(--dur) var(--ease); }
@media (hover: hover) { .pm-step-btn:not(:disabled):hover { border-color: var(--brand); } }
.pm-step-btn.pm-inc { border-color: var(--brand); background: var(--brand); color: var(--on-brand); }
.pm-step-btn:disabled { opacity: .35; cursor: default; }
.pm-step-q { min-width: 20px; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }
/* Nested groups are no longer indented inside their parent — they're peers appended at
   the end of the flat sequence (see flatGroups() in menu.js). `.pm-nested` and
   `.pm-group--nested` are retired. This names the value that revealed the group, and is
   only printed when the parent allowed several picks (a radio parent like Size doesn't
   need it; a checkbox parent does, or two cards at the bottom are a riddle). */
.pm-group-for { margin-top: -2px; margin-bottom: 6px; font-size: var(--fz-xs, 0.75rem); font-weight: 600; color: var(--brand); text-transform: uppercase; letter-spacing: 0.04em; }

.pm-notes-label { display: block; margin: 16px 0 6px; font-size: var(--fz-sm); font-weight: 600; color: var(--text-muted); }
.pm-notes { width: 100%; resize: vertical; min-height: 44px; padding: 10px 12px; border: 1.5px solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font: inherit; font-size: var(--fz-sm); }
.pm-notes:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px var(--ring); }
/* iOS zooms any focused field under 16px — force ≥16px on touch/small screens. */
@media (max-width: 640px) {
  .pm-notes, .voucher-input { font-size: 16px; }
}

/* Quantity stepper */
.qty-stepper { display: flex; align-items: center; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-pill); padding: 4px; flex-shrink: 0; }
.qbtn { position: relative; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; font-size: 20px; font-weight: 600; color: var(--text); background: transparent; border: 0; cursor: pointer; transition: background var(--dur) var(--ease); }
.qbtn:hover { background: var(--surface); }
.qbtn:focus-visible { outline: 3px solid var(--ring); outline-offset: -2px; }
.qv { min-width: 24px; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; }

/* Sticky action bar */
.pm-foot { flex: none; padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); background: var(--surface); border-top: 1px solid var(--border); }
.pm-hint { align-items: center; gap: 6px; margin: 0 2px 8px; font-size: var(--fz-xs); font-weight: 600; color: #9a6212; }
.pm-hint[hidden] { display: none; }
.pm-hint:not([hidden]) { display: flex; }
[data-theme="dark"] .pm-hint { color: #f5c451; }
.pm-foot-row { display: flex; align-items: center; gap: 12px; }
.pm-add { flex: 1; --bh: 52px; gap: 6px; }
.pm-dot { opacity: .55; }

/* Desktop: a centred dialog instead of a bottom sheet. */
@media (min-width: 700px) {
  .prod-modal { left: 50%; right: auto; bottom: auto; top: 50%; transform: translate(-50%, -50%); width: min(560px, calc(100vw - 40px)); max-height: 88dvh; border-radius: var(--r-xl); animation: modal-in .28s var(--ease) both; }
  .pm-grip { display: none; }
}

/* ---- Delight / motion ---- */
/* Groups rise in on first render (flag-gated in JS so re-renders on tap don't replay). */
.pm-group.pm-anim { animation: pm-rise .42s var(--ease) both; }
@keyframes pm-rise { from { opacity: 0; transform: translateY(12px); } }
/* Springy tick when an option is selected. */
.pm-opt.selected .pm-ind::after { animation: pm-pop .34s cubic-bezier(.3, 1.6, .5, 1); }
@keyframes pm-pop { 0% { transform: scale(0); } 70% { transform: scale(1.25); } 100% { transform: scale(1); } }
/* CTA gently breathes once all required choices are made, drawing the tap. */
.pm-add.ready { animation: pm-breathe 1.9s ease-in-out infinite; }
@keyframes pm-breathe {
  0%, 100% { box-shadow: 0 8px 22px -8px color-mix(in srgb, var(--brand) 70%, transparent); }
  50% { box-shadow: 0 12px 32px -6px color-mix(in srgb, var(--brand) 92%, transparent); }
}
/* Success morph on add. */
/* The green "Added to order" morph is gone: it only existed to hold the sheet open for
   620ms, and the sheet is now closed immediately so the dish can fly across a clean
   menu. openProduct() still defensively clears .added, so re-adding a morph is a matter
   of restoring this rule and setting the class on success. */
/* The hint's up-arrow bobs to point at the unmet choice. */
.pm-hint .os-ic { animation: pm-bob 1.1s ease-in-out infinite; }
@keyframes pm-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* === Fly-to-cart ==========================================================
   A clone of the dish arcs from the card/sheet into the cart button. Two nested
   elements on purpose: the OUTER carries translateX on an ease-OUT curve while the
   INNER carries translateY on an ease-IN curve. Composing those two produces a real
   parabola — a single element can only travel in a straight line, which reads as a
   sliding sticker rather than a thrown object.
   Transform + opacity only, so it runs on the compositor and never triggers layout.
   z-index 350: above the sheet (100) and the loader (300); it must fly over both. */
.os-fly { position: fixed; z-index: 350; pointer-events: none; will-change: transform; }
.os-fly-i {
  width: 100%; height: 100%; border-radius: 50%;
  background-size: cover; background-position: center;
  box-shadow: 0 10px 26px rgba(0,0,0,0.28);
  will-change: transform, opacity;
}
.os-fly--go   { transition: transform 460ms cubic-bezier(.25,.6,.4,1); }          /* X: ease-out */
.os-fly--go .os-fly-i { transition: transform 460ms cubic-bezier(.55,.06,.7,.19), /* Y: ease-in  */
                                    opacity 460ms ease-in; }

/* The badge catches the item: a quick overshoot so the arrival is felt, not just seen. */
@keyframes cart-catch { 0% { transform: scale(1); } 42% { transform: scale(1.45); } 100% { transform: scale(1); } }
.cart-btn.is-catching { animation: cart-catch 380ms cubic-bezier(.34,1.56,.64,1); }
.cart-count.is-catching { animation: cart-catch 380ms cubic-bezier(.34,1.56,.64,1) 40ms; }

@media (prefers-reduced-motion: reduce) {
  /* No flight, no bounce — the count still updates, which is the actual information. */
  .os-fly { display: none; }
  .cart-btn.is-catching, .cart-count.is-catching { animation: none; }
}

/* Cart lines */
.cart-line { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border); }
.cart-line:first-child { padding-top: 0; }
.cl-main { flex: 1; min-width: 0; }
.cl-name { font-weight: 600; }
.cl-mods { font-size: var(--fz-sm); color: var(--text-muted); margin-top: 2px; }
.cl-mod-line { display: block; }
.cl-mod-name { font-weight: 600; color: var(--text); }
.cl-notes { font-size: var(--fz-xs); color: var(--text-muted); font-style: italic; margin-top: 2px; }
.cl-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.cl-price { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.cl-actions { display: flex; align-items: center; gap: 8px; }
.cl-remove { width: 34px; height: 34px; flex: 0 0 auto; border-radius: 50%; display: grid; place-items: center; color: var(--text-muted); background: transparent; border: 1px solid transparent; cursor: pointer; transition: color var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.cl-remove:hover { color: var(--error, #e5484d); background: color-mix(in srgb, var(--error, #e5484d) 10%, transparent); border-color: color-mix(in srgb, var(--error, #e5484d) 25%, transparent); }
.cl-remove:focus-visible { outline: 3px solid var(--ring); outline-offset: -2px; }
.cl-remove svg { display: block; }
.cl-qty { display: flex; align-items: center; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-pill); padding: 2px; }
.cl-qty .qbtn { width: 28px; height: 28px; font-size: 17px; }
/* Keep the compact 28px visual in the cart line, but expand the hit area to ≥44px. */
.cl-qty .qbtn::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 44px; height: 44px; }
.cl-qty .qv { min-width: 18px; font-size: var(--fz-sm); }

/* Cart footer */
.drawer-foot { border-top: 1px solid var(--border); padding: 16px 20px calc(16px + env(safe-area-inset-bottom)); background: var(--surface); }
.cart-row { display: flex; justify-content: space-between; font-size: var(--fz-sm); margin-bottom: 8px; }
.cart-row span:last-child, .cart-total span:last-child { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.cart-row.muted { color: var(--text-muted); }
.cart-total { font-size: var(--fz-lg); font-weight: 800; margin: 10px 0 14px; }
.cart-minwarn { background: color-mix(in srgb, #f5a524 14%, var(--surface)); border: 1px solid color-mix(in srgb, #f5a524 45%, var(--border)); color: var(--text); font-size: var(--fz-sm); padding: 10px 12px; border-radius: var(--r-sm); margin-bottom: 12px; }
.cart-freedel { background: color-mix(in srgb, #12b76a 12%, var(--surface)); border: 1px solid color-mix(in srgb, #12b76a 38%, var(--border)); color: var(--text); font-size: var(--fz-sm); font-weight: 600; padding: 10px 12px; border-radius: var(--r-sm); margin-bottom: 12px; text-align: center; }
.cart-freedel.is-free { background: color-mix(in srgb, #12b76a 22%, var(--surface)); border-color: color-mix(in srgb, #12b76a 60%, var(--border)); color: #0a7f4f; }

/* Voucher + discounts */
.voucher-box { margin-bottom: 14px; }
.voucher-row { display: flex; gap: 8px; }
.voucher-input { flex: 1; min-width: 0; min-height: 44px; padding: 0 14px; border: 1.5px solid var(--border); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font: inherit; text-transform: uppercase; }
.voucher-input::placeholder { text-transform: none; }
.voucher-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px var(--ring); }
.voucher-btn { --bh: 44px; flex-shrink: 0; padding: 0 18px; }
.voucher-applied { display: flex; align-items: center; gap: 8px; font-size: var(--fz-sm); color: var(--on-brand-soft); background: var(--brand-softer); border: 1px solid color-mix(in srgb, var(--brand) 22%, transparent); padding: 11px 13px; border-radius: var(--r-sm); }
.voucher-applied strong { color: var(--text); }
.voucher-remove { margin-left: auto; font-size: var(--fz-xs); font-weight: 700; color: var(--text-muted); text-decoration: underline; background: none; }
.voucher-remove:hover { color: var(--text); }
.voucher-msg { margin-top: 8px; font-size: var(--fz-sm); color: var(--text-muted); }
.voucher-msg.err { color: #e5484d; }
.discount-row { color: #0a8a4f; font-weight: 600; }
[data-theme="dark"] .discount-row { color: #5fe3a1; }
.free-line .free-badge { font-size: 10px; font-weight: 800; color: #fff; background: #12b76a; padding: 2px 7px; border-radius: var(--r-pill); margin-left: 6px; vertical-align: middle; }

/* Toast */
/* Toast lives at the TOP by default (mobile + tablet), sliding down — this keeps it clear of the
   bottom "goes well with" upsell snackbar, which they used to collide with at bottom-centre. */
.toast { pointer-events: none; position: fixed; left: 50%; top: calc(14px + env(safe-area-inset-top)); bottom: auto; transform: translateX(-50%) translateY(-160%); z-index: 200; padding: 12px 18px; border-radius: var(--r-lg); font-weight: 600; font-size: var(--fz-sm); background: var(--text); color: var(--bg); box-shadow: var(--shadow-lg); opacity: 0; transition: opacity .25s var(--ease), transform .25s var(--ease); }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.toast-success { background: #12b76a; color: #fff; }
/* Desktop (wide enough that it can't overlap the centred snackbar): dock the toast bottom-LEFT and
   slide it in FROM the left, so "Added to your order" no longer sits on top of the suggestions. */
@media (min-width: 1024px) {
  .toast { left: 24px; top: auto; bottom: calc(24px + env(safe-area-inset-bottom)); transform: translateX(-160%); }
  .toast.show { transform: translateX(0); }
}

/* ---- Timed pricing (price rules) — struck original + offer tag ---- */
.p-was { color: var(--text-muted); text-decoration: line-through; font-weight: 600; font-size: var(--fz-sm); margin-right: 4px; }
.p-price--offer { color: #c2282c; }
.p-offer-tag { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: var(--r-pill); font-size: var(--fz-xs); font-weight: 800; letter-spacing: .02em; background: #fdecec; color: #c2282c; vertical-align: middle; }
.cl-was { color: var(--text-muted); text-decoration: line-through; font-weight: 600; font-size: var(--fz-xs); margin-right: 4px; }
.pm-was { color: var(--text-muted); text-decoration: line-through; font-weight: 600; opacity: .8; margin-right: 6px; }

/* ---- Welcome / sign-in invite (guests) ---- */
.welcome-overlay { position: fixed; inset: 0; z-index: 110; background: rgba(8, 10, 14, .55); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: fade-in .2s var(--ease); }
.welcome-modal { position: fixed; z-index: 111; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(440px, calc(100vw - 32px)); max-height: 90dvh; overflow-y: auto; overscroll-behavior: contain; padding: 26px 22px 20px; border-radius: var(--r-xl); box-shadow: var(--shadow-lg); animation: modal-in .28s var(--ease) both; }
/* Thin, themed, inset scrollbar — matches the product modal (.pm-body). */
.welcome-modal { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
.welcome-modal::-webkit-scrollbar { width: 10px; }
.welcome-modal::-webkit-scrollbar-track { background: transparent; }
.welcome-modal::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; border: 3px solid transparent; background-clip: padding-box; }
.welcome-modal::-webkit-scrollbar-thumb:hover { background: var(--text-muted); background-clip: padding-box; }
.welcome-modal .modal-close { position: absolute; top: 10px; right: 12px; }
.welcome-hero { text-align: center; margin-bottom: 18px; }
.welcome-emoji { display: block; font-size: 40px; line-height: 1; margin-bottom: 8px; }
.welcome-title { margin: 0 0 6px; font-size: var(--fz-xl); }
.welcome-sub { margin: 0; color: var(--text-muted); font-size: var(--fz-sm); line-height: 1.5; }
.welcome-perks { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 13px; }
.welcome-perks li { display: flex; gap: 12px; align-items: flex-start; }
.welcome-perks .wp-ic { flex: 0 0 38px; width: 38px; height: 38px; display: grid; place-items: center; font-size: 18px; border-radius: 50%; background: var(--brand-softer); }
.welcome-perks div { display: flex; flex-direction: column; gap: 1px; }
.welcome-perks strong { font-size: var(--fz-sm); color: var(--text); }
.welcome-perks div span { color: var(--text-muted); font-size: var(--fz-xs); line-height: 1.4; }
.welcome-actions { display: grid; gap: 10px; }
.welcome-guest { margin-top: 2px; background: none; border: 0; color: var(--text-muted); font: inherit; font-size: var(--fz-sm); padding: 8px; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.welcome-guest:hover { color: var(--text); }
body.welcome-open { overflow: hidden; }

/* Fallback for the `inert` attribute in engines that don't yet support it natively
   (native support neutralises pointer + focus itself). */
[inert] { pointer-events: none; cursor: default; user-select: none; }

/* ============================================================
   Upsells — cart strip ("You might also like") + after-add snackbar
   ============================================================ */
.cart-upsell { margin: 4px 0 12px; }
.us-title { font-size: var(--fz-xs); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 8px; }
.us-row { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.us-row::-webkit-scrollbar { display: none; }
.us-card {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  max-width: 220px; padding: 6px 8px; border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text); cursor: pointer; text-align: left;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.us-card:hover { border-color: var(--brand); }
.us-card:active { transform: scale(.97); }
.us-thumb { flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-sm); background-size: cover; background-position: center; background-color: var(--img-placeholder); }
.us-thumb-none { display: grid; place-items: center; color: var(--text-muted); background: var(--surface-2); }
.us-info { display: flex; flex-direction: column; min-width: 0; }
.us-name { font-size: var(--fz-sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.us-price { font-size: var(--fz-xs); color: var(--text-muted); }
.us-was { text-decoration: line-through; opacity: .6; margin-right: 3px; }
.us-add { flex: 0 0 auto; width: 24px; height: 24px; border-radius: var(--r-pill); display: grid; place-items: center; font-size: 18px; line-height: 1; font-weight: 700; background: var(--brand); color: var(--on-brand); }

/* After-add snackbar (phase 2a) — non-modal, bottom-centred. SOLID + high-contrast (the old
   frosted-glass version washed out over the menu and was barely readable). */
.upsell-snack {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom)); transform: translate(-50%, 175%);
  /* z-index 85: above the menu, but BELOW the product modal (100) and cart drawer (110) so it can
     never float over their "Add to order" / "Go to checkout" buttons and swallow the click. */
  z-index: 85; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  width: max-content; max-width: min(560px, calc(100vw - 20px)); padding: 12px 14px;
  background: var(--surface); border: 1.5px solid var(--brand-softer, var(--border));
  border-radius: var(--r-lg); box-shadow: 0 18px 44px -14px rgba(16,24,40,.34), 0 2px 8px rgba(16,24,40,.10);
  opacity: 0; transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.upsell-snack.show { transform: translate(-50%, 0); opacity: 1; }
.uk-lead { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fz-sm); font-weight: 700; color: var(--text); }
.uk-chip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 8px 13px;
  border: 1.5px solid var(--border-strong, var(--border)); border-radius: var(--r-pill); background: var(--surface-2);
  color: var(--text); font-size: var(--fz-sm); font-weight: 600; cursor: pointer;
}
.uk-chip:hover { border-color: var(--brand); background: var(--brand-softer, var(--surface-2)); }
.uk-chip:active { transform: scale(.97); }
.uk-plus { color: var(--brand); font-weight: 800; }
.uk-close { margin-left: 2px; width: 30px; height: 30px; flex: 0 0 auto; border: none; background: transparent; color: var(--text-muted); font-size: 20px; line-height: 1; cursor: pointer; border-radius: var(--r-pill); }
.uk-close:hover { background: var(--surface-2); color: var(--text); }
/* Mobile: sit just above the app bar / cart button, near full-width so it's obvious and tappable. */
@media (max-width: 560px) {
  .upsell-snack { left: 10px; right: 10px; transform: translateY(175%); max-width: none; width: auto; }
  .upsell-snack.show { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .upsell-snack { transition: opacity var(--dur) var(--ease); } }
