/*
 * Design tokens + global reset.
 *
 * Theme: the phone decides. Android flips `prefers-color-scheme` to dark at sunset, which is
 * exactly when this app is used in a car, so there is no in-app theme switch to forget to
 * press — the dark palette comes on by itself and goes away in the morning.
 *
 * `color-scheme` makes the browser follow along for the things CSS cannot reach: form control
 * chrome, scrollbars, and the default canvas colour before the stylesheet loads.
 */
@layer tokens, base, components, utilities;

/*
 * Self-hosted, and that is the point rather than a preference: the cookie notice says this
 * site loads nothing from a third party until you agree to the Picker, and a stylesheet link
 * to fonts.googleapis.com would make that sentence false — every visitor's IP would go to
 * Google before they had answered anything.
 *
 * Variable fonts, two subsets each. `latin-ext` is not optional here: without it Slovak loses
 * č, š, ž, ľ, ĺ, ŕ and ô to a fallback face, and a heading reading "Zakliata hora" in two
 * different typefaces is the first thing anybody notices.
 *
 * `font-display: swap` — the text is the content on these pages, so it has to be readable
 * before the face arrives, not after.
 */
@font-face {
    font-family: 'Fraunces';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../fonts/fraunces-latin-SfWU466.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: 400 700;
    font-display: swap;
    src: url("../fonts/fraunces-latin-ext-lB3xlu4.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: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../fonts/inter-latin-Gz7AlRl.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: 400 700;
    font-display: swap;
    src: url("../fonts/inter-latin-ext-1Br77OV.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;
}

@layer tokens {
    :root {
        color-scheme: light dark;

        /* Spacing and type scale: one ladder, used everywhere. */
        --space-2xs: 0.25rem;
        --space-xs: 0.5rem;
        --space-s: 0.75rem;
        --space-m: 1rem;
        --space-l: 1.5rem;
        --space-xl: 2.5rem;
        /* The air between sections of a public page. The app's screens never need this much;
           a landing page that does not breathe reads as a form. */
        --space-2xl: clamp(3.5rem, 9vw, 7rem);

        --text-s: 0.875rem;
        --text-m: 1rem;
        --text-l: 1.25rem;
        /* The state line is read from a car mount at arm's length. */
        --text-state: clamp(1.75rem, 7vw, 2.75rem);

        /*
         * The public pages only. Fluid, because they are read on a phone in a hand and on a
         * laptop, and a fixed 3rem headline is either enormous on one or timid on the other.
         */
        --text-display: clamp(2.5rem, 1.6rem + 4.2vw, 4.5rem);
        --text-title: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
        --text-section: clamp(1.35rem, 1.15rem + 0.9vw, 1.75rem);
        --text-lead: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);

        /*
         * Fraunces is a variable serif with an optical-size axis — it is the typeface doing the
         * "this belongs to somebody who writes books" work, and it is used for headings only.
         * Inter carries the prose, because a legal page set in a display serif is a legal page
         * nobody finishes.
         */
        --font-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
        --font-body: 'Inter', system-ui, sans-serif;
        --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

        /* Prose wants a narrower measure than a layout does. 34rem is roughly 70 characters
           in Inter at this size — past that the eye loses the next line. */
        --measure: 34rem;
        --measure-wide: 64rem;

        --radius-m: 0.75rem;
        --radius-l: 1.5rem;
        --radius-full: 999px;

        /* Hardware buttons are the primary control; on-screen ones are the fallback and must
           still be hittable without looking. 64px is well past the 44px minimum. */
        --control-size: 4rem;

        /* Light palette — daylight, phone on a desk. */
        --color-canvas: #f7f8fa;
        --color-surface: #ffffff;
        --color-border: #d8dde3;
        --color-text: #101418;
        --color-text-muted: #5b6672;
        --color-accent: #0a6cbf;
        --color-accent-contrast: #ffffff;
        --color-recording: #b3261e;
        --color-focus: #0a6cbf;

        /*
         * A second palette, for the pages a stranger sees: the landing page and the three
         * legal ones. Warm paper and ink rather than the player's cool neutral, because those
         * pages are about a manuscript and the player's palette is about a windscreen at
         * night. Deliberately separate tokens, not a redefinition — the car screen must not
         * change colour because the home page wanted to look like a book.
         */
        --paper: #fbf8f3;
        --paper-raised: #ffffff;
        --paper-sunken: #f2ece2;
        --ink: #1a1613;
        --ink-muted: #6b625a;
        --ink-line: #e2d9cb;
        /* Ultramarine: the colour of a pen somebody actually corrects a manuscript with. */
        --mark: #2b4acb;
        --mark-contrast: #ffffff;
        /* The highlighter behind a phrase under review. */
        --mark-wash: #fde9b8;
    }

    @media (prefers-color-scheme: dark) {
        :root {
            /* Dark palette — night driving. Deliberately low contrast against the canvas:
               a white-on-black screen in a windscreen mount is a mirror and a distraction.
               Text still clears WCAG AA against --color-canvas. */
            --color-canvas: #0d1013;
            --color-surface: #161b20;
            --color-border: #2b333b;
            --color-text: #e3e8ee;
            --color-text-muted: #9aa6b2;
            --color-accent: #5ac8fa;
            --color-accent-contrast: #06212e;
            --color-recording: #ff6b5e;
            --color-focus: #5ac8fa;

            /* Paper at night is not grey, it is warm and nearly black — the same shift a
               reading lamp makes. A neutral #111 here reads as "the app", not as a page. */
            --paper: #14110e;
            --paper-raised: #1d1915;
            --paper-sunken: #0e0c0a;
            --ink: #f0e9df;
            --ink-muted: #a2968a;
            --ink-line: #332d26;
            --mark: #9db4ff;
            --mark-contrast: #0e1430;
            --mark-wash: #4a3c15;
        }
    }
}

@layer base {
    *,
    *::before,
    *::after {
        box-sizing: border-box;
    }

    body {
        margin: 0;
        /* Keeps content clear of the notch and the home indicator in a landscape car mount. */
        padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
        min-height: 100dvh;
        background-color: var(--color-canvas);
        color: var(--color-text);
        font-family: system-ui, sans-serif;
        font-size: var(--text-m);
        line-height: 1.5;
    }

    /*
     * The pages a stranger sees — the landing page and the three legal ones — opt into the
     * paper palette and the real typefaces by one class on <body>.
     *
     * A class rather than a second stylesheet, and an opt-in rather than a default, so that
     * nothing here can reach the player: that screen is tuned for a windscreen at night and is
     * the one part of this app where "nicer" is the wrong goal.
     */
    body.public {
        --color-canvas: var(--paper);
        --color-surface: var(--paper-raised);
        --color-border: var(--ink-line);
        --color-text: var(--ink);
        --color-text-muted: var(--ink-muted);
        --color-accent: var(--mark);
        --color-accent-contrast: var(--mark-contrast);
        --color-focus: var(--mark);

        font-family: var(--font-body);
        /* Inter's defaults leave Slovak diacritics and digits looking slightly loose at body
           size; the contextual alternates and tabular figures are what make a date in a table
           line up with the one below it. */
        font-feature-settings: 'cv05', 'tnum';
        line-height: 1.65;
        -webkit-font-smoothing: antialiased;
    }

    body.public h1,
    body.public h2,
    body.public h3 {
        font-family: var(--font-display);
        /* Fraunces' SOFT and WONK axes at their defaults are a touch cute; the optical size is
           what actually matters — it thins the serifs as the heading grows. */
        font-variation-settings: 'opsz' 40;
        font-weight: 600;
        line-height: 1.1;
        letter-spacing: -0.015em;
        text-wrap: balance;
    }

    /* Prose, never a layout: a paragraph that breaks one word onto the last line is the most
       common thing wrong with a page that is otherwise fine. */
    body.public p {
        text-wrap: pretty;
    }

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

    button {
        font: inherit;
        color: inherit;
    }
}

@layer components {
    .login {
        display: grid;
        gap: var(--space-l);
        align-content: center;
        justify-items: stretch;
        max-width: 24rem;
        min-height: 100dvh;
        margin-inline: auto;
        padding: var(--space-l);
    }

    .login__title {
        margin: 0;
        text-align: center;
        font-size: var(--text-l);
    }

    .login__form {
        display: grid;
        gap: var(--space-xs);
        padding: var(--space-l);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-m);
        background-color: var(--color-surface);
    }

    .login__hint {
        margin: 0 0 var(--space-m);
        color: var(--color-text-muted);
        font-size: var(--text-s);
    }

    .login__label {
        font-size: var(--text-s);
        color: var(--color-text-muted);
    }

    .login__label:not(:first-of-type) {
        margin-top: var(--space-s);
    }

    .login__input {
        padding: var(--space-s);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-m);
        background-color: var(--color-canvas);
        color: inherit;
        font: inherit;
    }

    .login__error {
        margin: 0 0 var(--space-xs);
        color: var(--color-recording);
        font-size: var(--text-s);
    }

    .login__submit {
        margin-top: var(--space-l);
        padding: var(--space-s) var(--space-m);
        border: none;
        border-radius: var(--radius-full);
        background-color: var(--color-accent);
        color: var(--color-accent-contrast);
        font-size: var(--text-m);
        cursor: pointer;
    }

    /*
     * The three legal links, in the layout rather than in a component: they are on every
     * screen except the player, which overrides the block with nothing.
     *
     * Muted and small on purpose — these are links somebody goes looking for, not something
     * the app is trying to show anybody. The bottom padding is what keeps them clear of the
     * cookie banner while it is still there.
     */
    .legal {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: var(--space-xs) var(--space-m);
        padding: var(--space-l) var(--space-m) var(--space-xl);
        color: var(--color-text-muted);
        font-size: var(--text-s);

        & a {
            color: inherit;
            text-decoration: underline;
            text-decoration-color: var(--color-border);
        }
    }
}

@layer utilities {
    /*
     * Off-screen but still announced, and still part of the accessible name of its parent.
     *
     * This is how the play/pause button changes what it is called without JavaScript: both
     * labels are in the markup and the stylesheet hides one. `clip-path` rather than
     * `display: none`, which would remove it from the accessible name as well.
     */
    .visually-hidden {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
}
