/* ═══════════════════════════════════════════════════════════════════════════
   TechWork.Components — theme stylesheet (techwork-theme.css)

   Opt-in. Link it AFTER Bootstrap 5.3 and BEFORE the component sheet and the app's own CSS:

     <link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
     <link rel="stylesheet" href="_content/TechWork.Components/techwork-theme.css" />
     <link rel="stylesheet" href="_content/TechWork.Components/techwork-components.css" />
     <link rel="stylesheet" href="css/app.css" />

   Five sections, in cascade order:
     1. Tokens            --twc-* (light + dark) and the --color-* / --radius-* / --shadow-* /
                          --font-* aliases existing app CSS already uses
     2. Bootstrap bridge  --bs-* variables pointed at the tokens
     3. Base              html/body, links, headings
     4. Global layer      restyles the Bootstrap classes pages already use (cards, tables,
                          forms, buttons, badges, modals, …) so an unstyled page inherits the look
     5. Pattern classes   small CSS-only patterns (status dot + word, page card, KPI, …)

   Dark mode keys off [data-bs-theme="dark"] — the attribute the app writes to <html> before
   first paint. There is no prefers-color-scheme rule in this file: the attribute is the
   single source of truth for both themes.

   Re-branding: redefine --twc-color-primary (and -primary-hover, -primary-tint,
   -primary-tint-strong, -link, -category-1..4) in the app's own stylesheet, once under
   :root and once under [data-bs-theme="dark"]. Nothing else needs to change.

   R-numbers in the comments below are the design system's eleven rules:
   R1 state each number once · R2 one accent per screen, and it is primary · R3 semantic
   colour is reserved for semantics · R4 quantities get one hue, categories distinct hues,
   statuses a dot · R5 destructive actions are quiet until hovered · R6 collapse repeated
   chrome · R7 group what must not separate · R8 a label and its value are a pair · R9 tables:
   one line per row · R10 every text colour clears 4.5:1 against what is behind it · R11 empty
   states say what goes there. D2 / D8 are design decisions (tinted second-rank action /
   the global layer).
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   1. Tokens
   ═══════════════════════════════════════════════════════════════════════════ */

/* Light. [data-bs-theme="light"] as well as :root, so a light region nested inside a dark
   page (Bootstrap supports the attribute on any element) gets the light values back. */
:root,
[data-bs-theme="light"] {
    /* Colour */
    --twc-color-primary: #3b5bdb;
    --twc-color-primary-hover: #1e3a8a;
    --twc-color-primary-tint: rgba(59, 91, 219, 0.12);
    --twc-color-primary-tint-strong: rgba(59, 91, 219, 0.22);
    --twc-color-danger: #dc2626;
    --twc-color-danger-hover: #b91c1c;
    --twc-color-danger-bg: #fef2f2;
    --twc-color-success: #166534;
    --twc-color-success-bg: #dcfce7;
    --twc-color-warning: #92400e;
    --twc-color-warning-bg: #fef3c7;
    --twc-color-muted: #64748b;
    --twc-color-subtle: #475569;
    --twc-color-border: #e2e8f0;
    --twc-color-border-input: #cbd5e1;
    --twc-color-row-rule: #eef1f6;      /* rule between table rows, lighter than border */
    --twc-color-hover: #eef1f6;         /* row / nav hover on content surfaces */
    --twc-color-bg: #f5f6f8;            /* the page ground */
    --twc-color-card-bg: #ffffff;
    --twc-color-input-bg: #ffffff;
    --twc-color-surface-subtle: #f8fafc;
    --twc-color-sidebar-bg: #17212d;
    --twc-color-text: #111827;
    --twc-color-link: #3b5bdb;
    /* Label ink on a SOLID primary / danger fill (R10): white on the light theme's fills. */
    --twc-color-on-primary: #ffffff;
    --twc-color-on-danger: #ffffff;

    /* Categorical hues (a source, a channel, a type). Never for a quantity or a status:
       quantities take primary at varying alpha, statuses take a dot (R4). */
    --twc-color-category-1: #3b5bdb;
    --twc-color-category-2: #b45309;
    --twc-color-category-3: #0f766e;
    --twc-color-category-4: #6d28d9;

    /* Radius */
    --twc-radius-sm: 0.375rem;
    --twc-radius-md: 0.5rem;
    --twc-radius-lg: 0.5rem;
    --twc-radius-xl: 1rem;
    --twc-radius-btn: 0.5rem;
    --twc-radius-card: 0.875rem;

    /* Shadow */
    --twc-shadow-card: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
    --twc-shadow-modal: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.04);

    /* Type */
    --twc-font-sans: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    --twc-font-size-base: 1rem;
    --twc-font-size-sm: 0.9rem;
    --twc-font-size-xs: 0.8rem;

    /* Shell */
    --twc-sidebar-width: 224px;
    --twc-topbar-height: 56px;
}

[data-bs-theme="dark"] {
    --twc-color-primary: #748ffc;
    --twc-color-primary-hover: #a3b4ff;
    --twc-color-primary-tint: rgba(116, 143, 252, 0.14);
    --twc-color-primary-tint-strong: rgba(116, 143, 252, 0.24);
    --twc-color-danger: #f87171;
    --twc-color-danger-hover: #fca5a5;
    --twc-color-danger-bg: #2d1515;
    --twc-color-success: #86efac;
    --twc-color-success-bg: #14532d;
    --twc-color-warning: #fbbf24;
    --twc-color-warning-bg: #451a03;
    --twc-color-muted: #a8b0bb;
    --twc-color-subtle: #d7dce3;
    --twc-color-border: #3a424d;
    --twc-color-border-input: #4c5663;
    --twc-color-row-rule: #2c333c;
    --twc-color-hover: #232a33;
    --twc-color-bg: #20262d;
    --twc-color-card-bg: #15191f;
    --twc-color-input-bg: #20262d;
    --twc-color-surface-subtle: #1b222b;
    --twc-color-sidebar-bg: #101419;
    --twc-color-text: #f3f6fb;
    --twc-color-link: #748ffc;
    /* The dark fills are light, so their label is near-black (white is 2.97:1 on #748ffc). */
    --twc-color-on-primary: #15191f;
    --twc-color-on-danger: #15191f;

    --twc-color-category-1: #748ffc;
    --twc-color-category-2: #fbbf24;
    --twc-color-category-3: #34d399;
    --twc-color-category-4: #c4b5fd;

    --twc-shadow-card: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
    --twc-shadow-modal: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
}

/* Page gutter: AppShell's .content-area padding. Theme-independent, so declared once on :root and
   inherited by any themed region. Edge-to-edge regions (a tab workspace, a banner) pull out with
   margin: calc(-1 * var(--twc-content-padding)) instead of hard-coding the value. */
:root {
    --twc-content-padding: 1.5rem;
}

@media (max-width: 575.98px) {
    :root {
        --twc-content-padding: 1rem;
    }
}

/* Aliases — the names existing app CSS already uses, so it keeps working unchanged.
   Declared on :root AND on every [data-bs-theme] element: a variable that references
   another is resolved where it is declared, so the alias must be re-declared wherever the
   theme flips, or a themed region would inherit the root's resolved value. */
:root,
[data-bs-theme] {
    --color-primary: var(--twc-color-primary);
    --color-primary-hover: var(--twc-color-primary-hover);
    --color-primary-tint: var(--twc-color-primary-tint);
    --color-primary-tint-strong: var(--twc-color-primary-tint-strong);
    --color-danger: var(--twc-color-danger);
    --color-danger-hover: var(--twc-color-danger-hover);
    --color-danger-bg: var(--twc-color-danger-bg);
    --color-success: var(--twc-color-success);
    --color-success-bg: var(--twc-color-success-bg);
    --color-warning: var(--twc-color-warning);
    --color-warning-bg: var(--twc-color-warning-bg);
    --color-muted: var(--twc-color-muted);
    --color-subtle: var(--twc-color-subtle);
    --color-border: var(--twc-color-border);
    --color-border-input: var(--twc-color-border-input);
    --color-row-rule: var(--twc-color-row-rule);
    --color-hover: var(--twc-color-hover);
    --color-bg: var(--twc-color-bg);
    --color-card-bg: var(--twc-color-card-bg);
    --color-input-bg: var(--twc-color-input-bg);
    --color-surface-subtle: var(--twc-color-surface-subtle);
    --color-sidebar-bg: var(--twc-color-sidebar-bg);
    --color-text: var(--twc-color-text);
    --color-link: var(--twc-color-link);
    --color-on-primary: var(--twc-color-on-primary);
    --color-on-danger: var(--twc-color-on-danger);
    --color-category-1: var(--twc-color-category-1);
    --color-category-2: var(--twc-color-category-2);
    --color-category-3: var(--twc-color-category-3);
    --color-category-4: var(--twc-color-category-4);

    --radius-sm: var(--twc-radius-sm);
    --radius-md: var(--twc-radius-md);
    --radius-lg: var(--twc-radius-lg);
    --radius-xl: var(--twc-radius-xl);
    --radius-btn: var(--twc-radius-btn);
    --radius-card: var(--twc-radius-card);

    --shadow-card: var(--twc-shadow-card);
    --shadow-modal: var(--twc-shadow-modal);

    --font-sans: var(--twc-font-sans);
    --font-size-base: var(--twc-font-size-base);
    --font-size-sm: var(--twc-font-size-sm);
    --font-size-xs: var(--twc-font-size-xs);
}


/* ═══════════════════════════════════════════════════════════════════════════
   2. Bootstrap bridge
   Bootstrap-drawn chrome lands on the same surfaces as everything else. One block serves
   both themes because the tokens flip underneath it. --bs-* are Bootstrap's own variables.
   ═══════════════════════════════════════════════════════════════════════════ */
:root,
[data-bs-theme] {
    --bs-body-bg: var(--twc-color-card-bg);
    --bs-body-color: var(--twc-color-text);
    --bs-border-color: var(--twc-color-border);
    --bs-secondary-bg: var(--twc-color-bg);
    --bs-tertiary-bg: var(--twc-color-hover);
    --bs-link-color: var(--twc-color-link);
    --bs-link-hover-color: var(--twc-color-primary-hover);
}

:root,
[data-bs-theme="light"] {
    color-scheme: light;
}

[data-bs-theme="dark"] {
    color-scheme: dark;
}

/* Tables: transparent on whatever surface holds them, light row rules, a hover tint, and no
   zebra striping. */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--twc-color-text);
    --bs-table-border-color: var(--twc-color-row-rule);
    --bs-table-striped-bg: transparent;
    --bs-table-striped-color: var(--twc-color-text);
    --bs-table-hover-bg: var(--twc-color-hover);
    --bs-table-hover-color: var(--twc-color-text);
    --bs-table-active-bg: var(--twc-color-hover);
    --bs-table-active-color: var(--twc-color-text);
    color: var(--twc-color-text);
}

/* Browser autofill paints its own pale fill under light text; keep the field on the input
   surface in dark mode. */
[data-bs-theme="dark"] .form-control:-webkit-autofill,
[data-bs-theme="dark"] .form-control:-webkit-autofill:hover,
[data-bs-theme="dark"] .form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--twc-color-text);
    -webkit-box-shadow: 0 0 0 1000px var(--twc-color-input-bg) inset;
    transition: background-color 5000s ease-in-out 0s;
}


/* ═══════════════════════════════════════════════════════════════════════════
   3. Base
   ═══════════════════════════════════════════════════════════════════════════ */
html,
body {
    font-family: var(--twc-font-sans);
    margin: 0;
    background: var(--twc-color-bg);
    color: var(--twc-color-text);
}

a,
.btn-link {
    color: var(--twc-color-link);
}

/* Blazor moves focus to the page's h1 on navigation; that focus is not a user's. */
h1:focus {
    outline: none;
}

/* Type: hierarchy is size and space, never weight past 500. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: 500;
    letter-spacing: -0.01em;
}


/* ═══════════════════════════════════════════════════════════════════════════
   4. Global layer (D8)
   Restyles the Bootstrap classes pages already use, so an undrawn page inherits the
   treatment without a markup pass. Per-screen markup then only handles what CSS cannot.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Type ── */
.fw-bold,
.fw-bolder,
.fw-semibold {
    font-weight: 500 !important;
}

.text-muted {
    color: var(--twc-color-muted) !important;
}

.text-primary {
    color: var(--twc-color-primary) !important;
}

hr {
    border-color: var(--twc-color-border);
    opacity: 1;
}

/* ── Buttons: one accent (R2), destructive quiet until hovered (R5) ──
   Solid primary is the single most important action; every other Bootstrap variant that
   used to carry its own hue collapses to the neutral outline, and outline-danger becomes
   the quiet destructive. .btn-danger stays solid for a confirmation dialog's confirm.
   The label on the solid fills is the --twc-color-on-* token (white in light, near-black in
   dark) — see the solid-fill note below. */
/* justify-content: centre, because inline-flex drops the text-align: center Bootstrap relies on —
   without it a full-width (.w-100, .d-grid child, flex-grown) button left-aligns its label. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.5rem 1rem;
    border-radius: var(--twc-radius-btn);
    font-size: var(--twc-font-size-sm);
    font-family: var(--twc-font-sans);
    cursor: pointer;
    border: 1px solid transparent;
    line-height: 1.4;
    white-space: nowrap;
}

.btn-sm {
    padding: 0.3rem 0.65rem;
    font-size: var(--twc-font-size-xs);
}

/* Solid fills: the label is --twc-color-on-primary / --twc-color-on-danger, not a literal
   white. White clears 4.5:1 on the light fills (#3b5bdb 5.67:1, #dc2626 4.83:1) but not on the
   dark theme's lighter ones (#748ffc 2.97:1, #a3b4ff 1.99:1, #f87171 2.77:1), so dark mode inks
   the label near-black (#15191f, the dark card surface): 5.94:1 / 8.84:1 / 6.38:1 / 9.29:1 (R10).
   Bootstrap 5.3 paints :active, .active, :focus-visible, .show and .btn-check:checked from its
   --bs-btn-* variables (and out-ranks a plain .btn-primary there), so they are pointed at the
   tokens too; the explicit state rules below cover Bootstrap 5.1, which has no such variables. */
.btn-primary,
.btn-success,
.btn-warning {
    --bs-btn-color: var(--twc-color-on-primary);
    --bs-btn-bg: var(--twc-color-primary);
    --bs-btn-border-color: var(--twc-color-primary);
    --bs-btn-hover-color: var(--twc-color-on-primary);
    --bs-btn-hover-bg: var(--twc-color-primary-hover);
    --bs-btn-hover-border-color: var(--twc-color-primary-hover);
    --bs-btn-active-color: var(--twc-color-on-primary);
    --bs-btn-active-bg: var(--twc-color-primary-hover);
    --bs-btn-active-border-color: var(--twc-color-primary-hover);
    --bs-btn-disabled-color: var(--twc-color-on-primary);
    --bs-btn-disabled-bg: var(--twc-color-primary);
    --bs-btn-disabled-border-color: var(--twc-color-primary);
    background: var(--twc-color-primary);
    color: var(--twc-color-on-primary);
    border-color: var(--twc-color-primary);
}

.btn-primary:hover:not(:disabled),
.btn-success:hover:not(:disabled),
.btn-warning:hover:not(:disabled),
.btn-primary:focus-visible,
.btn-success:focus-visible,
.btn-warning:focus-visible,
.btn-primary:active,
.btn-success:active,
.btn-warning:active,
.btn-primary.active,
.btn-success.active,
.btn-warning.active,
.btn-check:checked + .btn-primary,
.btn-check:checked + .btn-success,
.btn-check:checked + .btn-warning,
.show > .btn-primary.dropdown-toggle {
    background: var(--twc-color-primary-hover);
    border-color: var(--twc-color-primary-hover);
    color: var(--twc-color-on-primary);
}

/* Bootstrap's `.btn:disabled` (higher specificity) swaps in its own blue background, so a
   disabled primary showed off-brand — and in dark mode read as an active button. Keep the
   brand colour and let opacity alone say "disabled". */
.btn-primary:disabled,
.btn-primary.disabled {
    background: var(--twc-color-primary);
    border-color: var(--twc-color-primary);
    color: var(--twc-color-on-primary);
    opacity: 0.45;
    cursor: not-allowed;
}

.btn-danger {
    --bs-btn-color: var(--twc-color-on-danger);
    --bs-btn-bg: var(--twc-color-danger);
    --bs-btn-border-color: var(--twc-color-danger);
    --bs-btn-hover-color: var(--twc-color-on-danger);
    --bs-btn-hover-bg: var(--twc-color-danger-hover);
    --bs-btn-hover-border-color: var(--twc-color-danger-hover);
    --bs-btn-active-color: var(--twc-color-on-danger);
    --bs-btn-active-bg: var(--twc-color-danger-hover);
    --bs-btn-active-border-color: var(--twc-color-danger-hover);
    --bs-btn-disabled-color: var(--twc-color-on-danger);
    --bs-btn-disabled-bg: var(--twc-color-danger);
    --bs-btn-disabled-border-color: var(--twc-color-danger);
    background: var(--twc-color-danger);
    color: var(--twc-color-on-danger);
    border-color: var(--twc-color-danger);
}

.btn-danger:hover:not(:disabled),
.btn-danger:focus-visible,
.btn-danger:active,
.btn-danger.active,
.btn-check:checked + .btn-danger,
.show > .btn-danger.dropdown-toggle {
    background: var(--twc-color-danger-hover);
    border-color: var(--twc-color-danger-hover);
    color: var(--twc-color-on-danger);
}

.btn-secondary,
.btn-light,
.btn-info,
.btn-outline-primary,
.btn-outline-secondary,
.btn-outline-success,
.btn-outline-info,
.btn-outline-warning,
.btn-outline-dark {
    background: transparent;
    color: var(--twc-color-text);
    border-color: var(--twc-color-border-input);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-secondary:hover:not(:disabled),
.btn-light:hover:not(:disabled),
.btn-info:hover:not(:disabled),
.btn-outline-primary:hover:not(:disabled),
.btn-outline-secondary:hover:not(:disabled),
.btn-outline-success:hover:not(:disabled),
.btn-outline-info:hover:not(:disabled),
.btn-outline-warning:hover:not(:disabled),
.btn-outline-dark:hover:not(:disabled),
.btn-secondary:focus-visible,
.btn-outline-primary:focus-visible,
.btn-outline-secondary:focus-visible {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
    border-color: var(--twc-color-border-input);
}

.btn-secondary:active,
.btn-outline-primary:active,
.btn-outline-secondary:active,
.btn-check:checked + .btn-outline-primary,
.btn-check:checked + .btn-outline-secondary,
.btn-outline-primary.active,
.btn-outline-secondary.active {
    background: var(--twc-color-primary-tint) !important;
    color: var(--twc-color-primary-hover) !important;
    border-color: color-mix(in srgb, var(--twc-color-primary) 45%, transparent) !important;
}

.btn-outline-danger {
    background: transparent;
    color: var(--twc-color-muted);
    border-color: transparent;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-outline-danger:hover:not(:disabled),
.btn-outline-danger:focus-visible {
    color: var(--twc-color-danger);
    background: color-mix(in srgb, var(--twc-color-danger) 10%, transparent);
    border-color: color-mix(in srgb, var(--twc-color-danger) 38%, transparent);
}

.btn:focus-visible {
    outline: 2px solid var(--twc-color-primary);
    outline-offset: 2px;
    box-shadow: none;
}

.btn-link {
    color: var(--twc-color-primary);
    text-decoration: none;
}

.btn-link:hover {
    color: var(--twc-color-primary-hover);
    text-decoration: underline;
}

.btn-close {
    --bs-btn-close-focus-shadow: 0 0 0 3px var(--twc-color-primary-tint);
}

[data-bs-theme="dark"] .btn-close {
    opacity: 0.75;
}

[data-bs-theme="dark"] .btn-close:hover {
    opacity: 1;
}

/* ── Forms: eyebrow labels (R8), one control size, primary focus ── */
.form-label {
    font-size: 0.6875rem;
    font-weight: 400;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-muted);
    margin-bottom: 0.25rem;
}

.form-control,
.form-select {
    width: 100%;
    border: 1px solid var(--twc-color-border-input);
    font-family: var(--twc-font-sans);
    box-sizing: border-box;
}

.form-control,
.form-select,
.input-group-text {
    min-height: 2.35rem;
    font-size: var(--twc-font-size-sm);
    background-color: var(--twc-color-input-bg);
    color: var(--twc-color-text);
    border-color: var(--twc-color-border-input);
    border-radius: var(--twc-radius-md);
}

/* .form-select keeps extra right padding so text never sits under the arrow. */
.form-control {
    padding: 0.5rem 0.75rem;
}

.form-select {
    padding: 0.5rem 2.25rem 0.5rem 0.75rem;
}

.form-control-sm,
.form-select-sm {
    min-height: 2.35rem;
    padding: 0.35rem 0.6rem;
    font-size: var(--twc-font-size-sm);
    border-radius: var(--twc-radius-md);
}

.form-control:focus,
.form-select:focus {
    outline: none;
    border-color: var(--twc-color-primary);
    box-shadow: 0 0 0 3px var(--twc-color-primary-tint);
    background-color: var(--twc-color-input-bg);
    color: var(--twc-color-text);
}

.form-control::placeholder {
    color: var(--twc-color-muted);
}

.form-check-input:checked {
    background-color: var(--twc-color-primary);
    border-color: var(--twc-color-primary);
}

/* The checked mark is a white glyph on the primary fill: 2.97:1 on the dark theme's #748ffc,
   under the 3:1 a graphic needs. Dark mode draws it in --twc-color-on-primary's near-black
   (5.94:1) instead. Set as background-image directly so Bootstrap 5.1 (no
   --bs-form-check-bg-image) gets it too; the switch keeps its knob shape. */
[data-bs-theme="dark"] .form-check-input[type="checkbox"]:checked:not(:indeterminate) {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%2315191f' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .form-check-input[type="radio"]:checked {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%2315191f'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .form-switch .form-check-input[type="checkbox"]:checked:not(:indeterminate) {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2315191f'/%3e%3c/svg%3e");
}

.form-check-input:focus {
    border-color: var(--twc-color-primary);
    box-shadow: 0 0 0 3px var(--twc-color-primary-tint);
}

.form-text {
    color: var(--twc-color-subtle);
    font-size: 0.78rem;
}

input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--twc-color-primary);
}

[data-bs-theme="dark"] .input-group-text {
    background-color: var(--twc-color-hover);
}

/* Bare inputs (date/time pickers, number fields, raw <select>) render with the browser's
   light chrome unless told otherwise. */
[data-bs-theme="dark"] input[type="date"],
[data-bs-theme="dark"] input[type="time"],
[data-bs-theme="dark"] input[type="datetime-local"],
[data-bs-theme="dark"] input[type="number"],
[data-bs-theme="dark"] input[type="text"],
[data-bs-theme="dark"] input[type="email"],
[data-bs-theme="dark"] input[type="password"],
[data-bs-theme="dark"] input[type="search"],
[data-bs-theme="dark"] input[type="tel"],
[data-bs-theme="dark"] input[type="url"],
[data-bs-theme="dark"] textarea,
[data-bs-theme="dark"] select {
    background-color: var(--twc-color-input-bg) !important;
    color: var(--twc-color-text) !important;
    border-color: var(--twc-color-border-input);
}

/* ── Validation (Blazor's .valid / .invalid / .validation-message) ──
   A valid field looks like every other field: outlining each edited, valid field in green
   made a form read as a patchwork. Only an invalid field is marked: its own border turns red. */
.invalid:not(.form-control):not(.form-select) {
    outline: 1px solid var(--twc-color-danger);
}

.form-control.invalid,
.form-select.invalid {
    border-color: var(--twc-color-danger) !important;
}

.validation-message {
    color: var(--twc-color-danger);
}

/* ── Cards: 14px radius, no shadow stack, header on the card surface ── */
.card {
    --bs-card-bg: var(--twc-color-card-bg);
    --bs-card-border-color: var(--twc-color-border);
    --bs-card-cap-bg: transparent;
    border-radius: var(--twc-radius-card) !important;
    border-color: var(--twc-color-border);
    box-shadow: none;
}

.card-header {
    border-radius: var(--twc-radius-card) var(--twc-radius-card) 0 0 !important;
    background: transparent;
    font-weight: 500;
    padding: 0.75rem 1rem;
    border-bottom-color: var(--twc-color-border);
}

.card-header strong,
.card-header h5,
.card-header h6 {
    font-weight: 500;
}

.card-footer {
    background: var(--twc-color-bg);
    border-top-color: var(--twc-color-border);
    border-radius: 0 0 var(--twc-radius-card) var(--twc-radius-card) !important;
}

/* Dark: a card stays on the card surface even when markup adds .bg-white / .bg-light. */
[data-bs-theme="dark"] .card {
    background-color: var(--twc-color-card-bg) !important;
    border-color: var(--twc-color-border) !important;
    color: var(--twc-color-text);
}

[data-bs-theme="dark"] .card-header {
    background: transparent !important;
    border-bottom-color: var(--twc-color-border) !important;
    color: var(--twc-color-text);
}

[data-bs-theme="dark"] .card-body {
    color: var(--twc-color-text);
}

/* ── Alerts: the semantic token pairs ── */
.alert {
    border-radius: var(--twc-radius-md) !important;
}

.alert-info,
.alert-primary {
    --bs-alert-bg: var(--twc-color-primary-tint);
    --bs-alert-color: var(--twc-color-primary-hover);
    --bs-alert-border-color: color-mix(in srgb, var(--twc-color-primary) 30%, transparent);
    --bs-alert-link-color: var(--twc-color-primary-hover);
}

.alert-success {
    --bs-alert-bg: var(--twc-color-success-bg);
    --bs-alert-color: var(--twc-color-success);
    --bs-alert-border-color: color-mix(in srgb, var(--twc-color-success) 30%, transparent);
    --bs-alert-link-color: var(--twc-color-success);
}

.alert-warning {
    --bs-alert-bg: var(--twc-color-warning-bg);
    --bs-alert-color: var(--twc-color-warning);
    --bs-alert-border-color: color-mix(in srgb, var(--twc-color-warning) 30%, transparent);
    --bs-alert-link-color: var(--twc-color-warning);
}

.alert-danger {
    --bs-alert-bg: var(--twc-color-danger-bg);
    --bs-alert-color: var(--twc-color-danger-hover);
    --bs-alert-border-color: color-mix(in srgb, var(--twc-color-danger) 30%, transparent);
    --bs-alert-link-color: var(--twc-color-danger-hover);
}

/* ── Badges → dot + word (R4) ──
   Every .badge.bg-* becomes a 6px dot in the state's colour followed by the word in body
   ink, app-wide, without a markup pass. Count badges (.rounded-pill) and the nav unread
   badge (.nav-badge) keep their fill. */
.badge {
    border-radius: var(--twc-radius-sm) !important;
}

/* Long single-token badges (enum values) wrap inside a table cell rather than overflow
   into the next column. */
.table td .badge,
.table th .badge {
    white-space: normal;
    overflow-wrap: anywhere;
}

.badge:not(.rounded-pill):not(.nav-badge) {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0;
    border-radius: 0;
    background: transparent !important;
    color: var(--twc-color-text) !important;
    font-weight: 400;
    font-size: 0.8rem;
    line-height: 1.4;
    white-space: nowrap;
    vertical-align: baseline;
}

.badge:not(.rounded-pill):not(.nav-badge)::before {
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--twc-color-muted);
}

/* DataGrid's mobile-only status slot is a .badge too; the inline-flex above must not
   out-rank its display:none on desktop. The dot-and-word rule's :not() arguments count
   towards its specificity (0,3,0), so a plain `.badge.rtable-mobile-status` (0,2,0) loses —
   repeat the same :not()s here (0,4,0) and on the mobile re-show (0,5,0) so each wins in
   its own viewport. */
.badge.rtable-mobile-status:not(.rounded-pill):not(.nav-badge) {
    display: none;
}

@media (max-width: 767.98px) {
    .rtable .badge.rtable-mobile-status:not(.rounded-pill):not(.nav-badge) {
        display: inline-flex;
    }
}

/* Dot colour per state. Same :not()s as the dot rule above, or its (0,3,1) specificity beats
   these and every dot renders grey. */
.badge.bg-success:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-success:not(.rounded-pill):not(.nav-badge)::before { background: var(--twc-color-success); }
.badge.bg-warning:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-warning:not(.rounded-pill):not(.nav-badge)::before { background: var(--twc-color-warning); }
.badge.bg-danger:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-danger:not(.rounded-pill):not(.nav-badge)::before { background: var(--twc-color-danger); }
.badge.bg-primary:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-primary:not(.rounded-pill):not(.nav-badge)::before,
.badge.bg-info:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-info:not(.rounded-pill):not(.nav-badge)::before { background: var(--twc-color-primary); }
.badge.bg-secondary:not(.rounded-pill):not(.nav-badge)::before,
.badge.bg-light:not(.rounded-pill):not(.nav-badge)::before,
.badge.bg-dark:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-secondary:not(.rounded-pill):not(.nav-badge)::before,
.badge.text-bg-light:not(.rounded-pill):not(.nav-badge)::before { background: var(--twc-color-muted); }

/* ── Neutral surfaces in dark ──
   Bootstrap's .bg-light / .bg-white are fixed near-whites, so neutral boxes that use them
   render as bright blocks in dark mode. Re-point them at the card surface. */
[data-bs-theme="dark"] .bg-white,
[data-bs-theme="dark"] [class*="bg-light"] {
    background-color: var(--twc-color-card-bg) !important;
    color: var(--twc-color-text) !important;
}

[data-bs-theme="dark"] .badge.bg-light {
    background-color: var(--twc-color-hover) !important;
    color: var(--twc-color-text) !important;
    border-color: var(--twc-color-border) !important;
}

/* ── Nav tabs: underline indicator only ──
   No 3-sided border "connecting" trick, so tabs read the same inside modals, cards and on
   the page ground. */
.nav-tabs {
    border-bottom: 1px solid var(--twc-color-border);
    gap: 0.125rem;
}

.nav-tabs .nav-link {
    color: var(--twc-color-muted);
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    padding: 0.5rem 1rem 0.375rem;
    margin-bottom: -1px;
    font-size: var(--twc-font-size-sm);
    font-weight: 500;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
    outline: none;
}

.nav-tabs .nav-link:focus,
.nav-tabs .nav-link:focus-visible {
    outline: none;
    box-shadow: none;
}

.nav-tabs .nav-link:hover {
    color: var(--twc-color-text);
    background: var(--twc-color-bg);
    border-bottom-color: var(--twc-color-border);
    border-radius: var(--twc-radius-sm) var(--twc-radius-sm) 0 0;
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-link.active:hover {
    color: var(--twc-color-primary);
    background: transparent;
    border-bottom: 2px solid var(--twc-color-primary);
    font-weight: 600;
}

/* Phones: the tabs stack full-width, one row each, so nothing overflows. The active
   indicator moves from a bottom underline to a left border so it stays visible stacked. */
@media (max-width: 575.98px) {
    .nav-tabs {
        flex-direction: column;
        border-bottom: none;
        gap: 0;
    }

    .nav-tabs .nav-item {
        width: 100%;
    }

    .nav-tabs .nav-link {
        width: 100%;
        text-align: left;
        margin-bottom: 0;
        padding: 0.625rem 0.75rem;
        border: none;
        border-left: 3px solid transparent;
        border-bottom: 1px solid var(--twc-color-border);
        border-radius: 0;
    }

    .nav-tabs .nav-link:hover {
        background: var(--twc-color-bg);
        border-radius: 0;
        border-bottom-color: var(--twc-color-border);
    }

    .nav-tabs .nav-link.active,
    .nav-tabs .nav-link.active:hover {
        background: var(--twc-color-bg);
        border-left-color: var(--twc-color-primary);
        border-bottom-color: var(--twc-color-border);
    }
}

/* ── Pill tabs → the underline treatment (R2: a filled active pill is a second accent) ── */
.nav-pills {
    gap: 0.125rem;
    border-bottom: 1px solid var(--twc-color-border);
}

.nav-pills .nav-link {
    color: var(--twc-color-muted);
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    padding: 0.5rem 1rem 0.375rem;
    margin-bottom: -1px;
    font-size: var(--twc-font-size-sm);
    font-weight: 500;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}

.nav-pills .nav-link:hover {
    color: var(--twc-color-text);
    background: var(--twc-color-bg);
    border-bottom-color: var(--twc-color-border);
    border-radius: var(--twc-radius-sm) var(--twc-radius-sm) 0 0;
}

.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    color: var(--twc-color-primary);
    background: transparent;
    border-bottom: 2px solid var(--twc-color-primary);
    font-weight: 600;
}

/* ── Tables: eyebrow headings on the page ground, light row rules, hover tint ── */
.table > thead > tr > th,
.table > thead.table-light > tr > th {
    font-size: 0.66rem;
    font-weight: 400;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-subtle);
    background: var(--twc-color-bg);
    border-bottom: 1px solid var(--twc-color-border);
    white-space: nowrap;
    vertical-align: middle;
}

.table-light,
.table > .table-light > tr > td,
.table > tfoot.table-light > tr > td {
    --bs-table-bg: var(--twc-color-bg);
    background: var(--twc-color-bg);
    color: var(--twc-color-text);
}

.table > :not(caption) > * > * {
    padding: 0.55rem 0.9rem;
}

.table > tbody > tr:last-child > td {
    border-bottom-width: 0;
}

/* Inside a flush card body (or a Flush DataGrid), line the first and last columns up with the
   card header / table toolbar. */
.card-body.p-0 .table > :not(caption) > * > *:first-child,
.twc-table-flush .table > :not(caption) > * > *:first-child {
    padding-left: 1rem;
}

.card-body.p-0 .table > :not(caption) > * > *:last-child,
.twc-table-flush .table > :not(caption) > * > *:last-child {
    padding-right: 1rem;
}

/* Inline code in cells (slugs, references) may break anywhere rather than widen the row. */
.table code {
    overflow-wrap: anywhere;
}

/* Plain tables without .table get the theme's rule colour. */
table:not(.table) thead th,
table:not(.table) tbody td,
table:not(.table) tfoot td {
    border-color: var(--twc-color-border);
}

/* ── Modals: card radius, one shadow, 500-weight title ──
   Sizes: .modal-sm 440px (confirmations) · default (forms) · .modal-fullscreen (rich panels). */
@media (min-width: 576px) {
    .modal-dialog {
        padding: 50px;
    }

    .modal-dialog.modal-sm {
        max-width: 440px;
    }
}

/* Full-screen means edge to edge on a phone: square corners below 576px (the radius below
   is !important, so it has to be undone here). From 576px the 50px inset above frames it as
   a rounded sheet. */
@media (max-width: 575.98px) {
    .modal-fullscreen > .modal-content {
        border-radius: 0 !important;
    }
}

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

.modal-title {
    font-size: 1.3rem;
    font-weight: 500;
    letter-spacing: -0.02em;
}

.modal-header {
    border-bottom-color: var(--twc-color-border);
    padding: 1rem 1.25rem;
}

.modal-footer {
    border-top-color: var(--twc-color-border);
    padding: 0.75rem 1.25rem;
}

.modal-body {
    padding: 1.25rem;
}

/* ── Dropdowns, list groups ── */
.dropdown-menu {
    --bs-dropdown-bg: var(--twc-color-card-bg);
    --bs-dropdown-color: var(--twc-color-text);
    --bs-dropdown-link-color: var(--twc-color-text);
    --bs-dropdown-link-hover-bg: var(--twc-color-hover);
    --bs-dropdown-link-hover-color: var(--twc-color-text);
    --bs-dropdown-border-color: var(--twc-color-border);
    --bs-dropdown-divider-bg: var(--twc-color-border);
    border-radius: var(--twc-radius-md);
    box-shadow: var(--twc-shadow-modal);
    font-size: var(--twc-font-size-sm);
}

.list-group-item {
    background: var(--twc-color-card-bg);
    color: var(--twc-color-text);
    border-color: var(--twc-color-row-rule);
}

.list-group-item-action:hover,
.list-group-item-action:focus {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
}

/* ── Progress: a quantity (R4) — one hue, never a semantic colour ── */
.progress {
    background: var(--twc-color-bg);
    border-radius: 3px;
}

[data-bs-theme="dark"] .progress {
    background: var(--twc-color-row-rule);
}

.progress-bar,
.progress-bar[class*="bg-"] {
    --bs-progress-bar-color: var(--twc-color-on-primary);
    background-color: var(--twc-color-primary) !important;
    color: var(--twc-color-on-primary);
}

/* ── Accordion ── */
.accordion {
    --bs-accordion-bg: var(--twc-color-card-bg);
    --bs-accordion-color: var(--twc-color-text);
    --bs-accordion-border-color: var(--twc-color-border);
    --bs-accordion-btn-bg: var(--twc-color-card-bg);
    --bs-accordion-btn-color: var(--twc-color-text);
    --bs-accordion-active-bg: var(--twc-color-hover);
    --bs-accordion-active-color: var(--twc-color-primary);
    --bs-accordion-btn-focus-box-shadow: 0 0 0 3px var(--twc-color-primary-tint);
}

/* ── Popover / tooltip ──
   The tooltip stays dark in both themes (a deliberate theme-independent literal pair). */
.popover {
    --bs-popover-bg: var(--twc-color-card-bg);
    --bs-popover-border-color: var(--twc-color-border);
    --bs-popover-header-bg: var(--twc-color-bg);
    --bs-popover-header-color: var(--twc-color-text);
    --bs-popover-body-color: var(--twc-color-text);
}

.tooltip {
    --bs-tooltip-bg: #0f172a;
    --bs-tooltip-color: #f1f5f9;
}

/* ── Pagination ── */
.pagination {
    --bs-pagination-color: var(--twc-color-link);
    --bs-pagination-bg: var(--twc-color-card-bg);
    --bs-pagination-border-color: var(--twc-color-border);
    --bs-pagination-hover-color: var(--twc-color-primary);
    --bs-pagination-hover-bg: var(--twc-color-hover);
    --bs-pagination-hover-border-color: var(--twc-color-border);
    --bs-pagination-focus-color: var(--twc-color-primary);
    --bs-pagination-focus-bg: var(--twc-color-hover);
    --bs-pagination-focus-box-shadow: 0 0 0 3px var(--twc-color-primary-tint);
    --bs-pagination-active-color: var(--twc-color-on-primary);
    --bs-pagination-active-bg: var(--twc-color-primary);
    --bs-pagination-active-border-color: var(--twc-color-primary);
    --bs-pagination-disabled-color: var(--twc-color-muted);
    --bs-pagination-disabled-bg: var(--twc-color-card-bg);
    --bs-pagination-disabled-border-color: var(--twc-color-border);
}

/* ── Offcanvas ── */
.offcanvas,
.offcanvas-start,
.offcanvas-end,
.offcanvas-top,
.offcanvas-bottom {
    --bs-offcanvas-bg: var(--twc-color-card-bg);
    --bs-offcanvas-color: var(--twc-color-text);
    --bs-offcanvas-border-color: var(--twc-color-border);
}


/* ═══════════════════════════════════════════════════════════════════════════
   5. Pattern classes
   Small utilities every redesigned screen consumes. Classes rather than components on
   purpose; every colour is a token, so each works in both themes without a dark rule.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── State messages ── */
.state-message {
    padding: 1rem;
    color: var(--twc-color-muted);
}

.state-loading {
    font-style: italic;
}

.state-error {
    color: var(--twc-color-danger-hover);
    background: var(--twc-color-danger-bg);
    border-radius: var(--twc-radius-md);
}

.state-empty {
    color: var(--twc-color-muted);
}

/* ── Form helpers ── */
.form-group {
    margin-bottom: 1rem;
}

.form-group label {
    display: block;
    margin-bottom: 0.35rem;
    font-weight: 500;
    font-size: var(--twc-font-size-sm);
}

.form-group.flex-1 {
    flex: 1;
    min-width: 6rem;
}

.form-group.flex-2 {
    flex: 2;
    min-width: 10rem;
}

.form-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-start;
}

.form-section-title {
    margin: 1rem 0 0.5rem;
    font-size: var(--twc-font-size-base);
    color: var(--twc-color-subtle);
}

.form-hint {
    margin: 0.25rem 0 0;
    font-size: var(--twc-font-size-sm);
    color: var(--twc-color-muted);
}

.form-error {
    background: var(--twc-color-danger-bg);
    color: var(--twc-color-danger-hover);
    padding: 0.75rem;
    border-radius: var(--twc-radius-md);
    margin-bottom: 1rem;
    font-size: var(--twc-font-size-sm);
}

.form-success {
    padding: 0.75rem;
    background: var(--twc-color-success-bg);
    color: var(--twc-color-success);
    border-radius: var(--twc-radius-md);
    margin-bottom: 1rem;
}

.required {
    color: var(--twc-color-danger-hover);
}

/* ── Back button ── */
.back-button {
    background: none;
    border: none;
    color: var(--twc-color-primary);
    cursor: pointer;
    padding: 0 0 0.5rem;
    margin-bottom: 0.5rem;
    font-size: var(--twc-font-size-sm);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.back-button:hover {
    text-decoration: underline;
}

/* ── Page layout ── */
.page-card {
    background: var(--twc-color-card-bg);
    border-radius: var(--twc-radius-card);
    border: 1px solid var(--twc-color-border);
    box-shadow: var(--twc-shadow-card);
    padding: 1.25rem;
    color: var(--twc-color-text);
}

.content-narrow {
    max-width: 980px;
}

.content-medium {
    max-width: 1160px;
}

/* minmax(0, 1fr), not the implicit auto track: an auto track cannot shrink below its widest
   child's min-content, so one wide table pushed every section past a phone's width. */
.section-stack {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

.detail-section {
    margin-bottom: 1.25rem;
}

.detail-section h3 {
    margin: 0 0 0.5rem;
    font-size: var(--twc-font-size-base);
    color: var(--twc-color-subtle);
}

.table-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--twc-color-border);
    background: color-mix(in srgb, var(--twc-color-card-bg) 84%, var(--twc-color-bg));
}

.table-toolbar-title {
    margin: 0;
    font-size: 0.92rem;
    font-weight: 500;   /* the type scale's heading cap; 700 broke it */
}

.table-toolbar-meta {
    color: var(--twc-color-muted);
    font-size: var(--twc-font-size-xs);
}

.action-group {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.danger-zone {
    margin-left: 0.5rem;
    padding-left: 0.65rem;
    border-left: 1px solid var(--twc-color-border);
}

/* Empty state (R11): the panel carries the card radius and a dashed edge. */
.empty-panel {
    min-height: 12rem;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 1.5rem;
    color: var(--twc-color-muted);
    background: color-mix(in srgb, var(--twc-color-card-bg) 88%, var(--twc-color-bg));
    border-radius: var(--twc-radius-card);
    border: 1px dashed var(--twc-color-border);
}

.empty-panel strong {
    display: block;
    margin-bottom: 0.25rem;
    color: var(--twc-color-text);
}

/* ── Eyebrow + value pairs (R8) ──
   An uppercase 11px muted label, then the value at body weight: bolding every value
   flattened the hierarchy, so size and space carry the pairing. .detail-item-meta is the
   optional third line. */
.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 0.9rem 1.5rem;
}

.detail-item-label {
    color: var(--twc-color-muted);
    font-size: 0.6875rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    margin-bottom: 0.15rem;
}

.detail-item-value {
    font-weight: 400;
}

.detail-item-meta {
    margin-top: 0.1rem;
    font-size: 0.72rem;
    color: var(--twc-color-muted);
}

.grid-column-full {
    grid-column: 1 / -1;
}

/* Eyebrow label outside a .detail-grid (filter labels, card sub-heads) — same treatment as
   .detail-item-label. Sits on card surfaces; on the bare page ground use the subtle colour
   (R10: muted is only 4.4:1 on the page ground). */
.eyebrow {
    display: block;
    font-size: 0.6875rem;
    font-weight: 400;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-muted);
    margin-bottom: 0.25rem;
}

.tabular {
    font-variant-numeric: tabular-nums;
}

/* ── Settings layout: rail + content ──
   A wrapping flex row rather than a fixed two-track grid. The content carries the dominant
   grow, so the rail keeps 14rem beside it at desktop width and drops above it as a short
   multi-column block when it can't fit. */
.settings-shell {
    max-width: 1280px;
}

.settings-layout {
    display: flex;
    flex-wrap: wrap;
    gap: 1.75rem;
    align-items: flex-start;
}

.settings-rail {
    flex: 1 1 14rem;
    max-width: 14rem;
    position: sticky;
    top: 5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.settings-rail-group {
    display: flex;
    flex-direction: column;
    gap: 1px;
    break-inside: avoid;
}

.settings-rail-heading {
    font-size: 0.6875rem;
    font-weight: 400;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-muted);
    padding: 0 0.525rem 0.25rem;
}

.settings-rail-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.settings-rail-link {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    color: var(--twc-color-text);
    text-decoration: none;
    padding: 0.375rem 0.525rem;
    border-radius: var(--twc-radius-sm);
    font-size: 0.845rem;
    font-weight: 400;
    line-height: 1.3;
    transition: background 0.12s, color 0.12s;
    cursor: pointer;
    outline: none;
}

.settings-rail-link:hover,
.settings-rail-link:focus-visible {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
}

/* Active: primary tint with an inset marker, not a filled block (R2). */
.settings-rail-link.active,
.settings-rail-link.active:hover {
    background: var(--twc-color-primary-tint);
    color: var(--twc-color-primary);
    box-shadow: inset 2px 0 0 var(--twc-color-primary);
}

.settings-rail-link:focus-visible {
    box-shadow: 0 0 0 2px var(--twc-color-primary);
}

.settings-content {
    flex: 100 1 32rem;
    min-width: 0;
    max-width: 56rem;
}

/* Section header inside a settings panel: title at 500 and a one-line lead (R1). */
.settings-section-head {
    margin-bottom: 0.9rem;
}

.settings-section-title {
    margin: 0 0 0.2rem;
    font-size: 1.2rem;
    font-weight: 500;
    letter-spacing: -0.015em;
}

.settings-section-lead {
    margin: 0;
    font-size: 0.845rem;
    color: var(--twc-color-subtle);
    max-width: 62ch;
    text-wrap: pretty;
}

@media (max-width: 767.98px) {
    .settings-layout {
        gap: 1rem;
    }

    /* The rail becomes a short multi-column block above the panel rather than a tall list. */
    .settings-rail {
        position: static;
        display: block;
        max-width: none;
        columns: 10.5rem;
        column-gap: 1.25rem;
    }

    .settings-rail-group {
        margin-bottom: 0.8rem;
    }

    .settings-rail-heading {
        padding: 0;
    }

    .settings-rail-link {
        padding: 0.625rem 0.75rem;
        font-size: var(--twc-font-size-base);
    }
}

/* ── Inactive badge ── */
.badge-inactive {
    display: inline-block;
    padding: 0.2rem 0.5rem;
    background: var(--twc-color-hover);
    color: var(--twc-color-muted);
    border-radius: var(--twc-radius-sm);
    font-size: var(--twc-font-size-xs);
    font-weight: 500;
}

/* ── Status dot + word (R4) ──
   The word is always present: the dot is never the only signal, and the pair is one
   inline-flex item so a wrapping row can never split them (R7). Modifiers:
   -primary        active / published / confirmed
   -muted          inactive / not started / cancelled / expired / unpaid
   -warning        needs attention (draft, part paid)
   -success        completed (paid)
   -danger         failed
   -category-1..4  a categorical hue (a source, a channel) — never a quantity or a status */
.status-word {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

.status-dot {
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--twc-color-muted);
}

.status-dot-primary { background: var(--twc-color-primary); }
.status-dot-muted { background: var(--twc-color-muted); }
.status-dot-warning { background: var(--twc-color-warning); }
.status-dot-success { background: var(--twc-color-success); }
.status-dot-danger { background: var(--twc-color-danger); }
.status-dot-category-1 { background: var(--twc-color-category-1); }
.status-dot-category-2 { background: var(--twc-color-category-2); }
.status-dot-category-3 { background: var(--twc-color-category-3); }
.status-dot-category-4 { background: var(--twc-color-category-4); }

/* Status chip (outlined): a state that reads as a token — Paid / Part paid in a list, a
   Draft + Unpaid pair in a detail header. -pending (dashed) marks a not-yet-true state. */
.status-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 2px 9px;
    border-radius: var(--twc-radius-sm);
    border: 1px solid color-mix(in srgb, var(--twc-color-primary) 45%, transparent);
    background: var(--twc-color-primary-tint);
    color: var(--twc-color-primary-hover);
    font-size: 0.78rem;
    line-height: 1.4;
    white-space: nowrap;
}

.status-chip-pending {
    background: transparent;
    border-style: dashed;
}

/* A chip for a state that IS a failure (a failed charge, an overdue action): the one place
   a chip takes the danger colour. */
.status-chip-danger {
    border-color: color-mix(in srgb, var(--twc-color-danger) 45%, transparent);
    background: color-mix(in srgb, var(--twc-color-danger) 10%, transparent);
    color: var(--twc-color-danger);
}

/* The quiet, plain-word state beside the chips (Unpaid). */
.payment-plain {
    color: var(--twc-color-subtle);
    font-size: 0.78rem;
    white-space: nowrap;
}

/* ── Internal-only band ──
   Figures that must not read as customer-facing (cost, margin): on the page ground at the
   foot of a card, an eyebrow with an icon, figures at 13px in the subtle colour. */
.internal-band {
    margin: 1rem -1rem -1rem;
    padding: 0.75rem 1rem;
    background: var(--twc-color-bg);
    border-top: 1px solid var(--twc-color-border);
    border-radius: 0 0 var(--twc-radius-card) var(--twc-radius-card);
}

.internal-band-label {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.6875rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-subtle);
    margin-bottom: 0.4rem;
}

.internal-band-label .material-icons {
    font-size: 0.9rem;
}

.internal-band-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    font-size: 0.82rem;
    color: var(--twc-color-subtle);
    padding: 0.15rem 0;
}

/* ── Hero figure (R1): the one number the user came for, stated large and once ── */
.hero-figure {
    font-size: 1.7rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

/* ── Ledger (R1): the quiet list beneath a hero — label left, figure right, a rule above totals ── */
.ledger {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.85rem;
}

.ledger-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
}

.ledger-row-muted {
    color: var(--twc-color-subtle);
    font-size: 0.8rem;
}

.ledger-row-total {
    margin-top: 0.35rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--twc-color-border);
    font-weight: 500;
}

.ledger-figure {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── Copy button beside a reference (R7: grouped with its value, never split from it) ──
   A 16px glyph in a 44×44 tap target (touch is first-class). The CopyButton component renders it. */
.copy-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: var(--twc-radius-sm);
    background: transparent;
    color: var(--twc-color-muted);
    cursor: pointer;
}

.copy-btn:hover,
.copy-btn:focus-visible {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
}

.copy-btn .material-icons {
    font-size: 1rem;
}

/* ── Button patterns ── */

/* Quiet destructive (R5). Quiet means quiet COLOUR, not hidden: the icon, aria-label, title
   and 44px target are always present, and under (hover: none) the button simply stays in
   this state. Only the danger tint waits for hover/focus. .btn-danger remains for a
   confirmation dialog's confirm button. */
.btn-quiet-danger {
    background: transparent;
    color: var(--twc-color-muted);
    border-color: transparent;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-quiet-danger:hover:not(:disabled),
.btn-quiet-danger:focus-visible {
    color: var(--twc-color-danger);
    background: color-mix(in srgb, var(--twc-color-danger) 10%, transparent);
    border-color: color-mix(in srgb, var(--twc-color-danger) 38%, transparent);
}

.btn-quiet-danger:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Second-rank primary (D2): the tinted outline for the action that sits beside the one
   solid .btn-primary on a screen. */
.btn-tinted {
    background: var(--twc-color-primary-tint);
    color: var(--twc-color-primary-hover);
    border-color: color-mix(in srgb, var(--twc-color-primary) 45%, transparent);
    font-weight: 500;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-tinted:hover:not(:disabled) {
    background: var(--twc-color-primary-tint-strong);
    border-color: var(--twc-color-primary);
    color: var(--twc-color-primary-hover);
}

.btn-tinted:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Neutral outline (second-rank neutral action: Export, View): transparent on the tokens,
   because Bootstrap's outline-secondary grey fails contrast in dark mode. */
.btn-neutral {
    background: transparent;
    color: var(--twc-color-text);
    border-color: var(--twc-color-border-input);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-neutral:hover:not(:disabled),
.btn-neutral:focus-visible {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
    border-color: var(--twc-color-border-input);
}

.btn-neutral:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.btn-neutral .material-icons {
    color: var(--twc-color-muted);
}

/* Dashed add (R6 / R11): "Add item", "Add row", and the action inside an empty state. */
.btn-dashed-add {
    background: transparent;
    color: var(--twc-color-primary-hover);
    border: 1px dashed var(--twc-color-primary);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-dashed-add:hover:not(:disabled) {
    border-style: solid;
    background: var(--twc-color-primary-tint);
    color: var(--twc-color-primary-hover);
}

.btn-quiet-danger:focus-visible,
.btn-tinted:focus-visible,
.btn-neutral:focus-visible,
.btn-dashed-add:focus-visible {
    outline: 2px solid var(--twc-color-primary);
    outline-offset: 2px;
}

/* Quiet icon button (R2, R5): a glyph-only action in a row — a 16px glyph in a 44×44 target. */
.btn-icon-quiet {
    display: inline-grid;
    place-items: center;
    padding: 0;
    width: 44px;
    height: 44px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--twc-color-subtle);
}

.btn-icon-quiet .material-icons {
    font-size: 1rem;
}

.btn-icon-quiet:hover:not(:disabled),
.btn-icon-quiet:focus-visible {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
}

.btn-icon-quiet:disabled {
    opacity: 0.35;
}

/* A pair of quiet icon buttons (move up / move down). */
.order-group {
    display: inline-flex;
    gap: 2px;
}

/* ── Quiet qualifier tag (R2): an outlined uppercase word beside a name ── */
.tag-quiet {
    display: inline-block;
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 1px 7px;
    border-radius: 5px;
    border: 1px solid var(--twc-color-border-input);
    color: var(--twc-color-subtle);
    white-space: nowrap;
    vertical-align: middle;
}

.tag-quiet-active {
    border-color: var(--twc-color-primary);
    color: var(--twc-color-primary);
    background: var(--twc-color-primary-tint);
}

/* ── Segmented control: 2–3 short mutually exclusive options instead of a select ──
   The active option is explicit in markup via aria-pressed, so it cannot drift from the value. */
.segmented {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--twc-color-border-input);
    border-radius: var(--twc-radius-btn);
    overflow: hidden;
}

.segmented-option {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    background: transparent;
    color: var(--twc-color-subtle);
    font: inherit;
    font-size: var(--twc-font-size-sm);
    padding: 0.5rem 0.9rem;
    min-height: 44px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.segmented-option + .segmented-option {
    border-left: 1px solid var(--twc-color-border-input);
}

.segmented-option:hover {
    background: var(--twc-color-hover);
    color: var(--twc-color-text);
}

.segmented-option[aria-pressed="true"] {
    background: var(--twc-color-primary-tint);
    color: var(--twc-color-primary-hover);
}

.segmented-option:focus-visible {
    outline: 2px solid var(--twc-color-primary);
    outline-offset: -2px;
}

/* ── KPI cards + strip (R2: figures in body ink) ── */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
    gap: 0.75rem;
}

.kpi {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.kpi-large {
    padding: 0.9rem 1rem;
    border: 1px solid var(--twc-color-border);
    border-radius: var(--twc-radius-card);
    background: var(--twc-color-card-bg);
}

.kpi-label {
    font-size: 0.66rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--twc-color-subtle);
}

.kpi-value {
    font-size: 1.7rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    line-height: 1.1;
    color: var(--twc-color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kpi-small .kpi-value {
    font-size: 1.05rem;
}

.kpi-suffix {
    font-size: 0.8rem;
    color: var(--twc-color-subtle);
    font-weight: 400;
}

.kpi-meta {
    font-size: 0.78rem;
    color: var(--twc-color-subtle);
}

/* One bordered strip: the cells are separated by the 1px grid gap showing the border colour. */
.kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
    gap: 1px;
    border: 1px solid var(--twc-color-border);
    border-radius: var(--twc-radius-card);
    background: var(--twc-color-border);
    overflow: hidden;
}

.kpi-strip .kpi {
    padding: 0.7rem 1rem;
    background: var(--twc-color-card-bg);
}

@media (max-width: 575.98px) {
    .kpi-value {
        font-size: 1.4rem;
    }
}

/* ── Phone list rows (≤767.98px) ──
   A phone-list grid swaps its stacked desktop columns for one purpose-built cell per row on
   phones, like a native list row: up to three short lines (a title with a right-hand aside,
   then quieter detail lines) and a chevron; the whole row is the tap target (give the grid an
   OnRowClick), so there is no Edit/Details button. The cell is either the DataGrid's own
   td.rtable-phone-row (PhoneRowTemplate — preferred) or a hand-built
   <TemplateColumn Title="" Class="phone-row-cell" HeaderClass="phone-row-cell"> in a grid with
   TableClass="phone-list"; either way it holds .phone-row, every other cell hides at this
   width and the phone cell hides above it.

   The row, not its cells, paints the hover/pressed tint, with no padding of its own, so the
   tint runs from separator to separator (Bootstrap paints row hover as an inset shadow on
   each cell, which on a stacked row stopped short). Separators are inset to the text. The
   selectors carry .rtable and .rtable-row so they out-rank the component sheet's
   .rtable .rtable-row padding and dark-mode border rules. */
.phone-list .phone-row-cell {
    display: none;
}

@media (max-width: 767.98px) {
    .rtable.phone-list tbody tr.rtable-row > td:not(.phone-row-cell):not(.rtable-phone-row) {
        display: none !important;
    }

    .rtable.phone-list tbody tr.rtable-row > td.phone-row-cell,
    .rtable.phone-list tbody tr.rtable-row > td.rtable-phone-row {
        display: block;
        padding: 0;
        border: 0;
        box-shadow: none !important;
        background: transparent !important;
    }

    .rtable.phone-list tbody tr.rtable-row {
        position: relative;
        padding: 0;
        border-bottom: 0;
        -webkit-tap-highlight-color: transparent;
        transition: background-color 0.12s;
    }

    .rtable.phone-list tbody tr.rtable-row:not(:last-child)::after {
        content: "";
        position: absolute;
        left: 1rem;
        right: 0;
        bottom: 0;
        border-top: 0.5px solid var(--twc-color-row-rule);
        pointer-events: none;
    }

    .rtable.phone-list tbody tr.rtable-row:active {
        background-color: var(--twc-color-hover);
    }

    @media (hover: hover) {
        .rtable.phone-list tbody tr.rtable-row:hover {
            background-color: var(--twc-color-hover);
        }
    }
}

.phone-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.7rem 0.5rem 0.7rem 1rem;
}

.phone-row-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.phone-row-line {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    min-width: 0;
}

.phone-row-line > :first-child {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.phone-row-line > :not(:first-child) {
    flex-shrink: 0;
}

.phone-row-title {
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--twc-color-text);
}

.phone-row-title.status-word {
    gap: 0.45rem;
}

.phone-row-aside {
    font-size: 0.9375rem;
    color: var(--twc-color-subtle);
}

.phone-row-sub {
    font-size: 0.875rem;
    color: var(--twc-color-subtle);
}

/* Text that reads as the row's second voice, not muted (a location, a status word). */
.phone-row-em {
    color: var(--twc-color-text);
}

.phone-row-muted {
    color: var(--twc-color-subtle);
}

/* A dot + word title: the word, not the dot, gives way to a long name. */
.phone-row-line .status-word > span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.phone-row-sub .status-chip {
    font-size: 0.75rem;
    padding: 1px 7px;
}

.phone-row-chevron {
    flex: none;
    font-size: 22px;
    color: var(--twc-color-subtle);
}

/* ── Phone list in a plain list: ul.phone-list > li > .phone-row ──
   The same rows outside a DataGrid (a short list in a detail panel, a More page, a picker) — at
   every width, since a plain list has no desktop table to swap back to. Each li is a row; the
   separator is inset to the text (1rem, the .phone-row's leading padding) like the grid version.
   The row element itself is the tap target: an <a class="phone-row"> or <button
   class="phone-row"> fills the li and takes the pressed (and, with a pointer, hover) tint from
   separator to separator; a plain <div class="phone-row"> is a static row and takes none.

     <ul class="phone-list">
         <li><a class="phone-row" href="/rooms/12"> …body… <span class="material-icons
             phone-row-chevron" aria-hidden="true">chevron_right</span></a></li>
     </ul> */
ul.phone-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

ul.phone-list > li {
    position: relative;
}

ul.phone-list > li:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 1rem;
    right: 0;
    bottom: 0;
    border-top: 0.5px solid var(--twc-color-row-rule);
    pointer-events: none;
}

ul.phone-list > li > a.phone-row,
ul.phone-list > li > button.phone-row {
    width: 100%;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.12s;
}

ul.phone-list > li > a.phone-row:active,
ul.phone-list > li > button.phone-row:active {
    background-color: var(--twc-color-hover);
}

@media (hover: hover) {
    ul.phone-list > li > a.phone-row:hover,
    ul.phone-list > li > button.phone-row:hover {
        background-color: var(--twc-color-hover);
    }
}

ul.phone-list > li > a.phone-row:focus-visible,
ul.phone-list > li > button.phone-row:focus-visible {
    outline: 2px solid var(--twc-color-primary);
    outline-offset: -2px;
}

/* ── Auth layout: a centred card on the page ground ── */
.auth-layout {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: var(--twc-color-bg);
    padding: 1.5rem;
}

.auth-card {
    width: 100%;
    max-width: 420px;
}
