/* ═══════════════════════════════════════════════════════════════
   Gatti@yzer — design system
   Self-contained: no external fonts, no CDN icons. Works fully offline,
   which matters for a locally-hosted shop with no internet guarantee.
   ═══════════════════════════════════════════════════════════════ */

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

:root {
  --brand:        #C8233C;
  --brand-strong: #a81c31;
  --brand-soft:   #fdeef0;
  --brand-ink:    #7a1523;

  --surface-0: #f6f5f3;
  --surface-1: #efedea;
  --surface-2: #ffffff;
  --surface-3: #ffffff;

  /* The cinematic hero's backdrop, and it is DELIBERATELY THE SAME IN BOTH
     THEMES. It was a bare #100f0e sitting in .cine-hero, which read as an
     oversight — the tokens beside it all flip and that one hex did not.
     It is not an oversight, it is a stage: the hero is white text and product
     photographs laid over it, and a light backdrop puts white type on near-white
     and loses the words on the first screen of the site. Cinemas are dark for
     the same reason.
     Named so the next person can see the decision instead of a stray colour, and
     change it in one place if the hero ever stops being photographic. */
  --hero-stage: #100f0e;
  --border:        rgba(0,0,0,0.10);
  --border-strong: rgba(0,0,0,0.20);
  --text-primary:   #1a1a18;
  --text-secondary: #55524d;
  --text-muted:     #8f8b83;

  --ok-bg: #eaf3de; --ok-fg: #3b6d11; --ok-bd: #c0dd97;
  --warn-bg:#faeeda; --warn-fg:#854f0b;
  --info-bg:#e6f1fb; --info-fg:#185fa5;
  --teal-bg:#e1f5ee; --teal-fg:#0f6e56;
  --err-bg: #fcebeb; --err-fg: #a32d2d; --err-bd:#f7c1c1;

  --radius:   10px;
  --radius-lg:16px;
  --radius-sm:7px;
  --shadow-1: 0 1px 2px rgba(0,0,0,0.04), 0 1px 3px rgba(0,0,0,0.06);
  --shadow-2: 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04);
  --shadow-pop: 0 12px 40px rgba(0,0,0,0.18);

  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --nav-h: 60px;
  --maxw: 1120px;
  --t-fast: 0.15s ease;
  --t: 0.22s cubic-bezier(0.4,0,0.2,1);
}

:root[data-mode="dark"] {
  --brand:        #e8394f;
  --brand-strong: #f04b60;
  --brand-soft:   #2a0c11;
  --brand-ink:    #f5a7b2;

  --surface-0: #100f0e;
  --surface-1: #1a1917;
  --surface-2: #222120;
  --surface-3: #2b2a28;
  --border:        rgba(255,255,255,0.10);
  --border-strong: rgba(255,255,255,0.22);
  --text-primary:   #f1efec;
  --text-secondary: #b0aca5;
  --text-muted:     #6f6b64;

  --ok-bg:#16300a; --ok-fg:#8ecf58; --ok-bd:#2c5416;
  --warn-bg:#3a2a0e; --warn-fg:#e0a94b;
  --info-bg:#0e2740; --info-fg:#6fb0e8;
  --teal-bg:#0c2f26; --teal-fg:#4fc9a6;
  --err-bg:#3a1414; --err-fg:#f08a8a; --err-bd:#5c2020;

  --shadow-1: 0 1px 2px rgba(0,0,0,0.4);
  --shadow-2: 0 4px 14px rgba(0,0,0,0.5);
  --shadow-pop: 0 12px 44px rgba(0,0,0,0.6);
}

html { scroll-behavior: smooth; }
body {
  font-family: var(--font);
  background: var(--surface-0);
  color: var(--text-primary);
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background var(--t), color var(--t);
}
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
svg.icon { width: 1.15em; height: 1.15em; stroke: currentColor; fill: none;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }

/* ── Layout ─────────────────────────────────────────────────── */
.app { display: flex; flex-direction: column; min-height: 100vh; }
.main { flex: 1; width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 1.5rem 1.25rem 4rem; }
.container-narrow { max-width: 640px; margin: 0 auto; }

/* ── Header / nav ───────────────────────────────────────────── */
nav.topnav {
  position: sticky; top: 0; z-index: 100;
  height: var(--nav-h);
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0 1.25rem;
  background: color-mix(in srgb, var(--surface-2) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--border);
}
.brand {
  font-size: 21px; font-weight: 700; letter-spacing: -0.02em;
  color: var(--brand); cursor: pointer; user-select: none; white-space: nowrap;
}
.brand span { color: var(--text-primary); }
.nav-spacer { flex: 1; }
.nav-links { display: flex; gap: 0.15rem; align-items: center; }
.nav-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--text-secondary);
  padding: 7px 12px; border-radius: var(--radius-sm);
  transition: background var(--t-fast), color var(--t-fast); white-space: nowrap;
}
.nav-btn:hover { background: var(--surface-1); color: var(--text-primary); }
.nav-btn.active { color: var(--brand); font-weight: 600; }
.nav-btn.active svg { color: var(--brand); }
.cart-btn { position: relative; }
.cart-badge {
  position: absolute; top: 1px; right: 2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--brand); color: #fff; border-radius: 9px;
  font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.token-pill {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--teal-bg); color: var(--teal-fg);
  font-size: 13px; font-weight: 600; padding: 5px 11px; border-radius: 20px;
}
.icon-btn {
  display: inline-grid; place-items: center;
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  background: none; border: none; cursor: pointer; color: var(--text-secondary);
  transition: background var(--t-fast);
}
.icon-btn:hover { background: var(--surface-1); color: var(--text-primary); }

/* The brand may shrink but never pushes the account controls off-screen.
   NOTE: do NOT put overflow:hidden on nav.topnav — it has a backdrop-filter,
   which makes it the containing block for the fixed mobile drawer, and
   overflow:hidden would then clip the whole drawer to nothing. */
.brand { min-width: 0; overflow: hidden; text-overflow: ellipsis; flex-shrink: 1; }
/* Account actions duplicated into the mobile drawer; hidden on desktop. */
.drawer-extra { display: none; }

/* Mobile nav drawer toggle */
/* ── The mobile menu button ───────────────────────────────────
   Hidden entirely on desktop, where the nav links sit in the bar.

   On a phone it is a bordered pill with the word "Menu", not a bare ☰. A
   first-time visitor does not recognise three grey lines as a control, and this
   button is the only route to Store, Delivery, Orders and Account on a phone —
   missing it means missing the site.

   .is-hint is added by app.js for a visitor who has never opened it, and
   removed for good the first time they do. It draws a soft ring three times and
   then stops on its own: enough to catch the eye once, not a thing that keeps
   moving while somebody is trying to read. Motion is dropped entirely under
   prefers-reduced-motion, where the ring simply rests visible instead. */
.nav-toggle { display: none; }

@media (max-width: 860px) {
  nav.topnav { gap: 0.4rem; padding: 0 0.8rem; }

  /* Icon ABOVE the label, not beside it. Side by side this pill measured 81px,
     which left the brand 7px of clearance at 375px and truncated "Gatti@yzer"
     outright at 320px (measured on the live site, not estimated). Stacked it is
     44px — 37px handed straight back to the brand — and the taller box is a
     better touch target as well: 40px against the old 34px, where 44px is the
     usual minimum.

     The WORD stays. See the note above: a bare ☰ is not recognised as a control
     by a first-time visitor, and this button is the only way to reach Store,
     Delivery, Orders and Account on a phone. Shrinking it must not mean
     deleting the one thing that says what it is. */
  .nav-toggle {
    display: inline-flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 1px;
    width: auto; min-width: 44px; height: 40px; padding: 0 6px;
    /* Not 999px any more: a pill that is nearly as tall as it is wide reads as
       a lozenge rather than a button. A rounded rectangle suits the new shape. */
    border: 1px solid var(--border); border-radius: 14px;
    /* background-COLOR, not the `background` shorthand. The shorthand resets
       background-image/size/position too, and a var() inside it that fails to
       resolve invalidates the whole declaration rather than just the colour. */
    background-color: var(--surface-1); color: var(--text-primary);
    font: inherit; font-size: 13.5px; font-weight: 600; line-height: 1;
  }
  .nav-toggle .icon { width: 16px; height: 16px; }
  .nav-toggle-label { font-size: 9.5px; letter-spacing: 0.03em; line-height: 1; }

  /* Pressed state reads as "this is open", so the pill and the drawer agree. */
  .nav-toggle[aria-expanded="true"] {
    background-color: var(--brand); border-color: var(--brand); color: #fff;
  }
  /* .icon-btn transitions `background`; name the same longhand here so the
     open/close colour change actually eases instead of snapping. */
  .nav-toggle { transition: background-color var(--t-fast), border-color var(--t-fast); }

  .nav-toggle.is-hint {
    animation: navHint 2.1s ease-out 3;
  }
  @keyframes navHint {
    0%        { box-shadow: 0 0 0 0 rgba(200, 35, 60, 0.42); }
    38%, 100% { box-shadow: 0 0 0 9px rgba(200, 35, 60, 0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .nav-toggle.is-hint {
      animation: none;
      box-shadow: 0 0 0 3px rgba(200, 35, 60, 0.28);
    }
  }
  .nav-links {
    position: fixed; inset: var(--nav-h) 0 auto 0; z-index: 200;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: var(--surface-2); border-bottom: 1px solid var(--border);
    padding: 8px; box-shadow: var(--shadow-2);
    max-height: calc(100vh - var(--nav-h)); overflow-y: auto;
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity var(--t), transform var(--t);
  }
  .nav-links.open { transform: translateY(0); opacity: 1; pointer-events: auto; }
  .nav-btn { padding: 11px 14px; font-size: 15px; }

  /* Show account actions inside the drawer; hide the secondary ones from the
     top bar so it fits. Only the wallet chip (or Sign in) stays up top. */
  .nav-links .drawer-extra { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--border); }
  .acct-secondary { display: none !important; }
  .token-pill { font-size: 12px; padding: 4px 9px; }
  .acct-signin span { display: inline; }
}
/* Very narrow phones: drop the wallet number to just the coin to save space. */
@media (max-width: 380px) {
  .token-amt { display: none; }
}

/* ── Typography ─────────────────────────────────────────────── */
h1 { font-size: clamp(22px, 3vw, 28px); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 1.25rem; }
h2 { font-size: 19px; font-weight: 600; margin-bottom: 1rem; }
h3 { font-size: 16px; font-weight: 600; margin-bottom: 0.6rem; }
.muted { color: var(--text-secondary); }
.small { font-size: 13px; }
.lead { font-size: 16px; color: var(--text-secondary); }
.section-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }

/* ── Buttons ────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: inherit; font-size: 14px; font-weight: 500;
  padding: 9px 16px; border-radius: var(--radius);
  border: 1px solid var(--border-strong); background: var(--surface-2);
  color: var(--text-primary); cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
}
.btn:hover { background: var(--surface-1); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.btn-primary { background: var(--brand); color: #fff; border-color: var(--brand); box-shadow: var(--shadow-1); }
.btn-primary:hover { background: var(--brand-strong); border-color: var(--brand-strong); }
.btn-ghost { background: none; border-color: transparent; }
.btn-ghost:hover { background: var(--surface-1); }
.btn-danger { color: var(--err-fg); border-color: var(--err-bd); }
.btn-danger:hover { background: var(--err-bg); }
.btn-sm { padding: 6px 11px; font-size: 13px; }
.btn-lg { padding: 12px 22px; font-size: 15px; }
.btn-block { width: 100%; }

/* ── Forms ──────────────────────────────────────────────────── */
.field { margin-bottom: 1rem; }
.field label { display: block; font-size: 13px; font-weight: 500; color: var(--text-secondary); margin-bottom: 5px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
input, select, textarea {
  width: 100%; font: inherit; font-size: 14px;
  padding: 9px 12px; border-radius: var(--radius);
  border: 1px solid var(--border-strong); background: var(--surface-2);
  color: var(--text-primary); outline: none;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
input::placeholder, textarea::placeholder { color: var(--text-muted); }
input:focus, select:focus, textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent);
}
input:disabled { opacity: 0.6; cursor: not-allowed; }
.field-hint { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
@media (max-width: 520px) { .field-row { grid-template-columns: 1fr; } }

/* ── Cards ──────────────────────────────────────────────────── */
.card {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 1.25rem; box-shadow: var(--shadow-1);
}
.card-pad-lg { padding: 1.75rem; }

/* ── Badges & pills ─────────────────────────────────────────── */
.badge { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 20px; }
.badge-brand { background: var(--brand-soft); color: var(--brand-ink); }
.badge-ok   { background: var(--ok-bg);   color: var(--ok-fg); }
.badge-warn { background: var(--warn-bg); color: var(--warn-fg); }
.badge-info { background: var(--info-bg); color: var(--info-fg); }
.badge-teal { background: var(--teal-bg); color: var(--teal-fg); }
.badge-err  { background: var(--err-bg);  color: var(--err-fg); }

/* Town chips are real <a href> elements now (each town has its own page and a
   crawler has to be able to follow it), so they need the link decoration undone
   and a hover state a badge never had. */
.town-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
a.town-chip {
  text-decoration: none; cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .15s ease;
}
a.town-chip:hover { background: var(--brand); color: #fff; transform: translateY(-1px); }
a.town-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── Breadcrumbs ─────────────────────────────────────────────
   On the town pages. Also what Google reads to draw the little
   Home › Delivery › Langebaan trail under a search result. */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center;
  font-size: 13px; color: var(--text-muted); margin: 0 0 1rem;
}
.crumbs a { color: var(--text-secondary); text-decoration: none; }
.crumbs a:hover { color: var(--brand); text-decoration: underline; }
.crumb-sep { opacity: .5; margin: 0 .45rem; }

/* ── Alerts ─────────────────────────────────────────────────── */
.alert { display: flex; align-items: flex-start; gap: 8px; padding: 10px 13px; border-radius: var(--radius); font-size: 14px; margin-bottom: 1rem; border: 1px solid transparent; }
.alert-ok  { background: var(--ok-bg);  color: var(--ok-fg);  border-color: var(--ok-bd); }
.alert-err { background: var(--err-bg); color: var(--err-fg); border-color: var(--err-bd); }
.alert-info{ background: var(--info-bg);color: var(--info-fg); }

/* ── Modal ──────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,0.5); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; padding: 1rem;
  animation: fadeIn var(--t-fast);
}
.modal {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-pop);
  width: 100%; max-width: 440px; max-height: 92vh; overflow-y: auto;
  padding: 1.5rem; animation: popIn var(--t);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; }
.modal-head h2 { margin: 0; }
.modal-foot { display: flex; gap: 0.6rem; justify-content: flex-end; margin-top: 1.5rem; }
.divider { height: 1px; background: var(--border); margin: 1.1rem 0; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: translateY(10px) scale(0.985); } to { opacity: 1; transform: none; } }

/* ── Hero (home) ────────────────────────────────────────────── */
.hero {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg); padding: 3rem 2rem;
  background:
    radial-gradient(120% 140% at 100% 0%, color-mix(in srgb, var(--brand) 22%, transparent), transparent 55%),
    linear-gradient(135deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border); box-shadow: var(--shadow-1); margin-bottom: 2rem;
}
.hero h1 { font-size: clamp(28px, 5vw, 44px); line-height: 1.08; margin-bottom: 0.9rem; }
.hero p { font-size: clamp(15px, 2vw, 18px); color: var(--text-secondary); max-width: 46ch; margin-bottom: 1.6rem; }
.hero-cta { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.hero-emoji { position: absolute; right: -10px; bottom: -20px; font-size: 190px; opacity: 0.10; pointer-events: none; user-select: none; }

/* ── Info strip ─────────────────────────────────────────────── */
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; }
.info-tile { display: flex; gap: 0.85rem; align-items: flex-start; padding: 1.1rem; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.info-tile .ico { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; background: var(--brand-soft); color: var(--brand); flex-shrink: 0; }
.info-tile .ico svg { width: 20px; height: 20px; }
.info-tile h3 { margin-bottom: 2px; }
.info-tile p { font-size: 13px; color: var(--text-secondary); }

/* ── Utilities ──────────────────────────────────────────────── */
.stack > * + * { margin-top: 1rem; }
.row { display: flex; gap: 0.75rem; align-items: center; }
.wrap { flex-wrap: wrap; }
.between { justify-content: space-between; }
.center { text-align: center; }
.mt-1 { margin-top: 0.5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.hidden { display: none !important; }
.empty-state { text-align: center; padding: 3rem 1rem; color: var(--text-secondary); }
.empty-state svg { width: 40px; height: 40px; opacity: 0.5; margin-bottom: 0.75rem; }

/* ── Spinner & loading ──────────────────────────────────────── */
.spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid color-mix(in srgb, currentColor 30%, transparent); border-top-color: currentColor; border-radius: 50%; animation: spin 0.6s linear infinite; }
.spinner-lg { width: 26px; height: 26px; border-width: 3px; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading-overlay { position: fixed; inset: 0; z-index: 300; background: rgba(0,0,0,0.28); display: flex; align-items: center; justify-content: center; }
.loading-box { display: flex; align-items: center; gap: 0.85rem; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.5rem; box-shadow: var(--shadow-pop); font-size: 14px; }

/* ── Toast ──────────────────────────────────────────────────── */
.toast-wrap { position: fixed; bottom: 1.25rem; left: 50%; transform: translateX(-50%); z-index: 400; display: flex; flex-direction: column; gap: 0.5rem; align-items: center; width: max-content; max-width: 92vw; }
.toast { display: flex; align-items: center; gap: 8px; padding: 10px 15px; border-radius: var(--radius); box-shadow: var(--shadow-pop); font-size: 14px; font-weight: 500; animation: toastIn var(--t); border: 1px solid var(--border); }
.toast-ok  { background: var(--ok-bg);  color: var(--ok-fg);  border-color: var(--ok-bd); }
.toast-err { background: var(--err-bg); color: var(--err-fg); border-color: var(--err-bd); }
.toast-info{ background: var(--surface-2); color: var(--text-primary); }
@keyframes toastIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* ── Theme toggle switch ────────────────────────────────────── */
.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; background: var(--border-strong); border-radius: 12px; cursor: pointer; transition: background var(--t-fast); }
.switch .track::before { content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: transform var(--t); box-shadow: var(--shadow-1); }
.switch input:checked + .track { background: var(--brand); }
.switch input:checked + .track::before { transform: translateX(18px); }

/* ── Store page ─────────────────────────────────────────────── */
.mb-2 { margin-bottom: 1.25rem; }
.ph-emoji { width: 100%; height: 100%; display: grid; place-items: center; }

/* Promo timer banner */
.promo-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  background: linear-gradient(120deg, var(--brand), var(--brand-strong));
  color: #fff; border-radius: var(--radius-lg); padding: 1.1rem 1.4rem; margin-bottom: 1.5rem;
  box-shadow: var(--shadow-2);
}
.promo-title { font-weight: 700; font-size: 16px; display: flex; align-items: center; gap: 7px; }
.promo-sub { font-size: 13px; opacity: 0.9; margin-top: 2px; }
.promo-clock { display: flex; gap: 7px; }
.promo-unit { background: rgba(0,0,0,0.22); border-radius: 9px; padding: 7px 11px; text-align: center; min-width: 52px; }
.promo-unit span { font-size: 21px; font-weight: 700; display: block; line-height: 1.1; font-variant-numeric: tabular-nums; }
.promo-unit small { font-size: 10px; opacity: 0.85; text-transform: uppercase; letter-spacing: 0.04em; }

/* Filters */
.store-filters { display: flex; gap: 0.7rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.search-wrap { position: relative; flex: 1; min-width: 200px; }
.search-wrap .search-ic { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.search-wrap input { padding-left: 36px; }
.store-filters select { width: auto; min-width: 170px; }

/* Category sections */
.cat-section { margin-bottom: 1.5rem; }
.cat-head { margin-bottom: 0.6rem; }
.cat-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; padding: 4px 12px; border-radius: 20px; }

/* Product row (list) */
.p-row {
  display: flex; align-items: center; gap: 0.9rem;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.7rem 0.9rem; margin-bottom: 0.55rem; transition: border-color var(--t-fast), transform var(--t-fast);
}
.p-row:hover { border-color: var(--border-strong); }
.p-thumb { position: relative; width: 48px; height: 48px; border-radius: 9px; overflow: hidden; flex-shrink: 0; display: grid; place-items: center; }
.p-row.is-soldout { opacity: 0.62; }
.p-row.is-soldout .p-thumb img, .offer-card .p-thumb img { filter: grayscale(0.4); }
.soldout-tag { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(0,0,0,0.45); color: #fff; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
.p-thumb .ph-emoji { font-size: 26px; }
.p-info { flex: 1; min-width: 0; }
.p-name { font-weight: 600; font-size: 14px; line-height: 1.25; }
.p-cat { font-size: 12px; color: var(--text-secondary); margin-top: 1px; }
.p-price-col { text-align: right; min-width: 84px; }

/* Price block */
.price { display: flex; align-items: baseline; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.price-now { font-size: 15px; font-weight: 700; color: var(--brand); }
.price-was { font-size: 12px; color: var(--text-muted); text-decoration: line-through; }
.price-off { font-size: 11px; font-weight: 700; background: var(--err-bg); color: var(--err-fg); padding: 1px 5px; border-radius: 4px; }

/* Product card grid (store) */
.pgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; }
.pcard { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-1); cursor: pointer; transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s; display: flex; flex-direction: column; }
.pcard:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--border-strong); }
.pcard-img { position: relative; aspect-ratio: 1; overflow: hidden; display: grid; place-items: center; }
.pcard-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.pcard:hover .pcard-img img { transform: scale(1.06); }
.pcard-img .ph-emoji { font-size: 56px; }
.pcard-badge { position: absolute; top: 8px; right: 8px; background: var(--brand); color: #fff; font-size: 12px; font-weight: 700; padding: 3px 8px; border-radius: 6px; }
.pcard-sold { position: absolute; top: 8px; left: 8px; background: rgba(0,0,0,0.72); color: #fff; font-size: 11px; font-weight: 700; text-transform: uppercase; padding: 3px 8px; border-radius: 6px; }
.pcard.is-soldout .pcard-img img { filter: grayscale(0.5); opacity: 0.7; }
.pcard-body { padding: 0.8rem 0.85rem 0.9rem; display: flex; flex-direction: column; gap: 0.5rem; flex: 1; }
.pcard-name { font-size: 14px; font-weight: 600; line-height: 1.3; }
.pcard .price { justify-content: flex-start; margin-top: -2px; }
.pcard-actions { display: flex; gap: 0.5rem; margin-top: auto; align-items: stretch; }
.pcard-view { flex: 1; }
.pcard-add { flex-shrink: 0; padding-left: 11px; padding-right: 11px; }
.pcard-add svg { width: 16px; height: 16px; }

@media (max-width: 520px) {
  .pgrid { grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
  .pcard-body { padding: 0.65rem 0.7rem 0.75rem; }
  .pcard-name { font-size: 13px; }
}

/* Offers grid (cards) */
.offer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 1rem; }
.offer-card { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-1); transition: transform var(--t-fast), box-shadow var(--t-fast); }
.offer-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.offer-media { height: 120px; display: grid; place-items: center; overflow: hidden; }
.offer-body { padding: 0.9rem; }
.offer-body .price { justify-content: flex-start; margin: 6px 0 10px; }

@media (max-width: 520px) {
  .store-filters select { flex: 1; min-width: 0; }
  .p-price-col { min-width: 70px; }
  .add-lbl { display: none; }
}

/* ── Cart page ──────────────────────────────────────────────── */
.cart-item { display: flex; align-items: center; gap: 0.85rem; padding: 0.85rem 0.4rem; border-bottom: 1px solid var(--border); }
.cart-item:last-child { border-bottom: none; }
.ci-info { flex: 1; min-width: 0; }
.ci-line { min-width: 78px; text-align: right; font-weight: 700; }
.qty { display: flex; align-items: center; gap: 4px; }
.qty-btn { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border-strong); background: var(--surface-1); color: var(--text-primary); cursor: pointer; font-size: 17px; line-height: 1; display: grid; place-items: center; transition: background var(--t-fast); }
.qty-btn:hover { background: var(--surface-0); border-color: var(--brand); }
.qty-in { width: 44px; text-align: center; padding: 6px 4px; font-weight: 600; }
.cart-summary { margin-bottom: 0.5rem; }
.sum-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 14px; }
.sum-row.grand { font-weight: 700; font-size: 16px; border-top: 1px solid var(--border); padding-top: 9px; margin-top: 5px; }
.bal-short { color: var(--err-fg); font-weight: 600; }

@media (max-width: 480px) {
  .cart-item { flex-wrap: wrap; }
  .ci-info { flex-basis: 100%; }
}

/* ── Checkout ───────────────────────────────────────────────── */
.co-options { display: flex; gap: 0.75rem; margin-bottom: 1rem; }
.co-option {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 1rem 0.5rem; border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); cursor: pointer; font: inherit; text-align: center;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.co-option:hover { border-color: var(--border-strong); }
.co-option.sel { border-color: var(--brand); background: var(--brand-soft); }
.co-ic { color: var(--brand); } .co-ic svg { width: 22px; height: 22px; }
.co-title { font-weight: 600; font-size: 14px; }
.co-sub { font-size: 12px; color: var(--text-secondary); }
.co-note { display: flex; gap: 9px; align-items: flex-start; padding: 10px 13px; border-radius: var(--radius); font-size: 14px; margin-bottom: 1rem; }
.co-note svg { flex-shrink: 0; margin-top: 2px; }
.co-note-info { background: var(--info-bg); color: var(--info-fg); }
.co-note-warn { background: var(--warn-bg); color: var(--warn-fg); }
.order-total { background: var(--surface-1); border-radius: var(--radius); padding: 0.9rem 1rem; margin-top: 0.5rem; }

/* Order confirmation */
.confirm .confirm-ic {
  width: 62px; height: 62px; margin: 0 auto 1rem; border-radius: 50%;
  display: grid; place-items: center; background: var(--ok-bg); color: var(--ok-fg);
  animation: popIn var(--t);
}
.confirm .confirm-ic svg { width: 32px; height: 32px; stroke-width: 2.5; }

/* ── Wallet ─────────────────────────────────────────────────── */
.wallet-hero {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: linear-gradient(130deg, var(--brand), var(--brand-strong));
  color: #fff; border: none; box-shadow: var(--shadow-2);
}
.wallet-hero .icon-btn { color: rgba(255,255,255,0.85); }
.wallet-hero .icon-btn:hover { background: rgba(0,0,0,0.18); color: #fff; }
.wallet-label { font-size: 13px; opacity: 0.9; }
.wallet-balance { font-size: clamp(30px, 7vw, 40px); font-weight: 700; letter-spacing: -0.02em; margin: 2px 0 4px; }
.wallet-hero .muted { color: rgba(255,255,255,0.8) !important; }

.topup-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.7rem; margin-bottom: 1rem; }
.topup-chip {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 0.9rem 0.4rem; border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); cursor: pointer; font: inherit; transition: border-color var(--t-fast), background var(--t-fast);
}
.topup-chip:hover { border-color: var(--border-strong); }
.topup-chip.sel { border-color: var(--brand); background: var(--brand-soft); }
.chip-amt { font-size: 20px; font-weight: 700; color: var(--brand); }
.chip-sub { font-size: 11px; color: var(--text-secondary); }

/* Each amount IS the pay button now, so it has to look pressable rather than
   selectable: a filled brand border, a lift on hover and a real press state.
   The old .sel style stays because nothing selects any more - it is kept only
   so an older cached wallet.js cannot render an unstyled chip. */
.topup-chip.go { border-color: var(--brand); background: var(--brand-soft); }
.topup-chip.go:hover:not(:disabled) { background: var(--brand); border-color: var(--brand); }
.topup-chip.go:hover:not(:disabled) .chip-amt,
.topup-chip.go:hover:not(:disabled) .chip-sub { color: #fff; }
.topup-chip.go:active:not(:disabled) { transform: translateY(1px); }
.topup-chip:disabled { opacity: 0.55; cursor: default; }

.topup-custom { margin-bottom: 1rem; }
.topup-custom label { display: block; margin-bottom: 5px; }
/* The amount and its button sit on one line, so typing and paying is one
   movement instead of a reach down the page. */
.custom-row { position: relative; display: flex; gap: 0.5rem; align-items: stretch; }
.custom-row input { flex: 1; min-width: 0; padding-left: 28px; font-size: 16px; font-weight: 600; }
.custom-row #customGo { flex: 0 0 auto; padding-left: 1.1rem; padding-right: 1.1rem; }
.cur-prefix { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-secondary); font-weight: 600; pointer-events: none; z-index: 1; }

/* The old gateway's pay button was styled here, in that gateway's own brand
   cyan, and it has been removed rather than renamed: nothing renders it. Paying
   is the amount chip itself (.topup-chip.go) or #customGo, and neither wants a
   second company's colours.

   This is deliberately NOT the .sel case a few rules up. That one is kept so a
   stale cached wallet.js cannot draw an unstyled chip — a cosmetic failure. An
   old cached wallet.js drawing THIS button would be offering to send a customer
   to a gateway the shop has no account with, which is broken whether or not it
   is styled, and styling it to look like a working pay button is the worse of
   the two outcomes. Assets carry a ?v= buster and index.html is served
   no-store, so that combination should not survive a deploy anyway. */
.pay-secure { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 0.75rem; }

@media (max-width: 420px) { .chip-amt { font-size: 17px; } }

/* ── Order history ──────────────────────────────────────────── */
.order-card { margin-bottom: 1rem; }
.oc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.75rem; }
.oc-id { font-weight: 700; font-size: 15px; }
.oc-badges { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }
.oc-badges .badge svg { width: 13px; height: 13px; margin-right: 2px; }
.oc-addr { display: flex; align-items: center; gap: 6px; margin-bottom: 0.6rem; }
.oc-addr svg { width: 14px; height: 14px; }
.oc-items { border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding: 0.6rem 0; margin-bottom: 0.6rem; }
.oi-row { display: flex; justify-content: space-between; font-size: 14px; padding: 3px 0; }
.oc-totals { font-size: 14px; }

@media (max-width: 460px) { .oc-head { flex-direction: column; } .oc-badges { flex-direction: row; align-items: center; } }

/* ── Back-to-top button ─────────────────────────────────────── */
.to-top {
  position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 90;
  width: 46px; height: 46px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--brand); color: #fff; box-shadow: var(--shadow-pop);
  display: grid; place-items: center;
  opacity: 0; transform: translateY(12px) scale(0.9); pointer-events: none;
  transition: opacity 0.25s, transform 0.25s, background 0.15s;
}
.to-top.show { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { background: var(--brand-strong); }
.to-top .icon { width: 22px; height: 22px; }

/* Corner cart button */
#cartTop { position: relative; }
#cartTop.active { color: var(--brand); }

/* ── Product detail page ────────────────────────────────────── */
.p-clickable { cursor: pointer; }
.pd-topbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.pd-back { margin-bottom: 0; }
.pd-next svg { width: 15px; height: 15px; }

/* Hot favourites */
.pd-faves { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border); }
.fave-row { display: flex; gap: 0.9rem; overflow-x: auto; padding-bottom: 0.5rem; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.fave-row::-webkit-scrollbar { height: 6px; }
.fave-row::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.fave-card { flex: 0 0 auto; width: 150px; scroll-snap-align: start; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-1); cursor: pointer; transition: transform 0.18s, box-shadow 0.18s; }
.fave-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.fave-img { position: relative; height: 130px; overflow: hidden; display: grid; place-items: center; background: var(--surface-1); }
.fave-img img { width: 100%; height: 100%; object-fit: cover; }
.fave-img .pd-emoji { font-size: 44px; }
.fave-body { padding: 0.6rem 0.7rem 0.75rem; }
.fave-name { font-size: 13px; font-weight: 600; line-height: 1.3; min-height: 2.6em; }
.fave-price { font-size: 14px; font-weight: 700; color: var(--brand); margin-top: 4px; }

/* legacy hero (old collage) unused now */
.pd-back { margin-bottom: 0; }
.pd-grid { display: grid; grid-template-columns: minmax(0, 420px) 1fr; gap: 2rem; align-items: start; }
.pd-media {
  position: relative; aspect-ratio: 1; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--surface-1); display: grid; place-items: center; box-shadow: var(--shadow-1);
}
.pd-media img { width: 100%; height: 100%; object-fit: cover; }
.pd-emoji { font-size: 120px; }
.pd-media.is-soldout img { filter: grayscale(0.5); opacity: 0.75; }
.pd-soldout { position: absolute; top: 12px; left: 12px; background: rgba(0,0,0,0.7); color: #fff; font-size: 12px; font-weight: 700; text-transform: uppercase; padding: 4px 10px; border-radius: 6px; }
.pd-discount { position: absolute; top: 12px; right: 12px; background: var(--brand); color: #fff; font-size: 14px; font-weight: 700; padding: 4px 10px; border-radius: 6px; }

.pd-cat { font-size: 13px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 5px; }
.pd-name { font-size: clamp(22px, 3.5vw, 30px); margin-bottom: 0.9rem; }
.pd-price { display: flex; align-items: baseline; gap: 10px; margin-bottom: 1rem; }
.pd-price-now { font-size: 30px; font-weight: 700; color: var(--brand); }
.pd-price .price-was { font-size: 17px; }
.pd-desc { font-size: 15px; color: var(--text-secondary); line-height: 1.6; margin-bottom: 1.25rem; }
.pd-incart { display: flex; align-items: center; gap: 6px; margin-bottom: 0.9rem; }
.pd-incart svg { width: 15px; height: 15px; }

.pd-actions { display: flex; gap: 0.75rem; align-items: stretch; margin-bottom: 1.75rem; flex-wrap: wrap; }
.pd-qty { border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 3px; }
.pd-qty .qty-btn { border: none; background: none; width: 38px; height: 38px; font-size: 20px; }
.pd-qty .qty-in { width: 48px; font-size: 15px; border: none; }
.pd-add { flex: 1; min-width: 180px; }

.pd-meta { border-top: 1px solid var(--border); padding-top: 1.1rem; display: flex; flex-direction: column; gap: 0.7rem; }
.pd-meta-row { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.pd-meta-row svg { width: 18px; height: 18px; color: var(--brand); flex-shrink: 0; }

/* ── FAQ ──────────────────────────────────────────────────────
   Built on <details>/<summary>, not JavaScript accordions. Three reasons that
   matter here: the answers are inside the DOM whether or not the item is open,
   so a crawler reads all of them; the browser gives keyboard and screen-reader
   behaviour for free; and Ctrl+F finds text in a closed section in Chrome. */
.faq-list { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 2rem; }

.faq-item {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface-1); overflow: hidden;
}
.faq-item[open] { border-color: var(--brand); }

.faq-q {
  cursor: pointer; padding: 1rem 1.1rem; font-weight: 600; font-size: 15px;
  list-style: none; display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; transition: color var(--t-fast);
}
.faq-q:hover { color: var(--brand); }
.faq-q:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Replace the default triangle with a chevron that rotates. ::-webkit-details-marker
   is still needed for Safari, which ignores list-style on summary. */
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: ''; flex: none; width: 9px; height: 9px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--t-fast); opacity: 0.55;
}
.faq-item[open] .faq-q::after { transform: rotate(-135deg) translate(-2px, -2px); }

.faq-a { padding: 0 1.1rem 1.1rem; }
.faq-a p { margin: 0; color: var(--text-secondary); font-size: 14.5px; line-height: 1.7; }

@media (prefers-reduced-motion: reduce) {
  .faq-q::after { transition: none; }
}

/* ── Share this product ───────────────────────────────────────
   Neutral by default and brand-coloured only on hover. Four saturated logo
   colours sitting permanently under the Add-to-cart button would compete with
   it; the point of the page is still to sell the box. */
.pd-share {
  border-top: 1px solid var(--border);
  margin-top: 1.1rem; padding-top: 1rem;
  display: flex; align-items: center; gap: 0.85rem; flex-wrap: wrap;
}
.pd-share-label { font-size: 13px; color: var(--text-muted); }
.pd-share-btns { display: flex; gap: 0.45rem; }

.pd-share-btn {
  width: 38px; height: 38px; display: grid; place-items: center;
  border: 1px solid var(--border); border-radius: 50%;
  background: var(--surface-1); color: var(--text-secondary);
  cursor: pointer; padding: 0; font: inherit;
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast);
}
.pd-share-btn:hover { transform: translateY(-2px); color: #fff; }
.pd-share-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.pd-share-ico { width: 17px; height: 17px; }

/* Official brand colours, on hover only. */
.pd-share-btn.is-wa:hover { background: #25D366; border-color: #25D366; }
.pd-share-btn.is-fb:hover { background: #1877F2; border-color: #1877F2; }
.pd-share-btn.is-x:hover  { background: #000;     border-color: #000; }
.pd-share-native:hover,
.pd-share-copy:hover { background: var(--brand); border-color: var(--brand); }

/* Confirmation without a layout shift: the circle turns green in place rather
   than swapping the glyph for a tick, which would jump the row. */
.pd-share-copy.is-copied {
  background: #16a34a; border-color: #16a34a; color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .pd-share-btn:hover { transform: none; }
}

@media (max-width: 720px) {
  .pd-grid { grid-template-columns: 1fr; gap: 1.25rem; }
  .pd-media { max-width: 360px; margin: 0 auto; width: 100%; }
  /* Touch targets: 38px is fine for a mouse, tight for a thumb. */
  .pd-share-btn { width: 42px; height: 42px; }
  .pd-share-ico { width: 18px; height: 18px; }
}

/* ── Admin dashboard ────────────────────────────────────────── */
.admin-tabs { display: flex; gap: 2px; margin-bottom: 1.5rem; border-bottom: 1px solid var(--border); overflow-x: auto; }
.admin-tab { padding: 9px 16px; border: none; background: none; cursor: pointer; font: inherit; font-size: 14px; color: var(--text-secondary); border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; transition: color var(--t-fast); }
.admin-tab:hover { color: var(--text-primary); }
.admin-tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

.chip-item { display: inline-block; background: var(--surface-1); border-radius: 5px; padding: 2px 8px; margin: 2px 2px 2px 0; font-size: 12px; }
.admin-order-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; border-top: 1px solid var(--border); margin-top: 0.75rem; padding-top: 0.75rem; }
.admin-order-actions select { width: auto; }

.metric-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.85rem; }
.metric-card { background: var(--surface-1); border-radius: var(--radius); padding: 1rem; }
.metric-card .lbl { font-size: 13px; color: var(--text-secondary); margin-bottom: 4px; }
.metric-card .val { font-size: 22px; font-weight: 700; }

.admin-table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 460px; }
.admin-table th { text-align: left; padding: 7px 6px; font-weight: 500; color: var(--text-secondary); border-bottom: 1px solid var(--border); }
.admin-table td { padding: 7px 6px; border-bottom: 1px solid var(--border); }
/* Money and counts read far faster right-aligned with figures of equal width —
   the decimal points line up so a column can be scanned rather than read. */
.admin-table th.num, .admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Password field + reveal eye. The button sits INSIDE the input's box, so the
   padding-right on the input is what stops long passwords running under it. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 2.8rem; }
.pw-eye {
  position: absolute; top: 50%; right: .45rem; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--text-secondary); cursor: pointer;
}
.pw-eye:hover { color: var(--text-primary); background: var(--surface-2); }
.pw-eye:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.pw-eye svg { width: 1.15rem; height: 1.15rem; }

/* Wide tables scroll INSIDE this wrapper instead of pushing the page sideways.
   .admin-table has min-width:460px, so on a phone the Customers and Delivery-fee
   tables would otherwise overflow the viewport and break the whole layout. */
.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Checkbox + label on one line, with the whole row clickable — a bare checkbox
   in a table cell is a small target and easy to miss on a phone. */
.switch-row { display: inline-flex; align-items: center; gap: .45rem; cursor: pointer; user-select: none; }
.switch-row input { width: 1.05rem; height: 1.05rem; accent-color: var(--brand); cursor: pointer; }

.disc-row, .prod-manage { display: flex; align-items: center; gap: 0.65rem; padding: 0.6rem 0.75rem; background: var(--surface-1); border-radius: var(--radius); margin-bottom: 0.5rem; flex-wrap: wrap; }
.disc-name, .pm-name { flex: 1; font-size: 14px; min-width: 130px; }
.prod-manage label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }

/* ── About / Delivery pages ─────────────────────────────────── */
.steps { display: grid; gap: 0.75rem; }
.step { display: flex; gap: 0.9rem; align-items: flex-start; padding: 1rem 1.1rem; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.step-num { flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%; background: var(--brand); color: #fff; font-weight: 700; display: grid; place-items: center; }
.step-title { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 15px; margin-bottom: 2px; }
.step-title svg { width: 17px; height: 17px; color: var(--brand); }

.partner-card { box-shadow: var(--shadow-1); }
.partner-head { display: flex; align-items: center; gap: 0.9rem; }
.partner-badge { width: 48px; height: 48px; border-radius: 12px; background: var(--info-bg); color: var(--info-fg); display: grid; place-items: center; flex-shrink: 0; }
.partner-badge svg { width: 24px; height: 24px; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1rem; }
.stat { text-align: center; padding: 0.5rem; }
.stat-big { font-size: clamp(20px, 4vw, 26px); font-weight: 700; color: var(--brand); letter-spacing: -0.02em; }
.stat-label { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }

.feature-list { list-style: none; display: grid; gap: 0.7rem; }
.feature-list li { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; }
.feature-list svg { width: 18px; height: 18px; color: var(--brand); flex-shrink: 0; margin-top: 1px; }

/* ── Phase 8: animated home ─────────────────────────────────── */
/* Scroll-reveal */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2,0.7,0.2,1); transition-delay: var(--d, 0ms); }
.reveal.in { opacity: 1; transform: none; }

/* Hero */
.home-hero {
  position: relative; overflow: hidden; border-radius: var(--radius-lg);
  padding: 3rem 2rem; margin-bottom: 2.5rem; min-height: 340px;
  display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 1rem; align-items: center;
  background: linear-gradient(135deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border); box-shadow: var(--shadow-2);
}
.hh-content { position: relative; z-index: 2; }
.hh-eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--brand); background: var(--brand-soft); padding: 5px 12px; border-radius: 20px; margin-bottom: 1rem; }
.hh-eyebrow svg { width: 15px; height: 15px; }
.hh-title { font-size: clamp(30px, 5.5vw, 52px); line-height: 1.05; letter-spacing: -0.03em; margin-bottom: 0.9rem; }
.hh-sub { font-size: clamp(15px, 2vw, 18px); color: var(--text-secondary); max-width: 44ch; margin-bottom: 1.6rem; }
.btn.glass { background: color-mix(in srgb, var(--surface-2) 70%, transparent); backdrop-filter: blur(6px); }

/* Moving blobs behind hero */
.hh-blob { position: absolute; border-radius: 50%; filter: blur(38px); opacity: 0.5; z-index: 1; }
.hh-blob-1 { width: 260px; height: 260px; background: radial-gradient(circle, color-mix(in srgb, var(--brand) 55%, transparent), transparent 70%); top: -60px; right: -30px; animation: blobFloat 9s ease-in-out infinite; }
.hh-blob-2 { width: 200px; height: 200px; background: radial-gradient(circle, #7ec8ff88, transparent 70%); bottom: -70px; left: 20%; animation: blobFloat 11s ease-in-out infinite reverse; }
@keyframes blobFloat { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-18px,20px) scale(1.12); } }

/* Floating product photos in hero */
.hh-pics { position: relative; height: 260px; z-index: 2; }
.hh-pic { position: absolute; border-radius: 18px; overflow: hidden; box-shadow: var(--shadow-pop); border: 3px solid var(--surface-2); background: var(--surface-1); cursor: pointer; transition: transform 0.25s; }
.hh-pic img { width: 100%; height: 100%; object-fit: cover; }
.hh-pic:hover { transform: scale(1.05) rotate(0deg) !important; z-index: 5; }
.hh-pic-0 { width: 150px; height: 190px; right: 30px; top: 20px; transform: rotate(5deg); animation: floaty 6s ease-in-out infinite; }
.hh-pic-1 { width: 110px; height: 140px; right: 150px; top: 90px; transform: rotate(-8deg); animation: floaty 7s ease-in-out infinite 0.6s; z-index: 3; }
.hh-pic-2 { width: 95px; height: 120px; right: 60px; bottom: 0; transform: rotate(-3deg); animation: floaty 8s ease-in-out infinite 1.2s; }
@keyframes floaty { 0%,100% { translate: 0 0; } 50% { translate: 0 -14px; } }
.hh-spark { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: var(--brand); opacity: 0.7; animation: twinkle 3s ease-in-out infinite; }
.hh-spark-1 { top: 10px; right: 200px; } .hh-spark-2 { bottom: 40px; right: 200px; background: #7ec8ff; animation-delay: 1s; } .hh-spark-3 { top: 120px; right: 10px; background: #1D9E75; animation-delay: 2s; }
@keyframes twinkle { 0%,100% { opacity: 0.2; transform: scale(0.7); } 50% { opacity: 0.9; transform: scale(1.2); } }

@media (max-width: 780px) {
  .home-hero { grid-template-columns: 1fr; min-height: 0; }
  .hh-pics { height: 200px; margin-top: 1rem; }
}

/* Motion showcase */

/* SVG scene animations */
.anim-bob { animation: sBob 3s ease-in-out infinite; transform-origin: center; }
.anim-bob2 { animation: sBob 3.4s ease-in-out infinite 0.3s; }
.anim-bob3 { animation: sBob 2.8s ease-in-out infinite 0.6s; }
@keyframes sBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
.anim-sprinkle { animation: sSprinkle 2.2s ease-in infinite; }
@keyframes sSprinkle { 0% { transform: translateY(-6px); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateY(18px); opacity: 0; } }
.anim-dip { animation: sDip 3s ease-in-out infinite; transform-origin: 60px 50px; }
@keyframes sDip { 0%,100% { transform: scaleY(1); } 50% { transform: scaleY(1.08); } }
.anim-drip { animation: sDrip 2.6s ease-in infinite; }
@keyframes sDrip { 0% { transform: translateY(0) scaleY(0.6); opacity: 0; } 40% { opacity: 1; } 100% { transform: translateY(22px) scaleY(1.4); opacity: 0; } }
.anim-drop { animation: sDrip 2.4s ease-in infinite 0.2s; }
.anim-drop2 { animation: sDrip 2.8s ease-in infinite 1s; }
.anim-spin { animation: sSpin 8s linear infinite; }
@keyframes sSpin { to { transform: rotate(360deg); } }
.anim-twinkle { animation: twinkle 2.4s ease-in-out infinite; transform-origin: center; }
.anim-twinkle2 { animation: twinkle 2.4s ease-in-out infinite 1.2s; transform-origin: center; }

/* ── Cinematic hero (video-style showcase) ──────────────────── */
.cine-hero {
  position: relative; width: 100%;
  height: clamp(440px, 72vh, 660px);
  border-radius: var(--radius-lg); overflow: hidden;
  margin-bottom: 2.5rem; box-shadow: var(--shadow-2);
  background: var(--hero-stage); isolation: isolate;
}
.cine-video, .cine-slides, .cine-slide, .cine-slide img, .cine-fallback { position: absolute; inset: 0; }
.cine-video { width: 100%; height: 100%; object-fit: cover; }
.cine-fallback { display: grid; place-items: center; font-size: 120px; background: linear-gradient(135deg, var(--surface-1), var(--surface-2)); }
.cine-slide { opacity: 0; transition: opacity 1.6s ease; }
.cine-slide.active { opacity: 1; }
.cine-slide img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.06); }
/* Slow Ken-Burns zoom on whichever slide is currently showing. */
.cine-slide.active img { animation: kenburns 6.4s ease-out both; }
@keyframes kenburns { from { transform: scale(1.02); } to { transform: scale(1.14); } }

.cine-overlay { position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.35) 42%, rgba(0,0,0,0.15) 70%, rgba(0,0,0,0.35) 100%),
    linear-gradient(to right, rgba(0,0,0,0.55), transparent 60%);
}
.cine-content { position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  padding: clamp(1.5rem, 4vw, 3rem); color: #fff; max-width: 760px; }
.cine-eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  color: #fff; background: rgba(200,35,60,0.9); padding: 6px 13px; border-radius: 20px; margin-bottom: 1rem; }
.cine-eyebrow svg { width: 15px; height: 15px; }
.cine-title { font-size: clamp(30px, 6vw, 60px); line-height: 1.02; letter-spacing: -0.03em; margin-bottom: 0.7rem;
  color: #fff; text-shadow: 0 2px 24px rgba(0,0,0,0.5); }
.cine-sub { font-size: clamp(15px, 2.2vw, 20px); color: rgba(255,255,255,0.9); max-width: 46ch; margin-bottom: 1.5rem;
  text-shadow: 0 1px 12px rgba(0,0,0,0.6); }
.cine-hero .hero-cta { margin-bottom: 1.1rem; }
.cine-hero .btn.glass { background: rgba(255,255,255,0.16); color: #fff; border-color: rgba(255,255,255,0.35); backdrop-filter: blur(6px); }
.cine-hero .btn.glass:hover { background: rgba(255,255,255,0.28); }

/* "Now showing" product chip — ties the hero to real, tappable products. */
.cine-now { min-height: 44px; }
.cine-chip { display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.25); backdrop-filter: blur(8px);
  color: #fff; font: inherit; padding: 8px 8px 8px 15px; border-radius: 30px; transition: background 0.2s; }
.cine-chip:hover { background: rgba(255,255,255,0.26); }
.cine-chip-name { font-size: 14px; font-weight: 600; }
.cine-chip-price { font-size: 14px; font-weight: 700; color: #ffd7de; }
.cine-chip-cta { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600;
  background: var(--brand); padding: 6px 12px; border-radius: 20px; }
.cine-chip-cta svg { width: 14px; height: 14px; }

.cine-dots { position: absolute; z-index: 2; top: 16px; right: 18px; display: flex; gap: 7px; }
.cine-dot { width: 8px; height: 8px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255,255,255,0.4); transition: all 0.2s; padding: 0; }
.cine-dot.on { background: #fff; width: 22px; border-radius: 4px; }
.cine-scroll { display: none; }

@media (max-width: 600px) {
  .cine-hero { height: clamp(420px, 78vh, 560px); }
  .cine-chip-cta { display: none; }
}

/* Product marquee */
.marquee { overflow: hidden; margin-bottom: 2.5rem; -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.marquee-track { display: flex; gap: 1rem; width: max-content; animation: marquee 42s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }
.mq-card { width: 160px; flex-shrink: 0; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-1); cursor: pointer; transition: transform 0.2s; }
.mq-card:hover { transform: translateY(-4px); }
.mq-img { height: 150px; overflow: hidden; background: var(--surface-1); }
.mq-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s; }
.mq-card:hover .mq-img img { transform: scale(1.08); }
.mq-name { padding: 0.6rem 0.7rem 0.1rem; font-size: 13px; font-weight: 600; line-height: 1.25; }
.mq-price { padding: 0 0.7rem 0.7rem; font-size: 14px; font-weight: 700; color: var(--brand); }

/* Reduced-motion respect */
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; }
  .hh-blob, .hh-pic, .hh-spark, .marquee-track, .cine-slide img,
  .anim-bob, .anim-bob2, .anim-bob3, .anim-sprinkle, .anim-dip, .anim-drip,
  .anim-drop, .anim-drop2, .anim-spin, .anim-twinkle, .anim-twinkle2 { animation: none !important; }
}

/* Reduced-motion respect */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* ═══════════════════════════════════════════════════════════════
   NOTIFICATIONS — success / error / warning / info
   Replaces the old flat .toast. Kept as a separate block so the
   original toast styles can stay for anything not yet migrated.
   ═══════════════════════════════════════════════════════════════ */
.nt-wrap {
  position: fixed; z-index: 500;
  top: calc(var(--nav-h) + 12px); right: 14px;
  display: flex; flex-direction: column; gap: 10px;
  width: min(380px, calc(100vw - 28px));
  pointer-events: none;                 /* clicks pass through the gaps */
}
.nt {
  pointer-events: auto;
  position: relative; overflow: hidden;
  display: grid; grid-template-columns: auto 1fr auto; gap: 11px;
  align-items: start;
  padding: 13px 13px 14px;
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 4px solid var(--text-muted);
  box-shadow: var(--shadow-pop);
  animation: ntIn 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes ntIn { from { opacity: 0; transform: translateX(28px) scale(0.97); } to { opacity: 1; transform: none; } }
.nt-out { animation: ntOut 0.26s ease forwards; }
@keyframes ntOut { to { opacity: 0; transform: translateX(28px) scale(0.97); } }

.nt-icon { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; flex: none; }
.nt-glyph { width: 15px; height: 15px; }
.nt-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.nt-title { font-size: 14px; font-weight: 650; color: var(--text-primary); line-height: 1.35; }
.nt-msg { font-size: 13px; color: var(--text-secondary); line-height: 1.45; }
.nt-action {
  align-self: flex-start; margin-top: 6px;
  font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 5px 11px; border-radius: var(--radius-sm);
  background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border-strong); cursor: pointer;
}
.nt-action:hover { background: var(--surface-3); }
.nt-close {
  background: none; border: 0; cursor: pointer; padding: 2px;
  color: var(--text-muted); border-radius: var(--radius-sm); flex: none;
}
.nt-close svg { width: 15px; height: 15px; display: block; }
.nt-close:hover { color: var(--text-primary); background: var(--surface-1); }
.nt-timer {
  position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  transform-origin: left; background: currentColor; opacity: 0.4;
  animation: ntTimer linear forwards;
}
@keyframes ntTimer { from { transform: scaleX(1); } to { transform: scaleX(0); } }

.nt-success { border-left-color: var(--ok-fg); }
.nt-success .nt-icon { background: var(--ok-bg); color: var(--ok-fg); }
.nt-success .nt-timer { color: var(--ok-fg); }
.nt-error { border-left-color: var(--err-fg); }
.nt-error .nt-icon { background: var(--err-bg); color: var(--err-fg); }
.nt-error .nt-timer { color: var(--err-fg); }
.nt-warning { border-left-color: var(--warn-fg); }
.nt-warning .nt-icon { background: var(--warn-bg); color: var(--warn-fg); }
.nt-warning .nt-timer { color: var(--warn-fg); }
.nt-info { border-left-color: var(--info-fg); }
.nt-info .nt-icon { background: var(--info-bg); color: var(--info-fg); }
.nt-info .nt-timer { color: var(--info-fg); }

/* On a phone, full-width along the top reads better than a floating card. */
@media (max-width: 560px) {
  .nt-wrap { left: 10px; right: 10px; width: auto; top: calc(var(--nav-h) + 8px); }
}

/* ═══════════════════════════════════════════════════════════════
   DIALOGS — confirm + problem panels
   ═══════════════════════════════════════════════════════════════ */
.ux-overlay {
  position: fixed; inset: 0; z-index: 600;
  background: rgba(0,0,0,0.45); backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 1.2rem;
  animation: uxFade 0.18s ease;
}
@keyframes uxFade { from { opacity: 0; } to { opacity: 1; } }
.ux-dialog {
  width: min(420px, 100%);
  background: var(--surface-2); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop); padding: 1.4rem 1.4rem 1.15rem;
  animation: uxPop 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}
.ux-dialog-wide { width: min(620px, 100%); }
@keyframes uxPop { from { opacity: 0; transform: translateY(14px) scale(0.97); } to { opacity: 1; transform: none; } }
.ux-dialog-title { margin: 0 0 0.45rem; font-size: 17px; font-weight: 680; }
.ux-dialog-msg { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text-secondary); }
.ux-dialog-actions { display: flex; justify-content: flex-end; gap: 0.55rem; margin-top: 1.3rem; }
.ux-problem-mark {
  width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  background: var(--err-bg); color: var(--err-fg); margin-bottom: 0.85rem;
}
.ux-problem-mark svg { width: 22px; height: 22px; }
.ux-problem-detail {
  margin: 0.85rem 0 0; padding: 8px 10px;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 12px; color: var(--text-muted); word-break: break-all;
}

/* ═══════════════════════════════════════════════════════════════
   GUIDED TOUR
   ═══════════════════════════════════════════════════════════════ */
.tour-veil { position: fixed; inset: 0; z-index: 700; background: rgba(0,0,0,0.55); animation: uxFade 0.25s ease; }
.tour-ring {
  position: fixed; z-index: 701; border-radius: 12px;
  border: 2px solid var(--brand);
  /* The huge spread is what "cuts the hole": it darkens everything outside the
     ring without needing a mask, while the target itself stays clickable. */
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.55), 0 0 0 5px color-mix(in srgb, var(--brand) 32%, transparent);
  pointer-events: none;
  transition: all 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.tour-veil + .tour-ring ~ .tour-pop { position: fixed; }
.tour-pop {
  position: fixed; z-index: 702;
  width: min(320px, calc(100vw - 24px));
  background: var(--surface-2); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop); padding: 1rem 1.05rem 0.9rem;
  animation: uxPop 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  transition: top 0.3s cubic-bezier(0.16,1,0.3,1), left 0.3s cubic-bezier(0.16,1,0.3,1);
}
.tour-step-count { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--brand); }
.tour-title { margin: 0.3rem 0 0.35rem; font-size: 15.5px; font-weight: 680; }
.tour-body { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--text-secondary); }
.tour-dots { display: flex; gap: 5px; margin: 0.85rem 0 0.7rem; }
.tour-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); transition: all var(--t); }
.tour-dot.on { background: var(--brand); width: 16px; border-radius: 3px; }
.tour-actions { display: flex; align-items: center; gap: 0.45rem; }
.tour-spacer { flex: 1; }
.tour-skip { background: none; border: 0; cursor: pointer; font: inherit; font-size: 12.5px; color: var(--text-muted); padding: 4px 2px; }
.tour-skip:hover { color: var(--text-primary); text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════
   ABOUT — logo hero
   The logo doubles as the backdrop (blurred + scrimmed) and as the
   crisp emblem in the middle. The scrim is what keeps the heading
   readable: the logo itself is a busy red/blue gradient.
   ═══════════════════════════════════════════════════════════════ */
.about-hero {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  margin-bottom: 2rem;
  padding: 3rem 1.5rem 2.6rem;
  text-align: center;
  isolation: isolate;
}
.about-hero-bg {
  position: absolute; inset: -10%;
  background: url('img/logo.jpg') center/cover no-repeat;
  filter: blur(38px) saturate(1.25);
  transform: scale(1.15);
  z-index: -2;
}
.about-hero-scrim {
  position: absolute; inset: 0; z-index: -1;
  /* Dark enough for white text to clear WCAG AA over the brightest part of
     the logo, in both themes. */
  background: linear-gradient(180deg, rgba(10,6,20,0.62), rgba(10,6,20,0.78));
}
.about-hero-inner { position: relative; display: grid; justify-items: center; gap: 0.9rem; }
.about-logo {
  width: min(320px, 74vw); height: auto;
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 34px rgba(0,0,0,0.42);
}
.about-hero h1 {
  margin: 0.4rem 0 0; color: #fff; font-size: clamp(1.5rem, 4.4vw, 2.15rem);
  text-shadow: 0 2px 14px rgba(0,0,0,0.5);
}
.about-hero p {
  margin: 0; max-width: 54ch; color: rgba(255,255,255,0.93);
  font-size: 15px; line-height: 1.6; text-shadow: 0 1px 10px rgba(0,0,0,0.5);
}

/* ── Our story ── */
.story-card p { line-height: 1.75; margin: 0 0 0.9rem; color: var(--text-secondary); }
.story-lead {
  font-size: 1.12rem; font-weight: 600; color: var(--text-primary) !important;
  font-style: italic;
}
.story-sign { margin-bottom: 0 !important; font-size: 13.5px; color: var(--text-muted) !important; }

/* ═══════════════════════════════════════════════════════════════
   SITE FOOTER
   ═══════════════════════════════════════════════════════════════ */
.site-footer {
  margin-top: 3rem; border-top: 1px solid var(--border);
  background: var(--surface-1); color: var(--text-secondary);
}
.footer-inner {
  max-width: var(--maxw); margin: 0 auto; padding: 2.2rem 1.25rem 1.5rem;
  display: grid; grid-template-columns: 1.5fr 0.8fr 1.4fr 1.2fr; gap: 2rem;
}
.footer-col h4 {
  margin: 0 0 0.7rem; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted);
}
.footer-brand { font-size: 1.25rem; font-weight: 800; color: var(--text-primary); }
.footer-brand span { color: var(--brand); }
.footer-blurb { margin: 0.5rem 0 0; font-size: 13.5px; line-height: 1.6; max-width: 34ch; }
.footer-link {
  display: flex; align-items: center; gap: 7px;
  background: none; border: 0; padding: 4px 0; cursor: pointer;
  font: inherit; font-size: 13.5px; color: var(--text-secondary);
  text-decoration: none; text-align: left; width: fit-content;
}
.footer-link:hover { color: var(--brand); }
.footer-wa { width: 15px; height: 15px; color: #25D366; flex: none; }

/* Address block. <address> is italic by default in every browser, which reads
   as an aside rather than as the shop's actual location — undo it. */
.footer-addr {
  font-style: normal; margin: 0.75rem 0 0;
  font-size: 13px; line-height: 1.65; color: var(--text-muted);
}

/* The delivery towns. Fourteen of them stacked one per line makes the footer
   absurdly tall on a phone, so they flow into as many short columns as fit. */
.footer-towns .footer-link { padding: 3px 0; }
.footer-towns > h4 { margin-bottom: 0.55rem; }
.footer-towns {
  display: block;
  column-width: 8.5rem; column-gap: 1.2rem;
}
.footer-towns > h4 { column-span: all; }

/* Town names, not links — the per-town pages were removed, so these are plain
   text now. Styled to match .footer-link so the footer column still reads as a
   list, but with no pointer cursor and no hover, because there is nowhere to
   go. The "How delivery works" link below them is the one thing that is. */
.footer-town {
  display: block; padding: 3px 0;
  font-size: 13.5px; line-height: 1.5;
  color: var(--text-secondary);
}
.footer-towns .footer-link { margin-top: 0.5rem; font-weight: 600; }
.footer-bar {
  max-width: var(--maxw); margin: 0 auto;
  /* THE BOTTOM PADDING IS CLEARANCE, NOT SPACING.
   *
   * Two buttons float over this line: the WhatsApp bubble at bottom-left and
   * back-to-top at bottom-right. The last thing in this bar is the line that
   * reads "Collections Tue, Thu, Fri, Sat & Sun - Delivery Thursdays", and both
   * buttons sat on top of its two ends - the owner reported the left one and a
   * screenshot showed back-to-top eating the "s" off Thursdays on the right.
   *
   * Hiding the WhatsApp button over the footer (see assets/support.js) fixes
   * one side and one button. This fixes BOTH sides for good, and keeps working
   * if a third floating thing is ever added: 4.5rem is past a 52px button plus
   * its 18px offset, so the text simply ends above them. */
  padding: 0.9rem 1.25rem 4.5rem; border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: space-between;
  font-size: 12.5px; color: var(--text-muted);
}
@media (max-width: 980px) {
  .footer-inner { grid-template-columns: 1.4fr 1fr; gap: 1.6rem 2rem; }
}
@media (max-width: 720px) {
  .footer-inner { grid-template-columns: 1fr; gap: 1.5rem; }
  .footer-bar { flex-direction: column; }
  .footer-towns { column-width: 7.5rem; }
}

/* ═══════════════════════════════════════════════════════════════
   WHATSAPP SUPPORT WIDGET
   Bottom-LEFT, because the back-to-top button owns bottom-right.
   ═══════════════════════════════════════════════════════════════ */
.wa-fab {
  position: fixed; left: 18px; bottom: 18px; z-index: 450;
  width: 52px; height: 52px; border-radius: 50%;
  border: 0; cursor: pointer;
  background: #25D366; color: #fff;
  box-shadow: 0 6px 20px rgba(37, 211, 102, 0.45);
  display: grid; place-items: center;
  transition: transform var(--t), box-shadow var(--t), opacity 0.35s ease, visibility 0.35s;
}

/* OUT OF THE WAY. Set while the page is being scrolled and while the footer is
 * on screen — see mountFab in assets/support.js for when and why.
 *
 * opacity and visibility ONLY, never transform: three other rules on this
 * button already own transform (:hover, .on, and the press state), and a fourth
 * writing to the same property would make the scale on hover fight the hide.
 *
 * visibility is what actually removes it: opacity:0 alone leaves a 52px circle
 * sitting over the footer link, catching the tap meant for "WhatsApp us". */
.wa-fab.wa-away {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Somebody who has asked for less motion gets the same behaviour with no fade —
 * the button still gets out of the way, it just does it instantly. */
@media (prefers-reduced-motion: reduce) {
  .wa-fab { transition: none; }
}
.wa-fab:hover { transform: scale(1.07); box-shadow: 0 8px 26px rgba(37,211,102,0.55); }
.wa-fab.on { transform: scale(0.94); }
.wa-fab:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; }
.wa-fab-icon { width: 27px; height: 27px; }

.wa-panel {
  position: fixed; left: 18px; bottom: 82px; z-index: 451;
  width: min(330px, calc(100vw - 36px));
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow-pop);
  animation: uxPop 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}
.wa-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 13px; background: #075E54; color: #fff;
}
.wa-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  background: rgba(255,255,255,0.18); display: grid; place-items: center;
}
.wa-head-icon { width: 20px; height: 20px; }
.wa-head-txt { display: flex; flex-direction: column; line-height: 1.25; flex: 1; min-width: 0; }
.wa-head-txt strong { font-size: 14px; }
.wa-head-txt span { font-size: 11.5px; opacity: 0.82; }
.wa-close {
  background: none; border: 0; color: #fff; cursor: pointer;
  font-size: 22px; line-height: 1; padding: 0 2px; opacity: 0.85;
}
.wa-close:hover { opacity: 1; }

.wa-body {
  padding: 14px 13px 10px; min-height: 92px;
  /* The faint tile pattern WhatsApp itself uses, drawn in CSS. */
  background:
    radial-gradient(circle at 20% 30%, rgba(37,211,102,0.05) 0 2px, transparent 2px),
    radial-gradient(circle at 70% 70%, rgba(37,211,102,0.05) 0 2px, transparent 2px),
    var(--surface-1);
  background-size: 42px 42px, 58px 58px, auto;
}
.wa-bubble {
  max-width: 88%; padding: 9px 12px; border-radius: 12px;
  font-size: 13.5px; line-height: 1.5; box-shadow: var(--shadow-1);
}
.wa-in { background: var(--surface-2); color: var(--text-primary); border-top-left-radius: 3px; }
.wa-note { margin: 10px 2px 0; font-size: 11.5px; color: var(--text-muted); line-height: 1.45; }

.wa-foot { display: flex; align-items: flex-end; gap: 8px; padding: 10px 11px; background: var(--surface-2); }
.wa-input {
  flex: 1; resize: none; font: inherit; font-size: 13.5px;
  padding: 9px 11px; border-radius: 18px;
  border: 1px solid var(--border-strong); background: var(--surface-1);
  color: var(--text-primary);
}
.wa-input:focus { outline: 2px solid #25D366; outline-offset: 1px; }
.wa-send {
  width: 38px; height: 38px; flex: none; border: 0; border-radius: 50%;
  background: #25D366; color: #fff; cursor: pointer; display: grid; place-items: center;
}
.wa-send:hover { background: #1fb457; }
.wa-send svg { width: 18px; height: 18px; }

/* Keep the WhatsApp button clear of the back-to-top button on small screens. */
@media (max-width: 480px) {
  .wa-fab { width: 46px; height: 46px; left: 12px; bottom: 12px; }
  .wa-fab-icon { width: 23px; height: 23px; }
  .wa-panel { left: 12px; bottom: 68px; }
}

/* ── Admin: pending-order approval row ─────────────────────────
   Visually louder than the status dropdown below it, because a pending
   order is the one thing on the page that is waiting on a human. */
.approve-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.55rem;
  margin: 0.85rem 0 0.2rem; padding: 0.7rem 0.85rem;
  background: var(--warn-bg); border: 1px solid color-mix(in srgb, var(--warn-fg) 28%, transparent);
  border-radius: var(--radius);
}
.approve-note {
  display: flex; align-items: center; gap: 6px;
  font-size: 13.5px; font-weight: 600; color: var(--warn-fg); flex: 1; min-width: 150px;
}
.approve-note .icon { width: 15px; height: 15px; }

/* Standing reminder for an unconfirmed email address. Sits between the nav and
   the page so it survives navigation — a customer should learn they cannot order
   BEFORE they have filled a cart, not at the checkout button. */
.verify-banner {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  max-width: 1100px; margin: .75rem auto 0; padding: .7rem 1rem;
  background: var(--warn-bg, #faeeda); color: var(--warn-fg, #854f0b);
  border-radius: var(--radius, 10px); font-size: 14px; line-height: 1.5;
}
.verify-banner .icon { flex: none; }
.verify-banner > div { flex: 1 1 240px; }

/* ── Admin dashboard: Overview ────────────────────────────────
   auto-fit + minmax rather than media queries: the tiles reflow by available
   width, so the same rule serves a phone, a split window and a wide monitor.
   The min is 150px because "Token liability" plus a formatted rand figure is
   the widest thing that has to fit without wrapping mid-number. */
.admin-stat-grid {
  display: grid; gap: .75rem; margin-bottom: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
/* Charts need more room than stats before they stop being readable — a bar
   chart under ~260px is a smudge — so they get their own, larger minimum. */
.admin-chart-grid {
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
/* min-width:0 on the children matters: a grid item defaults to min-content
   width, so a long product name in a chart card would otherwise push the
   column wider than its track and break the whole layout sideways. */
.admin-stat-grid > *, .admin-chart-grid > * { min-width: 0; }

/* ── Admin dashboard: the section rail ────────────────────────
   Every customer downloads this stylesheet on every page and none of them can
   ever open the dashboard, so this block is kept to what genuinely cannot live
   inside the admin JavaScript: a media query and a sticky position. Everything
   else the dashboard draws is styled inline in assets/panels/, which costs the
   shop nothing — the same reasoning as the note in panels/delivery-map.js.

   Six sections replaced ten tabs crammed into one scrolling row. A rail down
   the side because the list is now short enough to read at a glance and long
   enough that horizontal tabs would still cut off. */
.admin-shell {
  display: grid; gap: 1rem; align-items: start;
  grid-template-columns: 190px minmax(0, 1fr);
}
.admin-rail { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 74px; }
.admin-rail-btn {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; border: none; border-radius: var(--radius-sm);
  background: none; cursor: pointer; font: inherit; font-size: 14px; text-align: left;
  color: var(--text-secondary); white-space: nowrap; transition: color var(--t-fast);
}
.admin-rail-btn svg { width: 17px; height: 17px; flex: none; }
.admin-rail-btn:hover { background: var(--surface-1); color: var(--text-primary); }
.admin-rail-btn.active { background: var(--brand-soft); color: var(--brand); font-weight: 600; }
.admin-rail-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Thursday is not a desk day. Below 860px the rail lies down and scrolls
   sideways above the panel, and stops being sticky — a bar pinned to the top of
   a phone screen eats the little height there is. */
@media (max-width: 860px) {
  .admin-shell { grid-template-columns: minmax(0, 1fr); }
  .admin-rail {
    flex-direction: row; position: static; gap: 4px;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding-bottom: 4px; border-bottom: 1px solid var(--border);
  }
  .admin-rail-btn { flex: 0 0 auto; }
}
