/* @theme-name SiteTensor */
/* SiteTensor — the application's default theme.
 *
 * WHAT A THEME FILE IS. It maps the application's SEMANTIC role names
 * (--primary, --text-primary, --bg-card) onto the brand PRIMITIVES declared in
 * static/css/tokens.css (--st-blue, --st-graphite, --st-surface). Nothing else.
 * Every rule in main.css, every inline style and every render function reads
 * the semantic names, so redefining these twenty-one re-skins the whole
 * application without touching a single call site.
 *
 * NO RAW COLOUR APPEARS IN THIS FILE, deliberately and by test. Values live in
 * tokens.css, where they are checked against the committed brand sheet; a hex
 * typed here would be a colour nothing verifies. tests/smoke/test_theming.py
 * fails on one.
 *
 * TWO OF THE TWENTY-ONE ARE NOT THE BRAND'S. --warning and --warning-bg map
 * onto a caution colour the brand sheet explicitly forbids, admitted on the
 * owner's instruction (D-103) because the application has a genuine third
 * status state. The sheet is a tier-3 committed specification and an
 * application requirement beats a brand guideline; see
 * docs/project/SOURCE_OF_TRUTH.md, "Committed specifications", and the
 * departure header in tokens.css. Every other mapping here still resolves to a
 * value the brand publishes.
 *
 * AND FROM 02/09/2026 THAT PAIR ALSO COSTS AA IN LIGHT MODE. The ochre chosen
 * to reach 4.5:1 was replaced by main's bright #f39c12 on the owner's
 * instruction (D-130), so this file -- the DEFAULT theme -- carries pinned AA
 * exemptions for the first time: 2.02:1, 2.19:1 and 2.00:1, all light, all the
 * caution ink. Dark is untouched and still passes. R-36 holds the exposure.
 *
 * WHAT IS NOT HERE. Layout tokens (--main-pad-x, --search-box-width,
 * --gal-control-height, --filter-caption-height) stay in main.css. They are
 * geometry, not brand: they do not change between themes and they do not
 * change between light and dark, so putting them in a theme would mean
 * maintaining four copies of one number.
 *
 * THE THREE BLOCKS BELOW, and why the dark one is written twice. Plain CSS
 * cannot share one rule between a media query and an attribute selector, so
 * the dark mapping appears once for "the operating system asked for dark and
 * the user has not overridden it" and once for "the user chose dark". The
 * brand style sheet does exactly the same. A test asserts the two blocks are
 * identical, because the failure mode of hand-maintaining them is that one
 * drifts and only half the application follows the switch.
 *
 * The guard on the media query -- :root:not([data-theme="light"]) -- is what
 * makes an explicit LIGHT choice win over a dark operating system. Without it
 * a user on a dark laptop could never choose light.
 */

/* --- Light: the default, and what a system with no preference gets ------- */
:root {
    /* Brand */
    --primary: var(--st-blue);
    --primary-hover: var(--st-blue-hover);
    --font-ui: var(--st-font-ui);
    --gal-ink: var(--st-blue-deep);
    --success: var(--st-hold);

    /* Neutrals */
    --bg-app: var(--st-instrument-white);
    --bg-card: var(--st-surface);
    --bg-main: var(--st-surface-2);
    --border: var(--st-line);
    --text-primary: var(--st-graphite);
    --text-secondary: var(--st-steel);
    --text-disabled: var(--st-disabled-ink);
    --forest: var(--st-graphite);

    /* States */
    --focus-ring: var(--st-focus-ring);
    --row-hover: var(--st-surface-2);
    --row-selected: var(--st-blue-soft);

    /* Danger */
    --danger: var(--st-slip);
    --danger-bg: var(--st-slip-soft);
    --success-bg: var(--st-hold-soft);
    --warning: var(--st-caution);
    --warning-bg: var(--st-caution-soft);
}

/* --- Dark: the operating system asked, and the user has not said otherwise */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --primary: var(--st-blue-dark);
        --primary-hover: var(--st-blue-hover-dark);
        --font-ui: var(--st-font-ui);
        --gal-ink: var(--st-blue-dark);
        --success: var(--st-hold-dark);
        --bg-app: var(--st-ground-dark);
        --bg-card: var(--st-surface-dark);
        --bg-main: var(--st-surface-2-dark);
        --border: var(--st-line-dark);
        --text-primary: var(--st-ink-dark);
        --text-secondary: var(--st-ink-2-dark);
        --text-disabled: var(--st-disabled-ink-dark);
        --forest: var(--st-ink-dark);
        --focus-ring: var(--st-focus-ring-dark);
        --row-hover: var(--st-surface-2-dark);
        --row-selected: var(--st-blue-soft-dark);
        --danger: var(--st-slip-dark);
        --danger-bg: var(--st-slip-soft-dark);
        --success-bg: var(--st-hold-soft-dark);
        --warning: var(--st-caution-dark);
        --warning-bg: var(--st-caution-soft-dark);
    }
}

/* --- Dark: the user chose it ---------------------------------------------- */
:root[data-theme="dark"] {
    --primary: var(--st-blue-dark);
    --primary-hover: var(--st-blue-hover-dark);
    --font-ui: var(--st-font-ui);
    --gal-ink: var(--st-blue-dark);
    --success: var(--st-hold-dark);
    --bg-app: var(--st-ground-dark);
    --bg-card: var(--st-surface-dark);
    --bg-main: var(--st-surface-2-dark);
    --border: var(--st-line-dark);
    --text-primary: var(--st-ink-dark);
    --text-secondary: var(--st-ink-2-dark);
    --text-disabled: var(--st-disabled-ink-dark);
    --forest: var(--st-ink-dark);
    --focus-ring: var(--st-focus-ring-dark);
    --row-hover: var(--st-surface-2-dark);
    --row-selected: var(--st-blue-soft-dark);
    --danger: var(--st-slip-dark);
    --danger-bg: var(--st-slip-soft-dark);
    --success-bg: var(--st-hold-soft-dark);
    --warning: var(--st-caution-dark);
    --warning-bg: var(--st-caution-soft-dark);
}
