/* The tenant customization layer for BOTH guest surfaces — colours, font, type scale, spacing, radius, motion,
   surfaces and the functional status tones. It lived in the Menu's app.css and in the Showcase's app.css as two
   byte-identical copies, in sync only while a human kept re-syncing them: a stale copy of the layout presets (#2922),
   a contrast fix applied twice (#2950), an un-gated accent open in both (#2951). It now ships from the library both
   hosts already reference, linked from each App.razor ahead of that host's own app.css.

   Each host's 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, display spacing, hero focal, canvas); 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.

   TOKENS ONLY. This sheet owns :root and the theme blocks, so a class rule here would style the ordering app and the
   vitrine as though they were one product. Component rules stay in the host that draws the component — the mirror of
   content-sections.css, which carries class rules and declares no token because it also loads into the Dashboard. */

: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-accent-ink: #b45309;
    --brand-accent-line: #d97706;
    --brand-on-tint-dark: #f1f5f9;
    --brand-ink-accent-dark: #fbbf24;
    --brand-accent-dark: #fbbf24;
    --brand-accent-ink-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.
       --brand-canvas (App.razor) is a bounded, contrast-gated explicit override (Basta-cream case) and wins when
       set; the var() fallback is exactly the mix formula above, so an untouched tenant renders unchanged (#2867). */
    --surface-base: var(--brand-canvas, 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. --brand-interactive = foreground text/icon/border ink; --brand-primary-raised = the
       CTA fill floor. The ink role reads the resolver's AA-gated mirror in BOTH themes — the raw primary is a FILL
       input (--brand-on-primary is what is gated against it), so inking normal-size text with it shipped the payable
       total and the cart steppers at the tenant's own ratio: 3.19:1 for the amber default, lower for any lighter
       primary a tenant picks. The dark block re-points these again 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: var(--brand-ink-accent);
    --brand-primary-raised: var(--brand-primary);

    /* Semantic decorative. --accent-line is NOT decorative: it is the keyboard focus ring
       (`:focus-visible { outline: 2px solid var(--accent-line) }`) on both guest surfaces, so it is a focus indicator
       held to 3:1 by WCAG 2.2 SC 1.4.11. It read the RAW --brand-accent for as long as it existed, and nothing gates
       the raw accent: the platform's own amber-500 as a tenant accent drew the ring at 2.15:1 on white (#3290). It now
       reads the resolver's gated ring value, which the dark block re-points at the lightened dark mirror. */
    --accent-line: var(--brand-accent-line);
    --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 (word + dot, never colour alone). These twelve values ARE the canonical set: the
       Dashboard's Tailwind theme declares the same hex under --color-status-*, and StatusToneParityGuardTests renders
       the staff badge and reads both sides back, so neither side can move alone. It said "shared with the Dashboard"
       for two releases while Positive and Negative were not (#2954) — the guard is what makes the claim true. */
    --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-accent is
       the FILL/border input at the ≥3:1 non-text threshold; --brand-accent-ink is its text counterpart at ≥4.5:1, so
       the promo discount and prose links keep the accent hue without inheriting the fill's looser gate. */
    --brand-on-tint: var(--brand-on-tint-dark);
    --brand-ink-accent: var(--brand-ink-accent-dark);
    --brand-accent: var(--brand-accent-dark);
    --brand-accent-ink: var(--brand-accent-ink-dark);

    /* The focus ring takes the accent LIGHTENED against the dark canvas — the same ≥3:1 non-text gate as the light
       ring, in the direction the dark canvas needs (the palette rule: amber-500 is fine on dark, amber-700 is not).
       That value is --brand-accent-dark: AccentDark is already Lighten(accent, dark surface, 3:1), the identical
       function of the identical input, so pointing at it here is what keeps a second resolver field from existing. */
    --brand-accent-line: 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;
}
