/*
 * Storefront token contract — the base values.
 *
 * Three tiers, three owners, one precedence (the cascade does the enforcing):
 *
 *   1. Per-shop tokens   DATA. Emitted by /_theme/tokens.css from the shop's settings (ADR-0004 tier a).
 *                        Unlayered, so they beat every layer. Only the names marked [shop] below.
 *   2. Theme tokens      CODE. A theme redefines any token in `@layer theme` (themes/<code>/theme.css).
 *   3. Base values       this file, `@layer tokens` — the lowest layer. Every token has a value here,
 *                        so a theme that defines nothing still renders a conformant page.
 *
 * Structural constants (breakpoints, target size, z-order, the grid) are at the bottom and are not a theme's
 * to change: they carry accessibility and layout guarantees every page relies on.
 *
 * Every colour pair a component uses together is listed in the manual (#tokens-colour) with its contrast;
 * a theme that changes a colour re-checks its pairs against WCAG 2.1 AA (ADR-0015).
 */

@layer reset, tokens, base, layout, components, theme, utilities;

/*
 * Archivo (OFL, fonts/OFL.txt): a grotesque from the signage and price-ticket vernacular, variable in weight and
 * width. Shipped as ONE self-hosted file: axes limited to wght 400–800 and wdth 87.5–100, glyphs to Latin + Latin
 * Extended-A (sk, cs, hu, pl, de) — 68 kB. A theme that brings another face keeps within the same budget (#performance).
 */
@font-face {
    font-family: "Archivo";
    src: url("../fonts/archivo-variable-latin-ce-fHAjsAE.woff2") format("woff2");
    font-weight: 400 800;
    font-stretch: 87.5% 100%;
    font-style: normal;
    font-display: swap;
}

/* A metric-matched fallback: the swap from the system face to the web face moves no line (CLS budget). */
@font-face {
    font-family: "Archivo Fallback";
    src: local("Arial"), local("Helvetica Neue"), local("Helvetica");
    size-adjust: 103%;
    ascent-override: 85%;
    descent-override: 20.5%;
    line-gap-override: 0%;
}

@layer tokens {
    :root {
        /* ── Colour: brand ─────────────────────────────────────────────────────────── */
        --color-primary: #18212f;          /* [shop] actions, active states, links in chrome */
        --color-on-primary: #ffffff;       /* [shop] computed by the generator: the ink that clears 4.5:1 on primary */
        --color-primary-hover: color-mix(in oklab, var(--color-primary), #000 14%);  /* [shop] the generator emits it when darkening would lower on-primary's contrast */
        --color-primary-soft: color-mix(in oklab, var(--color-primary) 9%, var(--color-paper));
        /* A state mark (the current category, a chosen option's edge, a checked box) must clear 3:1 on paper, which a
           pale shop primary does not. [shop] the generator emits the primary when it clears 3:1 on the theme's paper,
           else var(--color-ink). */
        --color-selected: var(--color-primary);

        /* ── Colour: grounds ───────────────────────────────────────────────────────── */
        --color-paper: #ffffff;            /* the page */
        --color-surface: #ffffff;          /* raised panels: drawers, popovers, the order summary */
        --color-sunken: #f1f3f6;           /* media ground, quiet bands, table stripes */

        /* ── Colour: ink ───────────────────────────────────────────────────────────── */
        --color-ink: #18212f;              /* body text — 16.2:1 on paper, 14.6:1 on sunken */
        --color-ink-muted: #566072;        /* secondary text — 6.3:1 on paper, 5.7:1 on sunken */
        --color-line: #dde2e8;             /* decorative dividers only — never the only edge of a control */
        --color-line-strong: #7b8494;      /* control boundaries — 3.8:1 on paper (WCAG 1.4.11) */

        /* ── Colour: commerce ──────────────────────────────────────────────────────── */
        --color-price: var(--color-ink);   /* a price is ink, never brand: a pale brand would fail contrast */
        --color-sale: #b3261e;             /* the discounted price and its badge — 6.5:1 on paper */
        --color-on-sale: #ffffff;          /* text on the sale badge */
        --color-swatch-edge: rgb(24 33 47 / 0.18);  /* the hairline that keeps a white swatch visible on paper */
        --color-stock-in: #16794a;
        --color-stock-low: #8a5300;
        --color-stock-out: var(--color-ink-muted);

        /* ── Colour: feedback (text on its soft ground clears 4.5:1) ───────────────── */
        --color-success: #16794a;   --color-success-soft: #e3f4ea;
        --color-warning: #8a5300;   --color-warning-soft: #fff3d6;
        --color-danger: #b3261e;    --color-danger-soft: #fce8e6;
        --color-info: #1d5bbf;      --color-info-soft: #e6eefb;

        /* Focus never borrows the shop's primary: a pale primary would make the ring invisible. A region with its own
           ground has its own focus colour below. */
        --color-focus: #18212f;

        /* ── Type ──────────────────────────────────────────────────────────────────── */
        --font-body: "Archivo", "Archivo Fallback", system-ui, sans-serif;
        --font-display: var(--font-body);
        --font-weight-regular: 400;
        --font-weight-medium: 540;
        --font-weight-bold: 680;
        --font-weight-display: 760;
        --font-width-body: 100%;
        --font-width-display: 87.5%;       /* headings set narrow and heavy — the price-ticket voice */

        /* A modular scale on 16px: 1.2 on a phone, opening to ~1.25 on a desktop. Body text never shrinks. */
        --text-xs: 0.8125rem;                                   /* 13px — legal lines and counts only */
        --text-sm: 0.875rem;                                    /* 14px — secondary text */
        --text-md: 1rem;                                        /* 16px — body, inputs (iOS never zooms at 16) */
        --text-lg: 1.125rem;                                    /* 18px — lead text, card prices */
        --text-xl: clamp(1.25rem, 1.15rem + 0.45vw, 1.5rem);    /* 20 → 24 */
        --text-2xl: clamp(1.5rem, 1.3rem + 0.9vw, 2rem);        /* 24 → 32 */
        --text-3xl: clamp(1.8rem, 1.45rem + 1.6vw, 2.75rem);    /* 29 → 44 */
        --text-4xl: clamp(2.15rem, 1.5rem + 3vw, 3.75rem);      /* 34 → 60 — the home hero only */

        --leading-tight: 1.12;
        --leading-snug: 1.3;
        --leading-body: 1.55;
        --tracking-display: -0.018em;
        --tracking-body: 0;

        /* ── Space: a 4px rhythm ───────────────────────────────────────────────────── */
        --space-1: 0.25rem;   /*  4 */
        --space-2: 0.5rem;    /*  8 */
        --space-3: 0.75rem;   /* 12 */
        --space-4: 1rem;      /* 16 */
        --space-5: 1.5rem;    /* 24 */
        --space-6: 2rem;      /* 32 */
        --space-7: 3rem;      /* 48 */
        --space-8: 4rem;      /* 64 */
        --space-9: 6rem;      /* 96 */
        --section-gap: clamp(var(--space-7), 6vw, var(--space-9));  /* between page sections */

        /* ── Shape: a hierarchy, not one radius for everything ────────────────────── */
        --radius-control: 0.375rem;   /* buttons, inputs, option tiles */
        --radius-panel: 0.625rem;     /* drawers, the order summary, alerts */
        --radius-media: 0.25rem;      /* product imagery */
        --radius-pill: 999px;         /* chips, badges, counts */
        --radius-box: var(--radius-control);  /* boxes that hold more than a line: choice cards, textareas, the QR code */
        --radius-swatch: 50%;         /* colour swatches and the stock marker */
        --border-width: 1px;
        --border-width-control: 1px;

        /* ── Elevation: only what floats over content casts a shadow ───────────────── */
        --shadow-overlay: 0 1.25rem 2.5rem -0.75rem rgb(24 33 47 / 0.28), 0 0 0 1px rgb(24 33 47 / 0.06);
        --shadow-sticky: 0 -0.5rem 1.5rem -0.75rem rgb(24 33 47 / 0.25);
        --backdrop: rgb(24 33 47 / 0.45);

        /* ── Motion ────────────────────────────────────────────────────────────────── */
        --duration-quick: 120ms;
        --duration-base: 220ms;
        --ease-standard: cubic-bezier(0.2, 0, 0, 1);

        /* ── Media ─────────────────────────────────────────────────────────────────── */
        --media-ratio: 1 / 1;          /* one ratio per shop for cards and the gallery — rows stay aligned */
        --media-fit: cover;

        /* ── Components (a theme tunes these rather than re-writing the component) ─ */
        --button-height: 3rem;             /* 48px — every primary action */
        --control-height: 2.75rem;         /* 44px — inputs, secondary buttons, option tiles */
        --button-weight: var(--font-weight-bold);
        /* A region ground comes with its own ink: a theme that darkens the header sets both, and every text, icon and
           count in the region follows. The pair must clear 4.5:1 like any other. */
        --header-ground: var(--color-paper);
        --header-ink: var(--color-ink);
        --header-ink-muted: var(--color-ink-muted);
        --header-line: var(--color-line);
        --header-hover: var(--color-sunken);
        --header-focus: var(--color-focus);
        --header-selected: var(--color-selected);   /* the current category's mark on the header ground */
        --header-sale: var(--color-sale);
        --utility-ground: var(--color-sunken);
        --utility-ink: var(--color-ink);
        --utility-focus: var(--color-focus);
        --footer-ground: var(--color-sunken);
        --footer-ink: var(--color-ink);
        --card-gap: var(--space-3);        /* media → text inside a product card */
    }
}

/* ── Structural constants — not a theme's (see the manual, #layout) ────────────────── */
@layer tokens {
    :root {
        --page-max: 90rem;                                  /* 1440px — the container */
        --gutter: clamp(1rem, 3.6vw, 2.5rem);               /* the page's side margin */
        --grid-gap: clamp(1rem, 2vw, 1.5rem);
        --grid-columns: 4;                                  /* 4 → 8 → 12, set in layout */
        --measure: 68ch;                                    /* the longest line of running text */
        --target-min: 2.75rem;                              /* 44px — the smallest thing a finger presses */
        --focus-width: 3px;
        --focus-offset: 2px;
        --header-height: 4rem;
        --z-sticky: 10;
        --z-header: 20;
        --z-overlay: 30;
        --z-toast: 40;
        /* Breakpoints cannot be custom properties inside @media; they are written literally and only these:
           48rem (768px) tablet · 64rem (1024px) desktop · 80rem (1280px) wide. */
    }
}
