/*
 * Studio design tokens — the single source of colour, type, space and form.
 *
 * Ported from the Studio design system (Claude Design project
 * relay-aa1050ca-0a8e-48dd-abec-10a7b4d266ad). Every value below is the
 * system's; the only additions are marked "Studio addition".
 *
 * NEVER hard-code a colour anywhere else in the app. Light and dark both come
 * from this file, so a literal hex in a component breaks one of the two themes.
 *
 * Theming works in two layers:
 *   1. `@media (prefers-color-scheme: dark)` follows the OS.
 *   2. `:root[data-theme="dark"]` is the explicit opt-in.
 * The media query is scoped `:root:not([data-theme="light"])` so an explicit
 * "light" choice still wins on a dark-mode OS. That keeps the dark values to
 * two copies instead of the three the source spec needed.
 */

/*
 * The two faces, self-hosted.
 *
 * "No webfonts" was the rule here, and the reason behind it was sound: nothing
 * to download means the UI can never fall back to a face that failed to load,
 * and no request leaves for a font CDN. Self-hosting keeps both halves of that
 * — these five files ship with the app, from the app's own origin, and every
 * `font-family` below still ends in the native stack that was there before, so
 * a blocked or slow font degrades to exactly what Studio looked like yesterday.
 *
 * What it buys: one family across headings, labels, figures and body, instead
 * of a Georgia-class serif, whatever grotesque the OS happened to have, and an
 * unrelated mono. IBM Plex is drawn for dense interfaces and its mono is the
 * same design as its sans, which is the whole point — a count in a row and the
 * label above it now share a skeleton.
 *
 * 119 KB for all five, cached after the first screen. The sans is one variable
 * file covering 100–700, which is smaller than the four static weights the app
 * uses (400, 500, 600, 650, 700 — the 650s only render correctly *because* it
 * is variable). Google serves no variable Plex Mono, so its three weights are
 * static; mono is only used for labels and figures, so latin is enough.
 *
 * `swap`: the fallback shows immediately and the face replaces it. The one-off
 * reflow on a cold cache is worth less than a blank screen.
 */

@font-face {
    font-family: "IBM Plex Sans";
    font-style: normal;
    font-weight: 100 700;
    font-display: swap;
    src: url("../fonts/plex-sans-var-ext.f0e2925b3fa6.woff2") format("woff2-variations");
    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: "IBM Plex Sans";
    font-style: normal;
    font-weight: 100 700;
    font-display: swap;
    src: url("../fonts/plex-sans-var.b2c9031d9fd6.woff2") format("woff2-variations");
    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: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/plex-mono-400.79936b18df9f.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: "IBM Plex Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/plex-mono-500.b1c8a895f5fd.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: "IBM Plex Mono";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/plex-mono-600.5a2ce7798732.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;
}

:root {
    /* --- Brand + semantic hues ---------------------------------
       `--signal` is ACTION ONLY: links, primary buttons, focus rings, "today".
       Never use it for a status — lifecycle is marigold/posted/ink-3. */
    --signal: #2A44D4;         /* press-cobalt */
    --signal-strong: #1E33A8;
    --signal-tint: #ECEFFE;
    --marigold: #C77E17;       /* editor's highlighter — scheduled / on-deck */
    --marigold-tint: #FBEFD3;
    --posted: #12704A;
    --posted-tint: #E0F3EA;
    --critical: #B32B3D;
    --critical-tint: #FBE9EC;

    /* Studio addition: the foreground that sits on top of --signal. Having it as
       a token means .btn--primary and .cal__today need one rule, not one per
       theme (the source spec repeated six override rules to do this). */
    --pri-on: #ffffff;

    /* --- Neutrals (cool slate-indigo bias) --------------------- */
    --ink: #16182B;            /* primary text */
    --ink-2: #43485E;          /* secondary text */
    --ink-3: #71768B;          /* meta text — also the "draft" status colour */
    --paper: #F4F5F7;          /* page ground */
    --surface: #FFFFFF;        /* card ground */
    --surface-2: #FAFAFC;      /* inset ground */
    --line: #E4E6EC;           /* hairline */
    --line-strong: #CBD0DC;    /* input borders, stronger dividers */

    /* --- Type ---------------------------------------------------
       Native stacks by design: nothing to download, so the UI can never fall
       back to a webfont that failed to load. Three roles — an editorial serif
       for display, a humanist grotesque for UI, a monospace for anything that
       must line up or be read exactly (counts, times, slugs, model names).

       The named faces come BEFORE the `ui-*` generics, which is the one change
       from the source spec. `ui-sans-serif` resolves on Linux — to DejaVu Sans,
       a much wider face than SF Pro or Segoe UI — so with it leading, every
       later entry was unreachable and the UI rendered in the wrong grotesque
       anywhere but macOS. Ordering the real faces first keeps SF Pro on macOS
       and Segoe UI on Windows exactly as designed, and picks up Arial /
       Liberation Sans on Linux instead of DejaVu. Same reasoning for mono. */
    --font-ui: "IBM Plex Sans", -apple-system, "SF Pro Text", "Segoe UI", "Helvetica Neue", Arial, ui-sans-serif, system-ui, sans-serif;
    --font-data: "IBM Plex Mono", "SF Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", ui-monospace, monospace;

    /* `--font-display` is the face for HEADINGS AND TITLES, and it is the
       interface's own face — not an editorial one.

       It used to be the serif below, and that is what made Studio read as a
       magazine rather than as a tool: the serif was doing chrome work in
       nineteen places (top bar, page titles, drawer and modal titles, section
       heads, the empty states). Repointing it here is what retires that in one
       line — every one of those selectors already asks for this token, so none
       of them had to be touched.

       The serif still exists, as `--font-editorial`, and it is allowed on
       exactly the surfaces where somebody is reading rather than operating:
       a Core Article's title and headings, the field that must look like the
       title, rich-text headings, and the sign-in panel's brand claim. That
       boundary is enforced by `EditorialTypeTests` in tests_studio.py, not
       remembered — the whole point of the change is that it cannot creep back
       into the chrome one heading at a time. */
    --font-display: "IBM Plex Sans", -apple-system, "SF Pro Text", "Segoe UI", "Helvetica Neue", Arial, ui-sans-serif, system-ui, sans-serif;
    --font-editorial: "New York", Georgia, "Iowan Old Style", "Times New Roman", ui-serif, serif;

    /* The type scale: six steps, and the only place a text size is decided.

       It was nine, in three bands, and three of them were doing no work that the
       step above or below could not. `--t-help` (13) and `--t-body` (16) were a
       paragraph and a slightly smaller paragraph; `--t-lead` (18) was a slightly
       larger one; `--t-h3` (20), `--t-h2` (24), `--t-h1` (26) and `--t-display`
       (30) were four headings for an app with two kinds of heading. Nine steps
       means nine judgements, and the answer to "which of these is it" was
       usually "either".

       Six, and each one has a job you can name:

         micro  chrome labels — the uppercase mono ones, and nothing else
         meta   secondary metadata, timestamps, counts beside a label
         ui     everything in the interface: rows, fields, buttons, help
         read   prose somebody actually reads — an article, a piece, a lede
         h2     a section head inside a screen
         h1     the screen's own title

       The two that moved rather than merged: `ui` is 14, not 13 — 13 was the
       stated floor for a paragraph and most of the app's text was sitting on it.
       `h1` is 28, not 26, because with `--t-display` gone it is the largest
       thing on any screen and it was competing with 24. */
    --t-micro: 0.6875rem;  /* 11px */
    --t-meta: 0.75rem;     /* 12px */
    --t-ui: 0.875rem;      /* 14px */
    --t-read: 1rem;        /* 16px */
    --t-h2: 1.25rem;       /* 20px */
    --t-h1: 1.75rem;       /* 28px */

    /* --- Space + form ------------------------------------------
       One 4px-based scale drives every gap. Layout groups use `gap`, not
       per-element margins, so spacing never doubles or collapses. */
    --s1: 0.25rem;   /* 4px  */
    --s2: 0.5rem;    /* 8px  */
    --s3: 0.75rem;   /* 12px */
    --s4: 1rem;      /* 16px */
    --s5: 1.5rem;    /* 24px */
    --s6: 2rem;      /* 32px */
    --s7: 3rem;      /* 48px */
    --s8: 4.5rem;    /* 72px */

    /* The sign-in panel — `6a`'s left half.

       Pinned rather than themed. The panel is dark in both themes by design: it is
       a brand surface, the way the platform previews are platform surfaces, and a
       light version of it would be a different screen. So the values are the dark
       theme's, written once here, where hex belongs, instead of as literals in the
       stylesheet. Referenced only by the `.signin__*` rules. */
    --signin-panel: #16182B;
    --signin-panel-ink: #ECEDF4;
    --signin-panel-title: #FFFFFF;
    --signin-panel-quiet: #B4B8CC;
    --signin-panel-meta: #82869C;
    --signin-panel-line: #2A2E48;
    --signin-panel-rule: #3A3F5E;
    --signin-dot-a: #8FA0FF;
    --signin-dot-b: #E9B45C;
    --signin-dot-c: #63CE9A;

    /* Reading measures for the Core Article.

       Each is used twice — once by the element that displays the text and once by
       the field that replaces it — because the article has no separate edit page:
       a title that wraps differently while you are typing it than when an approver
       reads it is a different title. Naming each measure once is what stops the
       pair drifting.

       Wider than the mockup's 26/64/66ch, deliberately. `1g` is drawn as a reading
       view, where a narrow measure is right; the same numbers in the editor left a
       third of the column empty beside the rail. These sit at the top of the
       comfortable range (roughly 45–90 characters a line) rather than past it. */
    /* The form column's width. In `rem` rather than `ch` because a form is not
       one font-size: the three things that must line up down the edge of a
       Pulse Item — a 15.5px prose field, a 14px pair of columns and a banner —
       resolve `ch` against themselves and land 100px apart. 44rem is the
       76ch of `--measure-lede` at the prose field's own size, fixed. */
    --measure-form: 44rem;
    --measure-title: 32ch;
    --measure-lede: 76ch;
    --measure-body: 86ch;

    --r-sm: 5px;
    --r-md: 8px;
    /* Studio addition: the output editor's boxes — the caption surface, the
       media slots and the rail cards — all sit at 10px, between a control and
       a panel. Without the step they would have to hard-code a radius. */
    --r-ml: 10px;
    --r-lg: 12px;
    --r-pill: 999px;

    /* The stage the standalone preview stands on — `10n`.

       Pinned rather than themed, for the same reason the sign-in panel is: it
       is a viewing surface, not one of Studio's. The point of that page is to
       judge a post against the platform it is going for, and a preview whose
       surround flips with the reader's chrome is a different judgement each
       time. Everything translucent on it is derived with color-mix from these
       two, so there is one dark and one light and nothing else to keep in sync.
       Referenced only by the `.stage*` rules. */
    --stage: #101223;
    --stage-ink: #FFFFFF;

    /* Studio addition: the code surface. A prompt template is code, and a code
       surface is deliberately theme-invariant — an editor's syntax theme does not
       flip with the chrome around it, and the mockups draw this box dark inside a
       light screen. Declared as tokens rather than literals so the one place that
       decides "code looks like this" stays one place. */
    --code-surface: #16182B;
    --code-ink: #C9CCDA;
    --code-token: #8FA0FF;

    --shadow-1: 0 1px 2px rgba(22, 24, 43, .06), 0 1px 3px rgba(22, 24, 43, .05);
    --shadow-2: 0 6px 16px rgba(22, 24, 43, .10), 0 2px 5px rgba(22, 24, 43, .06);
    /* Studio addition: lifted surfaces (modals, the drag ghost). */
    --shadow-3: 0 24px 60px rgba(22, 24, 43, .22), 0 4px 12px rgba(22, 24, 43, .10);

    --ease: cubic-bezier(.2, .7, .2, 1);

    /* Studio addition: a stacking order. The source spec had exactly one
       z-index, which isn't enough once popovers, drawers and modals coexist. */
    --z-sticky: 30;
    --z-popover: 40;
    --z-scrim: 50;
    --z-drawer: 60;
    --z-modal: 70;
    --z-toast: 80;
}

/* Dark values, shared by the OS preference and the explicit toggle.
   Keep these two selector lists in sync — they must hold identical values. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --signal: #8FA0FF;
        --signal-strong: #AFBAFF;
        --signal-tint: #1D2350;
        --marigold: #E9B45C;
        --marigold-tint: #392C12;
        --posted: #63CE9A;
        --posted-tint: #123329;
        --critical: #F0788A;
        --critical-tint: #391C23;

        --pri-on: #10121F;

        --ink: #ECEDF4;
        --ink-2: #B4B8CC;
        --ink-3: #82869C;
        --paper: #0E1020;
        --surface: #181B2E;
        --surface-2: #12142440;   /* 8-digit: ~25% alpha over --surface */
        --line: #2A2E48;
        --line-strong: #3A3F5E;

        --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
        --shadow-2: 0 8px 24px rgba(0, 0, 0, .5), 0 2px 6px rgba(0, 0, 0, .35);
        --shadow-3: 0 24px 60px rgba(0, 0, 0, .6), 0 4px 12px rgba(0, 0, 0, .4);
    }
}

:root[data-theme="dark"] {
    --signal: #8FA0FF;
    --signal-strong: #AFBAFF;
    --signal-tint: #1D2350;
    --marigold: #E9B45C;
    --marigold-tint: #392C12;
    --posted: #63CE9A;
    --posted-tint: #123329;
    --critical: #F0788A;
    --critical-tint: #391C23;

    --pri-on: #10121F;

    --ink: #ECEDF4;
    --ink-2: #B4B8CC;
    --ink-3: #82869C;
    --paper: #0E1020;
    --surface: #181B2E;
    --surface-2: #12142440;
    --line: #2A2E48;
    --line-strong: #3A3F5E;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 8px 24px rgba(0, 0, 0, .5), 0 2px 6px rgba(0, 0, 0, .35);
    --shadow-3: 0 24px 60px rgba(0, 0, 0, .6), 0 4px 12px rgba(0, 0, 0, .4);
}
