/*
 * Public-site design tokens — the Waavo promo design system.
 *
 * Ported name for name from the Claude Design project "Waavo Travel Promo
 * Redesign" (_ds/waavo-promo-design-system/tokens/*.css). Keeping the DS names
 * means a value changed in the canvas is a value changed here, with no
 * translation step to get wrong.
 *
 * No other public stylesheet may contain a raw colour: every rule references a
 * custom property, so a palette change happens in one place (brief §10). The
 * hex literals below are the one permitted exception, because this IS the
 * declaration.
 *
 * The admin loads this same file. There is one design system and one typeface
 * across both surfaces; only the component layer differs (app.css vs admin.css).
 *
 * Loaded as its own file rather than @import-ed: AssetMapper has no bundler, so
 * an @import would cost a second round trip anyway and hide the dependency.
 */

/* --- self-hosted faces (§9: no third-party font CDN) ---------------------
 *
 * Both are variable fonts, so one file covers the whole weight range the design
 * uses. That is why the pair costs 61KB where the five static Source cuts they
 * replace cost 210KB.
 *
 * `font-display: optional`, not `swap`. Measured: swapping in Instrument Sans
 * after first paint reflows the hero and the header for 0.046 of cumulative
 * layout shift on the homepage — most of §9's 0.05 budget, spent on a font that
 * is already preloaded and 30KB. `optional` gives the browser a short window
 * and then commits to whatever it has, so the page never reflows. The cost is
 * that a first visit over a slow connection may render in the fallback; the
 * metric-matched face below is what keeps that from looking wrong, and the font
 * is cached from the second view on.
 */

@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-stretch: 100%;
    font-display: optional;
    src: url("../fonts/instrument-sans-var-latin-1Ubqs2a.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: 400 500;
    font-display: optional;
    src: url("../fonts/jetbrains-mono-var-latin-AcnlIJe.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;
}

/* A metric-matched stand-in for Instrument Sans, drawn from a face already on
 * the machine. Without it the swap from Arial reflows every line on the page
 * when the real font lands — worth about 0.3 of cumulative layout shift on the
 * homepage, measured. The overrides are Instrument Sans's own metrics scaled to
 * Arial's em box.
 */
@font-face {
    font-family: 'Instrument Fallback';
    src: local('Arial'), local('Helvetica Neue'), local('Liberation Sans');
    size-adjust: 97%;
    ascent-override: 96%;
    descent-override: 24%;
    line-gap-override: 0%;
}

/* latin-ext. Not decoration: Lithuanian, Latvian, Polish, Romanian and Estonian
   live almost entirely in this range — ė, ą, ł, ș, š — and so does the company's
   own street address, Ukmergės, which is on every page of the site. Without
   these two faces those glyphs fall through to the system stack, which is what
   the site did until they were added.

   `unicode-range` is what keeps this cheap: a page whose text is pure latin
   never requests them. They are 11KB each, and the homepage fetches only the
   mono one, because the only latin-ext text there is the mono footer address.

   ── WHY THESE TWO SAY `swap` WHERE THE LATIN FACES SAY `optional` ────────────
   `optional` refuses to use a face that arrives after its short block window,
   so on a cold visit the diacritics rendered from the fallback even though the
   file had downloaded — measured, not assumed. `swap` uses it as soon as it
   lands.

   That trade is only cheap because of what each face covers. The latin face
   carries every character on the page, so swapping it reflows everything — that
   was 0.046 of layout shift, most of §9's budget, and the reason it is
   `optional`. The latin-ext face carries a handful of glyphs; today that is one
   word in a footer, and switching it to `swap` left CLS at 0.0002, unchanged.

   This flips for a locale whose text lives in this range. A Lithuanian page has
   diacritics in every headline, and `swap` would reflow it broadly. When those
   locales land, preload the latin-ext file for them so it is inside the block
   window, and put this back to `optional`. See docs/plans/0001-multilingual.md.
   ───────────────────────────────────────────────────────────────────────────── */

@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-stretch: 100%;
    font-display: swap;
    src: url("../fonts/instrument-sans-var-latin-ext-mz-WyKA.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: 400 500;
    font-display: swap;
    src: url("../fonts/jetbrains-mono-var-latin-ext-c8h-btv.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;
}

/* --- base ramps ---------------------------------------------------------- */

:root {
    /* Signal blue — the Waavo brand colour. --blue-600 is rgb(27, 79, 166). */
    --blue-50: #EFF4FC;
    --blue-100: #DBE6F7;
    --blue-200: #B7CBEF;
    --blue-300: #85A8E1;
    --blue-400: #4A7CC9;
    --blue-500: #2A61B4;
    --blue-600: #1B4FA6;
    --blue-700: #163F85;
    --blue-800: #112F64;
    --blue-900: #0C2246;

    /* Ink — cool neutral ramp (never pure black). */
    --ink-50: #F7F8FA;
    --ink-100: #EDEFF3;
    --ink-200: #DDE1E8;
    --ink-300: #C3C9D4;
    --ink-400: #9AA3B2;
    --ink-500: #737D8D;
    --ink-600: #525B69;
    --ink-700: #363E4A;
    --ink-800: #232935;
    --ink-900: #131820;

    /* Paper surfaces. */
    --bone-0: #FFFFFF;
    --bone-50: #FBFCFD;
    --bone-100: #F4F6F9;
    --bone-200: #E9EDF2;

    /* Sand — secondary accent, highlights, chart fills. */
    --sand-100: #FBF0D9;
    --sand-200: #F4DFAF;
    --sand-300: #E9C273;
    --sand-400: #D9A33C;
    --sand-500: #B4801F;

    /* Semantic hues, deliberately distinct from the brand blue. */
    --green-100: #DDF0E4;
    --green-500: #1F7A4D;
    --green-700: #145636;
    --amber-100: #FCEBCF;
    --amber-500: #B8730C;
    --amber-700: #8A5406;
    --vermilion-100: #FBE2DC;
    --vermilion-500: #C2361F;
    --vermilion-700: #932514;
    --slate-100: #E4E9EE;
    --slate-500: #4A5B6E;
    --slate-700: #2F3C4A;

    /* Translucent whites, for the inverse surfaces. */
    --on-dark-4: #FFFFFF0F;
    --on-dark-10: #FFFFFF1A;
    --on-dark-15: #FFFFFF26;
    --on-dark-16: #FFFFFF29;
    --on-dark-40: #FFFFFF66;
}

/* --- semantic aliases — always author against these ----------------------- */

:root {
    --brand: var(--blue-600);
    --brand-hover: var(--blue-700);
    --brand-press: var(--blue-800);
    --brand-subtle: var(--blue-50);
    --brand-border: var(--blue-200);
    --brand-on: var(--bone-0);

    --accent: var(--sand-400);
    --accent-subtle: var(--sand-100);
    --accent-on: var(--ink-900);

    --surface-page: var(--bone-50);
    --surface-card: var(--bone-0);
    --surface-sunken: var(--bone-100);
    --surface-raised: var(--bone-0);
    --surface-inverse: var(--ink-900);
    --surface-brand: var(--blue-600);
    --surface-brand-deep: var(--blue-800);
    --surface-hover: var(--ink-50);
    --surface-tint: var(--blue-50);
    --surface-tile: var(--blue-100);
    /* The translucent veil behind the sticky header. */
    --surface-veil: rgb(251 252 253 / 88%);
    /* Behind the admin's drawer and dialogs. Dark in both schemes, so it is
       defined once and never re-pointed: an overlay dims whatever it covers. */
    --surface-scrim: rgb(8 11 16 / 55%);

    --text-display: var(--ink-900);
    --text-heading: var(--ink-900);
    --text-body: var(--ink-700);
    --text-strong: var(--ink-800);
    --text-muted: var(--ink-500);
    --text-label: var(--blue-700);
    --text-faint: var(--ink-400);
    --text-on-brand: var(--bone-0);
    --text-on-inverse: var(--bone-100);
    --text-on-inverse-muted: var(--ink-400);
    --text-link: var(--blue-600);
    --text-link-hover: var(--blue-800);

    --border-hairline: var(--ink-200);
    --border-strong: var(--ink-300);
    --border-inverse: var(--on-dark-16);
    --border-focus: var(--blue-500);

    --state-success: var(--green-500);
    --state-success-subtle: var(--green-100);
    --state-warning: var(--amber-500);
    --state-warning-subtle: var(--amber-100);
    --state-danger: var(--vermilion-500);
    --state-danger-subtle: var(--vermilion-100);
    --state-info: var(--slate-500);
    --state-info-subtle: var(--slate-100);

    /* Text ON a subtle state ground, and on a filled danger control. Separate
       aliases because the ramp value that reads on paper is invisible on ink:
       green-700 on a dark green tint is dark-on-dark. */
    --state-success-text: var(--green-700);
    --state-warning-text: var(--amber-700);
    --state-danger-text: var(--vermilion-700);
    --state-info-text: var(--slate-700);
    --text-on-danger: var(--bone-0);

    /* A neutral chip ground — the "draft" pill and anything else that is a
       state without being a status. */
    --surface-neutral: var(--ink-100);
}

/* --- typography ---------------------------------------------------------- */

:root {
    --font-core: 'Instrument Sans', 'Instrument Fallback', Arial, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --font-display: var(--font-core);
    --font-heading: var(--font-core);
    --font-body: var(--font-core);
    --font-ui: var(--font-core);
    --font-data: var(--font-mono);

    /* Scale — 1.25 major-third-ish, tuned by hand at the display end. */
    --text-display-1: clamp(44px, 6vw, 76px);
    --text-display-2: clamp(36px, 4.6vw, 56px);
    --text-h1: 40px;
    --text-h2: 31px;
    --text-h3: 24px;
    --text-h4: 20px;
    --text-lead: 19px;
    --text-body-lg: 17px;
    --text-body-size: 15px;
    --text-sm: 13.5px;
    --text-xs: 12px;
    --text-micro: 11px;

    --leading-display: 0.98;
    --leading-tight: 1.14;
    --leading-snug: 1.32;
    --leading-body: 1.55;
    --leading-loose: 1.7;

    /* 400 body, 500 UI, 600 headings. 700 reserved for numerals and labels. */
    --weight-regular: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    /* Negative on display, positive on all-caps labels. */
    --tracking-display: -0.03em;
    --tracking-heading: -0.018em;
    --tracking-body: 0em;
    --tracking-label: 0.09em;
    --tracking-eyebrow: 0.16em;

    --measure-prose: 66ch;
    --measure-lead: 52ch;
}

/* --- spacing ------------------------------------------------------------- */

:root {
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 48px;
    --space-10: 64px;
    --space-11: 80px;
    --space-12: 104px;
    --space-13: 136px;

    --gap-inline: var(--space-2);
    --gap-stack: var(--space-4);
    --gap-grid: var(--space-6);
    --pad-card: var(--space-6);
    --pad-card-lg: var(--space-8);
    --pad-control-x: var(--space-4);
}

/* --- radii --------------------------------------------------------------- */

:root {
    /* Two families: soft 10px for surfaces, pill for controls and tags.
       Fields, icon tiles and list cards use 8px, matching the booking product. */
    --radius-xs: 4px;
    --radius-sm: 6px;
    --radius-field: 8px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-pill: 999px;
    --radius-card: var(--radius-md);
    --radius-control: var(--radius-pill);
    --radius-input: var(--radius-field);
    --radius-tile: var(--radius-field);
    --radius-media: var(--radius-md);
}

/* --- elevation ----------------------------------------------------------- */

:root {
    /* Shadows are cool-tinted and low-contrast; the hairline border does most
       of the separation work. Never more than two layers. */
    --shadow-hairline: 0 0 0 1px var(--border-hairline);
    --shadow-1: 0 1px 2px rgb(19 24 32 / 5%);
    --shadow-2: 0 2px 4px rgb(19 24 32 / 5%), 0 8px 20px -8px rgb(19 24 32 / 10%);
    --shadow-3: 0 4px 8px rgb(19 24 32 / 6%), 0 20px 44px -16px rgb(19 24 32 / 16%);
    --shadow-brand: 0 12px 32px -12px rgb(27 79 166 / 42%);
    --ring-focus: 0 0 0 3px rgb(27 79 166 / 28%);
    --blur-veil: saturate(140%) blur(14px);
}

/* --- motion -------------------------------------------------------------- */

:root {
    --dur-instant: 80ms;
    --dur-fast: 140ms;
    --dur-base: 200ms;
    --dur-slow: 320ms;
    --dur-reveal: 520ms;

    /* No bounce, no overshoot. Everything decelerates. */
    --ease-standard: cubic-bezier(0.2, 0.7, 0.25, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in: cubic-bezier(0.5, 0, 0.9, 0.3);
    --transition-control:
        background-color var(--dur-fast) var(--ease-standard),
        color var(--dur-fast) var(--ease-standard),
        border-color var(--dur-fast) var(--ease-standard),
        box-shadow var(--dur-fast) var(--ease-standard),
        transform var(--dur-instant) var(--ease-standard);
}

/* --- layout -------------------------------------------------------------- */

:root {
    color-scheme: light;

    /* Which wordmark the header draws. Re-pointed by the dark blocks below,
       exactly like every other semantic alias — the artwork is the token. */
    --logo-src: url("../images/logo-6Ip47ub.svg");

    --container-max: 1200px;
    --container-narrow: 760px;
    --container-wide: 1400px;
    --gutter: clamp(16px, 4vw, 64px);
    --header-h: 72px;
    --hairline: 1px solid var(--border-hairline);
    /* The vertical rhythm every section band shares. */
    --section-y: clamp(44px, 6vw, 96px);
    --section-y-tight: clamp(32px, 5vw, 72px);
}

/* --- dark ----------------------------------------------------------------
 *
 * The imported design system is authored light-only. Rather than invent a
 * second palette, the dark scheme re-points the SEMANTIC aliases at the ramps
 * that already exist: paper surfaces become ink, ink text becomes bone, and the
 * brand lightens to keep its contrast against a dark ground. Every ramp value
 * above is untouched, so the canvas and the site still agree on what
 * --blue-600 means.
 */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --logo-src: url("../images/logo-inverse-29r9lLc.svg");

        --brand: var(--blue-300);
        --brand-hover: var(--blue-200);
        --brand-press: var(--blue-100);
        --brand-subtle: #16233A;
        --brand-border: var(--blue-800);
        --brand-on: var(--ink-900);

        --surface-page: #0E1219;
        --surface-card: #161C26;
        --surface-sunken: #11161F;
        --surface-raised: #1B2230;
        --surface-inverse: #080B10;
        --surface-brand: var(--blue-700);
        --surface-brand-deep: var(--blue-900);
        --surface-hover: #1B2230;
        --surface-tint: #16233A;
        --surface-tile: #1B2C48;
        --surface-veil: rgb(14 18 25 / 88%);

        --text-display: var(--bone-50);
        --text-heading: var(--bone-50);
        --text-body: var(--ink-300);
        --text-strong: var(--bone-200);
        --text-muted: var(--ink-400);
        --text-label: var(--blue-300);
        --text-faint: var(--ink-500);
        /* The dark scheme lightens the brand, so a filled control needs dark
           text on it — white would land at about 2:1. */
        --text-on-brand: var(--ink-900);
        --text-on-inverse: var(--bone-100);
        --text-on-inverse-muted: var(--ink-400);
        --text-link: var(--blue-300);
        --text-link-hover: var(--blue-200);

        --border-hairline: #242C39;
        --border-strong: #333D4D;
        --border-inverse: var(--on-dark-16);
        --border-focus: var(--blue-300);

        --state-success: #4FB585;
        --state-success-subtle: #10281C;
        --state-warning: #D99A3C;
        --state-warning-subtle: #2A1F0D;
        --state-danger: #E5745C;
        --state-danger-subtle: #2E1310;
        --state-info: #8FA3B8;
        --state-info-subtle: #1A222C;

        --state-success-text: #7FD4A8;
        --state-warning-text: #E8BC72;
        --state-danger-text: #F0A08C;
        --state-info-text: #B8C7D6;
        /* The dark scheme lightens the danger colour, so a filled danger
           control needs dark text on it for the same reason --brand does. */
        --text-on-danger: var(--ink-900);

        --surface-neutral: #1E2632;

        /* Shadows do almost nothing on a dark ground; the borders carry it. */
        --shadow-1: 0 1px 2px rgb(0 0 0 / 40%);
        --shadow-2: 0 2px 4px rgb(0 0 0 / 32%), 0 8px 20px -8px rgb(0 0 0 / 50%);
        --shadow-3: 0 4px 8px rgb(0 0 0 / 36%), 0 20px 44px -16px rgb(0 0 0 / 60%);
        --shadow-brand: 0 12px 32px -12px rgb(133 168 225 / 30%);
        --ring-focus: 0 0 0 3px rgb(133 168 225 / 32%);
    }
}

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

    --logo-src: url("../images/logo-inverse-29r9lLc.svg");

    --brand: var(--blue-300);
    --brand-hover: var(--blue-200);
    --brand-press: var(--blue-100);
    --brand-subtle: #16233A;
    --brand-border: var(--blue-800);
    --brand-on: var(--ink-900);

    --surface-page: #0E1219;
    --surface-card: #161C26;
    --surface-sunken: #11161F;
    --surface-raised: #1B2230;
    --surface-inverse: #080B10;
    --surface-brand: var(--blue-700);
    --surface-brand-deep: var(--blue-900);
    --surface-hover: #1B2230;
    --surface-tint: #16233A;
    --surface-tile: #1B2C48;
    --surface-veil: rgb(14 18 25 / 88%);

    --text-display: var(--bone-50);
    --text-heading: var(--bone-50);
    --text-body: var(--ink-300);
    --text-strong: var(--bone-200);
    --text-muted: var(--ink-400);
    --text-label: var(--blue-300);
    --text-faint: var(--ink-500);
    /* The dark scheme lightens the brand, so a filled control needs dark
       text on it — white would land at about 2:1. */
    --text-on-brand: var(--ink-900);
    --text-on-inverse: var(--bone-100);
    --text-on-inverse-muted: var(--ink-400);
    --text-link: var(--blue-300);
    --text-link-hover: var(--blue-200);

    --border-hairline: #242C39;
    --border-strong: #333D4D;
    --border-inverse: var(--on-dark-16);
    --border-focus: var(--blue-300);

    --state-success: #4FB585;
    --state-success-subtle: #10281C;
    --state-warning: #D99A3C;
    --state-warning-subtle: #2A1F0D;
    --state-danger: #E5745C;
    --state-danger-subtle: #2E1310;
    --state-info: #8FA3B8;
    --state-info-subtle: #1A222C;

    --state-success-text: #7FD4A8;
    --state-warning-text: #E8BC72;
    --state-danger-text: #F0A08C;
    --state-info-text: #B8C7D6;
    /* The dark scheme lightens the danger colour, so a filled danger
       control needs dark text on it for the same reason --brand does. */
    --text-on-danger: var(--ink-900);

    --surface-neutral: #1E2632;

    /* Shadows do almost nothing on a dark ground; the borders carry it. */
    --shadow-1: 0 1px 2px rgb(0 0 0 / 40%);
    --shadow-2: 0 2px 4px rgb(0 0 0 / 32%), 0 8px 20px -8px rgb(0 0 0 / 50%);
    --shadow-3: 0 4px 8px rgb(0 0 0 / 36%), 0 20px 44px -16px rgb(0 0 0 / 60%);
    --shadow-brand: 0 12px 32px -12px rgb(133 168 225 / 30%);
    --ring-focus: 0 0 0 3px rgb(133 168 225 / 32%);
}
