/* tokens.css -- primitive scales and theme-invariant design tokens.
 *
 * Two-tier system:
 *   tier 1 (here): primitive ramps (neutral, brand, semantic) + structural
 *                  scales (spacing, type, radii, etc). Theme-invariant.
 *   tier 2 (themes/*.css): semantic aliases mapping primitives into roles.
 *
 * Patterns and components consume tier-2 aliases. They may consume tier-1
 * primitives directly when a non-themed scale value is wanted (rare). No
 * component-scoped tier-3 tokens -- ever.
 */

/* ---- @font-face declarations ----
 * Self-hosted WOFF2 subsets from Google Fonts (under /shared/fonts/). Two
 * subsets per family: latin (U+0000-00FF) loads always; latin-ext loads only
 * when the page contains Latin Extended characters (Finnish ä/ö, Czech, etc).
 *
 * font-display:
 *   optional for Inter and JetBrains Mono -- prevents CLS, falls back forever
 *   if not loaded within 100ms. UI text stays stable.
 *   swap for Fraunces -- display headings tolerate a brief flash; the brand
 *   font is the personality of the page.
 */
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: optional;
    src: url("/shared/fonts/inter/inter-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: optional;
    src: url("/shared/fonts/inter/inter-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/shared/fonts/fraunces/fraunces-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/shared/fonts/fraunces/fraunces-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "JetBrains Mono";
    font-style: normal;
    font-weight: 100 800;
    font-display: optional;
    src: url("/shared/fonts/jetbrains-mono/jetbrains-mono-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "JetBrains Mono";
    font-style: normal;
    font-weight: 100 800;
    font-display: optional;
    src: url("/shared/fonts/jetbrains-mono/jetbrains-mono-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Vainio brand fonts (self-hosted variable WOFF2 subsets from Google Fonts).
 * Schibsted Grotesk (display, wght 400-800) is the personality font -- swap,
 * like Fraunces. Instrument Sans (body/UI, wght 400-600) uses optional so UI
 * text stays CLS-safe and falls back forever if not loaded in 100ms, like
 * Inter. Consumed by [data-theme="vainio-light"] via --font-display /
 * --font-body; latin-ext carries Finnish ae/oe. */
@font-face {
    font-family: "Schibsted Grotesk";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/shared/fonts/schibsted-grotesk/schibsted-grotesk-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Schibsted Grotesk";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/shared/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Instrument Sans";
    font-style: normal;
    font-weight: 400 600;
    font-display: optional;
    src: url("/shared/fonts/instrument-sans/instrument-sans-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Instrument Sans";
    font-style: normal;
    font-weight: 400 600;
    font-display: optional;
    src: url("/shared/fonts/instrument-sans/instrument-sans-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* ---- color primitives -- OKLCH ramps ---- */

    /* neutral ramp -- slight cool tint (hue 250) */
    --neutral-0:  oklch(99% 0.003 250);
    --neutral-1:  oklch(97% 0.004 250);
    --neutral-2:  oklch(94% 0.005 250);
    --neutral-3:  oklch(90% 0.006 250);
    --neutral-4:  oklch(85% 0.008 250);
    --neutral-5:  oklch(75% 0.010 250);
    --neutral-6:  oklch(62% 0.012 250);
    --neutral-7:  oklch(50% 0.014 250);
    --neutral-8:  oklch(40% 0.014 250);
    --neutral-9:  oklch(30% 0.014 250);
    --neutral-10: oklch(22% 0.012 250);
    --neutral-11: oklch(15% 0.010 250);
    --neutral-12: oklch(9%  0.008 250);

    /* brand ramp -- blue, hue 252 */
    --brand-soft:   oklch(94% 0.04 252);
    --brand-1:      oklch(68% 0.16 252);
    --brand-2:      oklch(58% 0.20 252);
    --brand-3:      oklch(48% 0.20 252);
    --brand-strong: oklch(38% 0.18 252);

    /* success -- green, hue 145 */
    --success-soft:   oklch(94% 0.05 145);
    --success-base:   oklch(58% 0.16 145);
    --success-strong: oklch(42% 0.16 145);

    /* warning -- amber, hue 75 */
    --warning-soft:   oklch(95% 0.07 75);
    --warning-base:   oklch(72% 0.15 75);
    --warning-strong: oklch(50% 0.13 75);

    /* danger -- red, hue 25 */
    --danger-soft:   oklch(95% 0.04 25);
    --danger-base:   oklch(60% 0.20 25);
    --danger-strong: oklch(45% 0.18 25);

    /* info -- cyan, hue 220 */
    --info-soft:   oklch(94% 0.04 220);
    --info-base:   oklch(60% 0.14 220);
    --info-strong: oklch(45% 0.14 220);

    /* ---- spacing scale (rem) ---- */
    --space-xs:  0.25rem;  /* 4px  */
    --space-sm:  0.5rem;   /* 8px  */
    --space-md:  0.75rem;  /* 12px */
    --space-lg:  1rem;     /* 16px */
    --space-xl:  1.5rem;   /* 24px */
    --space-2xl: 2rem;     /* 32px */
    --space-3xl: 3rem;     /* 48px */

    /* ---- typography ----
     * Body uses Inter (self-hosted, latin/latin-ext subsets, font-display:
     * optional -- falls back to system stack if not loaded in 100ms; CLS-safe).
     * Display uses Fraunces (variable serif with opsz + wght axes; swap so
     * the brand font appears once loaded). Mono uses JetBrains Mono.
     * Each has a system-font fallback chain so pages render perfectly even
     * before the brand fonts arrive.
     *
     * --font-sans is a permanent synonym of --font-body; both names are
     * supported and stable. Reach for --font-body in new code.
     */
    --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-display: "Fraunces", ui-serif, Georgia, Cambria, "Times New Roman", serif;
    --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    --font-sans:    var(--font-body);

    /* Type ladder. xs..2xl are fixed (UI text -- predictable rhythm matters
     * more than viewport responsiveness). 3xl..7xl use clamp() for hero
     * surfaces -- they grow with viewport but never past the "billboard
     * cosplay" ceiling (~80px). marketing-pages.md keeps 7xl on the calm
     * side of editorial.
     *
     * Mins are stepped so the ramp stays monotonically non-decreasing at
     * every viewport (3xl-min >= 2xl, each level >= the previous). */
    --text-xs:   0.75rem;                                     /* 12px */
    --text-sm:   0.875rem;                                    /* 14px */
    --text-base: 1rem;                                        /* 16px */
    --text-lg:   1.125rem;                                    /* 18px */
    --text-xl:   1.375rem;                                    /* 22px */
    --text-2xl:  1.75rem;                                     /* 28px */
    --text-3xl:  clamp(1.875rem, 1.5rem  + 1.2vw,   2rem);    /* 30-32px */
    --text-4xl:  clamp(2rem,     1.4rem  + 1.875vw, 2.5rem);  /* 32-40px */
    --text-5xl:  clamp(2.5rem,   1.5rem  + 3.125vw, 3rem);    /* 40-48px */
    --text-6xl:  clamp(3rem,     1.5rem  + 4.7vw,   3.75rem); /* 48-60px */
    --text-7xl:  clamp(3.75rem,  1.5rem  + 7vw,     5rem);    /* 60-80px */

    --weight-regular: 400;
    --weight-medium:  500;
    --weight-bold:    700;

    --leading-tight: 1.2;
    --leading-base:  1.5;

    /* letter-spacing -- display tightening + all-caps tracking */
    --tracking-tight: -0.02em;
    --tracking-wide:   0.05em;

    /* ---- radii ---- */
    --radius-none: 0;
    --radius-sm:   4px;
    --radius-md:   8px;
    --radius-lg:   14px;   /* cards / modules -- Vainio (design-system.md 8.1) */
    --radius-xl:   16px;   /* modal / dialog card -- Vainio (request-documents.md 8, #105) */
    --radius-full: 9999px;

    /* ---- shadows (theme-overridable in dark) ---- */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 1px rgba(0, 0, 0, 0.04);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.04);
    --shadow-lg: 0 24px 48px rgba(0, 0, 0, 0.18), 0 12px 24px rgba(0, 0, 0, 0.08);

    /* ---- polish tokens (overridden per [data-style] in themes/styles/*.css) ----
     * Patterns consume these instead of -sm/-md/-lg directly; the style theme
     * decides the stack (flat=none, precision=layered+highlight, vivid=
     * precision plus brand glow on emphasis surfaces).
     * Defaults here are flat-shaped (no card shadow, no lift) so apps without
     * a style theme loaded render cleanly. Motion stays at the tokens.css
     * baseline below; flat overrides it to slightly tighter values.
     */
    --shadow-card:       none;
    --shadow-card-hover: none;
    --shadow-pop:        var(--shadow-lg);
    --lift-on-hover:     none;
    --lift-on-active:    none;

    --gradient-fill-strong: none;   /* overlay on filled colored buttons */
    --gradient-fill-soft:   none;   /* overlay on soft intent backgrounds */

    /* ---- emphasis-glow tokens (vivid style theme fills these) ----
     * Default is none so precision and flat compose cleanly. vivid.css
     * sets it to a brand-colored bloom on focus rings. Components opt in
     * by referencing the variable; non-vivid style themes get no glow.
     */
    --shadow-glow-focus:   none;   /* colored focus ring under vivid */

    /* ---- marketing-surface gradient slots (themed per color theme) ----
     * Hero / card decorative gradients for landing-page surfaces. Default
     * none; each color theme can fill with a brand-coherent value. Stay
     * within the marketing-pages.md constraints: max 3 stops, low chroma,
     * never animated unless cycle >= 10s + reduced-motion kills it.
     */
    --color-gradient-hero: none;
    --color-gradient-card: none;

    /* focus ring uses a theme-scoped color, defined per-theme */

    /* ---- z-layers ---- */
    --z-base:     0;
    --z-sticky:   100;
    --z-dropdown: 200;
    --z-overlay:  300;
    --z-modal:    400;
    --z-toast:    500;

    /* ---- breakpoints (documentation only -- @media queries use literals) ---- */
    --bp-md: 48rem;   /* 768px  */
    --bp-lg: 64rem;   /* 1024px */

    /* ---- motion (style-theme overridable) ---- */
    --motion-fast:   120ms;
    --motion-easing: cubic-bezier(0.2, 0, 0, 1);   /* ease-out */
}
