/* Semantic-token theme layer (P0). App.razor emits ONLY the raw resolver-validated brand vars
   (--brand-primary/-on-primary/-accent/-on-tint/-ink-accent + the dark on-colour mirrors + font/spacing);
   ALL surface derivation lives here and is mixed against each theme's own --surface-base, so light and dark
   both stay contrast-gated. The unbranded slate default yields an authentic "ardoise" dark canvas with amber
   popping; a configured brand kit overrides the raw vars and every derived token follows automatically. */

/* Self-hosted editorial display face (P1-1). Fraunces variable, latin subset, woff2 (OFL — see fonts/Fraunces-OFL.txt).
   font-display:swap so a heading paints immediately in the fallback and swaps when the face arrives; no external/CDN
   font (CSP + LCP). It is referenced only by --font-display via the serif brand-font stack, so it downloads only for a
   serif tenant (App.razor preloads the woff2 exactly then). Body always stays on the system --font-body. */
@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/fraunces-latin-var.woff2") format("woff2");
}

:root,
[data-theme="light"] {
    color-scheme: light;

    /* Raw brand-kit fallbacks; App.razor overrides these from the tenant's resolved kit. */
    --brand-primary: #d97706;
    --brand-on-primary: #1c1308;
    --brand-on-tint: #d97706;
    --brand-ink-accent: #b45309;
    --brand-accent: #d97706;
    --brand-on-tint-dark: #f1f5f9;
    --brand-ink-accent-dark: #fbbf24;
    --brand-accent-dark: #fbbf24;
    --brand-font: ui-sans-serif, system-ui, sans-serif;
    --brand-display-spacing: -0.01em;

    /* Editorial type scale (fluid, mobile-first) + display/body split. */
    --font-display: var(--brand-font);
    --font-body: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
    --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
    --step-0: clamp(0.95rem, 0.92rem + 0.18vw, 1.05rem);
    --step-1: clamp(1.1rem, 1.03rem + 0.35vw, 1.35rem);
    --step-2: clamp(1.3rem, 1.18rem + 0.6vw, 1.75rem);
    --step-3: clamp(1.6rem, 1.4rem + 1vw, 2.3rem);
    --step-4: clamp(1.95rem, 1.6rem + 1.75vw, 3.3rem);

    /* Spacing (4px base) + radius + motion. */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --radius-sm: 0.375rem;
    --radius-md: 0.5rem;
    --radius-lg: 0.75rem;
    --radius-xl: 1rem;
    --radius-pill: 999px;
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --ease-emphasis: cubic-bezier(0.2, 0, 0, 1);
    --dur-1: 0.12s;
    --dur-2: 0.2s;
    --dur-3: 0.32s;

    /* Base surfaces + ink. The surface + hairlines are gently warmed toward the tenant brand (like the dark block
       derives its canvas from the primary) so a warm brand reads as cream and a cool brand as cool-white — the light
       theme integrates with the identity instead of a sterile white. Ink stays slate: high contrast on any tint. */
    --surface-base: color-mix(in srgb, var(--brand-primary) 6%, #ffffff);
    --ink: #0f172a;
    --muted: #475569;
    --subtle: #64748b;
    --line: color-mix(in srgb, var(--brand-primary) 9%, #e2e8f0);
    --border-strong: color-mix(in srgb, var(--brand-primary) 11%, #cbd5e1);
    --bg: var(--surface-base);

    /* Brand-derived surface tints — mixed against THIS theme's --surface-base (re-declared per theme block). */
    --brand-tint: color-mix(in srgb, var(--brand-primary) 6%, var(--surface-base));
    --brand-tint-2: color-mix(in srgb, var(--brand-primary) 12%, var(--surface-base));
    --brand-band: color-mix(in srgb, var(--brand-primary) 7%, var(--surface-base));
    --brand-accent-soft: color-mix(in srgb, var(--brand-accent) 14%, var(--surface-base));
    --brand-hairline: color-mix(in srgb, var(--brand-primary) 22%, var(--line));
    --on-accent-soft: #1c1308;

    /* Theme-adaptive brand roles. Light = the raw primary; the dark block re-points these so a slate-default primary
       (near-black) never renders as an invisible foreground or a fill that blends into the near-black canvas.
       --brand-interactive = foreground text/icon/border ink; --brand-primary-raised = the CTA fill floor. */
    --brand-interactive: var(--brand-primary);
    --brand-primary-raised: var(--brand-primary);

    /* Semantic decorative. */
    --accent-line: var(--brand-accent);
    --shadow: 0 8px 24px rgba(15, 23, 42, 0.14);
    --shadow-lg: 0 6px 24px rgba(15, 23, 42, 0.18);
    --shadow-bar: 0 -4px 20px rgba(15, 23, 42, 0.16);

    /* Danger / error band. */
    --danger-ink: #b91c1c;
    --danger-bg: #fef2f2;
    --danger-line: #dc2626;

    /* Inverted banner (offline). */
    --invert-bg: #0f172a;
    --invert-ink: #f1f5f9;
    --invert-muted: #cbd5e1;

    /* Functional status tones — the canonical set shared with the Dashboard (word + dot, never colour alone). */
    --status-positive-ink: #166534;
    --status-positive-bg: #dcfce7;
    --status-positive-dot: #16a34a;
    --status-caution-ink: #92400e;
    --status-caution-bg: #fef3c7;
    --status-caution-dot: #f59e0b;
    --status-negative-ink: #991b1b;
    --status-negative-bg: #fee2e2;
    --status-negative-dot: #dc2626;
    --status-neutral-ink: #334155;
    --status-neutral-bg: #f1f5f9;
    --status-neutral-dot: #64748b;

    /* Dish-tag tones. */
    --tag-bg: var(--brand-tint-2);
    --tag-ink: var(--ink);
    --tag-line: var(--brand-hairline);
    --tag-muted-bg: #f1f5f9;
    --tag-muted-ink: #334155;
    --tag-muted-line: #cbd5e1;
}

[data-theme="dark"] {
    color-scheme: dark;

    /* An authentic slate-tinted near-black canvas; a brand primary tints it toward the tenant's hue. */
    --surface-base: color-mix(in srgb, var(--brand-primary) 8%, #0b0f14);
    --ink: #f1f5f9;
    --muted: #cbd5e1;
    --subtle: #94a3b8;
    --line: #334155;
    --border-strong: #475569;
    --bg: var(--surface-base);

    /* Brand on-colours flip to the resolver's lightened dark mirrors (still AA on the dark canvas). */
    --brand-on-tint: var(--brand-on-tint-dark);
    --brand-ink-accent: var(--brand-ink-accent-dark);
    --brand-accent: var(--brand-accent-dark);

    /* Foreground ink flips to the resolver's AA-gated text mirror so a near-black slate primary stays legible on the
       dark canvas; CTA fills floor toward a light slate so a slate primary reads as a raised chip. Mixing toward a
       LIGHT slate (not a dark one) is deliberate: it lifts a dark primary yet keeps a bright primary's dark on-primary
       label AA — mixing toward a dark slate would darken a bright primary and break that label. */
    --brand-interactive: var(--brand-ink-accent-dark);
    --brand-primary-raised: color-mix(in srgb, var(--brand-primary) 80%, #f8fafc);

    /* Elevated surface tints floor toward a lighter slate (#1e293b, the palette's dark surface) instead of the near-black
       canvas, so panels regain hierarchy when the primary is near-black; a chromatic brand still tints the floor. */
    --brand-tint: color-mix(in srgb, var(--brand-primary) 24%, #1e293b);
    --brand-tint-2: color-mix(in srgb, var(--brand-primary) 40%, #1e293b);
    --brand-band: color-mix(in srgb, var(--brand-primary) 20%, #1e293b);
    --brand-accent-soft: color-mix(in srgb, var(--brand-accent) 20%, var(--surface-base));
    --brand-hairline: color-mix(in srgb, var(--brand-accent) 26%, var(--line));
    --on-accent-soft: #f8fafc;

    --shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
    --shadow-lg: 0 10px 28px rgba(0, 0, 0, 0.6);
    --shadow-bar: 0 -4px 20px rgba(0, 0, 0, 0.5);

    --danger-ink: #fca5a5;
    --danger-bg: color-mix(in srgb, #dc2626 20%, var(--surface-base));
    --danger-line: #ef4444;

    --invert-bg: #f1f5f9;
    --invert-ink: #0b0f14;
    --invert-muted: #334155;

    --status-positive-ink: #86efac;
    --status-positive-bg: color-mix(in srgb, #16a34a 22%, var(--surface-base));
    --status-positive-dot: #22c55e;
    --status-caution-ink: #fcd34d;
    --status-caution-bg: color-mix(in srgb, #f59e0b 20%, var(--surface-base));
    --status-caution-dot: #fbbf24;
    --status-negative-ink: #fca5a5;
    --status-negative-bg: color-mix(in srgb, #dc2626 20%, var(--surface-base));
    --status-negative-dot: #f87171;
    --status-neutral-ink: #cbd5e1;
    --status-neutral-bg: color-mix(in srgb, #64748b 22%, var(--surface-base));
    --status-neutral-dot: #94a3b8;

    --tag-muted-bg: color-mix(in srgb, #64748b 18%, var(--surface-base));
    --tag-muted-ink: #cbd5e1;
    --tag-muted-line: #475569;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-body, ui-sans-serif, system-ui, sans-serif);
    font-size: var(--step-0);
    color: var(--ink);
    background: var(--bg);
    line-height: 1.5;
}

button {
    font: inherit;
    cursor: pointer;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border: none;
    border-radius: var(--radius-md);
    padding: 0.55rem 1.1rem;
    transition: filter .12s ease, transform .06s ease;
}

button:hover { filter: brightness(1.08); }

@media (prefers-reduced-motion: no-preference) {
    button:active { transform: scale(.97); }
}

input,
select,
textarea {
    font: inherit;
    font-size: 1rem;
    min-height: 44px;
    width: 100%;
    padding: 0.55rem 0.75rem;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
}

textarea { min-height: 5.5rem; resize: vertical; line-height: 1.5; }

:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 2px; }

img { max-width: 100%; }

/* Utility layer — the Menu's styling convention going forward: compose markup from these single-purpose classes
   instead of new bespoke BEM component classes (no new __ / -- ). Hand-rolled (no Tailwind, no build step) so the
   guest site stays script-free and fast; values map to the brand tokens. Legacy BEM components migrate opportunistically
   as each is touched. Keep this list lean — add a utility only when a real consumer needs it. */
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.grid { display: grid; }
.hidden { display: none; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.items-baseline { align-items: baseline; }
.items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.justify-center { justify-content: center; }
.grow { flex: 1; }
.flex-1 { flex: 1 1 0%; }
.flex-none { flex: none; }
.min-w-0 { min-width: 0; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
.pt-3 { padding-top: 0.75rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-4 { margin-top: 1rem; }
.m-0 { margin: 0; }
.w-full { width: 100%; }
.size-16 { width: 64px; height: 64px; }
.rounded { border-radius: 0.4rem; }
.rounded-lg { border-radius: 0.75rem; }
.rounded-full { border-radius: 999px; }
.favthumb { width: 3rem; height: 3rem; border-radius: var(--radius-md); object-fit: cover; }
.object-cover { object-fit: cover; }
.text-xs { font-size: 0.8rem; }
.text-sm { font-size: 0.9rem; }
.text-display { font-size: 2rem; line-height: 1.1; }
.leading-snug { line-height: 1.4; }
.font-semibold { font-weight: 600; }
.font-display { font-family: var(--brand-font); letter-spacing: var(--brand-display-spacing); }
.nowrap { white-space: nowrap; }
.tabular-nums { font-variant-numeric: tabular-nums; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-muted { color: var(--muted); }
.text-invert-muted { color: var(--invert-muted); }
.text-ink { color: var(--ink); }
.text-accent { color: var(--brand-ink-accent, #b45309); }
.text-brand-accent { color: var(--brand-accent); }
.link { color: var(--brand-interactive); text-decoration: none; font-weight: 600; }
.link:hover { text-decoration: underline; }
.text-interactive { color: var(--brand-interactive); }
.underline { text-decoration: underline; }
.bg-surface { background: var(--bg); }
.bg-tint { background: var(--brand-tint); }
.bg-band { background: var(--brand-band); }
.border-hairline { border: 1px solid var(--brand-hairline); }
.border-t-hairline { border-top: 1px solid var(--brand-hairline); }
.border-b-hairline { border-bottom: 1px solid var(--brand-hairline); }
.cursor-pointer { cursor: pointer; }
.list-none { list-style: none; }
.py-4 { padding-top: 1rem; padding-bottom: 1rem; }
.pb-4 { padding-bottom: 1rem; }
.whitespace-pre-line { white-space: pre-line; }
.size-7 { width: 1.75rem; height: 1.75rem; }
.place-items-center { place-items: center; }
.rotate-on-open { transition: transform var(--dur-2) var(--ease); }
details[open] > summary .rotate-on-open { transform: rotate(45deg); }
summary::-webkit-details-marker { display: none; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-5 { margin-bottom: 1.25rem; }
.mb-6 { margin-bottom: 1.5rem; }
.mt-8 { margin-top: 2rem; }
.mr-3 { margin-right: 0.75rem; }
.gap-2 { gap: 0.5rem; }
.rounded-xl { border-radius: 0.75rem; }
.overflow-hidden { overflow: hidden; }
.text-inherit { color: inherit; }
.no-underline { text-decoration: none; }
.h-48 { height: 12rem; }
.block { display: block; }
.inline-block { display: inline-block; }
.text-lg { font-size: 1.125rem; }
.mx-auto { margin-left: auto; margin-right: auto; }
.aspect-video { aspect-ratio: 16 / 9; }
.max-w-article { max-width: 44rem; }
.max-h-article { max-height: 22rem; }
.prose { color: var(--ink); line-height: 1.7; }
.prose img { max-width: 100%; height: auto; border-radius: 0.5rem; }
.prose a { color: var(--brand-accent); }
.gap-6 { gap: 1.5rem; }
.p-5 { padding: 1.25rem; }
.text-xl { font-size: 1.25rem; }
.text-subhead { font-size: 1.4rem; }
.mb-1 { margin-bottom: 0.25rem; }
.mb-3 { margin-bottom: 0.75rem; }
.italic { font-style: italic; }
.rounded-sm { border-radius: 0.25rem; }
.border-l-accent { border-left: 3px solid var(--brand-accent); }
.mt-1 { margin-top: 0.25rem; }
.mt-3 { margin-top: 0.75rem; }
.mt-6 { margin-top: 1.5rem; }
.p-0 { padding: 0; }
.px-2 { padding-left: 0.6rem; padding-right: 0.6rem; }
.py-1 { padding-top: 0.15rem; padding-bottom: 0.15rem; }
.bg-tint2 { background: var(--brand-tint-2); }
.bg-accent-soft { background: var(--brand-accent-soft); }
.text-on-accent-soft { color: var(--on-accent-soft); }
.border-accent { border-color: var(--brand-accent); }
.bg-caution { background: var(--status-caution-bg); }
.text-caution { color: var(--status-caution-ink); }
.border-caution { border-color: var(--status-caution-dot); }
.bg-tagmuted { background: var(--tag-muted-bg); }
.text-tagmuted { color: var(--tag-muted-ink); }
.border-tagmuted { border-color: var(--tag-muted-line); }
.border-line { border-color: var(--line); }
.self-center { align-self: center; }
.min-h-tap { min-height: 44px; }

.skip-link {
    position: absolute;
    left: 0;
    top: 0;
    transform: translateY(-120%);
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    padding: 0.5rem 1rem;
    z-index: 100;
}
.skip-link:focus { transform: translateY(0); }

.site-header-home { display: inline-flex; }
.site-header-logo { height: 2.5rem; width: auto; display: block; }

/* Single logo control, two canvas variants (#1092): the dark-canvas logo is hidden until the dark theme is active,
   so SSR (no data-theme yet) shows the light-canvas logo. A tenant with no dark variant only renders the light img. */
[data-logo="dark"] { display: none; }
[data-theme="dark"] [data-logo="light"] { display: none; }
[data-theme="dark"] [data-logo="dark"] { display: block; }

.hero-tagline { color: var(--muted); font-size: 1.1rem; margin: 0 0 1rem; }

.content-section { margin: 2rem 0; }
.content-section-body { color: var(--ink); margin: 0; white-space: pre-line; }
.content-section-hours { color: var(--ink); margin: 0; white-space: pre-line; }
.content-section-contact { color: var(--ink); margin: 0; font-style: normal; display: flex; flex-direction: column; gap: 0.25rem; }
.content-section-contact-line { color: inherit; }
.content-section-legal { color: var(--ink); margin: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.content-section-legal-line { color: var(--muted); font-size: 0.875rem; margin: 0; }
.content-section-faq { margin: 0; color: var(--ink); }
.content-section-faq-question { font-weight: 600; margin: 0.75rem 0 0.25rem; }
.content-section-faq-answer { margin: 0; }
.content-section-cta {
    display: inline-block;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.5rem;
    padding: 0.6rem 1.2rem;
    text-decoration: none;
    font-weight: 600;
}

.page {
    max-width: 44rem;
    margin: 0 auto;
    padding: 1.25rem 1rem 4rem;
    scroll-padding-bottom: calc(5.5rem + env(safe-area-inset-bottom));
}

h1 { font-family: var(--font-display); letter-spacing: var(--brand-display-spacing); font-size: var(--step-3); margin: var(--space-2) 0 var(--space-5); line-height: 1.15; }
h2 { font-family: var(--font-display); letter-spacing: var(--brand-display-spacing); font-size: var(--step-2); margin: var(--space-6) 0 var(--space-2); line-height: 1.2; }

.quickfind {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 1rem;
    padding: 0.3rem 0.6rem;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}
.quickfind[hidden] { display: none !important; }
.quickfind:focus-within { border-color: var(--brand-accent); }
@media (min-width: 48rem) { .quickfind { max-width: 44rem; } }
.quickfind-icon { display: inline-flex; flex: none; color: var(--muted); }
.quickfind-input {
    font: inherit;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    padding: 0.25rem 0;
    color: var(--ink);
    background: transparent;
    border: none;
}
.quickfind-input:focus { outline: none; }
.quickfind-input::-webkit-search-cancel-button { display: none; }
.quickfind-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 44px;
    height: 44px;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--muted);
    background: transparent;
    border: none;
    border-radius: 0.4rem;
    cursor: pointer;
}
.quickfind-clear[hidden] { display: none !important; }
.quickfind-clear:hover { color: var(--ink); }
.quickfind-empty {
    margin: 0 0 1.5rem;
    padding: 1.5rem 1rem;
    color: var(--muted);
    text-align: center;
}
.quickfind-empty[hidden] { display: none !important; }
.quickfind-count { margin: 0; }
.dish[hidden], .menu-section[hidden], .menu[hidden], .cat-nav-list li[hidden] { display: none !important; }

.menu-search {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin: 0 0 1.5rem;
    padding: 1rem;
    background-color: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
/* On wide screens the search/filter card must not stretch to the full content width as empty space and push the
   food down — cap it so dishes surface sooner. */
@media (min-width: 48rem) { .menu-search { max-width: 44rem; } }
.menu-search-input {
    font: inherit;
    width: 100%;
    min-height: 44px;
    padding: 0.55rem 0.75rem;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}
.menu-search-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    border: none;
}
.menu-search-legend {
    width: 100%;
    padding: 0;
    margin: 0 0 0.5rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--muted);
}
.menu-search-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    padding: 0.4rem 0.85rem;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    color: var(--ink);
    font-size: 0.9rem;
    cursor: pointer;
}
.menu-search-chip:hover { border-color: var(--brand-accent); }
.menu-search-chip:has(input:checked) {
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-color: var(--brand-primary-raised);
}
.menu-search-chip:has(input:focus-visible) {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
}
.menu-search-chip input {
    width: 1rem;
    height: 1rem;
    margin: 0;
    accent-color: var(--brand-interactive);
}
.menu-search-chip-allergen:has(input:checked) { border-color: var(--brand-primary-raised); }
.menu-search-diet {
    gap: 0.6rem;
}
.menu-search-chip-diet {
    font-size: 0.95rem;
    font-weight: 600;
}
.menu-search-diet-icon {
    font-size: 1.1rem;
    line-height: 1;
}
.menu-search-avail {
    gap: 0.6rem;
}
.menu-search-chip-avail {
    font-weight: 600;
}
.menu-search-avail-icon {
    font-size: 1rem;
    line-height: 1;
}
.menu-search-chips-ingredients {
    padding-top: 0.75rem;
    border-top: 1px solid var(--line);
}

/* Collapsible filter drawer (native <details> — SSR, zero JS): search + dish-type chips stay one tap,
   the rest folds away so the mobile menu opens on dishes, not a wall of controls. */
.menu-filters { margin: 0; }
.menu-filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    padding: 0.4rem 0.85rem;
    list-style: none;
    cursor: pointer;
    color: var(--ink);
    font-size: 0.95rem;
    font-weight: 600;
    background: var(--bg);
    border: 1px solid var(--brand-hairline);
    border-radius: 999px;
}
.menu-filters-toggle::-webkit-details-marker { display: none; }
.menu-filters-toggle::after { content: "▾"; color: var(--muted); font-size: 0.8rem; }
.menu-filters[open] > .menu-filters-toggle::after { content: "▴"; }
.menu-filters-toggle:hover { border-color: var(--brand-accent); }
.menu-filters-toggle-icon { display: inline-flex; align-items: center; }
.menu-filters-toggle-text { line-height: 1.2; }
.menu-filters-body {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding-top: 1rem;
}
/* The 14-allergen wall stays legally one tap away, behind its own labelled disclosure. */
.menu-filters-allergens {
    padding-top: 0.75rem;
    border-top: 1px solid var(--line);
}
.menu-filters-allergens-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    list-style: none;
    cursor: pointer;
    color: var(--ink);
    font-size: 0.9rem;
    font-weight: 600;
}
.menu-filters-allergens-toggle::-webkit-details-marker { display: none; }
.menu-filters-allergens-toggle::after { content: "▾"; color: var(--muted); font-size: 0.8rem; }
.menu-filters-allergens[open] > .menu-filters-allergens-toggle::after { content: "▴"; }
.menu-filters-allergens-note {
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
    line-height: 1.4;
    color: var(--muted);
}
.menu-search-chips-allergens { padding-top: 0.5rem; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
/* Allergen note: the full legal disclosure stays present + expandable (compliance), but collapsed by default so it
   doesn't push the whole menu below the fold. The per-dish allergens are always visible regardless. */
.allergen-note {
    margin: 0;
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    background: var(--bg);
}
.allergen-note-summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0.75rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    list-style: none;
}
.allergen-note-summary::-webkit-details-marker { display: none; }
.allergen-note-summary::after { content: "›"; margin-left: auto; transition: transform var(--dur-1, 0.15s) ease; }
.allergen-note[open] .allergen-note-summary::after { transform: rotate(90deg); }
.allergen-note-text {
    margin: 0;
    padding: 0 0.75rem 0.6rem;
    font-size: 0.85rem;
    color: var(--ink);
}
/* Search is a secondary action: browsing + ordering own the filled-amber weight, so the submit is a calm outline —
   the boldest fill on the page must be the cart bar / add control, never "Search". */
.menu-search-submit {
    min-height: 44px;
    align-self: flex-start;
    background: var(--bg);
    color: var(--brand-ink-accent, #b45309);
    border: 1.5px solid var(--brand-hairline);
}
.menu-search-submit:hover { border-color: var(--brand-accent); filter: none; }

.menu-search-status {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 0 0 0.5rem;
}
.menu-search-count { color: var(--muted); margin: 0; font-size: 0.95rem; }
.menu-search-clear {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--ink);
    font-size: 0.95rem;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.menu-search-clear:hover { color: var(--muted); }
.menu-search-active {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 1rem;
    font-size: 0.9rem;
    color: var(--muted);
}
.menu-search-active-label { font-weight: 600; color: var(--ink); }
.menu-search-active-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.6rem;
    background: var(--brand-tint-2);
    border: 1px solid var(--brand-hairline);
    border-radius: 999px;
    color: var(--ink);
}
.menu-search-active-chip-avail { gap: 0.3rem; }

.menu-description { color: var(--muted); margin: 0 0 1rem; }
/* Category heading: a distinct middle tier between the display group title (`.menu h2`, larger, on-tint, 2px rule)
   and the dish rows. The tenant identity now rides the brand font + the AA-gated ink-accent colour and a light
   hairline underline — NOT a filled accent-soft box, which read identically to the allergen/alert callouts and
   flattened the hierarchy. Smaller than the group title so the two tiers read as two tiers. */
.category-heading {
    display: block;
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    font-size: var(--step-1);
    line-height: 1.2;
    font-weight: 700;
    margin: 3rem 0 0.85rem;
    padding: 0 0 0.4rem;
    color: var(--brand-ink-accent, #b45309);
    border-bottom: 1px solid var(--brand-hairline);
}
/* First category sits tight under the search/hero; only later ones need the big top gap. */
.menu-section:first-of-type .category-heading { margin-top: 0.5rem; }
.menu-section-items { list-style: none; margin: 0; padding: 0; }

.dish { padding: 0.75rem 0; border-bottom: 1px solid var(--line); scroll-margin-top: 4.5rem; }
.dish-image {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: 0.75rem;
    margin: 0 0 0.75rem;
    display: block;
    background: var(--line);
}
.dish-head { display: flex; justify-content: space-between; gap: 1rem; font-weight: 600; }
.dish-description { color: var(--muted); margin: 0.35rem 0 0; max-width: 42ch; font-weight: 400; }
.dish-price { display: block; white-space: nowrap; color: var(--brand-ink-accent, #b45309); font-weight: 700; margin: 0.35rem 0 0; font-variant-numeric: tabular-nums; }
/* A long FR name must shrink/wrap instead of squeezing the price (#1229 P1-6): the name takes min-width:0 so flex can
   shrink it, the price block never shrinks so the two-line dual price stays right-aligned and fully visible at 320px. */
.dish-head .dish-name { min-width: 0; overflow-wrap: anywhere; }
.dish-head .dish-price { margin: 0; flex: 0 0 auto; }

/* Premium no-photo presentation (list preset, crucial for Basta): an editorial "menu card" whose name and price
   are tied together by a dotted leader (name ···· price). aria-hidden — purely decorative rhythm. */
.dish-lead { display: none; }
[data-menu-layout="list"] .dish-head,
[data-menu-layout="card-grid"] .dish-head { align-items: baseline; }
[data-menu-layout="list"] .dish-lead,
[data-menu-layout="card-grid"] .dish-lead {
    display: block;
    flex: 1 1 auto;
    align-self: center;
    min-width: 1.25rem;
    margin: 0 0.4rem;
    border-bottom: 1px dotted var(--brand-hairline);
    opacity: 0.6;
}
/* Editorial hover (P1-2, desktop / hover-capable pointers only): the dotted leader thickens and the dish name nudges
   2px toward it, tying name → price with a premium flourish. Gated behind both hover capability and no-preference, so
   touch devices and reduced-motion users see no motion. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    [data-menu-layout="list"] .dish-name,
    [data-menu-layout="card-grid"] .dish-name { transition: transform var(--dur-1) var(--ease); }
    [data-menu-layout="list"] .dish-lead,
    [data-menu-layout="card-grid"] .dish-lead { transition: border-bottom-width var(--dur-1) var(--ease); }
    [data-menu-layout="list"] .dish:hover .dish-name,
    [data-menu-layout="card-grid"] .dish:hover .dish-name { transform: translateX(2px); }
    [data-menu-layout="list"] .dish:hover .dish-lead,
    [data-menu-layout="card-grid"] .dish:hover .dish-lead { border-bottom-width: 3px; }
}

/* Bounded menu-layout presets (per-tenant brand kit, never free CSS). The wrapper carries
   data-menu-layout=list|card-grid|large-photo; each renders the same dish markup differently
   with a brand-led identity. Defined after the base .dish/.dish-image rules so these win by source order. */
.menu-layout { display: block; }

/* list = editorial: roomier line-height and a bottom hairline (from .dish) separate rows. The old per-dish accent
   left-rule was dropped — stacked under the filter card, disclaimer and category it made every dish a blockquote
   and muddied the hierarchy; the row's own bottom hairline is enough. */
[data-menu-layout="list"] .dish {
    line-height: 1.6;
}

[data-menu-layout="card-grid"] .menu-section-items {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}
[data-menu-layout="card-grid"] .dish {
    border: 1px solid var(--brand-hairline);
    border-top: 3px solid var(--brand-accent);
    border-radius: 0.75rem;
    padding: 0.85rem;
    background: var(--bg);
    transition: background-color 0.15s ease;
}
[data-menu-layout="card-grid"] .dish:hover { background: var(--brand-tint); }

/* Add control rides a right rail instead of a tall dead row under each dish: the dish becomes a 2-col grid (content |
   action), the "+" spans all rows vertically-centred beside its dish. Cuts height across the whole list; scoped to the
   text presets so large-photo (price-over-photo) is untouched. */
[data-menu-layout="list"] .dish,
[data-menu-layout="card-grid"] .dish {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 1rem;
    align-items: start;
    /* Named container so the rail below reacts to the CARD's width, not the viewport's: the list goes two-up on a
       wide screen, which makes each card NARROWER exactly when a media query would say there is room. */
    container: dish / inline-size;
}
[data-menu-layout="list"] .dish > *,
[data-menu-layout="card-grid"] .dish > * { grid-column: 1; }
[data-menu-layout="list"] .dish-image,
[data-menu-layout="card-grid"] .dish-image { grid-column: 1 / -1; }

/* The rail is OPT-IN, not the default. `.dish-add` is a quantity stepper plus a nowrap "Add to cart" label, so its
   min-content is ~19rem and it cannot shrink; parked in the `auto` track it took the whole card and left the `1fr`
   content track at 0px, which rendered every dish name one character per line (measured: 143px card content vs a
   301px rail). Full-width row by default — always correct — and the rail returns only once the card can seat both. */
[data-menu-layout="list"] .dish-add,
[data-menu-layout="card-grid"] .dish-add {
    grid-column: 1 / -1;
    margin: 0.3rem 0 0;
}

@container dish (min-width: 34rem) {
    [data-menu-layout="list"] .dish-add,
    [data-menu-layout="card-grid"] .dish-add {
        grid-column: 2;
        grid-row: 1 / -1;
        align-self: center;
        margin: 0;
    }
}

/* Allergen safety reminder: while an exclusion filter is active the note must stay in view as the dish list scrolls,
   so it pins just under the masthead (CSS-only, works JS-off). Icon + words carry the warning — never colour alone. */
.allergenpin {
    position: sticky;
    top: calc(3.75rem + env(safe-area-inset-top));
    z-index: 25;
    margin: 0 -1rem 1.25rem;
    padding: 0.6rem 1rem;
    background: var(--brand-accent-soft);
    border-bottom: 1px solid var(--brand-hairline);
    color: var(--ink);
    font-size: 0.85rem;
    line-height: 1.35;
    font-weight: 500;
}
.allergenpin-icon { color: var(--brand-ink-accent, #b45309); }
/* When the reminder is pinned, drop the category bar below it so the two sticky bars stack instead of overlapping. */
.allergenpin ~ .cat-nav { top: calc(3.75rem + env(safe-area-inset-top) + 3.5rem); }

/* Category jump-nav: a horizontally-scrollable chip bar that anchors to each section, sticky just under the sticky
   masthead so a guest can switch sections mid-scroll instead of thumbing past ~25 dishes. Anchor links work with JS
   off; scroll-margin keeps a jumped-to heading clear of the two sticky bars. */
.cat-nav {
    position: sticky;
    top: calc(3.75rem + env(safe-area-inset-top));
    z-index: 20;
    margin: 0 -1rem 1.25rem;
    padding: 0.6rem 1rem;
    background: var(--bg);
    border-bottom: 1px solid var(--brand-hairline);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* Feather both edges so guests see the chip row scrolls (the last category no longer clips hard). */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 1rem, #000 calc(100% - 1.5rem), transparent);
            mask-image: linear-gradient(90deg, transparent, #000 1rem, #000 calc(100% - 1.5rem), transparent);
}
.cat-nav::-webkit-scrollbar { display: none; }
.cat-nav-list { list-style: none; padding: 0; width: max-content; }
.cat-chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0.9rem;
    border-radius: 999px;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    color: var(--brand-ink-accent, #b45309);
    font-weight: 600;
    font-size: 0.85rem;
    white-space: nowrap;
    text-decoration: none;
}
.cat-chip:hover { border-color: var(--brand-accent); background: var(--brand-tint-2, var(--brand-tint)); }
@media (prefers-reduced-motion: no-preference) {
    .cat-chip { transition: transform var(--dur-1) var(--ease), background var(--dur-1) var(--ease); }
    .cat-chip:active { transform: scale(0.96); }
}
/* Scroll-spy active chip (menu-nav.js sets aria-current): a bordered emphasis, not a loud amber fill — it marks
   location, and filled amber stays reserved for ordering. Degrades to no highlight with JS off. */
.cat-chip[aria-current="true"] {
    background: var(--brand-accent-soft);
    border-color: var(--brand-accent);
    color: var(--brand-ink-accent, #b45309);
    font-weight: 700;
}
.menu-section { scroll-margin-top: calc(7.5rem + env(safe-area-inset-top)); }

/* large-photo = photo-forward: the price rides over the dish image as a brand pill, bottom-right. */
[data-menu-layout="large-photo"] .dish { position: relative; }
[data-menu-layout="large-photo"] .dish-image {
    aspect-ratio: 4 / 3;
    margin-bottom: 1rem;
}
[data-menu-layout="large-photo"] .dish-name { font-size: 1.15rem; }
[data-menu-layout="large-photo"] .dish-price {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    padding: 0.2rem 0.7rem;
    background: var(--brand-primary);
    color: var(--brand-on-primary);
    border-radius: 999px;
    font-weight: 700;
    z-index: 1;
}
[data-menu-layout="compact"] .dish-image { display: none; }
[data-menu-layout="compact"] .dish { line-height: 1.35; }
[data-menu-layout="compact"] .dish-lead {
    display: block;
    flex: 1 1 auto;
    align-self: center;
    min-width: 1.25rem;
    margin: 0 0.4rem;
    border-bottom: 1px dotted var(--brand-hairline);
    opacity: 0.6;
}
[data-menu-layout="compact"] .dish-head { align-items: baseline; }

/* Server-rendered add-to-cart confirmation (#1231): a persistent positive chip on the just-added dish, shown after the
   POST-Redirect-GET so it survives with JS off. Colour is never the sole signal — the check icon + word carry it too. */
.dish-added {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin: 0.3rem 0 0;
    padding: 0.1rem 0.55rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--status-positive-ink);
    background: var(--status-positive-bg);
    border: 1px solid color-mix(in srgb, var(--status-positive-dot) 40%, transparent);
    border-radius: 999px;
}
.dish-added-icon { display: inline-flex; color: var(--status-positive-dot); }
.dish-added-text { white-space: nowrap; }

/* Favourite toggle for a signed-in guest (#1208): a JS-off form-post heart on each dish card. Filled/outline icon PLUS
   the aria-label carry the state — never colour alone (WCAG 2.2). ≥44px tap target on the guest surface. */
.heart { display: flex; justify-content: flex-end; margin: 0.35rem 0 0; }
.heart button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 999px;
    color: var(--subtle);
    cursor: pointer;
}
.heart button[aria-pressed="true"] { color: var(--brand-ink-accent, #b45309); }
.heart button:hover { color: var(--brand-ink-accent, #b45309); }

/* Discreet return-to-hub link on the account sub-pages (#1297): keeps the guest's "where am I" on /account/* pages.
   Kept a full 44px tap target on the guest surface. */
.backlink {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    min-height: 44px;
    padding: 0.35rem 0;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
}
.backlink:hover { color: var(--brand-ink-accent, #b45309); }

/* Low-stock band (design-system-ux.md availability vocabulary): the dish stays orderable, so this is an inline caution
   chip on the still-available card. Colour is never the sole signal — the alert icon + the "Low stock" word carry it. */
.lowstock {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin: 0.35rem 0 0;
    padding: 0.1rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--status-caution-ink);
    background: var(--status-caution-bg);
    border: 1px solid color-mix(in srgb, var(--status-caution-dot) 40%, transparent);
    border-radius: 999px;
}
.lowstock-icon { display: inline-flex; color: var(--status-caution-dot); }
.lowstock-text { white-space: nowrap; }

/* Sold-out chip for a cart line whose dish went unavailable while in the cart (design-system-ux.md availability
   vocabulary, WCAG 2.2): the word + alert icon carry it, never colour alone. Block-level so it sits on its own line
   under the dish name; the line itself is de-emphasised and struck through by .cart-line-unavailable. */
.soldout {
    display: flex;
    width: fit-content;
    align-items: center;
    gap: 0.3rem;
    margin: 0.35rem 0 0;
    padding: 0.1rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--status-negative-ink);
    background: var(--status-negative-bg);
    border: 1px solid color-mix(in srgb, var(--status-negative-dot) 40%, transparent);
    border-radius: 999px;
}
.soldout-icon { display: inline-flex; color: var(--status-negative-dot); }
.soldout-text { white-space: nowrap; }

/* Sold-out refinement (P1-4, contrast fix #1466): the name recedes to --subtle, the price carries a light strike, and
   only the photo dims to ~0.6 — the description/tags/ingredients keep full opacity because --muted (#475569) already
   clears WCAG 2.2 AA 4.5:1 on white; an opacity multiplier on top of --muted dropped body copy under the floor. The
   "Indisponible" text badge AND the legal allergen caption stay untouched too, so availability is never conveyed by
   opacity alone and allergen disclosure stays legible. No opacity on .dish itself, or the badge/allergens would
   inherit the dim. */
.dish-sold-out .dish-name { color: var(--subtle); }
.dish-sold-out .dish-price {
    color: var(--subtle);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}
.dish-sold-out .dish-image { opacity: 0.6; }

.pay-stripe,
.receipt-pay-stripe {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin: 1rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}

.pay-card-heading,
.receipt-pay-card-heading {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: var(--ink);
}

.pay-amount,
.receipt-pay-amount,
.receipt-pay-total {
    margin: 0;
    color: var(--ink);
}

.receipt-pay-total {
    font-size: 1.25rem;
    font-weight: 700;
}

.receipt-pay-total-amount {
    color: var(--brand-interactive);
}

.pay-element,
.receipt-pay-element {
    min-height: 3rem;
    padding: 0.85rem;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}

.pay-element[data-loading]::after,
.receipt-pay-element[data-loading]::after {
    content: attr(data-loading);
    display: block;
    color: var(--muted);
    font-size: 0.9rem;
}

.pay-submit,
.receipt-pay-submit {
    min-height: 48px;
    width: 100%;
    font-weight: 600;
    font-size: 1rem;
}

.pay-submit:disabled,
.receipt-pay-submit:disabled {
    background: var(--border-strong);
    color: var(--muted);
    cursor: not-allowed;
    filter: none;
}

.pay-stripe-error,
.receipt-pay-stripe-error {
    margin: 0;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
    font-size: 0.95rem;
}

.pay-field,
.receipt-pay-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0 0 1rem;
    color: var(--ink);
    font-weight: 600;
}

.pay-field input,
.receipt-pay-field input {
    font: inherit;
    width: 100%;
    min-height: 44px;
    font-size: 1rem;
    padding: 0.55rem 0.75rem;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}

.offline-banner {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.6rem 1rem;
    background: var(--invert-bg);
    color: var(--invert-ink);
    text-align: center;
    font-size: 0.9rem;
}

.offline-banner[hidden] { display: none !important; }


@media (min-width: 40rem) {
    .offline-banner {
        flex-direction: row;
        justify-content: center;
        gap: 0.5rem;
    }
}


/* Site chrome: sticky full-bleed bar; an inner column centres the nav to the page width on desktop.
   The masthead fills the brand band so the skeleton — not just the accents — reads as this restaurant;
   the accent signature line sits over it. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    /* Honour the top notch/status-bar inset: installed as a PWA with a black-translucent status bar, content runs
       under the notch, so the masthead needs the top safe-area or the wordmark underlaps the Dynamic Island. */
    padding: calc(0.6rem + env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) 0.6rem max(1rem, env(safe-area-inset-left));
    background: var(--brand-band);
    border-bottom: 2px solid var(--brand-accent);
}

.site-header-wordmark {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    color: var(--ink);
    font-family: var(--brand-font);
    font-weight: 700;
    font-size: 1.2rem;
    line-height: 1.1;
    text-decoration: none;
    letter-spacing: 0.01em;
}
.site-header-mark { display: block; height: 1.9rem; width: auto; }

/* Wordmark logotype: the tenant name inked cream on the brand-primary plaque (resolver-gated AA pair, so any tenant
   stays legible in both themes). The italic display cut gives the warm, casual voice; the fills are tokens, never
   hardcoded, so a configured tenant brand drives it and Basta reads as cream "basta." on olive-gold. */
.brand-wordmark { display: block; height: auto; }
/* When the wordmark IS the header mark it must respect the header cap: the intrinsic SVG height (120) would
   otherwise win over `.site-header-mark` by source order, blowing the logo up to ~120px and clipping the mobile
   nav. This combined selector out-specifies the base rule so the header logo stays a compact ~36px logotype. */
.site-header-mark.brand-wordmark { height: 2.25rem; width: auto; }
.brand-wordmark-plaque { fill: var(--brand-primary); }
.brand-wordmark-text {
    fill: var(--brand-on-primary);
    font-family: var(--brand-font);
    font-weight: 700;
    font-style: italic;
    letter-spacing: 0.01em;
}

.site-header-inner {
    display: flex;
    align-items: center;
    gap: 0.5rem 1rem;
}

.token-icon { display: block; flex: none; }

/* Theme toggle (progressive enhancement, SSR-safe): flips data-theme, persists the choice, 44px target with
   aria-pressed. The sun/moon icons swap on the active theme — the icon shows the theme you switch TO. */
.site-theme {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0.35rem;
    color: var(--ink);
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
}
.site-theme:hover { background: var(--brand-tint-2); filter: none; }
.site-theme-icon { display: inline-flex; }
.site-theme-icon-sun { display: none; }
[data-theme="dark"] .site-theme-icon-sun { display: inline-flex; }
[data-theme="dark"] .site-theme-icon-moon { display: none; }

/* Compact chrome: wordmark left; one 🌐 language control, the cart icon and the nav disclosure right.
   Both menus are native <details> dropdowns (SSR, zero JS), 44px targets throughout. */
.site-header-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
    /* Five fixed 44px touch targets: this side cannot give, so the wordmark is the one that yields (below). */
    flex-shrink: 0;
}

/* Nothing in the header row could shrink — both sides defaulted to min-width:auto, so a long tenant name plus the
   five controls simply ran past the viewport (measured 519px of content in a 453px row) and dragged the
   absolutely-positioned nav panel off-screen with it, giving the whole guest site a horizontal scrollbar on a phone.
   The wordmark truncates instead; the controls stay whole because they are the interactive ones. */
.site-header-wordmark {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Below ~26rem even a truncated wordmark is a stub, so the menu toggle drops its visible word and keeps the icon.
   Visually hidden, NOT display:none — the button must keep its accessible name. */
@media (max-width: 26rem) {
    .site-menu-label {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

.site-lang,
.site-menu { position: relative; }

.site-lang-toggle,
.site-menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    min-width: 44px;
    min-height: 44px;
    padding: 0.35rem 0.6rem;
    list-style: none;
    cursor: pointer;
    color: var(--ink);
    font-size: 0.85rem;
    font-weight: 600;
    border-radius: 0.5rem;
}

.site-lang-toggle::-webkit-details-marker,
.site-menu-toggle::-webkit-details-marker { display: none; }

.site-lang-toggle:hover,
.site-menu-toggle:hover { background: var(--brand-tint-2); }

.site-lang[open] > .site-lang-toggle,
.site-menu[open] > .site-menu-toggle { background: var(--brand-tint-2); }

.site-lang-abbr { line-height: 1; }
.site-menu-label { line-height: 1; }

.site-lang-menu,
.site-nav {
    position: absolute;
    right: 0;
    top: calc(100% + 0.4rem);
    z-index: 45;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 12rem;
    padding: 0.5rem;
    background: var(--bg);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
    box-shadow: var(--shadow);
}

.site-nav-link {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.35rem 0.75rem;
    color: var(--ink);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    border-radius: 0.5rem;
}

.site-nav-link:hover { background: var(--brand-tint-2); }

.site-nav-link-active {
    box-shadow: inset 3px 0 0 0 var(--brand-accent);
    background: var(--brand-tint);
}

.site-cart {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    color: var(--brand-interactive);
    border-radius: 0.5rem;
}

.site-cart:hover { background: var(--brand-tint-2); }

.site-account {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    color: var(--brand-interactive);
    border-radius: 0.5rem;
}

.site-account:hover { background: var(--brand-tint-2); }

/* Signed-in presence cue on the account icon — a filled dot reads at a glance where the subtle bg tint alone did not.
   Decorative (aria-hidden); the authenticated state is already named by the anchor's aria-label. */
.presence-dot {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
    width: 0.5rem;
    height: 0.5rem;
    background: var(--brand-primary-raised);
    border-radius: 999px;
    box-shadow: 0 0 0 2px var(--brand-band);
}

.account { display: flex; flex-direction: column; gap: 1rem; align-items: flex-start; list-style: none; padding: 0; }

.navcard {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.75rem 1rem;
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
    background: var(--bg);
    color: var(--ink);
    text-decoration: none;
}
.navcard:hover { border-color: var(--brand-accent); background: var(--brand-tint); }
.navicon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 0.6rem;
    background: var(--brand-tint);
    color: var(--brand-ink-accent, #b45309);
}

.orders { display: flex; flex-direction: column; gap: 1rem; list-style: none; padding: 0; }
.orders > li { gap: 0.5rem; padding-top: 1rem; border-top: 1px solid var(--brand-hairline); }
.orders > li:first-child { border-top: 0; padding-top: 0; }

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.6rem 1.4rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border: 0;
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
    cursor: pointer;
}

.btn:hover { filter: brightness(1.08); }

.btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.55rem 1.2rem;
    background: transparent;
    color: var(--brand-interactive);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
    cursor: pointer;
}

.btn-ghost:hover { background: var(--brand-tint-2); }

.site-cart-count {
    position: absolute;
    top: 0.15rem;
    right: 0.05rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.15rem;
    height: 1.15rem;
    padding: 0 0.3rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
/* Basket counter pop (P1-2): ludic.js adds this class when the count grew since the last render (an item was added),
   springing the badge with the emphasis easing. Gated behind no-preference — reduced-motion sees the new number, no pop. */
@media (prefers-reduced-motion: no-preference) {
    .site-cart-count-pop { animation: count-pop var(--dur-3) var(--ease-emphasis); }
}
@keyframes count-pop {
    0% { transform: scale(1); }
    35% { transform: scale(1.4); }
    70% { transform: scale(0.9); }
    100% { transform: scale(1); }
}

.site-lang-link {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.25rem 0.75rem;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    white-space: nowrap;
    border-radius: 0.5rem;
}

.site-lang-link:hover { background: var(--brand-tint-2); color: var(--ink); }

.site-lang-link-active {
    color: var(--brand-on-primary);
    background: var(--brand-primary-raised);
}

/* Home: hero, signatures */
.hero { margin: 0 0 1.5rem; }
.hero-heading {
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    font-size: clamp(1.9rem, 6.5vw, 3.4rem);
    line-height: 1.1;
    margin: 0.5rem 0 0.75rem;
}

/* Branded hero: the tenant's image as a background band behind an overlaid title (the LCP element). The reserved
   aspect-ratio box + the explicit img width/height kill layout shift; the scrim keeps the white title AA over any photo. */
.hero-branded {
    position: relative;
    border-radius: 0.75rem;
    overflow: hidden;
    aspect-ratio: 2 / 1;
    margin: 0 0 1.5rem;
}
.hero-branded .hero-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--brand-hero-focal, 50% 50%);
    display: block;
}
/* Brand-tinted scrim: a faint primary wash up top deepening to a near-black brand shade (primary 72%-toward-black) at
   the bottom text band, so the photo reads as the tenant's — and the white overlaid title stays AA over the dark band. */
.hero-branded::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--brand-primary) 10%, transparent),
        color-mix(in srgb, var(--brand-primary), #000000 72%) 88%);
}
.hero-branded .hero-overlay {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 1;
    padding: clamp(1.25rem, 4vw, 2.25rem);
}
.hero-branded .hero-heading,
.hero-branded .hero-tagline {
    color: #f8fafc;
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
}

/* No-image fallback: a warm brand-tint band with a 4px accent rule across the top keeps the home identity-led; the title
   inks in the on-tint brand colour (the primary, gated to AA-large ≥3:1 on the near-white tint) and the tenant logo leads
   above the wordmark. */
.hero-tint {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: clamp(17rem, 42vh, 26rem);
    padding: clamp(2rem, 5vw, 3.25rem) clamp(1.25rem, 4vw, 2.75rem);
    border-radius: 0.75rem;
    background-color: var(--brand-tint);
    background-image:
        radial-gradient(125% 90% at 12% 0%, color-mix(in srgb, var(--brand-primary) 12%, transparent), transparent 62%),
        repeating-linear-gradient(
            135deg,
            color-mix(in srgb, var(--brand-primary) 2%, transparent) 0,
            color-mix(in srgb, var(--brand-primary) 2%, transparent) 1px,
            transparent 1px,
            transparent 4px);
    border: 1px solid var(--brand-hairline);
    border-top: 4px solid var(--brand-accent);
}
.hero-tint .hero-logo {
    height: 3.5rem;
    width: auto;
    display: block;
    margin: 0 0 0.85rem;
}
/* No-photo hero: type is the identity. A tracked olive-gold eyebrow (with an accent rule), a large confident heading
   inked in the AA-gated on-tint brand colour, and a measured tagline — all on the warm brand-tint band. Every colour
   is a theme-adaptive token, so it re-inks correctly in the dark canvas and for any configured tenant brand. */
.hero-eyebrow {
    display: inline-flex;
    align-items: center;
    align-self: start;
    gap: 0.6rem;
    margin: 0 0 0.6rem;
    font-family: var(--brand-font);
    font-size: var(--step--1);
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--brand-ink-accent);
}
.hero-eyebrow::before {
    content: "";
    width: 1.75rem;
    height: 2px;
    border-radius: 999px;
    background: var(--brand-accent);
}
.hero-tint .hero-heading {
    margin-top: 0;
    color: var(--brand-on-tint);
    font-size: clamp(2.4rem, 9vw, 4.4rem);
    line-height: 1.02;
    letter-spacing: -0.015em;
}
.hero-tint .hero-tagline {
    max-width: 36ch;
    font-size: var(--step-1);
}

/* Home layout templates (bounded owner presets — never free CSS): data-home-template varies the hero composition.
   classic is the default treatment above; centered / split-image / minimal adjust alignment, layout, or chrome. */
.hero[data-home-template="centered"] { text-align: center; }
.hero-tint[data-home-template="centered"] { align-items: center; }
.hero[data-home-template="centered"] .hero-eyebrow { align-self: center; }
.hero[data-home-template="centered"] .hero-tagline { margin-left: auto; margin-right: auto; }
.hero[data-home-template="centered"] .hero-actions { justify-content: center; }

@media (min-width: 40rem) {
    .hero-branded[data-home-template="split-image"] {
        aspect-ratio: auto;
        display: grid;
        grid-template-columns: 1fr 1fr;
        align-items: stretch;
        min-height: 20rem;
    }
    .hero-branded[data-home-template="split-image"] .hero-image { position: relative; }
    .hero-branded[data-home-template="split-image"]::after { display: none; }
    .hero-branded[data-home-template="split-image"] .hero-overlay {
        position: relative;
        inset: auto;
        display: flex;
        flex-direction: column;
        justify-content: center;
        background: color-mix(in srgb, var(--brand-primary), #000000 72%);
    }
}

.hero-tint[data-home-template="minimal"] {
    background-image: none;
    border: none;
    padding-left: 0;
    padding-right: 0;
    min-height: auto;
}
.hero[data-home-template="minimal"] .hero-eyebrow { display: none; }
.hero-branded[data-home-template="minimal"] { aspect-ratio: 21 / 9; }

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 1.25rem 0 0;
}
.hero-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.6rem 1.4rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
}
.hero-cta:hover { filter: brightness(1.08); }
.hero-cta-secondary {
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--brand-accent);
}
.hero-cta-secondary:hover { background: var(--brand-accent-soft); filter: none; }

/* Landing info strip: the profile's canonical address / hours / phone — only the facts that exist, no empty shells. */
.home-info {
    margin: 0 0 1.5rem;
    padding: 0.85rem 1rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.home-info-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.home-info-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    color: var(--ink);
}
.home-info-icon {
    display: inline-flex;
    align-items: center;
    min-height: 1.5rem;
    color: var(--brand-interactive);
}
.home-info-text { line-height: 1.5; }
.home-info-text-hours { white-space: pre-line; }
.home-info-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin: -0.6rem 0;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: none;
}
.home-info-link:hover { text-decoration: underline; }

/* Landing reservation invitation — a warm band with the one action; hidden entirely once a reservations
   on/off tenant setting exists and is off. */
.home-reserve {
    margin: 2rem 0;
    padding: 1.5rem 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-left: 4px solid var(--brand-accent);
    border-radius: 0.75rem;
}

.signatures { margin: 2rem 0; }
/* Suggestion of the day: an accent rail + accent title mark it as "today", distinct from the permanent signatures. */
.suggestion { padding-left: 0.9rem; border-left: 3px solid var(--brand-accent); }
.signature-heading {
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    font-size: 1.4rem;
    margin: 0 0 0.75rem;
}
.signatures-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
}
.signatures-item { margin: 0; }
.signatures-link {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 0.85rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
    text-decoration: none;
    color: var(--ink);
}
.signatures-link:hover { border-color: var(--brand-accent); }
.signatures-name { font-weight: 600; }
.signatures-price { white-space: nowrap; color: var(--brand-ink-accent, #b45309); font-weight: 600; }

/* Menu: table banner, status messages, off-hours, sections */
.menu { margin: 0 0 2rem; }
/* Group title: brand font (serif=bistro / rounded=casual / sans=modern) inked in the on-tint brand colour, on a hairline
   section rule so each menu group opens with a structural, restaurant-led divider. AA-large (≥3:1) on bold display type. */
.menu h2 {
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    color: var(--brand-on-tint);
    padding-bottom: 0.4rem;
    border-bottom: 2px solid var(--brand-hairline);
}
.menu-section { margin: 0 0 0.5rem; }
.menu-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.85rem;
    margin: 1.5rem 0;
    padding: 2.5rem 1.5rem;
    color: var(--ink);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.menu-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-interactive);
}
.menu-empty-title {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--ink);
}
.menu-empty-text { margin: 0; color: var(--muted); }
.menu-empty-cta,
.cart-empty-cta {
    display: inline-flex;
    align-items: center;
    min-height: 48px;
    padding: 0.6rem 1.4rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
}
.menu-empty-cta:hover,
.cart-empty-cta:hover { filter: brightness(1.08); }
.menu-empty-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}
.menu-empty-contact {
    display: inline-flex;
    align-items: center;
    min-height: 48px;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.menu-empty-contact:hover { color: var(--ink); }
/* Dish-list skeleton (P1-3): shown by the streaming SSR render while the menu API resolves, replaced by the real dishes
   the moment they arrive. Under no-preference the bars shimmer; under reduced-motion they are static muted blocks (the
   shimmer keyframe simply never applies). aria-hidden decoration — a visually-hidden aria-live line announces loading. */
.menu-skeleton { list-style: none; margin: 1.5rem 0 0; padding: 0; }
.menu-skeleton-group { margin: 0 0 2rem; }
.menu-skeleton-heading {
    height: 1.5rem;
    width: 40%;
    margin: 0 0 1rem;
    border-radius: var(--radius-sm);
    background: var(--brand-tint-2);
}
.menu-skeleton-item {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line);
}
.menu-skeleton-line {
    height: 0.85rem;
    border-radius: var(--radius-sm);
    background: var(--brand-tint-2);
}
.menu-skeleton-line-title { width: 55%; height: 1.05rem; }
.menu-skeleton-line-price { width: 20%; }
.menu-skeleton-line-desc { width: 85%; }
@media (prefers-reduced-motion: no-preference) {
    .menu-skeleton-heading,
    .menu-skeleton-line {
        background: linear-gradient(90deg, var(--brand-tint-2) 25%, var(--brand-tint) 50%, var(--brand-tint-2) 75%);
        background-size: 200% 100%;
        animation: skeleton-shimmer 1.4s ease-in-out infinite;
    }
}
@keyframes skeleton-shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}
.menu-cartbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 56px;
    padding: 0.75rem 1.25rem;
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
    color: var(--brand-on-primary);
    background: var(--brand-primary-raised);
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--shadow-bar);
}
/* When the fixed cartbar is showing, reserve its full height PLUS the notch inset below the carte so the last dish's
   Add button stays fully tappable (#1229 P1-3): min-height 56px + vertical padding + env(safe-area-inset-bottom). */
.menu-layout-has-cartbar { padding-bottom: calc(56px + 1.5rem + env(safe-area-inset-bottom)); }
/* The reserve above lives INSIDE .menu-layout, but the MainLayout footer sits AFTER it — so the fixed cartbar covered
   the mentions-légales links at full scroll (#2252 item 4). Lift the footer's own bottom pad by the bar's full height
   (56px + vertical padding + safe-area) so the legal links always clear the fixed bar, on every viewport. */
.page:has(.menu-cartbar) ~ .site-footer { padding-bottom: calc(2rem + 56px + 1.5rem + env(safe-area-inset-bottom)); }
.menu-cartbar:hover { filter: brightness(1.06); }
.menu-cartbar-summary { font-variant-numeric: tabular-nums; }
.menu-cartbar-cta {
    display: inline-flex;
    align-items: center;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.menu-table-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 1.25rem;
    padding: 0.75rem 1rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}
.menu-table-banner-text { font-weight: 600; }
.menu-leave-table {
    min-height: 44px;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--border-strong);
}
.menu-leave-table:hover { border-color: var(--brand-accent); filter: none; }
.call-waiter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 44px;
    padding: 0.5rem 1rem;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
    font-weight: 600;
    text-decoration: none;
}
.call-waiter:hover { border-color: var(--brand-accent); }
.call-waiter:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; }
.menu-off-hours-badge {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--muted);
    background: var(--brand-tint-2);
    border: 1px solid var(--brand-hairline);
    border-radius: 999px;
    vertical-align: middle;
}
.menu-off-hours { opacity: 0.85; }
.menu-search-chip-text { line-height: 1.2; }

/* Dish: name, tags, dual-price layout, add-to-cart */
.dish-name {
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    font-weight: 600;
}
.dish-price-dual {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.1rem;
    white-space: normal;
    text-align: right;
}
.dish-price-line {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem;
}
[data-menu-layout="large-photo"] .dish-price-dual {
    align-items: flex-end;
    text-align: right;
}
.dish-price-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
/* Add control = a labelled "+ Add" amber pill at the row's trailing edge: the one action that matters, so it reads as a
   button not an anonymous glyph. Amber fill carries dark on-primary ink (palette AA); ≥44px tap target. */
.dish-add { margin: 0.3rem 0 0; display: flex; align-items: center; justify-content: flex-end; gap: 0.5rem; }
.qty-stepper { display: flex; align-items: stretch; gap: 0.25rem; }
.qty-button {
    min-width: 44px;
    min-height: 44px;
    font-size: 1.25rem;
    font-weight: 700;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}
.qty-button:hover { border-color: var(--brand-interactive); filter: none; }
.qty-input { width: 3rem; min-height: 44px; text-align: center; }
.dish-add-button {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: 44px;
    padding: 0 0.9rem;
    border-radius: 999px;
    font-weight: 700;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border: 1.5px solid transparent;
}
.dish-add-plus { font-size: 1.25em; line-height: 1; font-weight: 700; }
.dish-add-label { white-space: nowrap; }
/* Dish modifier picker (#1194): when a dish has option groups the add form becomes a column — the groups stack, then a
   live total row, then the add button. Maps to brand tokens; the total is amber ink like every other price. */
.dish-add[data-dish-options] { flex-direction: column; align-items: stretch; gap: 0.6rem; }
.dish-options { display: flex; flex-direction: column; gap: 0.75rem; }
.dish-options-group { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.dish-options-legend { display: flex; align-items: baseline; gap: 0.5rem; padding: 0; font-weight: 700; }
.dish-options-name { font-weight: 700; }
.dish-options-flag { font-size: 0.8rem; font-weight: 600; color: var(--muted); }
.dish-option { display: flex; align-items: center; gap: 0.5rem; min-height: 44px; cursor: pointer; }
.dish-option input { width: 20px; height: 20px; accent-color: var(--brand-ink-accent); }
.dish-option-text { flex: 1 1 auto; }
.dish-option-delta { font-weight: 600; color: var(--brand-ink-accent); }
.dish-options-total { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin: 0; font-weight: 700; }
.dish-options-total-label { font-weight: 700; }
.dish-options-total-value { color: var(--brand-ink-accent); }
.dish-options-error { margin: 0; font-weight: 600; color: var(--danger-ink); }
.dish-options-hint,
.formule-hint { margin: 0; font-weight: 600; color: var(--muted); }
.dish-add-button[disabled] { opacity: 0.5; cursor: not-allowed; }
/* Guest formule builder (#1209): the tenant's fixed-price set menus at the top of the menu. Each formule is a card;
   a course is a fieldset of radio choices (one dish per course); the fixed price reads in amber ink like every price. */
.formules { margin: 2rem 0; display: flex; flex-direction: column; gap: 1rem; }
.formule {
    margin: 0;
    padding: 1rem;
    border: 1.5px solid var(--border-strong);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.formule-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.formule-name { font-weight: 700; font-size: 1.1rem; }
.formule-price { font-weight: 700; color: var(--brand-ink-accent); }
.formule-error { margin: 0; font-weight: 600; color: var(--danger-ink); }
.formule-form { display: flex; flex-direction: column; gap: 0.75rem; }
.formule-course { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.formule-course-legend { display: flex; align-items: baseline; gap: 0.5rem; padding: 0; font-weight: 700; }
.formule-course-label { font-weight: 700; }
.formule-course-flag { font-size: 0.8rem; font-weight: 600; color: var(--muted); }
.formule-choice { display: flex; align-items: center; gap: 0.5rem; min-height: 44px; cursor: pointer; }
.formule-choice input { width: 20px; height: 20px; accent-color: var(--brand-ink-accent); }
.formule-choice-text { flex: 1 1 auto; }
.formule-fixed { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin: 0; font-weight: 700; }
.formule-fixed-label { font-weight: 700; }
.formule-fixed-value { color: var(--brand-ink-accent); }
.formule-add-button { align-self: stretch; }
/* Per-course formule progress (#1247, P2-12): an always-visible checklist of courses chosen vs still needed. The
   server re-renders picks after submit (no-JS source of truth); formule.js mirrors it live. State is never colour
   alone — the check/ring glyph and the word carry it, positive ink only reinforces "chosen". */
.tally { margin: 0; font-weight: 600; color: var(--muted); }
.checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.checkstep { display: flex; align-items: center; gap: var(--space-2); color: var(--muted); }
.checkstep[data-state="chosen"] { color: var(--status-positive-ink); font-weight: 600; }
.checkstep-todo { display: inline-block; width: 0.7rem; height: 0.7rem; border: 1px solid currentColor; border-radius: 9999px; }
.cart-line-formule { display: block; font-weight: 400; font-size: 0.85rem; color: var(--muted); }
.cart-line-formule-course { display: block; }
/* Hover/press feedback on the one action that matters — a slight darken on hover and a press scale, so adding a dish
   feels responsive even before the check-morph fires. */
.dish-add-button:hover { filter: brightness(0.96); }
/* Add-to-cart morph (P1-2, progressive enhancement via ludic.js): the instant the form is submitted the label swaps to
   a check glyph and the button micro-pops, acknowledging the add before the SSR round-trip re-renders. The class is only
   added by JS; the pop animation is gated behind no-preference (reduced-motion still gets the check swap, just no pop). */
.dish-add-button-added { color: transparent; }
.dish-add-button-added::after {
    content: "✓";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-on-primary);
    font-weight: 700;
}
@media (prefers-reduced-motion: no-preference) {
    .dish-add-button { transition: transform var(--dur-1) var(--ease-emphasis), background var(--dur-1) var(--ease-emphasis); }
    .dish-add-button:active { transform: scale(0.9); }
    .dish-add-button-added { animation: add-pop var(--dur-2) var(--ease-emphasis); }
}
@keyframes add-pop {
    0% { transform: scale(1); }
    45% { transform: scale(1.06); }
    100% { transform: scale(1); }
}

/* Cart */
.cart {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}
.cart-empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.85rem;
    margin: 1.5rem 0 1rem;
    padding: 1.5rem;
    color: var(--ink);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.cart-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-interactive);
}
.cart-empty-title {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--ink);
}
.cart-empty-text { margin: 0; color: var(--muted); }
.cart-line {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line);
}
.cart-line-name { font-weight: 600; grid-column: 1; }
.cart-line-options { display: block; font-weight: 400; font-size: 0.85rem; color: var(--muted); }
.cart-line-price {
    grid-column: 2;
    color: var(--brand-ink-accent, #b45309);
    font-weight: 700;
    text-align: right;
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.3;
}
/* Per-unit transparency under the line total (shown only when qty > 1). */
.cart-line-unit { font-size: 0.78rem; font-weight: 500; color: var(--muted); }
.cart-line-total { font-weight: 700; }
/* A line whose dish went unavailable while in the cart: name recedes, price strikes through; paired with the
   .soldout word badge above so the guest sees what changed and why. Excluded from the payable total server-side. */
.cart-line-unavailable .cart-line-name { color: var(--subtle); }
.cart-line-unavailable .cart-line-price { color: var(--subtle); text-decoration: line-through; text-decoration-thickness: 1px; }
.cart-line-name .lowstock { display: flex; width: fit-content; }
/* Dine-in "sent to the kitchen" confirmation actions (View bill / Add another round). */
.cart-sent-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; margin-top: 0.5rem; }
.cart-sent-more {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 600;
}
.cart-stepper {
    grid-column: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.cart-step-form { display: inline-flex; }
.cart-step {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    line-height: 1;
    font-weight: 700;
    padding: 0;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--border-strong, #cbd5e1);
    border-radius: 0.5rem;
}
.cart-step-dec,
.cart-step-inc { color: var(--brand-interactive); }
.cart-step:hover { border-color: var(--brand-accent); filter: none; }
.cart-line-qty {
    min-width: 1.75rem;
    text-align: center;
    font-weight: 700;
    font-size: 1.1rem;
}
.cart-remove-form { grid-column: 2; justify-self: end; display: inline-flex; }
.cart-remove {
    min-height: 44px;
    background: var(--bg);
    color: var(--brand-ink-accent, #b45309);
    border: 1px solid var(--border-strong);
}
.cart-remove:hover { border-color: var(--brand-ink-accent, #b45309); filter: none; }
.cart-total {
    margin: 1rem 0;
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--brand-ink-accent, #b45309);
    font-variant-numeric: tabular-nums;
}
.cart-clear-form { margin-top: 1rem; }
.cart-clear {
    min-height: 44px;
    background: var(--bg);
    color: var(--muted);
    border: 1px solid var(--border-strong);
}
.cart-clear:hover { border-color: var(--border-strong); filter: none; }

/* Checkout / dine-in */
.checkout {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 1.5rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.checkout-dinein { gap: 0.6rem; }
.checkout-heading { margin: 0; font-size: 1.2rem; }
.checkout-dinein-note { margin: 0; color: var(--muted); }
.checkout-closed {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 1.5rem 0;
    padding: 1rem;
    color: var(--ink);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}
/* Blocking helper shown above a disabled send/pay CTA when a cart line is unavailable: tells the guest the one action
   that unblocks checkout (remove the dish). Reads on the danger ink, pairing the word with the disabled button state. */
.checkout-hint {
    margin: 0 0 0.35rem;
    color: var(--status-negative-ink);
    font-weight: 600;
    font-size: 0.9rem;
}
.checkout-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-weight: 600;
    color: var(--ink);
}
.checkout-submit {
    min-height: 48px;
    margin-top: 0.5rem;
    font-weight: 600;
    font-size: 1rem;
}
.checkout-submit-primary {
    min-height: 56px;
    width: 100%;
    font-size: 1.15rem;
    font-weight: 700;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.6rem;
}
.checkout-submit-primary:hover { filter: brightness(1.06); }
.checkout-submit-primary:disabled {
    background: var(--border-strong);
    color: var(--muted);
    cursor: not-allowed;
    filter: none;
}
/* The money-commit CTA (+ its inline total and any send error) pins to the bottom edge as the checkout form scrolls,
   so the guest never loses the send/pay button below the fold (#1731 P0-2). Echoes .menu-cartbar: page-bg fill so
   content scrolls under it cleanly, an upward shadow to lift it, and safe-area bottom padding for the iOS home bar. */
.cartbar-send {
    position: sticky;
    bottom: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-top: 0.75rem;
    padding-top: 0.5rem;
    padding-bottom: calc(0.5rem + env(safe-area-inset-bottom));
    background: var(--bg);
    box-shadow: var(--shadow-bar);
}
.checkout-confirmed {
    margin: 1.5rem 0;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
/* Order-confirmation flourish (P1-3): a luxe accent underline that "draws" in left-to-right on the confirmation banners
   (dine-in / pickup / reservation) — no confetti. The ::after is full-width by default (reduced-motion = instant, complete
   underline); the draw is a scaleX 0→1 gated behind no-preference with the emphasis easing over --dur-3. */
.checkout-confirmed,
.pay-confirmed,
.reserve-confirmed {
    position: relative;
    overflow: hidden;
}
.checkout-confirmed::after,
.pay-confirmed::after,
.reserve-confirmed::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background: var(--brand-accent);
    transform-origin: left center;
}
@media (prefers-reduced-motion: no-preference) {
    .checkout-confirmed::after,
    .pay-confirmed::after,
    .reserve-confirmed::after {
        animation: underline-draw var(--dur-3) var(--ease-emphasis) both;
    }
}
@keyframes underline-draw {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}
.checkout-bill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 56px;
    width: 100%;
    margin: 0 0 1.5rem;
    padding: 0 1rem;
    font-size: 1.15rem;
    font-weight: 700;
    text-align: center;
    text-decoration: none;
    color: var(--brand-on-primary);
    background: var(--brand-primary-raised);
    border-radius: 0.6rem;
}
.checkout-bill:hover { filter: brightness(1.06); }
.checkout-error {
    margin: 1rem 0;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.checkout-error::before,
.reserve-error::before,
.pay-error::before { content: "\26A0\00A0"; font-weight: 700; }

/* Contact */
.contact {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Legal notice (mentions légales) */

/* Footer: closes the page on the same brand band as the masthead so the chrome frames the tenant's site top-to-bottom.
   Carries the restaurant identity (name / address / phone / hours) so guests always have the essentials at the bottom
   of every page, then the legal + contact links. */
.site-footer {
    border-top: 1px solid var(--brand-hairline);
    padding: 2rem 1rem;
    margin-top: 2.5rem;
    background: var(--brand-band);
}
.site-footer-inner {
    max-width: 44rem;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
.site-footer-identity {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.site-footer-name {
    margin: 0;
    font-family: var(--brand-font);
    letter-spacing: var(--brand-display-spacing);
    font-size: var(--step-1);
    font-weight: 600;
    color: var(--brand-ink-accent);
}
.site-footer-line {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1.5;
}
.site-footer-hours { white-space: pre-line; }
.site-footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--brand-hairline);
}
.site-footer-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.9rem;
}
.site-footer-name .site-footer-link,
.site-footer-line .site-footer-link { min-height: 0; }
.site-footer-link:hover { color: var(--brand-interactive); text-decoration: underline; }

/* Delivery */
.delivery {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.25rem;
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
    background: var(--brand-tint);
}
.delivery-covered-block { border-left: 4px solid var(--brand-accent); }
.delivery-covered { margin: 0; font-weight: 600; }
.delivery-fee { margin: 0; color: var(--ink); }
.delivery-minimum { margin: 0; color: var(--muted); }
.delivery-total { margin: 0.5rem 0 0; font-weight: 700; color: var(--brand-ink-accent, #b45309); }
.delivery-shortfall { margin: 0; font-weight: 600; color: var(--muted); }
.delivery-not-covered {
    margin: 1.5rem 0;
    padding: 1rem;
    color: var(--ink);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}

/* FAQ — native <details> disclosure (SSR/crawlable, no JS); answers stay in the DOM when collapsed */

/* Blog (per-tenant, feature-gated) */

/* Reviews */
.reviews {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.reviews-empty { color: var(--muted); }
.reviews-summary {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0 0 1.25rem;
}
.reviews-summary-score {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--ink);
}
.reviews-summary-star { color: var(--brand-accent); font-size: 1.2rem; }
.reviews-summary-count { color: var(--muted); }
.review {
    padding: 0.85rem 1rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}

/* Order tracking — the reassuring post-order touchpoint a diner watches (mobile-first, 390px). */
.track {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1.5rem 1.25rem calc(1.5rem + env(safe-area-inset-bottom));
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 1rem;
}
.track-empty {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.85rem;
    margin: 1.5rem 0;
    color: var(--muted);
}
.track-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand-interactive);
}
.track-empty-title {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--ink);
}
.track-empty-text { margin: 0; }
.track-empty-cta {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.track-empty-cta:hover { color: var(--ink); }
.track-header {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    text-align: center;
}
.track-channel {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.track-code {
    margin: 0;
    font-size: 2rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    color: var(--ink);
}
.track-placed {
    margin: 0;
    font-size: 0.85rem;
    color: var(--subtle);
}
/* Order-journey timeline (placed → preparing → ready → collected/delivered): a connected stepper where each step
   pairs an icon glyph (✓ done / ● current / ○ upcoming) with its label, so state never rests on colour alone
   (design-system-ux.md, WCAG 2.2). The connector into a done/current step and the done/current markers use the tenant
   brand accent; upcoming is muted slate. aria-hidden — the aria-live status line is the screen-reader source of truth. */
.track-progress {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: flex-start;
}
.track-step {
    flex: 1 1 0;
    min-width: 0;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    text-align: center;
}
.track-step + .track-step::before {
    content: "";
    position: absolute;
    top: 0.85rem;
    left: -50%;
    width: 100%;
    height: 2px;
    background: var(--brand-hairline);
    z-index: 0;
}
.track-step-done::before,
.track-step-current::before { background: var(--brand-accent); }
.track-step-icon {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.7rem;
    height: 1.7rem;
    font-size: 0.85rem;
    line-height: 1;
    border-radius: 999px;
    border: 2px solid var(--brand-hairline);
    background: var(--bg);
    color: var(--muted);
    flex: none;
}
.track-step-label {
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.15;
    color: var(--muted);
}
.track-step-done .track-step-icon {
    color: var(--brand-on-primary);
    background: var(--brand-accent);
    border-color: var(--brand-accent);
}
.track-step-done .track-step-label { color: var(--ink); }
.track-step-current .track-step-icon {
    color: var(--brand-accent);
    background: var(--brand-accent-soft);
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 4px var(--brand-accent-soft);
}
.track-step-current .track-step-label { color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
    .track-step-icon { transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease; }
    .track-step-current .track-step-icon { animation: track-pulse 2s ease-in-out infinite; }
}
@keyframes track-pulse {
    0%, 100% { box-shadow: 0 0 0 4px var(--brand-accent-soft); }
    50% { box-shadow: 0 0 0 7px transparent; }
}
/* Order status badge: the canonical functional tones (design-system-ux.md) — same colour semantics as the staff
   Dashboard, never the tenant brand, and never colour alone (the word stays + a dot precedes it). */
.track-status {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    align-self: center;
    padding: 0.45rem 0.95rem;
    font-weight: 700;
    color: var(--status-neutral-ink);
    background: var(--status-neutral-bg);
    border-radius: 999px;
}
.track-status::before {
    content: "";
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 999px;
    background: var(--status-neutral-dot);
    flex: none;
}
.track-status-positive { color: var(--status-positive-ink); background: var(--status-positive-bg); }
.track-status-positive::before { background: var(--status-positive-dot); }
.track-status-caution { color: var(--status-caution-ink); background: var(--status-caution-bg); }
.track-status-caution::before { background: var(--status-caution-dot); }
.track-status-negative { color: var(--status-negative-ink); background: var(--status-negative-bg); }
.track-status-negative::before { background: var(--status-negative-dot); }
.track-status-neutral { color: var(--status-neutral-ink); background: var(--status-neutral-bg); }
.track-status-neutral::before { background: var(--status-neutral-dot); }
.track-reassurance {
    margin: -0.5rem 0 0;
    text-align: center;
    color: var(--muted);
    line-height: 1.4;
}
.track-pickup {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem;
    text-align: center;
    background: var(--brand-accent-soft);
    border: 1px solid var(--brand-accent);
    border-radius: 0.75rem;
}
.track-pickup-hint {
    margin: 0;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--ink);
}
.track-pickup-code {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    color: var(--ink);
}
.track-qr {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    margin: 0.25rem 0 0;
}
.track-qr-image {
    display: block;
    width: 9.5rem;
    max-width: 60vw;
    aspect-ratio: 1 / 1;
    padding: 0.5rem;
    background: white;
    border-radius: 0.5rem;
}
.track-qr-image svg {
    display: block;
    width: 100%;
    height: auto;
}
.track-qr-caption {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
    text-align: center;
}
.track-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--brand-hairline);
}
.track-total {
    margin: 0;
    font-size: 1.3rem;
    font-weight: 800;
}
.track-paid {
    display: inline-block;
    padding: 0.2rem 0.65rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border: 1px solid var(--brand-accent);
    border-radius: 999px;
}
.track-items-heading { font-size: 1.1rem; margin: 0.25rem 0 0; }
.track-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.track-item {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--line);
}

/* Table landing (QR) */
.table-landing {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.table-landing-empty {
    margin: 1.5rem 0;
    color: var(--muted);
}
.table-landing-intro { margin: 0; color: var(--muted); }
.table-landing-ordered {
    margin: 0;
    padding: 0.6rem 0.85rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.table-landing-order {
    min-height: 48px;
    width: 100%;
    font-weight: 600;
    font-size: 1rem;
}
.table-landing-order-primary {
    min-height: 56px;
    padding: 0.85rem 1.4rem;
    font-size: 1.15rem;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12);
}
.table-landing-order-help {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}
.table-landing-menu-link {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    min-height: 44px;
    color: var(--muted);
    text-decoration: underline;
    text-underline-offset: 2px;
    font-weight: 500;
}
.table-landing-menu-link:hover { color: var(--ink); }
.table-landing-bill {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.table-landing-call-heading { font-size: 1.2rem; margin: 1.5rem 0 0.5rem; }
.table-landing-called {
    margin: 0;
    padding: 0.6rem 0.85rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.table-landing-called-reason { font-weight: 700; }
.table-landing-call-help { margin: 0 0 0.65rem; color: var(--muted); }
/* One-tap reason chips: two-up grid on phones, keeps each tap target ≥ 56px tall. */
.table-landing-call-reasons {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.6rem;
}
.table-landing-call-onetap.chip {
    min-height: 56px;
    font-size: 1.05rem;
}
.chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.6rem 0.85rem;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.6rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.chip:hover { border-color: var(--brand-accent); }
.chip:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
}
.chip-icon { font-size: 1.35rem; line-height: 1; }

/* Reserve / waiter-call / review forms (shared form chrome) */
.reserve {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 1rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.reserve-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-weight: 600;
    color: var(--ink);
}
.reserve-submit {
    min-height: 48px;
    margin-top: 0.5rem;
    font-weight: 600;
    font-size: 1rem;
}
.reserve-confirmed {
    margin: 1.5rem 0;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.reserve-recap {
    margin: -0.75rem 0 1.5rem;
    color: var(--muted);
    font-weight: 600;
}
.reserve-deposit {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 1.5rem 0;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
}
.reserve-deposit-line { margin: 0; font-weight: 600; }
.reserve-deposit-pay {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
    min-height: 48px;
    padding: 0.6rem 1.4rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
}
.reserve-deposit-pay:hover { filter: brightness(1.08); }
.reserve-error {
    margin: 1rem 0;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.reserve-error-heading { margin: 0 0 0.35rem; font-size: 1rem; }
.reserve-error-list { margin: 0; padding-left: 1.25rem; }
.reserve-error-list a { color: inherit; font-weight: 600; }
.reserve-expectation { margin: 0.5rem 0 0; color: var(--muted); }
.reserve-hint { margin: -0.35rem 0 0; font-size: 0.85rem; font-weight: 400; color: var(--muted); }
.reserve-group {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0;
    padding: 0;
    border: 0;
}
.reserve-legend { padding: 0; margin-bottom: 0.1rem; font-weight: 700; color: var(--ink); }
.reserve-note { margin: 0; font-size: 0.85rem; font-weight: 400; color: var(--muted); }
.reserve-stepper { display: flex; align-items: stretch; gap: 0.5rem; }
.reserve-stepper-button {
    min-width: 44px;
    min-height: 44px;
    font-size: 1.25rem;
    font-weight: 700;
    background: var(--bg);
    color: var(--ink);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}
.reserve-stepper-button:hover { border-color: var(--brand-interactive); filter: none; }
.reserve-stepper-input { width: 6rem; text-align: center; }
.reserve-call { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 1.25rem 0 0; color: var(--muted); }
.reserve-call-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
    background: var(--bg);
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: none;
}
.reserve-call-link:hover { border-color: var(--brand-interactive); text-decoration: underline; }

/* Pickup payment surface (wraps the existing .pay-stripe island) */
.pay { margin: 1rem 0 0; }
.pay-confirmed {
    margin: 1.5rem 0 1rem;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.pay-paid-amount {
    margin: 0 0 1rem;
    color: var(--ink);
    font-size: 1.1rem;
    font-weight: 700;
}
.pay-error {
    margin: 1rem 0;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.pay-unavailable {
    margin: 1.5rem 0 1rem;
    padding: 1rem;
    color: var(--muted);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.5rem;
}
.pay-track {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-right: 1rem;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.pay-retry {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    margin-right: 1rem;
    padding: 0.6rem 1.4rem;
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 600;
}
.pay-retry:hover { filter: brightness(1.08); }

/* Receipt */
.receipt {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.receipt-empty {
    margin: 1.5rem 0;
    color: var(--muted);
}
.receipt-items-heading { font-size: 1.1rem; margin: 0 0 0.5rem; }
.receipt-items {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}
.receipt-item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--line);
}
.receipt-item-qty { color: var(--muted); font-variant-numeric: tabular-nums; }
.receipt-item-name { font-weight: 600; }
.receipt-item-price { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.receipt-bill {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.3rem 1rem;
    margin: 0.5rem 0;
    padding: 0.85rem 0;
    border-top: 1px solid var(--line);
}
.receipt-bill dt { margin: 0; color: var(--muted); }
.receipt-bill dd { margin: 0; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.receipt-discount-label { color: var(--brand-accent); }
.receipt-discount { color: var(--brand-accent); font-weight: 600; }
.receipt-total-label { font-weight: 700; color: var(--ink); }
.receipt-total {
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--brand-ink-accent, #b45309);
}
.receipt-paid { margin: 0.5rem 0 0; color: var(--ink); }
.receipt-settled {
    display: inline-block;
    align-self: flex-start;
    padding: 0.15rem 0.6rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border: 1px solid var(--brand-accent);
    border-radius: 999px;
}
.receipt-remaining { margin: 0.5rem 0 0; font-weight: 600; }
.receipt-payments-heading { font-size: 1.1rem; margin: 1rem 0 0.5rem; }
.receipt-payments {
    list-style: none;
    margin: 0;
    padding: 0;
}
.receipt-line {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--line);
}
.receipt-line-method { font-weight: 600; }
.receipt-line-amount { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.receipt-line-refunded {
    flex: 1 1 100%;
    color: var(--brand-ink-accent, #b45309);
    font-size: 0.9rem;
}
.receipt-refunded-total { margin: 0.5rem 0 0; color: var(--brand-ink-accent, #b45309); font-weight: 600; }
.receipt-pay {
    margin: 1.5rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.receipt-pay-heading { margin: 0 0 0.5rem; font-size: 1.2rem; }
.receipt-pay-error {
    margin: 0 0 1rem;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.receipt-pay-form {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.receipt-split {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 0 0 1rem;
}
.receipt-split-modes {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    border: 0;
}
.receipt-split-legend {
    padding: 0;
    margin: 0 0 0.25rem;
    font-weight: 700;
    color: var(--ink);
}
.receipt-split-mode {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 44px;
    color: var(--ink);
    font-weight: 600;
}
.receipt-split-mode input {
    width: 1.15rem;
    height: 1.15rem;
    accent-color: var(--brand-accent);
}
.receipt-split-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    color: var(--ink);
    font-weight: 600;
}
.receipt-split-field input {
    font: inherit;
    width: 100%;
    min-height: 44px;
    font-size: 1rem;
    padding: 0.55rem 0.75rem;
    color: var(--ink);
}
.receipt-split-preview {
    min-height: 48px;
    width: 100%;
    font-weight: 600;
    font-size: 1rem;
}
.receipt-split-share {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0 0 1rem;
    padding: 0.75rem 0.85rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
}
.receipt-split-share-amount { font-weight: 700; font-variant-numeric: tabular-nums; }
.receipt-split-share-hint { color: var(--muted); font-size: 0.9rem; }
.receipt-split-error {
    margin: 0 0 1rem;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.receipt-pick-form {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 0 0 1rem;
}
.receipt-pick {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    border: 0;
}
.receipt-pick-legend {
    padding: 0;
    margin: 0 0 0.35rem;
    font-weight: 700;
    color: var(--ink);
}
.receipt-pick-row {
    display: grid;
    grid-template-columns: 1.15rem 1fr auto;
    align-items: center;
    gap: 0.6rem;
    min-height: 44px;
    padding: 0.35rem 0.15rem;
    color: var(--ink);
    border-bottom: 1px solid var(--brand-hairline);
}
.receipt-pick-row input {
    width: 1.15rem;
    height: 1.15rem;
    accent-color: var(--brand-accent);
}
.receipt-pick-name { font-weight: 600; }
.receipt-pick-price {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.receipt-pick-covered {
    grid-column: 2 / -1;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--muted);
}
.receipt-pick-row-claimed {
    opacity: 0.55;
}
.receipt-pick-row-claimed .receipt-pick-name,
.receipt-pick-row-claimed .receipt-pick-price {
    text-decoration: line-through;
}
.receipt-pick-remaining {
    margin: 0;
    font-weight: 600;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.receipt-pick-subtotal {
    margin: 0;
    min-height: 1.25rem;
}
.receipt-pick-subtotal-amount {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    padding: 0.35rem 0.6rem;
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    display: inline-block;
}
.receipt-pick-conflict,
.receipt-pick-error {
    margin: 0;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-line);
    border-radius: 0.25rem;
}
.receipt-pick-actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.receipt-review {
    margin: 1.5rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.receipt-review-heading { margin: 0 0 0.35rem; font-size: 1.2rem; }
.receipt-review-intro { margin: 0 0 1rem; color: var(--muted); }
.receipt-review-thanks {
    margin: 0;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.receipt-bill-email {
    margin: 1.5rem 0 0;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.receipt-bill-email-heading { margin: 0 0 0.5rem; font-size: 1.2rem; }
.receipt-bill-email-status { margin: 0; }
.receipt-bill-email-confirmed {
    display: block;
    padding: 0.85rem 1rem;
    color: var(--on-accent-soft);
    background: var(--brand-accent-soft);
    border-left: 3px solid var(--brand-accent);
    border-radius: 0.25rem;
    font-weight: 600;
}
.receipt-bill-email-error {
    display: block;
    padding: 0.75rem 0.85rem;
    color: var(--danger-ink);
    background: var(--danger-bg);
    border-left: 3px solid var(--danger-ink);
    border-radius: 0.25rem;
    font-weight: 600;
}
.receipt-bill-email-form {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.receipt-bill-email-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    color: var(--ink);
    font-weight: 600;
}
.receipt-bill-email-field input {
    font: inherit;
    width: 100%;
    min-height: 44px;
    font-size: 1rem;
    padding: 0.55rem 0.75rem;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}
.receipt-bill-email-submit {
    min-height: 48px;
    width: 100%;
    font-weight: 600;
    font-size: 1rem;
}

/* Not found */
.not-found {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 2rem 0;
}

/* Tablet refinements */
@media (min-width: 48rem) {
    .page { padding: 2rem 1.5rem 5rem; }

    .site-header { padding: calc(0.75rem + env(safe-area-inset-top)) max(1.5rem, env(safe-area-inset-right)) 0.75rem max(1.5rem, env(safe-area-inset-left)); }

    .signatures-list {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }

    .menu-section-items {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        grid-auto-rows: max-content;
        gap: 0.5rem 1.5rem;
    }

    [data-menu-layout="large-photo"] .menu-section-items {
        grid-template-columns: 1fr;
    }
    [data-menu-layout="card-grid"] .menu-section-items {
        gap: 1rem;
    }

    .hero-actions { gap: 1rem; }

    .pay-stripe,
    .receipt-pay-stripe { max-width: 30rem; }
}

/* Desktop refinements */
@media (min-width: 64rem) {
    .page { max-width: 52rem; }

    .site-header-inner { max-width: 52rem; margin: 0 auto; }
    .site-footer-inner { max-width: 52rem; }

    .signatures-list { grid-template-columns: repeat(3, 1fr); }

    .menu-section-items { gap: 0.5rem 2.5rem; }

    .cart-line {
        grid-template-columns: 1fr auto auto auto;
        align-items: center;
    }
    .cart-line-name { grid-column: 1; }
    .cart-stepper { grid-column: 2; }
    .cart-line-price { grid-column: 3; }
    .cart-remove-form { grid-column: 4; }
}

/* API/network-failure fallback: a warm, branded retry surface so a transport error never blanks the page. */
.api-error {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.85rem;
    margin: 1.5rem 0;
    padding: 1.5rem;
    color: var(--ink);
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}

/* Table-aware cartbar (#1020): when an at-table session is active the cartbar leads with the bound table so the guest
   sees, at the point of action, which table their order is charged to. Reads on the amber bar's on-primary ink. */
.menu-cartbar-table { font-weight: 800; }
/* Receipt UX (aiko audit): amount-due hero + collapsible bill detail + collapsible split machinery. */
.due {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0 0 1rem;
    padding: 1.25rem;
    background: var(--brand-tint);
    border: 1px solid var(--brand-hairline);
    border-radius: 0.75rem;
}
.due-amount {
    margin: 0;
    font-size: var(--step-4);
    font-weight: 800;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    color: var(--brand-ink-accent, #b45309);
}
.receipt-detail {
    margin: 1.5rem 0 0;
    border-top: 1px solid var(--line);
}
.receipt-detail > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    list-style: none;
}
.receipt-detail > summary::-webkit-details-marker { display: none; }
.receipt-detail > summary::after { content: "›"; margin-left: auto; transition: transform var(--dur-1, 0.15s) ease; }
.receipt-detail[open] > summary::after { transform: rotate(90deg); }
.split-more {
    margin: 0.25rem 0 0;
}
.split-more > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    font-weight: 600;
    color: var(--brand-interactive);
    cursor: pointer;
    list-style: none;
}
.split-more > summary::-webkit-details-marker { display: none; }
.split-more > summary::after { content: "›"; margin-left: auto; transition: transform var(--dur-1, 0.15s) ease; }
.split-more[open] > summary::after { transform: rotate(90deg); }
/* pay page: read-only order summary above the card (aiko fix #8) */
.paysummary {
    margin: 0 0 1rem;
    padding: 0.75rem 1rem;
    background: var(--brand-tint);
    border: 1px solid var(--border-strong);
    border-radius: 0.5rem;
}
.paysummary h2 {
    margin: 0 0 0.5rem;
    font-size: 1rem;
    font-weight: 600;
}
.paysummary ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
.paysummary li {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.25rem 0;
    font-variant-numeric: tabular-nums;
}
.paytotal {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0.5rem 0 0;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-strong);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
/* Table landing hierarchy (aiko #12): one dominant primary action, a clearly subordinate call-waiter block. */
.table-landing-primary {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.table-landing-call {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    margin-top: 0.75rem;
    padding-top: 1.35rem;
    border-top: 1px solid var(--line);
}
.table-landing-call .table-landing-call-heading {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--muted);
}

/* Tip chips (aiko #2): one-tap whole-bill tip presets computed server-side from the amount due. Selected chip carries
   the amber fill with dark ink (palette §7); "Other" reveals the free amount. Radio dot is visually hidden, the whole
   chip is the >=44px target, focus ring rides the label via :has(:focus-visible). */
.tipchips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 0.85rem;
    padding: 0;
    border: none;
}
.tipchips-legend {
    width: 100%;
    padding: 0;
    margin: 0 0 0.5rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--muted);
}
.tipchip {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.1rem;
    min-height: 44px;
    min-width: 44px;
    padding: 0.4rem 0.9rem;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: 0.65rem;
    color: var(--ink);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}
.tipchip:hover { border-color: var(--brand-accent); }
.tipchip:has(input:checked) {
    background: var(--brand-primary-raised);
    color: var(--brand-on-primary);
    border-color: var(--brand-primary-raised);
}
.tipchip:has(input:focus-visible) {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
}
.tipchip input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}
.tipchip-amount {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--brand-ink-accent);
}
.tipchip:has(input:checked) .tipchip-amount { color: inherit; }
.tipother {
    width: 100%;
    margin: 0;
}
.tipother summary {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    color: var(--brand-interactive);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}
.tipother input {
    margin-top: 0.45rem;
    width: 100%;
}
/* Hero-adjacent opening-hours reassurance cue: an honest jump to the practical-info strip (hours/contact),
   never a fabricated open/closed state — the profile carries only free-text hours today. */
.hourscue {
    margin: -0.5rem 0 1.5rem;
    color: var(--muted);
    font-size: 0.95rem;
}
.hourscue svg { color: var(--brand-interactive); }
.hourscue a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--brand-interactive);
    font-weight: 600;
    text-decoration: none;
}
.hourscue a:hover { text-decoration: underline; }

/* Print / save the receipt (#1267). The button is progressive enhancement over the browser's native print;
   it styles as a secondary outline action and is dropped from the printed page via .no-print. */
.printbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 44px;
    margin: 0 0 1rem;
    padding: 0.5rem 1rem;
    background: var(--brand-tint);
    color: var(--brand-ink-accent);
    border: 1px solid var(--brand-hairline);
    border-radius: var(--radius-md);
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
}
.printbtn:hover { background: var(--brand-band); }

/* Fiscal ticket print (#1267): drop every chrome + interactive surface and render only the receipt on white — a
   dark theme must never carry its slate canvas into the printout and waste ink. Forcing light here is deliberate. */
.receipt-print-brand { display: none; }

@media print {
    :root { color-scheme: light; }
    body {
        background: white;
        color: #0f172a;
    }
    .site-header,
    .site-footer,
    .skip-link,
    .offline-banner,
    .track,
    .due,
    .receipt-pay,
    .receipt-review,
    .receipt-bill-email,
    .no-print {
        display: none !important;
    }
    .page {
        max-width: none;
        margin: 0;
        padding: 0;
    }
    .receipt-print-brand {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.25rem;
        text-align: center;
        margin-bottom: 1rem;
    }
    .receipt-print-logo,
    .receipt-print-mark {
        max-height: 64px;
        width: auto;
    }
    .receipt-print-name {
        font-weight: 600;
        font-size: 1.125rem;
    }
    .receipt-print-address {
        font-size: 0.875rem;
    }
    .receipt {
        background: white;
        color: #0f172a;
        box-shadow: none;
        border: 0;
    }
}
