/* app.css */

/* ═══════════════════════════════════════════════════
   UCOM brand palette — v1 Styleguide, "Farbsystem" (pages 12-14).
   Theme-independent raw values; the --tac-* role tokens below map them
   per theme. Tints are derived with color-mix from these bases (the guide
   defines tint ramps but no exact tint values), so their origin stays visible.
   ═══════════════════════════════════════════════════ */
:root {
    /* Highlight */
    --ucom-yellow: #FFEF26;
    /* Primär */
    --ucom-fuchsia: #E60B75;
    --ucom-violet-blue: #3459A5;
    /* Sekundär */
    --ucom-orange: #F18F34;
    --ucom-mandarin: #FDC800;
    /* Tertiär — Status */
    --ucom-success: #43B67E;
    --ucom-warning: #E6D200;
    --ucom-error: #E64C3C;
    --ucom-info: #2D9CDB;
    --ucom-neutral: #A26CD2;

    /* The sidebar is deliberately dark in both themes (fixed gradient in
       MainLayout), so its accent is pinned to the dark-ground tint instead of
       following --tac-primary, which flips to the solid colour in light mode. */
}

/* 1) Base tokens (LIGHT default) */
:root {
    color-scheme: light;

    /* Brand. Violet blue carries the UI (buttons, table heads, active states):
       white on it reaches 6.3:1, and it reads 7.4:1 as text on white. Fuchsia is
       reserved as the accent so it stays a highlight instead of covering the UI. */
    --tac-primary: var(--ucom-violet-blue);
    --tac-primary-hover: color-mix(in srgb, var(--ucom-violet-blue) 85%, #000);
    /* Fills that carry white text (buttons, table heads, active chips). Stays the
       solid brand violet in both themes: --tac-primary is lightened on the dark
       ground for legibility as text, which would drop white-on-primary to ~3:1. */
    --tac-primary-solid: var(--ucom-violet-blue);
    --tac-link: var(--ucom-violet-blue);

    --tac-accent: var(--ucom-fuchsia);
    --tac-focus: var(--ucom-info);

    /* Surfaces — neutrals biased towards the brand blue */
    --tac-bg: #ffffff;
    --tac-surface: #f6f8fb;
    --tac-border: #e3e8f3;

    /* Text */
    --tac-text: #0f172a;
    --tac-text-muted: #475569;

    /* Status */
    --tac-valid: var(--ucom-success);
    --tac-invalid: var(--ucom-error);
    --tac-warning: var(--ucom-warning);
    --tac-info: var(--ucom-info);
    --tac-neutral: var(--ucom-neutral);

    /* Status colours as TEXT. The styleguide values are mid-tone fills; on the
       light ground they only reach ~1.6-3.4:1, so text variants are darkened.
       Use the plain --tac-valid/-warning/-invalid for fills, dots and borders. */
    --tac-valid-text: color-mix(in srgb, var(--ucom-success) 72%, #000);
    --tac-warning-text: color-mix(in srgb, var(--ucom-warning) 55%, #000);
    --tac-invalid-text: color-mix(in srgb, var(--ucom-error) 82%, #000);

    /* Sidebar chrome — follows the theme like every other surface. */
    --tac-nav-bg-top: color-mix(in srgb, var(--ucom-violet-blue) 4%, #ffffff);
    --tac-nav-bg-mid: color-mix(in srgb, var(--ucom-violet-blue) 7%, #f7f9fc);
    --tac-nav-bg-bottom: color-mix(in srgb, var(--ucom-violet-blue) 5%, #f2f5fa);
    --tac-nav-text: #33415c;
    --tac-nav-text-strong: #0f172a;
    --tac-nav-accent: var(--ucom-violet-blue);

    /* Shadows */
    --tac-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
}

/* 2) DARK tokens (automatic when OS is dark) */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;

        /* Near-black rather than navy: the old navy sat close to violet blue in
           hue and muted the brand. A faint violet bias keeps it from reading as a
           dead grey; pure #000 would flatten elevation and shadows. */
        --tac-bg: color-mix(in srgb, var(--ucom-violet-blue) 5%, #08080a);
        --tac-surface: color-mix(in srgb, var(--ucom-violet-blue) 8%, #1c1c22);
        --tac-border: color-mix(in srgb, var(--ucom-violet-blue) 18%, #303038);

        --tac-text: #e5e7eb;
        --tac-text-muted: #a8b3c7;

        /* Tints of the brand colours: the solid values are too dark to read as
           text on the navy ground. */
        --tac-primary: color-mix(in srgb, var(--ucom-violet-blue) 62%, #fff);
        --tac-primary-hover: color-mix(in srgb, var(--ucom-violet-blue) 48%, #fff);
        --tac-primary-solid: var(--ucom-violet-blue);
        --tac-link: color-mix(in srgb, var(--ucom-info) 72%, #fff);

        --tac-focus: color-mix(in srgb, var(--ucom-info) 65%, transparent);

        --tac-valid: color-mix(in srgb, var(--ucom-success) 80%, #fff);
        --tac-invalid: color-mix(in srgb, var(--ucom-error) 80%, #fff);

        --tac-valid-text: color-mix(in srgb, var(--ucom-success) 80%, #fff);
        --tac-warning-text: color-mix(in srgb, var(--ucom-warning) 85%, #fff);
        --tac-invalid-text: color-mix(in srgb, var(--ucom-error) 80%, #fff);

        --tac-nav-bg-top: color-mix(in srgb, var(--ucom-violet-blue) 6%, #050506);
        --tac-nav-bg-mid: color-mix(in srgb, var(--ucom-violet-blue) 10%, #0b0b0e);
        --tac-nav-bg-bottom: color-mix(in srgb, var(--ucom-violet-blue) 8%, #08080a);
        --tac-nav-text: #c9c9d2;
        --tac-nav-text-strong: #ffffff;
        --tac-nav-accent: color-mix(in srgb, var(--ucom-violet-blue) 62%, #fff);

        --tac-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
    }
}

/* 3) Manual override (wins over OS preference) */
/* Force LIGHT */
html[data-theme="light"] {
    color-scheme: light;

    --tac-bg: #ffffff;
    --tac-surface: #f6f8fb;
    --tac-border: #e3e8f3;

    --tac-text: #0f172a;
    --tac-text-muted: #475569;

    --tac-primary: var(--ucom-violet-blue);
    --tac-primary-hover: color-mix(in srgb, var(--ucom-violet-blue) 85%, #000);
    /* Fills that carry white text (buttons, table heads, active chips). Stays the
       solid brand violet in both themes: --tac-primary is lightened on the dark
       ground for legibility as text, which would drop white-on-primary to ~3:1. */
    --tac-primary-solid: var(--ucom-violet-blue);
    --tac-link: var(--ucom-violet-blue);

    --tac-focus: var(--ucom-info);
    --tac-valid: var(--ucom-success);
    --tac-invalid: var(--ucom-error);
    --tac-valid-text: color-mix(in srgb, var(--ucom-success) 72%, #000);
    --tac-warning-text: color-mix(in srgb, var(--ucom-warning) 55%, #000);
    --tac-invalid-text: color-mix(in srgb, var(--ucom-error) 82%, #000);
    --tac-nav-bg-top: color-mix(in srgb, var(--ucom-violet-blue) 4%, #ffffff);
    --tac-nav-bg-mid: color-mix(in srgb, var(--ucom-violet-blue) 7%, #f7f9fc);
    --tac-nav-bg-bottom: color-mix(in srgb, var(--ucom-violet-blue) 5%, #f2f5fa);
    --tac-nav-text: #33415c;
    --tac-nav-text-strong: #0f172a;
    --tac-nav-accent: var(--ucom-violet-blue);
    --tac-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
}

/* Force DARK */
html[data-theme="dark"] {
    color-scheme: dark;

    --tac-bg: color-mix(in srgb, var(--ucom-violet-blue) 5%, #08080a);
    --tac-surface: color-mix(in srgb, var(--ucom-violet-blue) 8%, #1c1c22);
    --tac-border: color-mix(in srgb, var(--ucom-violet-blue) 18%, #303038);

    --tac-text: #e5e7eb;
    --tac-text-muted: #a8b3c7;

    --tac-primary: color-mix(in srgb, var(--ucom-violet-blue) 62%, #fff);
    --tac-primary-hover: color-mix(in srgb, var(--ucom-violet-blue) 48%, #fff);
    --tac-primary-solid: var(--ucom-violet-blue);
    --tac-link: color-mix(in srgb, var(--ucom-info) 72%, #fff);

    --tac-focus: color-mix(in srgb, var(--ucom-info) 65%, transparent);
    --tac-valid: color-mix(in srgb, var(--ucom-success) 80%, #fff);
    --tac-invalid: color-mix(in srgb, var(--ucom-error) 80%, #fff);
    --tac-valid-text: color-mix(in srgb, var(--ucom-success) 80%, #fff);
    --tac-warning-text: color-mix(in srgb, var(--ucom-warning) 85%, #fff);
    --tac-invalid-text: color-mix(in srgb, var(--ucom-error) 80%, #fff);
    --tac-nav-bg-top: color-mix(in srgb, var(--ucom-violet-blue) 6%, #050506);
    --tac-nav-bg-mid: color-mix(in srgb, var(--ucom-violet-blue) 10%, #0b0b0e);
    --tac-nav-bg-bottom: color-mix(in srgb, var(--ucom-violet-blue) 8%, #08080a);
    --tac-nav-text: #c9c9d2;
    --tac-nav-text-strong: #ffffff;
    --tac-nav-accent: color-mix(in srgb, var(--ucom-violet-blue) 62%, #fff);
    --tac-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* 4) Apply tokens */
html, body {
    /* Styleguide p.16: Poppins is the primary face, Helvetica the fallback. */
    font-family: 'Poppins', Helvetica, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    -webkit-font-smoothing: antialiased;
    background: var(--tac-bg);
    color: var(--tac-text);
}

/* Links */
a,
.btn-link {
    color: var(--tac-link);
}
a:hover,
.btn-link:hover {
    color: var(--tac-primary);
}

/* Focus ring */
.btn:focus,
.btn:active:focus,
.btn-link.nav-link:focus,
.form-control:focus,
.form-check-input:focus {
    box-shadow: 0 0 0 0.1rem var(--tac-bg), 0 0 0 0.25rem var(--tac-focus);
}

/* Validation */
.valid.modified:not([type=checkbox]) { outline: 1px solid var(--tac-valid); }
.invalid { outline: 1px solid var(--tac-invalid); }
.validation-message { color: var(--tac-invalid-text); }

/* Blazor error boundary (keep SVG, adapt bg for theme) */
.blazor-error-boundary {
    background:
            url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=)
            no-repeat 1rem/1.8rem,
            #b91c1c;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}
.blazor-error-boundary::after { content: "An error has occurred."; }

/* Blazor error toast. Must be GLOBAL (not scoped): the #blazor-error-ui div
   lives in the static index.html host page, so a scoped .razor.css selector
   (#blazor-error-ui[b-xxx]) can never match it and the toast would show
   permanently. blazor.webassembly.js flips display to block on a real error. */
#blazor-error-ui {
    color-scheme: light only;
    background: #1e1e2e;
    border-top: 2px solid #dc2626;
    color: #f87171;
    bottom: 0;
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.4);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.65rem 1.25rem 0.75rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: 0.875rem;
    letter-spacing: 0.02em;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
        opacity: 0.7;
        transition: opacity 0.15s;
    }

    #blazor-error-ui .dismiss:hover {
        opacity: 1;
    }

/* ═══════════════════════════════════════════════════
   Row actions: kebab (⋮) overflow menu + confirm/edit modal.
   Global so every admin table shares the same pattern
   (Geräte, UCom-Geräte, Benutzer).
   ═══════════════════════════════════════════════════ */
.actions-col,
.actions-cell {
    width: 5rem;
    text-align: center;
}

.actions-cell {
    position: relative;
    white-space: nowrap;
}

.kebab-btn {
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    width: 2.2rem;
    height: 2.2rem;
    line-height: 1;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--tac-text);
    cursor: pointer;
}

.kebab-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--tac-text) 8%, transparent);
    border-color: var(--tac-border);
}

.kebab-btn:disabled {
    opacity: 0.4;
    cursor: default;
}

.kebab-backdrop {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: transparent;
}

.kebab-menu {
    position: fixed;
    z-index: 2001;
    transform: translate(-90%, 6px);
    min-width: 9rem;
    background: var(--tac-surface);
    border: 1px solid var(--tac-border);
    border-radius: 8px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
    padding: 0.3rem;
    display: flex;
    flex-direction: column;
}

.kebab-item {
    background: transparent;
    border: none;
    text-align: left;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    color: var(--tac-text);
    cursor: pointer;
    font-size: 0.9rem;
}

.kebab-item:hover {
    background: color-mix(in srgb, var(--tac-text) 8%, transparent);
}

.kebab-item:disabled {
    opacity: 0.4;
    cursor: default;
}

.kebab-item.danger {
    color: var(--tac-invalid-text);
}

.tac-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1050;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 8vh;
}

/* A modal opened on top of an open detail drawer (e.g. tariff windows editor):
   lift it above the drawer (z 1091) so it is usable and its backdrop covers the drawer. */
.tac-modal-backdrop.win-over {
    z-index: 1200;
}

.tac-modal {
    width: min(30rem, 92vw);
    background: var(--tac-surface);
    border: 1px solid var(--tac-border);
    border-radius: 12px;
    padding: 1.25rem 1.4rem 1.4rem;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.4);
}

.tac-modal h3 {
    margin-top: 0;
    margin-bottom: 1rem;
    color: var(--tac-text);
    font-size: 1.1rem;
}

.tac-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
}

/* Wider modal variant for field-heavy forms (e.g. tariff editor). */
.tac-modal-wide {
    width: min(52rem, 94vw);
}

/* Page header row for action/report pages without a ListToolbar (title + optional action). */
.tac-page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.tac-page-head h1 {
    margin: 0;
}

/* Horizontal scroll wrapper for a wide table inside the narrow detail drawer. */
.detail-scroll {
    overflow-x: auto;
}

/* ═══════════════════════════════════════════════════
   Global toast notifications (see ToastHost.razor).
   Fixed bottom-right stack, auto-dismissed by ToastService.
   ═══════════════════════════════════════════════════ */
.toast-host {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: min(28rem, calc(100vw - 2rem));
}

.toast-item {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.7rem 0.85rem;
    border-radius: 10px;
    border: 1px solid var(--tac-border);
    border-left-width: 4px;
    background: var(--tac-surface);
    color: var(--tac-text);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
    font-size: 0.9rem;
    animation: toast-in 0.18s ease-out;
}

.toast-item.toast-error {
    border-left-color: var(--ucom-error);
}

.toast-item.toast-success {
    border-left-color: var(--ucom-success);
}

.toast-item.toast-info {
    border-left-color: var(--ucom-violet-blue);
}

.toast-msg {
    flex: 1 1 auto;
    word-break: break-word;
}

.toast-close {
    flex: 0 0 auto;
    background: none;
    border: none;
    color: var(--tac-text-muted);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.15rem;
}

.toast-close:hover {
    color: var(--tac-text);
}

@keyframes toast-in {
    from { opacity: 0; transform: translateY(0.5rem); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ═══════════════════════════════════════════════════
   Gültigkeitsfenster editor (see Tariffs.razor + WeekCoverage.razor).
   ═══════════════════════════════════════════════════ */
.tac-modal-xl { width: min(60rem, 96vw); }
.win-accent { color: var(--ucom-violet-blue); }
.win-warn { color: var(--ucom-mandarin); }

.win-dialog-body { display: grid; grid-template-columns: 1fr 300px; gap: 22px; align-items: start; }
@media (max-width: 820px) { .win-dialog-body { grid-template-columns: 1fr; } }
.win-editor { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

/* presets + weekday toggles */
.win-presets { display: flex; flex-wrap: wrap; gap: 7px; }
.win-chip { border: 1px solid var(--tac-border); background: transparent; color: var(--tac-text-muted);
    border-radius: 999px; padding: 5px 13px; font-size: 12.5px; font-weight: 500; cursor: pointer; }
.win-chip:hover { border-color: var(--ucom-violet-blue); color: var(--tac-text); }
.win-days { display: flex; gap: 6px; }
.win-day { flex: 1; border: 1px solid var(--tac-border); background: transparent; color: var(--tac-text-muted);
    border-radius: 8px; padding: 8px 0; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.win-day:hover { border-color: var(--ucom-violet-blue); }
.win-day.on { background: var(--ucom-violet-blue); border-color: var(--ucom-violet-blue); color: #fff; }
.win-day.on.wknd { background: var(--ucom-mandarin); border-color: var(--ucom-mandarin); }

/* 24h bar */
.win-bar { position: relative; height: 30px; background: var(--tac-surface); border: 1px solid var(--tac-border);
    border-radius: 8px; overflow: hidden; }
.win-bar-fill { position: absolute; top: 0; bottom: 0; background: rgba(76,139,245,.20);
    border-left: 2px solid var(--ucom-violet-blue); border-right: 2px solid var(--ucom-violet-blue); }
.win-bar-lab { position: absolute; bottom: 2px; font-size: 9px; color: var(--tac-text-muted);
    font-variant-numeric: tabular-nums; }

/* weekly coverage grid */
.win-week { display: flex; gap: 6px; min-height: 280px; }
.win-week.compact { min-height: 150px; }
.win-hours { display: flex; flex-direction: column; justify-content: space-between; padding-top: 15px;
    font-size: 9px; color: var(--tac-text-muted); width: 16px; text-align: right; font-variant-numeric: tabular-nums; }
.win-cols { flex: 1; display: flex; gap: 3px; min-width: 0; }
.win-col { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.win-hd { font-size: 10px; font-weight: 600; color: var(--tac-text-muted); text-align: center; padding-bottom: 4px; }
.win-col.wknd .win-hd { color: var(--ucom-mandarin); }
.win-track { position: relative; flex: 1; background: var(--tac-surface); border: 1px solid var(--tac-border);
    border-radius: 6px; overflow: hidden; }
.win-hline { position: absolute; left: 0; right: 0; height: 1px; background: color-mix(in srgb, var(--tac-border) 70%, transparent); }
.win-blk { position: absolute; left: 1px; right: 1px; border-radius: 3px;
    background: var(--wcs); border-left: 2.5px solid var(--wc); }
.win-blk.win-preview { background: color-mix(in srgb, var(--ucom-violet-blue) 18%, transparent); border: 1.5px dashed var(--ucom-violet-blue); }
.win-c0 { --wc: var(--ucom-violet-blue); --wcs: color-mix(in srgb, var(--ucom-violet-blue) 22%, transparent); }
.win-c1 { --wc: var(--ucom-mandarin); --wcs: color-mix(in srgb, var(--ucom-mandarin) 20%, transparent); }
.win-c2 { --wc: var(--ucom-success); --wcs: color-mix(in srgb, var(--ucom-success) 20%, transparent); }
.win-c3 { --wc: var(--ucom-neutral); --wcs: color-mix(in srgb, var(--ucom-neutral) 20%, transparent); }

/* window list rows in the dialog */
.win-list { display: flex; flex-direction: column; }
.win-row { display: flex; align-items: center; gap: 10px; padding: 7px 9px; border: 1px solid var(--tac-border);
    border-radius: 8px; margin-bottom: 6px; font-size: 12.5px; }
.win-swatch { width: 4px; align-self: stretch; border-radius: 3px; background: var(--wc); flex: 0 0 4px; }
.win-row-nm { font-weight: 600; min-width: 130px; }
.win-row-days { color: var(--tac-text-muted); }
.win-row-tm { margin-left: auto; color: var(--tac-text-muted); font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════
   Standard list/tree toolbar (see ListToolbar.razor):
   search + filter on the left, actions on the right,
   expandable filter panel below.
   ═══════════════════════════════════════════════════ */
.tac-list-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1rem;
    flex-wrap: wrap;
}

.tac-list-toolbar-left {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 0;
}

.tac-list-search {
    max-width: 22rem;
}

.tac-filter-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    flex: 0 0 auto;
    border: 1px solid var(--tac-border);
    border-radius: 6px;
    background: transparent;
    color: var(--tac-text);
    cursor: pointer;
}

.tac-filter-btn:hover {
    background: color-mix(in srgb, var(--tac-text) 8%, transparent);
}

.tac-filter-btn.active {
    background: var(--tac-surface);
    border-color: var(--ucom-violet-blue);
    color: var(--ucom-violet-blue);
}

.tac-list-toolbar-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
}

.tac-list-filter-panel {
    border: 1px solid var(--tac-border);
    background: var(--tac-surface);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
}

/* ═══════════════════════════════════════════════════
   Detail drawer (see DetailDrawer.razor) + key/value rows.
   Global so page-supplied ChildContent rows are styled too
   (scoped .razor.css would not reach content authored elsewhere).
   ═══════════════════════════════════════════════════ */
.detail-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1090;
    background: rgba(0, 0, 0, 0.45);
}

.detail-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 1091;
    width: min(420px, 92vw);
    display: flex;
    flex-direction: column;
    background: var(--tac-surface);
    border-left: 1px solid var(--tac-border);
    box-shadow: -12px 0 32px rgba(0, 0, 0, 0.35);
    animation: detail-drawer-in 0.18s ease-out;
    outline: none;
}

@keyframes detail-drawer-in {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}

.detail-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--tac-border);
}

.detail-drawer-title {
    margin: 0;
    font-size: 1.1rem;
    color: var(--tac-text);
}

.detail-drawer-close {
    background: transparent;
    border: none;
    color: var(--tac-text-muted);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.25rem;
}

.detail-drawer-close:hover {
    color: var(--tac-text);
}

.detail-drawer-body {
    padding: 1rem 1.25rem 1.5rem;
    overflow-y: auto;
}

.detail-row {
    display: flex;
    gap: 1rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid color-mix(in srgb, var(--tac-border) 60%, transparent);
    font-size: 0.9rem;
}

.detail-row:last-child {
    border-bottom: none;
}

.detail-key {
    flex: 0 0 42%;
    color: var(--tac-text-muted);
}

.detail-val {
    flex: 1 1 auto;
    color: var(--tac-text);
    word-break: break-word;
}

/* Muted secondary id shown next to a resolved name (e.g. "Hauptzähler · #3"). */
.detail-id {
    color: var(--tac-text-muted);
    font-size: 0.85em;
}

/* Stacked values inside a .detail-val (one item per line). */
.detail-list {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.detail-section-title {
    margin-top: 1.25rem;
    margin-bottom: 0.35rem;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--tac-text-muted);
}

/* Inline add/edit form inside a detail drawer (nested management). */
.tac-inline-form {
    border: 1px solid var(--tac-border);
    border-radius: 8px;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
}

/* A managed sub-item row inside a detail drawer (e.g. tariff window, ZEV participant). */
.detail-window {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.45rem 0;
    border-bottom: 1px solid color-mix(in srgb, var(--tac-border) 60%, transparent);
}

.detail-window:last-child {
    border-bottom: none;
}

.detail-window-main {
    min-width: 0;
}

.detail-window-actions {
    display: flex;
    gap: 0.25rem;
    flex-shrink: 0;
}

/* Clickable list rows that open the detail drawer. */
tr.row-clickable {
    cursor: pointer;
}

/* Compact count pill for a table cell; full list in the title tooltip + detail drawer. */
.count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    background: color-mix(in srgb, var(--ucom-violet-blue) 16%, transparent);
    color: var(--ucom-violet-blue);
}

/* Checkbox border */
.darker-border-checkbox.form-check-input { border-color: #929292; }

/* Keep template behavior */
.form-floating > .form-control-plaintext::placeholder,
.form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}
.form-floating > .form-control-plaintext:focus::placeholder,
.form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Optional: unify borders a bit */
.card,
.modal-content,
.dropdown-menu {
    border-color: var(--tac-border);
    background: var(--tac-surface);
    box-shadow: var(--tac-shadow-sm);
    color: var(--tac-text);
}

/* ═══════════════════════════════════════════════════
   Global UI Enhancements — modern / sleek / techy
   ═══════════════════════════════════════════════════ */

/* ── Headings ───────────────────────────────────────── */
h1 {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--tac-text);
    margin-bottom: 1.25rem;
}

h1:focus { outline: none; }

/* ── Tables ─────────────────────────────────────────── */
.table {
    border-collapse: separate;
    border-spacing: 0;
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid var(--tac-border);
    font-size: 0.875rem;
    background: var(--tac-surface);
}

.table thead th {
    background: var(--tac-primary-solid) !important;
    color: #fff !important;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    border: none;
    padding: 0.75rem 1rem;
}

.table-dark th {
    background: var(--tac-primary-solid) !important;
}

.table tbody tr {
    border-bottom: 1px solid var(--tac-border);
    transition: background 0.12s;
}

.table-striped > tbody > tr:nth-of-type(odd) > * {
    background: color-mix(in srgb, var(--tac-surface) 85%, var(--tac-border));
    color: var(--tac-text);
}

.table-hover > tbody > tr:hover > * {
    background: color-mix(in srgb, var(--tac-primary) 8%, var(--tac-surface));
    color: var(--tac-text);
}

.table td, .table th {
    padding: 0.65rem 1rem;
    vertical-align: middle;
}

/* ── Cards ──────────────────────────────────────────── */
/* The DevExpress theme paints .card in its own grey. index.html loads that theme
   before app.css, so this plain selector wins on load order. */
.card {
    border-radius: 10px;
    border: 1px solid var(--tac-border);
    background: var(--tac-surface);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--tac-border);
    font-weight: 600;
    font-size: 0.875rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--tac-text-muted);
    padding: 0.85rem 1.25rem;
}

.card-body {
    padding: 1.25rem;
}

/* ── Inline code (override Bootstrap's pink) ────────── */
code {
    color: var(--tac-primary);
    background: color-mix(in srgb, var(--tac-primary) 12%, transparent);
    padding: 0.08rem 0.35rem;
    border-radius: 4px;
    font-size: 0.85em;
}

pre code {
    background: transparent;
    padding: 0;
}

/* ── Table cells inherit the themed surface (Bootstrap
      otherwise paints each cell white via --bs-table-bg) ── */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--tac-text);
    --bs-table-striped-bg: color-mix(in srgb, var(--tac-surface) 85%, var(--tac-border));
    --bs-table-striped-color: var(--tac-text);
    --bs-table-hover-bg: color-mix(in srgb, var(--tac-primary) 8%, var(--tac-surface));
    --bs-table-hover-color: var(--tac-text);
    --bs-table-border-color: var(--tac-border);
    color: var(--tac-text);
}

/* ── Form controls ──────────────────────────────────── */
.form-control,
.form-select {
    background: var(--tac-bg);
    border: 1px solid var(--tac-border);
    color: var(--tac-text);
    border-radius: 6px;
    font-size: 0.875rem;
    padding: 0.45rem 0.75rem;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.form-control:focus,
.form-select:focus {
    background: var(--tac-bg);
    border-color: var(--tac-primary);
    color: var(--tac-text);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--tac-focus) 30%, transparent);
    outline: none;
}

.form-label {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tac-text-muted);
    margin-bottom: 0.35rem;
}

/* ── Buttons ────────────────────────────────────────── */
.btn {
    border-radius: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
    padding: 0.4rem 1rem;
}

.btn:active { transform: translateY(1px); }

.btn-primary {
    color: #fff;
    background-color: var(--tac-primary);
    border-color: var(--tac-primary);
}
.btn-primary:hover,
.btn-primary:active,
.btn-primary.active {
    color: #fff;
    background-color: var(--tac-primary-hover);
    border-color: var(--tac-primary-hover);
    box-shadow: 0 2px 8px rgba(11, 58, 83, 0.35);
}

.btn-success {
    background: #15803d;
    border-color: #15803d;
    color: #fff;
}
.btn-success:hover {
    background: #166534;
    border-color: #166534;
    color: #fff;
}

.btn-outline-primary {
    color: var(--tac-primary);
    border-color: var(--tac-primary);
}
.btn-outline-primary:hover {
    background: var(--tac-primary);
    border-color: var(--tac-primary);
    color: #fff;
}

.btn-sm {
    padding: 0.25rem 0.65rem;
    font-size: 0.78rem;
    border-radius: 5px;
}

/* ── Alerts ─────────────────────────────────────────────
   One source of truth: these set background/border directly (a variant-coloured
   left stripe), which beats Bootstrap's --bs-alert-* variables, so the variables
   are not used for alerts at all. */
.alert {
    border-radius: 8px;
    font-size: 0.875rem;
    color: var(--tac-text);
}

.alert-danger {
    background: color-mix(in srgb, var(--ucom-error) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--ucom-error) 30%, transparent);
    border-left: 3px solid var(--ucom-error);
}

.alert-warning {
    background: color-mix(in srgb, var(--ucom-warning) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--ucom-warning) 35%, transparent);
    border-left: 3px solid var(--ucom-warning);
}

.alert-success {
    background: color-mix(in srgb, var(--ucom-success) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--ucom-success) 30%, transparent);
    border-left: 3px solid var(--ucom-success);
}

.alert-info {
    background: color-mix(in srgb, var(--ucom-info) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--ucom-info) 30%, transparent);
    border-left: 3px solid var(--ucom-info);
}

/* ── Loading / empty states ─────────────────────────── */
p em {
    color: var(--tac-text-muted);
    font-style: normal;
    font-size: 0.875rem;
}

.text-muted {
    color: var(--tac-text-muted) !important;
    font-size: 0.875rem;
}

/* ── Page content padding ───────────────────────── */
.content {
    padding-top: 1.75rem;
    padding-bottom: 2rem;
}

/* ── Sign-in modal ──────────────────────────────── */
.modal-content {
    border-radius: 12px;
    border: 1px solid var(--tac-border);
    background: var(--tac-surface);
    color: var(--tac-text);
}

.modal-header {
    border-bottom: 1px solid var(--tac-border);
    padding: 1rem 1.25rem;
}

.modal-footer {
    border-top: 1px solid var(--tac-border);
    padding: 0.85rem 1.25rem;
}

/* ═══════════════════════════════════════════════════
   Status panels — shared visual language for the Status page
   (Wetterstatus, Build-Infos); mirrors the API-Health look.
   Soft status dot + tint instead of full-colour Bootstrap cards.
   ═══════════════════════════════════════════════════ */
.status-banner {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.8rem 1rem;
    border-radius: 12px;
    border: 1px solid var(--tac-border);
    background: var(--tac-surface);
}
.status-banner.is-ok   { background: color-mix(in srgb, var(--tac-valid) 10%, var(--tac-surface));   border-color: color-mix(in srgb, var(--tac-valid) 32%, var(--tac-border)); }
.status-banner.is-bad  { background: color-mix(in srgb, var(--tac-invalid) 10%, var(--tac-surface)); border-color: color-mix(in srgb, var(--tac-invalid) 32%, var(--tac-border)); }
.status-banner.is-warn { background: color-mix(in srgb, var(--tac-accent) 10%, var(--tac-surface));  border-color: color-mix(in srgb, var(--tac-accent) 32%, var(--tac-border)); }
.status-banner-main { flex: 1 1 auto; min-width: 0; }
.status-banner-title { font-weight: 600; font-size: 0.98rem; }
.status-banner.is-ok   .status-banner-title { color: var(--tac-valid); }
.status-banner.is-bad  .status-banner-title { color: var(--tac-invalid); }
.status-banner.is-warn .status-banner-title { color: var(--tac-accent); }
.status-banner-sub { font-size: 0.8rem; color: var(--tac-text-muted); }
.status-banner-aside { font-size: 0.75rem; color: var(--tac-text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

.status-dot { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 11px; position: relative; background: var(--tac-text-muted); }
.status-dot.is-ok   { background: var(--tac-valid); }
.status-dot.is-bad  { background: var(--tac-invalid); }
.status-dot.is-warn { background: var(--tac-accent); }
.status-banner.is-ok .status-dot::after {
    content: ""; position: absolute; inset: -5px; border-radius: 50%;
    border: 2px solid var(--tac-valid); opacity: 0.35; animation: status-pulse 2.4s ease-out infinite;
}
@keyframes status-pulse { 0% { transform: scale(0.7); opacity: 0.5; } 100% { transform: scale(1.5); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .status-banner.is-ok .status-dot::after { animation: none; } }

.status-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.75rem; margin-top: 0.85rem; }
@media (max-width: 560px) { .status-tiles { grid-template-columns: 1fr; } }
.status-tile {
    border: 1px solid var(--tac-border); border-left: 3px solid var(--st, var(--tac-text-muted));
    border-radius: 10px; background: var(--tac-surface); padding: 0.7rem 0.85rem;
    display: flex; flex-direction: column; gap: 0.4rem; min-width: 0;
}
.status-tile.is-ok      { --st: var(--tac-valid); }
.status-tile.is-bad     { --st: var(--tac-invalid); }
.status-tile.is-neutral { --st: var(--tac-text-muted); }
.status-tile-head { display: flex; align-items: center; gap: 0.5rem; }
.status-tile-name { font-size: 0.68rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tac-text-muted); font-weight: 600; }
.status-tile-val { font-size: 1.4rem; font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.status-tile-val small { font-size: 0.8rem; color: var(--tac-text-muted); font-weight: 500; }
.status-tile-code { font-size: 0.95rem; font-weight: 600; }
.status-tile-code code { font-size: 0.95rem; }
.status-tile-note { font-size: 0.76rem; color: var(--tac-text-muted); word-break: break-word; }

.status-pill {
    align-self: flex-start; font-size: 0.68rem; font-weight: 600; padding: 0.12rem 0.55rem; border-radius: 999px;
    background: color-mix(in srgb, var(--tac-text-muted) 15%, transparent); color: var(--tac-text-muted);
}
.status-pill.is-ok   { background: color-mix(in srgb, var(--tac-valid) 14%, transparent);   color: var(--tac-valid); }
.status-pill.is-bad  { background: color-mix(in srgb, var(--tac-invalid) 14%, transparent); color: var(--tac-invalid); }
.status-pill.is-warn { background: color-mix(in srgb, var(--tac-accent) 16%, transparent);  color: var(--tac-accent); }

.status-meta { display: flex; flex-wrap: wrap; gap: 0.35rem 1.4rem; margin-top: 0.85rem; font-size: 0.8rem; color: var(--tac-text-muted); }
.status-meta b { color: var(--tac-text); font-weight: 500; font-variant-numeric: tabular-nums; }


/* Messdaten mode switch (segmented control in the ListToolbar actions) */
.mode-switch { display: inline-flex; background: var(--tac-surface); border: 1px solid var(--tac-border); border-radius: 9px; padding: 2px; }
.mode-btn { border: none; background: transparent; color: var(--tac-text-muted); font: inherit; font-size: 0.85rem; font-weight: 600; padding: 0.3rem 0.75rem; border-radius: 7px; cursor: pointer; }
.mode-btn.on { background: var(--tac-primary-solid); color: #fff; }
.edit-values { max-height: 40vh; overflow-y: auto; overflow-x: hidden; padding-right: 0.25rem; }

/* DevExpress chart: recolor DevExtreme's grey axis/grid/labels to --tac-* tokens.
   Class names verified against DevExtreme (dxc-axes-group = axis lines + labels,
   dxc-grids-group = gridlines). */
.measurements-chart .dxc-grids-group path { stroke: var(--tac-border) !important; opacity: 1 !important; }

/* Chart tooltip. The DevExpress theme paints the bubble in its own colours; re-skin it
   with the app palette so it follows light/dark. The pointer is the little arrow. */
.dxbl-chart-tooltip > .dxbl-chart-tooltip-content-container {
    background: var(--tac-surface);
    border-color: var(--tac-border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.dxbl-chart-tooltip > .dxbl-chart-tooltip-content-container + .dxbl-chart-tooltip-pointer {
    background: var(--tac-surface);
    border-color: transparent var(--tac-border) var(--tac-border) transparent;
}
.ts-tt { min-width: 7rem; font-size: 0.8rem; line-height: 1.4; }
.ts-tt-name { font-weight: 600; color: var(--tac-text); margin-bottom: 0.1rem; }
.ts-tt-time { color: var(--tac-text-muted); font-variant-numeric: tabular-nums; }
.ts-tt-val { color: var(--tac-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.measurements-chart .dxc-axes-group path { stroke: var(--tac-border) !important; }
.measurements-chart .dxc-axes-group text { fill: var(--tac-text-muted) !important; }

/* Zeitreihe series accordion (token-based, matches the chart) */
.ts-series { border: 1px solid var(--tac-border); border-radius: 12px; overflow: hidden; background: var(--tac-surface); margin-bottom: 0.6rem; }
.ts-series-head { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.7rem 1rem; background: transparent; border: none; color: var(--tac-text); font: inherit; cursor: pointer; text-align: left; }
.ts-series-head:hover { background: color-mix(in srgb, var(--tac-primary) 6%, var(--tac-surface)); }
.ts-series-title { display: inline-flex; align-items: center; gap: 0.6rem; font-weight: 600; font-size: 0.9rem; }
.ts-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.ts-series-meta { display: inline-flex; align-items: center; gap: 0.7rem; }
.ts-count { font-size: 0.72rem; color: var(--tac-text-muted); border: 1px solid var(--tac-border); border-radius: 999px; padding: 0.1rem 0.55rem; }
.ts-chev { color: var(--tac-text-muted); font-size: 0.8rem; width: 1rem; text-align: center; }
.ts-series-body { border-top: 1px solid var(--tac-border); max-height: 320px; overflow: auto; }
.ts-mini { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
.ts-mini thead th { position: sticky; top: 0; background: var(--tac-surface); text-align: left; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--tac-text-muted); padding: 0.5rem 1rem; border-bottom: 1px solid var(--tac-border); }
.ts-mini td { padding: 0.45rem 1rem; border-bottom: 1px solid var(--tac-border); color: var(--tac-text); font-variant-numeric: tabular-nums; }
.ts-mini tbody tr:last-child td { border-bottom: none; }
.ts-mini tbody tr:hover td { background: color-mix(in srgb, var(--tac-primary) 6%, var(--tac-surface)); }
.ts-mini .num { text-align: right; }

/* ═══════════════════════════════════════════════════
   Bootstrap semantic colours → UCOM styleguide.
   Bootstrap's own palette and the DevExpress theme both ship their colours
   (DevExpress ships purple buttons); app.css loads after both, so mapping the
   --bs-* variables here re-points every .btn-*, .bg-*, .text-* and .alert-*
   in the app at the styleguide instead of patching them one by one.
   ═══════════════════════════════════════════════════ */
:root {
    --bs-primary: var(--ucom-violet-blue);
    --bs-primary-rgb: 52, 89, 165;
    --bs-secondary: var(--tac-text-muted);
    --bs-secondary-rgb: 71, 85, 105;
    --bs-success: var(--ucom-success);
    --bs-success-rgb: 67, 179, 126;
    --bs-danger: var(--ucom-error);
    --bs-danger-rgb: 230, 76, 60;
    --bs-warning: var(--ucom-warning);
    --bs-warning-rgb: 230, 210, 0;
    --bs-info: var(--ucom-info);
    --bs-info-rgb: 45, 156, 219;
    --bs-link-color: var(--tac-link);
    --bs-link-hover-color: var(--tac-primary-hover);
}

/* ── Filled buttons ─────────────────────────────────── */
.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--tac-primary-solid);
    --bs-btn-border-color: var(--tac-primary-solid);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--tac-primary-solid) 75%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--tac-primary-solid) 75%, #000);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: color-mix(in srgb, var(--tac-primary-solid) 55%, var(--tac-surface));
    --bs-btn-disabled-border-color: transparent;
}

/* Secondary is a supporting action: neutral, never a second loud colour. */
.btn-secondary {
    --bs-btn-color: var(--tac-text);
    --bs-btn-bg: color-mix(in srgb, var(--tac-text) 8%, transparent);
    --bs-btn-border-color: var(--tac-border);
    --bs-btn-hover-color: var(--tac-text);
    --bs-btn-hover-bg: color-mix(in srgb, var(--tac-text) 14%, transparent);
    --bs-btn-hover-border-color: var(--tac-border);
    --bs-btn-active-color: var(--tac-text);
    --bs-btn-active-bg: color-mix(in srgb, var(--tac-text) 18%, transparent);
    --bs-btn-active-border-color: var(--tac-border);
    --bs-btn-disabled-color: var(--tac-text-muted);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--tac-border);
}

.btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--ucom-error);
    --bs-btn-border-color: var(--ucom-error);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--ucom-error) 85%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--ucom-error) 85%, #000);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--ucom-error) 75%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--ucom-error) 75%, #000);
}

.btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--ucom-success);
    --bs-btn-border-color: var(--ucom-success);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--ucom-success) 85%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--ucom-success) 85%, #000);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--ucom-success) 75%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--ucom-success) 75%, #000);
}

/* Warning yellow is too light for white text — keep it on dark ink. */
.btn-warning {
    --bs-btn-color: #0f172a;
    --bs-btn-bg: var(--ucom-warning);
    --bs-btn-border-color: var(--ucom-warning);
    --bs-btn-hover-color: #0f172a;
    --bs-btn-hover-bg: color-mix(in srgb, var(--ucom-warning) 88%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--ucom-warning) 88%, #000);
    --bs-btn-active-color: #0f172a;
    --bs-btn-active-bg: color-mix(in srgb, var(--ucom-warning) 80%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--ucom-warning) 80%, #000);
}

/* ── Outline buttons ────────────────────────────────── */
.btn-outline-primary {
    --bs-btn-color: var(--tac-primary);
    --bs-btn-border-color: var(--tac-primary);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--tac-primary-solid);
    --bs-btn-hover-border-color: var(--tac-primary-solid);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--tac-primary-solid);
    --bs-btn-active-border-color: var(--tac-primary-solid);
    --bs-btn-disabled-color: var(--tac-text-muted);
    --bs-btn-disabled-border-color: var(--tac-border);
}

.btn-outline-danger {
    --bs-btn-color: var(--tac-invalid);
    --bs-btn-border-color: var(--tac-invalid);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ucom-error);
    --bs-btn-hover-border-color: var(--ucom-error);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--ucom-error);
    --bs-btn-active-border-color: var(--ucom-error);
    --bs-btn-disabled-color: var(--tac-text-muted);
    --bs-btn-disabled-border-color: var(--tac-border);
}

.btn-outline-secondary {
    --bs-btn-color: var(--tac-text);
    --bs-btn-border-color: var(--tac-border);
    --bs-btn-hover-color: var(--tac-text);
    --bs-btn-hover-bg: color-mix(in srgb, var(--tac-text) 10%, transparent);
    --bs-btn-hover-border-color: var(--tac-primary);
    --bs-btn-active-color: var(--tac-text);
    --bs-btn-active-bg: color-mix(in srgb, var(--tac-text) 14%, transparent);
    --bs-btn-active-border-color: var(--tac-primary);
    --bs-btn-disabled-color: var(--tac-text-muted);
    --bs-btn-disabled-border-color: var(--tac-border);
}

.btn-link {
    --bs-btn-color: var(--tac-link);
    --bs-btn-hover-color: var(--tac-primary-hover);
}


/* Badges: .bg-secondary is the app's default chip and must stay legible. */
.badge.bg-secondary {
    background-color: color-mix(in srgb, var(--tac-text) 12%, transparent) !important;
    color: var(--tac-text);
}

/* ═══════════════════════════════════════════════════
   DevExpress components → UCOM styleguide.
   The prebuilt themes hardcode their own accent (blazing-berry #5f368d,
   blazing-dark #9b17e2) inside component-scoped custom properties, so they
   cannot be re-pointed from :root. These rules redeclare the same properties on
   the same selectors; app.css loads after the theme, so they win on order.
   Only the components this app actually uses are covered: DxChart and DxTreeView.
   ═══════════════════════════════════════════════════ */
.dxbl-checkbox {
    --dxbl-checkbox-check-element-checked-bg: var(--tac-primary-solid);
    --dxbl-checkbox-check-element-checked-hover-bg: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --dxbl-checkbox-switch-checked-bg: var(--tac-primary-solid);
    --dxbl-checkbox-switch-checked-hover-bg: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --dxbl-checkbox-radio-checked-border-color: var(--tac-primary-solid);
    --dxbl-checkbox-radio-check-bg: var(--tac-primary-solid);
    --dxbl-checkbox-radio-checked-hover-bg: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --dxbl-checkbox-radio-checked-hover-border-color: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --dxbl-checkbox-validation-valid-color: var(--ucom-success);
    --dxbl-checkbox-validation-invalid-color: var(--ucom-error);
}

.dxbl-treeview {
    --dxbl-treeview-checkbox-checked-bg: var(--tac-primary-solid);
    --dxbl-treeview-checkbox-checked-hover-bg: color-mix(in srgb, var(--tac-primary-solid) 85%, #000);
    --dxbl-treeview-item-focus-outline-color: var(--tac-focus);
    --dxbl-treeview-item-selection-bg: color-mix(in srgb, var(--tac-primary-solid) 16%, transparent);
    --dxbl-treeview-item-selection-color: var(--tac-text);
    --dxbl-treeview-item-hover-bg: color-mix(in srgb, var(--tac-text) 7%, transparent);
}

.dxbl-chart-root {
    --dxbl-chart-focus-outline-color: var(--tac-focus);
}
