/* ══════════════════════════════════════════════════════════════════════════
   bk-radzen.css — THE ENTIRE INTEGRATION SEAM FOR Radzen.Blazor 11.2.8.

   DESIGN-PLAN.md §3A is the decision. This file is the whole of its
   implementation on the CSS side: one import that puts the library underneath
   Bookary's own system, and one block that teaches its variables to speak the
   `--bk-*` palette. If it ever needs a third thing, that is the signal that
   the boundary in §3A has moved and the document has to move with it.

   ── WHY THIS IS AN @import AND NOT A SECOND <link> ────────────────────────

   Because a <link> cannot be put in a cascade layer, and this one has to be.
   Radzen's `standard-base.css` is 756 KB of somebody else's opinions, and
   measured in 11.2.8 it does NOT confine itself to `.rz-*`. Counted: of 4,198
   top-level rules, four are not — two `body` (one of them a fixed gradient
   carrying a data: URI), one bare `input` and one `input::placeholder` — plus
   a fifth, `:root:has(.rz-layout) body{colour, background, font-family,
   font-size, line-height}`, which is inert only while no page renders
   `RadzenLayout`. Unlayered, all of those outrank every layer in
   app.css, because unlayered normal declarations win over layered ones
   regardless of layer order. `layer(radzen)` puts them below `base`, where
   they are outranked — with ONE measured exception, which is the `body` rule at
   the bottom of this file. See the `@layer` comment at the top of app.css for
   the order and for why that IS the boundary rather than a description of it.

   The cost of the import, stated rather than discovered: the browser cannot
   discover `standard-base.css` until this file has arrived, so it is one
   serialised round trip on a cold load. App.razor preloads it to close that
   gap. The URL is deliberately the unfingerprinted `_content/` path — a
   stylesheet cannot ask Blazor for `@Assets[…]` — so it caches by ETag rather
   than immutably, which is the price of the layer.

   ── WHY standard-base RATHER THAN standard ────────────────────────────────

   Diffed, not assumed. `standard.css` adds exactly this and nothing else:
   `h1`–`h6`, `:root{font-size}`, `body`, `p`, `label`, `::selection` and the
   `::-webkit-scrollbar` family. Every one of those is a global element rule
   this app already decides for itself in app.css's `base` layer. The `-base`
   variant is not "the theme without colours" — it still ships the full
   `:root{--rz-*}` block that the mapping below overrides — it is the theme
   without the global reset. That is the one we want.

   ── WHY THE MAPPING IS THIS SHORT ─────────────────────────────────────────

   Radzen's `:root` block is 1,761 declarations, of which 894 hold a literal
   and 867 are `var()` chains onto other ones. Everything semantic derives:
   `--rz-text-color` is `var(--rz-base-800)`, `--rz-dialog-background-color`
   is `var(--rz-base-background-color)`, `--rz-menu-item-color` is
   `var(--rz-text-color)`, and so on down. So the seam remaps the ~70 ROOTS of
   that graph and lets the rest follow, instead of restating a theme.

   ── AND WHY THERE IS NO PER-THEME BLOCK IN THIS FILE ──────────────────────

   There cannot be one, and that is the point rather than an omission. Every
   `--bk-*` colour is redefined by `:root[data-theme="light"|"dark"|"sepia"]`
   and by the `prefers-color-scheme` block in app.css. A mapping written as
   `var(--bk-…)` is re-resolved in whichever of those four themes is active, so
   ONE block themes Radzen four times — including sepia, which no library ships
   and no `light-dark()` could express (§9). A literal colour anywhere below
   would be a fifth theme that follows nothing, so there are none.
   ══════════════════════════════════════════════════════════════════════════ */

@import url("_content/Radzen.Blazor/css/standard-base.css") layer(radzen);

@layer bk-radzen {
    :root {
        /* ── THE NEUTRAL RAMP ──────────────────────────────────────────────
           Radzen's ramp runs light (50) to dark (900) in a light theme and
           inverts wholesale in its dark themes. Bookary's tokens ALREADY
           invert per theme, so mapping by ROLE rather than by lightness gets
           the polarity right in all four schemes for free: `--bk-surface-raised`
           is #fffdf7 under light and #24211a under dark, and `--rz-base-50`
           follows it both ways without a second block.

           `--rz-white` and `--rz-black` are not literal here. They are the two
           ends of whatever theme is running — Radzen uses `--rz-white` as
           tooltip TEXT over a `--rz-base-900` tooltip, so binding it to the
           surface keeps that pair legible in sepia and in dark rather than
           painting white on brown. */
        --rz-white: var(--bk-surface);
        --rz-black: var(--bk-text);

        --rz-base-50: var(--bk-surface-raised);
        --rz-base-100: var(--bk-surface-alt);
        --rz-base-200: var(--bk-border);
        --rz-base-300: var(--bk-edge);
        --rz-base-400: var(--bk-edge);
        --rz-base-500: var(--bk-muted);
        --rz-base-600: var(--bk-muted);
        --rz-base-700: var(--bk-muted);
        --rz-base-800: var(--bk-text);
        --rz-base-900: var(--bk-text);

        --rz-base: var(--bk-edge);
        --rz-base-light: var(--bk-border);
        --rz-base-lighter: var(--bk-surface-alt);
        --rz-base-dark: var(--bk-muted);
        --rz-base-darker: var(--bk-text);

        /* The surface every floating thing is painted on: dialog, menu, panel,
           input, grid. `.bk-panel` uses --bk-surface-raised for exactly this
           job, so the two agree by construction. */
        --rz-base-background-color: var(--bk-surface-raised);

        --rz-on-base: var(--bk-text);
        --rz-on-base-light: var(--bk-text);
        --rz-on-base-lighter: var(--bk-text);
        --rz-on-base-dark: var(--bk-surface);
        --rz-on-base-darker: var(--bk-surface);

        /* ── THE ACCENT ────────────────────────────────────────────────────
           §4.0's oxblood. Radzen names its shades by LIGHTNESS (`-light`,
           `-dark`) and Bookary names its by ROLE (`--bk-accent-hover`), and
           the two do not line up: the hover shade is darker under light and
           lighter under dark. Role wins — a hover state that goes the wrong
           way in one theme is worse than a `-light` that is not lighter.

           `-lighter` is the one exception, and it is not a shade at all in
           Radzen's usage: it is the tinted BACKGROUND behind hovered rows,
           selected cells and text selection. `--bk-accent-subtle` is that
           token, and it already inverts per theme. */
        --rz-primary: var(--bk-accent);
        --rz-primary-light: var(--bk-accent-hover);
        --rz-primary-dark: var(--bk-accent-hover);
        --rz-primary-darker: var(--bk-accent-hover);
        --rz-primary-lighter: var(--bk-accent-subtle);
        --rz-on-primary: var(--bk-accent-contrast);
        --rz-on-primary-light: var(--bk-accent-contrast);
        --rz-on-primary-dark: var(--bk-accent-contrast);
        --rz-on-primary-darker: var(--bk-accent-contrast);
        --rz-on-primary-lighter: var(--bk-text);

        /* Bookary has ONE accent, so secondary is the same colour. Radzen
           derives `--rz-link-color` from `--rz-secondary`, which is the reason
           this family cannot simply be left alone: unmapped, every link inside
           a Radzen component would be Radzen's cornflower blue. */
        --rz-secondary: var(--bk-accent);
        --rz-secondary-light: var(--bk-accent-hover);
        --rz-secondary-dark: var(--bk-accent-hover);
        --rz-secondary-darker: var(--bk-accent-hover);
        --rz-secondary-lighter: var(--bk-accent-subtle);
        --rz-on-secondary: var(--bk-accent-contrast);
        --rz-on-secondary-light: var(--bk-accent-contrast);
        --rz-on-secondary-dark: var(--bk-accent-contrast);
        --rz-on-secondary-darker: var(--bk-accent-contrast);
        --rz-on-secondary-lighter: var(--bk-text);

        /* ── STATUS ────────────────────────────────────────────────────────
           §4.5's destructive grammar says colour is NOT what separates
           "proceed" from "this erases things" here, because oxblood and alarm
           red sit 0.7° apart — form carries it. So `--rz-danger` being close
           to `--rz-primary` is correct rather than a collision, and any Radzen
           surface that leans on hue alone to mean "destructive" is a surface
           that needs the grammar applied by hand when it is migrated.

           Bookary's palette has no INFO hue and does not want one: §9 says no
           rebrand, and inventing a fifth colour to satisfy a component nobody
           has adopted yet is exactly the creep this seam exists to stop. Info
           is the accent. Warning is `--bk-highlight`, the gold, which is what
           it was always for. */
        --rz-danger: var(--bk-danger);
        --rz-danger-light: var(--bk-danger);
        --rz-danger-dark: var(--bk-danger);
        --rz-danger-darker: var(--bk-danger);
        --rz-danger-lighter: var(--bk-accent-subtle);
        --rz-on-danger: var(--bk-accent-contrast);
        --rz-on-danger-light: var(--bk-accent-contrast);
        --rz-on-danger-dark: var(--bk-accent-contrast);
        --rz-on-danger-darker: var(--bk-accent-contrast);
        --rz-on-danger-lighter: var(--bk-danger);

        --rz-success: var(--bk-success);
        --rz-success-light: var(--bk-success);
        --rz-success-dark: var(--bk-success);
        --rz-success-darker: var(--bk-success);
        --rz-success-lighter: var(--bk-surface-alt);
        --rz-on-success: var(--bk-accent-contrast);
        --rz-on-success-light: var(--bk-accent-contrast);
        --rz-on-success-dark: var(--bk-accent-contrast);
        --rz-on-success-darker: var(--bk-accent-contrast);
        --rz-on-success-lighter: var(--bk-text);

        --rz-warning: var(--bk-highlight);
        --rz-warning-light: var(--bk-highlight);
        --rz-warning-dark: var(--bk-highlight);
        --rz-warning-darker: var(--bk-highlight);
        --rz-warning-lighter: var(--bk-surface-alt);
        --rz-on-warning: var(--bk-text);
        --rz-on-warning-light: var(--bk-text);
        --rz-on-warning-dark: var(--bk-text);
        --rz-on-warning-darker: var(--bk-text);
        --rz-on-warning-lighter: var(--bk-text);

        --rz-info: var(--bk-accent);
        --rz-info-light: var(--bk-accent-hover);
        --rz-info-dark: var(--bk-accent-hover);
        --rz-info-darker: var(--bk-accent-hover);
        --rz-info-lighter: var(--bk-accent-subtle);
        --rz-on-info: var(--bk-accent-contrast);
        --rz-on-info-light: var(--bk-accent-contrast);
        --rz-on-info-dark: var(--bk-accent-contrast);
        --rz-on-info-darker: var(--bk-accent-contrast);
        --rz-on-info-lighter: var(--bk-text);

        /* ── TYPE, GEOMETRY AND MOTION ─────────────────────────────────────
           §4.4's scales, which are the same in every theme and so are named
           here once. `--rz-body-font-size` becomes --bk-text-sm — not because
           0.9rem is much bigger than the shipped 0.875rem (it is 14.4px against
           14px, and both are under §1's 16px reading floor) but because that
           floor is a rule about PROSE and this is chrome: `.bk-button` is
           --bk-text-sm too. What the mapping buys is that Radzen's control text
           moves when the app's scale moves, instead of sitting at a number this
           repository never chose. The one place 16px is not negotiable is a
           text INPUT, where iOS Safari zooms the page below it and leaves it
           zoomed — and that is `.bk-field`'s rule, held at --bk-text-base,
           which no Radzen input inherits from this line.

           `--rz-text-font-family` matters more than it looks: unmapped, every
           Radzen component would silently pull `Source Sans Pro` from
           `_content/Radzen.Blazor/fonts/` — a real font download for a face
           this product deliberately does not use (§4.4: UI face vs reading
           face). Bound to --bk-font-ui, that fetch never happens.

           MATERIAL SYMBOLS IS A SEPARATE AND MUCH LARGER MATTER, AND NO
           VARIABLE CAN TURN IT OFF. `MaterialSymbolsOutlined.woff2` is 1.02 MB
           on disk and is already compressed, so brotli does nothing for it —
           measured in this app's own publish output, not quoted. It is fetched
           the first time any Radzen component renders a glyph, INCLUDING the
           ones a menu draws for itself. That is comfortably the largest single
           cost of this adoption and it does not appear in the WASM payload
           where anyone would look for it. §9's "no icon system" is about the
           app's own glyphs and does not reach inside a library's chrome, so the
           rule the migration needs is narrower and belongs with it: prefer
           Radzen components that render no icon, and pass inline SVG where one
           is wanted. */
        --rz-text-font-family: var(--bk-font-ui);
        --rz-body-font-size: var(--bk-text-sm);
        --rz-body-line-height: var(--bk-leading-normal);
        --rz-root-font-size: 16px;

        --rz-border-radius: var(--bk-radius-md);
        --rz-border-width: var(--bk-edge-width);
        --rz-gap: var(--bk-space-4);
        --rz-icon-size: 1.25rem;

        --rz-transition: var(--bk-duration-quick) var(--bk-ease);
        --rz-transition-all: all var(--bk-duration-quick) var(--bk-ease);
        --rz-dialog-transition: var(--bk-duration-gentle) var(--bk-ease);

        /* §4.3 as decided 2026-09-02: the shadows are HARD OFFSETS in the
           theme's shadow ink (the pixel library replaced the warm blur).
           Two levels of elevation exist in this system and no more, so
           Radzen's six collapse onto them: 1–2 are the resting level, 3–6 are
           the floating one. A dialog is the only thing that floats above a
           floating thing, and it still gets --bk-shadow-2 rather than a
           seventh value invented here. */
        --rz-shadow-1: var(--bk-shadow-1);
        --rz-shadow-2: var(--bk-shadow-1);
        --rz-shadow-3: var(--bk-shadow-2);
        --rz-shadow-4: var(--bk-shadow-2);
        --rz-shadow-5: var(--bk-shadow-2);
        --rz-shadow-6: var(--bk-shadow-2);
        --rz-dialog-shadow: var(--bk-shadow-2);
        --rz-overlay-shadow: var(--bk-shadow-2);
        --rz-tooltip-shadow: var(--bk-shadow-2);
        --rz-scrollbar-color: var(--bk-border-strong);

        /* ── WHERE A ROOT MAPPING AND A DECIDED RULE DISAGREE ──────────────
           Six of them, and they are listed rather than absorbed because each
           one is app.css winning an argument the library did not know it was
           having. Anything longer than this list belongs in app.css as a rule,
           not here as an exception.

           1-2. ONE RING EVERYWHERE (app.css, `.bk-button:focus-visible`): 2px
                solid --bk-focus, offset 2px. Radzen's default outline colour
                is `--rz-primary-light`, which the accent mapping above would
                make the hover shade rather than the focus token. */
        --rz-outline-color: var(--bk-focus);
        --rz-outline-width: 2px;

        /*  3-4. AND RADZEN'S INPUTS HAVE NO RING AT ALL: shipped,
                `--rz-input-focus-outline` is `var(--rz-outline-normal)`, which
                is `none`, and focus is carried by a hard-coded blue box-shadow
                instead. That is a WCAG 2.4.7 regression against `.bk-field`
                and it is a literal colour that follows no theme, so both are
                replaced by the ring the rest of the app uses. */
        --rz-input-focus-outline: var(--rz-outline-focus);
        --rz-input-focus-shadow: none;

        /*  5. 44 x 44 (§5.4, WCAG 2.2 2.5.8). Radzen's medium control is
               2.25rem — 36px, the same failure `.bk-button` was measured at
               and fixed for in phase 1. Adopting the library at its own size
               would reintroduce it uniformly. --rz-input-height and
               --rz-button-size-md both derive from these. */
        --rz-input-size-md: 2.75rem;
        --rz-button-size-md: 2.75rem;

        /*  6. Radzen hovers a menu row with the ACCENT TINT; `.bk-menu-item`
               hovers with paper (--bk-surface-alt) and reserves the tint for
               selection. The primitive is the decision, so the library follows
               it — this is the one place the seam names a component, and it is
               named because a migrated menu that hovers differently from the
               hand-rolled one beside it is the visible edge of the boundary. */
        --rz-menu-item-hover-background-color: var(--bk-surface-alt);
        --rz-menu-item-hover-color: var(--bk-text);

        /* Two hard-coded greys with no var() behind them; they would survive
           every mapping above and be the only Radzen-grey left on the page. */
        --rz-button-base-background-color: var(--bk-surface-alt);
        --rz-button-base-color: var(--bk-text);
    }

    /* ── THE ONE RULE HERE THAT IS NOT A TOKEN, AND THE MEASUREMENT THAT PUT
       IT HERE ───────────────────────────────────────────────────────────────

       A LAYER DOES NOT PROTECT A PROPERTY NOBODY DECLARES. This file's first
       draft asserted that putting Radzen below `base` meant its
       `body{background:… url("data:image/svg+xml;base64,…")}` gradient could
       never apply and its data: URI could never be fetched. That was wrong,
       and Chromium said so: `img-src blocked data` on /login and /library, in
       an E2E run that had passed on the commit before. Layers order competing
       declarations of the SAME property, and app.css's base layer declares
       `background-color` — a LONGHAND. Radzen's `background` SHORTHAND also
       sets `background-image`, which nothing in this app declares at all, so
       there was no competition to win and the gradient came through the layer
       untouched. One declaration closes it.

       Left alone this was not merely cosmetic: the app origin's CSP names no
       `img-src`, so it falls back to `default-src 'self'` and a `data:` URI is
       refused. Every page would have logged a CSP violation for a decoration
       nobody asked for — and the refusal is the reason the app still LOOKED
       right, which is exactly how this would have shipped unnoticed if the
       browser-level check had only ever looked at the harness page.

       Two rules follow from it, and they are the migration task's, not this
       one's. Anywhere Bookary declares a longhand and a library declares the
       shorthand, the library wins the properties Bookary never named — so a
       version bump means re-diffing `standard-base.css`'s handful of global
       selectors, not just its variables. And DO NOT USE `RadzenLayout`: the
       stylesheet carries a `:root:has(.rz-layout) body{…}` rule that restyles
       colour, background, font-family, font-size and line-height, and it is
       inert only for as long as no page renders that component. */
    body {
        background-image: none;
    }
}
