/*
 * theme.css — shared design tokens for every portal-rendered document.
 *
 * See docs/decisions/0004-design-token-layer.md.
 *
 * This is the ONLY stylesheet allowed to contain raw hex values. Skin files
 * (header.css, login.css, app_page.css, …) consume var(--token).
 *
 * Load order matters: this file goes AFTER the Bootstrap <link> so it wins on
 * equal specificity, and BEFORE the per-surface skin so the skin can override.
 */

/* --------------------------------------------------------------------------
 * Fonts — self-hosted, no fonts.googleapis.com request. See ADR 0004.
 * Inter and Archivo are variable fonts; one file covers each weight range.
 * -------------------------------------------------------------------------- */

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('/public/vendor/fonts/inter-latin-ext.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 600;
    font-display: swap;
    src: url('/public/vendor/fonts/inter-latin.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: 'Archivo';
    font-style: normal;
    font-weight: 700 800;
    font-display: swap;
    src: url('/public/vendor/fonts/archivo-latin-ext.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: 'Archivo';
    font-style: normal;
    font-weight: 700 800;
    font-display: swap;
    src: url('/public/vendor/fonts/archivo-latin.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;
}

/* --------------------------------------------------------------------------
 * Tokens
 * -------------------------------------------------------------------------- */

:root {
    --bg-0: #0a0813;
    --bg-1: #131022;
    --bg-2: #1b1730;
    --bg-3: #241f3d;

    --border: rgba(168, 153, 204, 0.16);
    --border-strong: rgba(168, 153, 204, 0.28);

    --text-0: #f6f4fb;
    --text-1: #c7bfdc;
    --text-2: #8f85ab;

    --accent-0: #a98cf0;
    --accent-1: #8a5cc8;
    --accent-2: #46299b;
    --accent-3: #241241;

    --glow: rgba(160, 130, 255, 0.35);
    --radius: 10px;

    /* Derived — used by more than one skin, kept here so they stay in sync. */
    --accent-gradient: linear-gradient(160deg, var(--accent-2), var(--accent-3));
    --accent-shadow: inset 0 1px 0 rgba(160, 130, 255, .32), 0 6px 18px rgba(70, 41, 155, .35);
    --row-stripe: rgba(255, 255, 255, .02);
    --row-hover: rgba(138, 92, 200, .14);
    --underline-hover: rgba(169, 140, 240, 0.40);

    /* ----------------------------------------------------------------------
     * Palette-dependent values that used to be written inline in the rules
     * below. They are tokens because they are NOT neutral: every one of them
     * is tuned for a dark surface and has to be restated by any other palette.
     *
     * Why they are spelled out rather than derived from --accent-* etc.: a
     * translucent value cannot be built from a hex token without color-mix(),
     * which is far newer than the Edge 16 floor ADR 0004 set. No build step
     * here either, so explicit is the honest option.
     * -------------------------------------------------------------------- */

    /* Elevation. Shadows are part of the palette, not a constant — a 60% black
       drop that reads as depth on near-black reads as dirt on white. */
    --shadow-nav:      0 5px 5px rgba(0, 0, 0, .2);
    --shadow-card:     0 8px 24px rgba(0, 0, 0, .35);
    --shadow-dropdown: 0 12px 32px rgba(0, 0, 0, .5);
    --shadow-popup:    0 16px 40px rgba(0, 0, 0, .55);
    --shadow-auth:     0 1.5rem 3rem 0 rgba(0, 0, 0, .55);
    --shadow-modal:    0 24px 64px rgba(0, 0, 0, .6);

    /* Text sitting on an accent fill (buttons, active pagination, active day). */
    --on-accent: #fdfbff;

    /*
     * A quiet accent-tinted surface that --text-0 sits on directly (the
     * datepicker's "today" cell). This is NOT --accent-3, even though it holds
     * the same value here: --accent-3 is the DARK END OF THE BUTTON GRADIENT,
     * which a light palette must keep dark for white button labels, while this
     * has to stay light enough for near-black body text. The two meanings only
     * coincide on a dark ground.
     */
    --accent-subtle: #241241;

    /* The page wash the body rule paints over --bg-0. */
    --body-wash: radial-gradient(900px 500px at 15% -10%, rgba(90, 50, 180, 0.28), transparent 60%);

    /* Sticky navbar backdrop: --bg-1 carrying alpha, so it cannot be var()-derived. */
    --nav-backdrop: rgba(19, 16, 34, .85);

    /* Semantic hues — table row markers and alert rules. */
    --status-danger:  #e47297;
    --status-warning: #e8b35a;
    --status-success: #86c541;
    --status-info:    #1d8ecd;   /* chat "me" marker in component.css */

    /* Contextual table row washes. */
    --row-wash-danger:  rgba(228, 114, 151, .13);
    --row-wash-warning: rgba(232, 179, 90, .13);
    --row-wash-success: rgba(134, 197, 65, .13);
    --row-wash-info:    rgba(138, 92, 200, .16);

    --table-cell-border: rgba(168, 153, 204, .09);
    --row-hover-soft:    rgba(138, 92, 200, .08);

    /* Status chips. Deliberately a lighter, higher-chroma family than the
       markers above — a chip is small type that has to clear AA on its own
       tinted fill, a marker is a 3px rule that only has to be seen. */
    --chip-success-fg: #6ee7a8;
    --chip-success-bg: rgba(110, 231, 168, .13);
    --chip-success-br: rgba(110, 231, 168, .28);
    --chip-danger-fg:  #f2879f;
    --chip-danger-bg:  rgba(242, 135, 159, .13);
    --chip-danger-br:  rgba(242, 135, 159, .28);
    --chip-warning-fg: #e8b35a;
    --chip-warning-bg: rgba(232, 179, 90, .13);
    --chip-warning-br: rgba(232, 179, 90, .28);
    --chip-info-bg:    rgba(169, 140, 240, .14);
    --chip-info-br:    rgba(169, 140, 240, .30);
    --chip-neutral-bg: rgba(168, 153, 204, .09);
}

/* --------------------------------------------------------------------------
 * Light palette — direction "Paper" (ADR 0009)
 *
 * A warm neutral ground with the violet kept as the accent, so the brand
 * survives where it is actually load-bearing (buttons, links, active rows,
 * focus rings) while dense tables get a calm surface to sit on.
 *
 * This block restates ONLY what differs from the dark ramp above. --on-accent
 * and --radius are absent because they are identical in both palettes.
 *
 * There is deliberately no @media (prefers-color-scheme) copy of this block.
 * theme.js resolves stored-choice-then-system-preference and always stamps an
 * explicit data-theme on <html> before first paint, so one selector is enough
 * and the palette has exactly one definition. The cost is that the page stays
 * dark with JS disabled — the portal already hard-requires jQuery, Bootstrap,
 * Chart.js and Dropzone, so that is not a supported mode.
 * -------------------------------------------------------------------------- */

:root[data-theme="light"] {
    --bg-0: #faf9fb;
    --bg-1: #ffffff;
    --bg-2: #f3f1f6;
    --bg-3: #e9e5ef;

    --border: rgba(60, 45, 90, 0.14);
    --border-strong: rgba(60, 45, 90, 0.26);

    --text-0: #17131f;
    --text-1: #3d3550;
    --text-2: #6b6280;

    /* Accents darken on a light ground: the dark theme's #a98cf0 sits at 2.1:1
       on white. --accent-2/-3 stay dark — they are the button gradient, and
       --on-accent is near-white on top of them (6.17:1 at the lightest stop). */
    --accent-0: #6d3fd4;
    --accent-1: #5c31bd;
    --accent-2: #6d3fd4;
    --accent-3: #4a1f9e;

    --glow: rgba(109, 63, 212, .16);

    --accent-gradient: linear-gradient(160deg, var(--accent-2), var(--accent-3));
    --accent-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 5px 14px rgba(74, 31, 158, .26);
    --row-stripe: rgba(20, 10, 45, .022);
    --row-hover: rgba(109, 63, 212, .11);
    --underline-hover: rgba(109, 63, 212, .34);

    /* Elevation drops to roughly a third of the dark set. A 60% black shadow
       reads as depth on near-black and as grime on white. */
    --shadow-nav:      0 1px 2px rgba(20, 10, 45, .06);
    --shadow-card:     0 4px 14px rgba(20, 10, 45, .09);
    --shadow-dropdown: 0 8px 24px rgba(20, 10, 45, .14);
    --shadow-popup:    0 10px 28px rgba(20, 10, 45, .16);
    --shadow-auth:     0 1rem 2.5rem 0 rgba(20, 10, 45, .13);
    --shadow-modal:    0 18px 48px rgba(20, 10, 45, .22);

    --accent-subtle: #e7ddfa;

    --body-wash: radial-gradient(900px 500px at 15% -10%, rgba(109, 63, 212, 0.07), transparent 60%);
    --nav-backdrop: rgba(255, 255, 255, .85);

    /* Semantic hues darken until small type clears AA on a light fill. The dark
       theme's #86c541 is 2.1:1 on white and unusable here. */
    --status-danger:  #c2245a;
    --status-warning: #9a6a10;
    --status-success: #3f7d1f;
    --status-info:    #1367a0;

    --row-wash-danger:  rgba(194, 36, 90, .09);
    --row-wash-warning: rgba(154, 106, 16, .11);
    --row-wash-success: rgba(63, 125, 31, .10);
    --row-wash-info:    rgba(109, 63, 212, .16);

    --table-cell-border: rgba(60, 45, 90, .10);
    --row-hover-soft:    rgba(109, 63, 212, .055);

    --chip-success-fg: #2f6b18;
    --chip-success-bg: rgba(63, 125, 31, .11);
    --chip-success-br: rgba(63, 125, 31, .30);
    --chip-danger-fg:  #b01e52;
    --chip-danger-bg:  rgba(194, 36, 90, .10);
    --chip-danger-br:  rgba(194, 36, 90, .28);
    --chip-warning-fg: #855a0c;
    --chip-warning-bg: rgba(154, 106, 16, .13);
    --chip-warning-br: rgba(154, 106, 16, .30);
    --chip-info-bg:    rgba(109, 63, 212, .11);
    --chip-info-br:    rgba(109, 63, 212, .34);
    --chip-neutral-bg: rgba(60, 45, 90, .07);
}

/*
 * Bootstrap's .navbar-dark hardcodes rgba(255,255,255,.5) on its links and a
 * white burger icon. The shell's navbar carries that class, so on a light
 * ground the operator name and toggler would wash out to near-invisible.
 */
:root[data-theme="light"] .navbar-dark .navbar-nav .nav-link {
    color: var(--text-1);
}

:root[data-theme="light"] .navbar-dark .navbar-nav .nav-link:hover,
:root[data-theme="light"] .navbar-dark .navbar-nav .nav-link:focus {
    color: var(--text-0);
}

:root[data-theme="light"] .navbar-dark .navbar-toggler {
    color: var(--text-1);
    border-color: var(--border);
}

:root[data-theme="light"] .navbar-dark .navbar-toggler-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2861,53,80,0.85%29' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* --------------------------------------------------------------------------
 * Theme toggle (navbar)
 * -------------------------------------------------------------------------- */

#theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .4rem .55rem;
    border: 1px solid transparent;
    border-radius: 8px;
    color: var(--text-1);
    background: transparent;
    line-height: 1;
}

#theme-toggle:hover,
#theme-toggle:focus {
    color: var(--text-0);
    background: var(--row-hover);
    border-color: var(--border);
    text-decoration: none;
    outline: none;
}

#theme-toggle:focus-visible {
    box-shadow: 0 0 0 3px var(--glow);
}

/*
 * Show the icon for the mode the button switches TO, not the one in effect:
 * on a dark page the button offers light, so it shows the sun.
 */
#theme-toggle .theme-icon-to-light { display: inline-block; }
#theme-toggle .theme-icon-to-dark  { display: none; }
:root[data-theme="light"] #theme-toggle .theme-icon-to-light { display: none; }
:root[data-theme="light"] #theme-toggle .theme-icon-to-dark  { display: inline-block; }

/* --------------------------------------------------------------------------
 * Base elements
 *
 * NOTE: the supplied sheet scoped this to `body#top, #wrapper`. `#top` is not
 * universal — app_page renders <body id="app-page-body"> — so the qualifier is
 * dropped here and the #wrapper half lives in header.css.
 * -------------------------------------------------------------------------- */

body {
    background:
        var(--body-wash),
        var(--bg-0);
    background-attachment: fixed;
    color: var(--text-1);
    font-family: 'Inter', sans-serif;
}

h1, h2, h3, h4, h5, h6 {
    font-family: 'Archivo', sans-serif;
    font-weight: 800;
    color: var(--text-0);
    letter-spacing: -.01em;
}

/*
 * Links carry no underline at rest — in a dense admin table almost every cell
 * is a link, and a permanent rule under each one reads as noise. The line
 * appears on hover only, and softly: dotted, 1px, 40% accent.
 *
 * NOTE the longhands. `text-decoration` is a shorthand, so writing
 * `text-decoration: underline` in a more specific rule silently resets style,
 * colour and thickness back to initial (solid, currentColor, auto). Setting
 * the appearance here on `a` — where it is inert while the line is off — and
 * having :hover flip only `text-decoration-line` means surface stylesheets can
 * turn the line on with a single longhand and inherit this treatment instead
 * of fighting it.
 */
a {
    color: var(--text-1);
    text-decoration-line: none;
    text-decoration-style: dotted;
    text-decoration-color: var(--underline-hover);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

/*
 * The appearance longhands are repeated here on purpose. Bootstrap ships
 * `a:hover { text-decoration: underline }` — a shorthand at specificity
 * (0,1,1), which outranks the `a` rule above (0,0,1). Without restating them
 * the hover line renders with Bootstrap's reset values: solid, currentColor,
 * auto thickness. theme.css loads after Bootstrap, so at equal specificity
 * these win.
 */
a:hover, a:focus {
    color: var(--text-0);
    text-decoration-line: underline;
    text-decoration-style: dotted;
    text-decoration-color: var(--underline-hover);
    text-decoration-thickness: 1px;
}

/*
 * `table.table a` (0,1,2) also outranks `a:hover` (0,1,1), so without this a
 * link inside a table never lightens on hover.
 */
table.table a:hover,
table.table a:focus {
    color: var(--text-0);
}

hr {
    border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
 * Tables
 * -------------------------------------------------------------------------- */

/*
 * Hairline tables.
 *
 * The table carries no fill of its own: it sits on the page colour and its
 * structure comes from rules alone, with a stronger line under the header.
 * A filled slab (previously --bg-1 with a --bg-2 header) read as a distinctly
 * purple block two steps above the page, which was louder than the data.
 */
table.table {
    color: var(--text-1);
    background: transparent;
    border: 0;
    border-radius: 0;
    border-collapse: separate;
    border-spacing: 0;
}

table.table thead th,
table.table th {
    background: transparent;
    color: var(--text-2);
    text-transform: uppercase;
    font-size: .72rem;
    letter-spacing: .06em;
    border: none;
    border-bottom: 1px solid var(--border-strong);
    padding: .85rem 1rem;
}

/*
 * Bootstrap ships `.table .thead-light th` — two classes, which outranks the
 * one-class selector above no matter the load order. Matched here.
 */
table.table .thead-light th,
table.table thead.thead-light th {
    background: transparent;
    color: var(--text-2);
    border-color: transparent;
    border-bottom: 1px solid var(--border-strong);
}

table.table td {
    border-color: var(--table-cell-border);
    padding: .75rem 1rem;
}

/*
 * Contextual row classes. Bootstrap paints these onto the td/th, not the tr,
 * at pale tints (#f5c6cb and friends) that leave light text unreadable.
 * Re-tinted to a wash over the dark surface, with a left marker carrying the
 * semantic colour so the meaning survives.
 */
table.table .table-danger > td, table.table .table-danger > th,
table.table .table-warning > td, table.table .table-warning > th,
table.table .table-success > td, table.table .table-success > th,
table.table .table-info > td, table.table .table-info > th,
table.table .table-primary > td, table.table .table-primary > th,
table.table .table-secondary > td, table.table .table-secondary > th,
table.table .table-active > td, table.table .table-active > th {
    color: var(--text-1);
}

table.table .table-danger > td    { background: var(--row-wash-danger); }
table.table .table-warning > td   { background: var(--row-wash-warning); }
table.table .table-success > td   { background: var(--row-wash-success); }
table.table .table-info > td,
table.table .table-primary > td   { background: var(--row-wash-info); }
table.table .table-secondary > td,
table.table .table-active > td    { background: var(--bg-2); }

table.table .table-danger > td:first-child  { box-shadow: inset 3px 0 0 var(--status-danger); }
table.table .table-warning > td:first-child { box-shadow: inset 3px 0 0 var(--status-warning); }
table.table .table-success > td:first-child { box-shadow: inset 3px 0 0 var(--status-success); }

table.table tbody tr:nth-child(odd) {
    background: var(--row-stripe);
}

/*
 * Bootstrap paints the contextual fill on the `tr` as well as on its cells
 * (`.table-success, .table-success > td, .table-success > th`). The rules above
 * re-tint the cells, but an untouched `tr` keeps Bootstrap's opaque pastel —
 * and because the cell wash is only 13% alpha, that pastel reads straight
 * through as an unreadable light band under light text.
 *
 * It survived the gate-1 audit because `tbody tr:nth-child(odd)` above happens
 * to overwrite the `tr` fill, so only EVEN-positioned contextual rows showed
 * the defect. Reset here for every position: the cell wash then sits directly
 * on the page colour, so a contextual row looks the same wherever it lands.
 *
 * Must stay AFTER the nth-child rule (equal specificity, (0,2,3)) and BEFORE
 * tr:hover, which should still win.
 */
table.table tbody tr.table-danger,
table.table tbody tr.table-warning,
table.table tbody tr.table-success,
table.table tbody tr.table-info,
table.table tbody tr.table-primary,
table.table tbody tr.table-secondary,
table.table tbody tr.table-active {
    background: transparent;
}

table.table tbody tr:hover {
    background: var(--row-hover-soft);
}

table.table a {
    color: var(--text-1);
    font-weight: 500;
}

/* --------------------------------------------------------------------------
 * Buttons
 * -------------------------------------------------------------------------- */

.btn {
    border-radius: 8px;
    font-weight: 500;
    text-decoration: none;
}

.btn:hover, .btn:focus {
    text-decoration: none;
}

.btn-primary,
.btn-secondary {
    background: var(--accent-gradient);
    border: none;
    color: var(--on-accent);
    box-shadow: var(--accent-shadow);
}

.btn-primary:hover, .btn-primary:focus, .btn-primary:active,
.btn-secondary:hover, .btn-secondary:focus, .btn-secondary:active {
    background: var(--accent-gradient);
    border: none;
    color: var(--on-accent);
    filter: brightness(1.15);
}

.btn-light {
    background: var(--bg-2);
    color: var(--text-1);
    border: 1px solid var(--border);
}

.btn-light:hover, .btn-light:focus {
    background: var(--bg-3);
    color: var(--text-0);
    border: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
 * Forms
 * -------------------------------------------------------------------------- */

/*
 * The "Ruhe" input style (the reference column in the borders preview): the
 * field always shows its 1px border, so it reads as a field even when empty,
 * but the fill is invisible at rest. It stays calm on hover — no fill flashing
 * under the cursor — and only the field you focus lights up: --bg-2 fill, an
 * accent border, and the glow.
 */
.form-control,
select.form-control,
input.form-control,
textarea.form-control {
    background: transparent;
    color: var(--text-0);
    border: 1px solid var(--border);
    border-radius: 8px;
    transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.form-control:focus {
    background: var(--bg-2);
    color: var(--text-0);
    border-color: var(--accent-1);
    box-shadow: 0 0 0 3px var(--glow);
}

.form-control::placeholder {
    color: var(--text-2);
}

/* Read-only / disabled fields stay flat with muted text. */
.form-control:disabled,
.form-control[readonly] {
    background: transparent;
    color: var(--text-2);
}

/*
 * Autofilled fields. Chrome paints -webkit-autofill with an internal
 * background that ignores `background`, so an autofilled login form renders as
 * two near-white blocks on a dark card. The inset box-shadow is the only way
 * to repaint it; the absurd transition delay stops Chrome animating back to
 * its own colour on focus.
 */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-text-fill-color: var(--text-0);
    -webkit-box-shadow: 0 0 0 1000px var(--bg-2) inset;
    box-shadow: 0 0 0 1000px var(--bg-2) inset;
    caret-color: var(--text-0);
    transition: background-color 9999s ease-in-out 0s;
}

/* --------------------------------------------------------------------------
 * Scrollbars (WebKit / Blink only; Firefox ignores these)
 * -------------------------------------------------------------------------- */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg-0); }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent-1); }

/* --------------------------------------------------------------------------
 * Bootstrap components the supplied sheet did not cover
 *
 * Every rule below was added in response to a defect observed in a browser
 * during the gate-1 audit, not predicted from reading CSS.
 * -------------------------------------------------------------------------- */

.card {
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.card-header, .card-footer {
    background: var(--bg-2);
    border-color: var(--border);
    color: var(--text-1);
}

.modal-content {
    background: var(--bg-1);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-1);
    box-shadow: var(--shadow-modal);
}

.modal-header, .modal-footer {
    border-color: var(--border);
}

.modal-backdrop.show {
    opacity: .7;
}

.close, .close:hover {
    color: var(--text-1);
    text-shadow: none;
    opacity: .8;
}

.close:hover {
    color: var(--text-0);
    opacity: 1;
}

.alert-success, .alert-info, .alert-warning,
.alert-danger, .alert-secondary, .alert-primary, .alert-light, .alert-dark {
    background: var(--bg-2);
    border: 1px solid var(--border-strong);
    color: var(--text-1);
}

.alert-danger  { border-left: 3px solid var(--status-danger); }
.alert-warning { border-left: 3px solid var(--status-warning); }
.alert-success { border-left: 3px solid var(--status-success); }

.pagination .page-link {
    background: var(--bg-2);
    border-color: var(--border);
    color: var(--text-1);
    text-decoration: none;
}

.pagination .page-link:hover {
    background: var(--bg-3);
    border-color: var(--border);
    color: var(--text-0);
}

.pagination .page-item.active .page-link {
    background: var(--accent-gradient);
    border-color: transparent;
    color: var(--on-accent);
}

.pagination .page-item.disabled .page-link {
    background: var(--bg-1);
    border-color: var(--border);
    color: var(--text-2);
}

.nav-tabs {
    border-bottom-color: var(--border);
}

.nav-tabs .nav-link {
    color: var(--text-2);
    text-decoration: none;
}

.nav-tabs .nav-link:hover {
    border-color: var(--border);
    color: var(--text-0);
}

.nav-tabs .nav-link.active {
    background: var(--bg-2);
    border-color: var(--border) var(--border) transparent;
    color: var(--text-0);
}

.input-group-text {
    background: var(--bg-3);
    border-color: var(--border);
    color: var(--text-1);
}

.custom-control-label,
.form-check-label,
.col-form-label,
label {
    color: var(--text-1);
}

/* Bootstrap ships .text-muted as #6c757d !important. */
.text-muted {
    color: var(--text-2) !important;
}

/*
 * Native <select> popups on macOS inherit the option background. Left
 * transparent they render white-on-white against a dark control.
 */
select.form-control option {
    background: var(--bg-2);
    color: var(--text-0);
}

/* --------------------------------------------------------------------------
 * Vendored widgets
 * -------------------------------------------------------------------------- */

/*
 * bootstrap-datepicker — its popup is an unstyled white block, and the
 * in-month day numbers inherit the page's light text, so the whole calendar
 * reads white-on-white. This was the worst defect the audit found.
 */
.datepicker,
.datepicker-dropdown {
    background: var(--bg-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-1);
    box-shadow: var(--shadow-popup);
}

.datepicker-dropdown:before { border-bottom-color: var(--border-strong); }
.datepicker-dropdown:after  { border-bottom-color: var(--bg-2); }
.datepicker-dropdown.datepicker-orient-bottom:before { border-top-color: var(--border-strong); }
.datepicker-dropdown.datepicker-orient-bottom:after  { border-top-color: var(--bg-2); }

.datepicker table tr td,
.datepicker table tr th {
    color: var(--text-1);
    border-radius: 6px;
}

.datepicker table tr td.day:hover,
.datepicker table tr td.focused,
.datepicker table tr th.datepicker-switch:hover,
.datepicker table tr th.prev:hover,
.datepicker table tr th.next:hover,
.datepicker table tr td span:hover {
    background: var(--bg-3);
    color: var(--text-0);
}

.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.active,
.datepicker table tr td span.active {
    background: var(--accent-gradient);
    color: var(--on-accent);
    text-shadow: none;
}

.datepicker table tr td.today,
.datepicker table tr td.today:hover {
    background: var(--accent-subtle);
    color: var(--text-0);
}

.datepicker table tr td.old,
.datepicker table tr td.new,
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
    color: var(--text-2);
    background: transparent;
}

/* bootstrap4-toggle — the handle must not match the off track, or the
   switch reads as a flat block with no affordance. */
.toggle.btn {
    border: 1px solid var(--border);
}

.toggle-handle {
    background: var(--bg-1);
    border-color: var(--border-strong);
}

/* dropzone */
.dropzone .dz-message {
    color: var(--text-2);
}

.dropzone .dz-preview .dz-image {
    border-radius: 8px;
}

/* --------------------------------------------------------------------------
 * Status chips (Direction A — "Quiet Surfaces")
 *
 * Bootstrap's contextual badges are solid fills with white text and three of
 * the four fail WCAG AA outright against their own background:
 *   badge-warning  #fff on #ffc107 = 1.63:1
 *   badge-info     #fff on #17a2b8 = 3.04:1
 *   badge-success  #fff on #28a745 = 3.13:1
 * They are replaced by a tinted surface: the semantic hue at ~13% over the
 * panel, the hue itself as text, a 28% border. Every pairing clears 7.7:1.
 * -------------------------------------------------------------------------- */

.badge {
    font-weight: 500;
    font-size: 12.5px;
    letter-spacing: .01em;
    border-radius: 6px;
    padding: .4rem .6rem;
    border: 1px solid transparent;
    vertical-align: baseline;
}

.badge-success {
    background: var(--chip-success-bg);
    color: var(--chip-success-fg);
    border-color: var(--chip-success-br);
}

.badge-danger {
    background: var(--chip-danger-bg);
    color: var(--chip-danger-fg);
    border-color: var(--chip-danger-br);
}

.badge-warning {
    background: var(--chip-warning-bg);
    color: var(--chip-warning-fg);
    border-color: var(--chip-warning-br);
}

.badge-info,
.badge-primary {
    background: var(--chip-info-bg);
    color: var(--accent-0);
    border-color: var(--chip-info-br);
}

.badge-secondary,
.badge-light,
.badge-dark {
    background: var(--chip-neutral-bg);
    color: var(--text-1);
    border-color: var(--border);
}

a.badge:hover,
a.badge:focus {
    filter: brightness(1.25);
    text-decoration: none;
}
