/* ============================================================================
   Atasoft Control Center — global design system.
   Loaded after bootstrap.min.css, so everything here overrides Bootstrap
   defaults. All pages share these Bootstrap building blocks (cards, tables,
   badges, buttons, tabs, forms), so restyling them here restyles every page.

   Since the 2026-09 design review the Control Center and InvoiceCraft share ONE
   semantic token set (roles, five status tones, type/spacing/radius scale). This
   file is the Bootstrap host adapter for those roles: `--cc-*` names the role,
   Bootstrap's component variables and the BlazorMHD `--mhd-*` bridge read it.
   The values are Tailwind v4 palette entries (slate / indigo / emerald / amber /
   rose / sky) converted to sRGB hex, so both apps render the same colours.
   ========================================================================== */

:root {
    /* The dark block below declares `color-scheme: dark`; this is its counterpart. theme.js always
       writes an explicit data-theme, so an operator on a dark OS who picks the LIGHT theme would
       otherwise keep the UA's dark scrollbars, <select> popups and date pickers inside a light page. */
    color-scheme: light;

    /* ── Colour roles (T-1) ─────────────────────────────────────────────── */
    --cc-bg: #f1f5f9;               /* canvas — slate-100 */
    --cc-surface: #ffffff;          /* cards, inputs, menus */
    --cc-surface-muted: #f8fafc;    /* surface-subtle — table headers, neutral hover, read-only */
    --cc-surface-raised: #ffffff;   /* dialogs, popovers, toasts */
    --cc-text: #0f172b;             /* slate-900 */
    --cc-text-secondary: #314158;   /* slate-700 */
    /* WCAG 1.4.3 (AA, 4.5:1 for body text): slate-500 reaches only 4.35:1 on the canvas, so muted
       text is slate-600 — 6.9:1 on the canvas, 7.6:1 on white. */
    --cc-muted: #45556c;
    --cc-border: #e2e8f0;           /* decorative — slate-200 */
    --cc-border-control: #62748e;   /* essential control boundary — slate-500, 3:1 on the surface */

    /* One primary indigo for both apps (D-A): Tailwind v4 indigo-600. */
    --cc-primary: #4f39f6;
    --cc-primary-hover: #432dd7;    /* indigo-700 */
    --cc-primary-pressed: #372aac;  /* indigo-800 */
    --cc-primary-soft: #eef2ff;     /* primary-subtle — selected nav / filter, never a second action */
    --cc-on-primary: #ffffff;
    --cc-primary-ring: rgba(97, 95, 255, 0.35);   /* indigo-500 at 35 % */
    --cc-focus: #615fff;            /* indigo-500 — 2px focus-visible outline */

    /* Link/foreground accent, kept SEPARATE from --cc-primary (which is a FILL colour). In light
       mode they are a shade apart; in dark mode they must not coincide — a fill dark enough for
       white text is far too dark to read as text itself. */
    --cc-link: #432dd7;             /* indigo-700, 8.1:1 on white */
    --cc-link-hover: #372aac;

    /* Danger ACTION fill (a red chip is a tone, not a button). */
    --cc-danger: #c70036;           /* rose-700, white text 6.0:1 */
    --cc-danger-hover: #a50036;
    --cc-danger-pressed: #8b0836;
    --cc-on-danger: #ffffff;

    --cc-disabled-bg: #f1f5f9;
    --cc-disabled-text: #62748e;
    --cc-overlay: rgba(15, 23, 42, 0.4);

    /* ── Five status tones (T-2): foreground / background ────────────────── */
    --cc-tone-success-fg: #006045;  --cc-tone-success-bg: #ecfdf5;   /* emerald-800 / 50 — 7.2:1 */
    --cc-tone-warning-fg: #973c00;  --cc-tone-warning-bg: #fffbeb;   /* amber-800 / 50   — 6.8:1 */
    --cc-tone-danger-fg:  #c70036;  --cc-tone-danger-bg:  #fff1f2;   /* rose-700 / 50    — 5.5:1 */
    --cc-tone-info-fg:    #00598a;  --cc-tone-info-bg:    #f0f9ff;   /* sky-800 / 50     — 7.1:1 */
    --cc-tone-neutral-fg: #45556c;  --cc-tone-neutral-bg: #f1f5f9;   /* slate-600 / 100  — 6.9:1 */

    /* Older aliases, still read by the stat tiles / counters below. */
    --cc-ok-text: var(--cc-tone-success-fg);
    --cc-warn-text: var(--cc-tone-warning-fg);
    --cc-danger-text: var(--cc-tone-danger-fg);

    /* The dark operator sidebar keeps its own opaque nav tokens in BOTH themes (C-19). */
    --cc-sidebar-1: #0f172b;
    --cc-sidebar-2: #131a34;
    --cc-nav-text: #e2e8f0;
    --cc-nav-muted: #90a1b9;
    --cc-nav-selected-bg: #312c85;  /* indigo-900 */
    --cc-nav-selected-text: #ffffff;
    --cc-nav-indicator: #a3b3ff;    /* indigo-300 */
    --cc-nav-hover-bg: #1d293d;     /* slate-800, opaque */
    --cc-nav-hover-text: #ffffff;

    /* Surfaces that were previously hard-coded in component CSS. Tokenised so the dark override
       below reaches them instead of leaving white patches on a dark page. */
    --cc-topbar-bg: rgba(255, 255, 255, 0.85);
    --cc-topbar-text: var(--cc-text-secondary);
    --cc-topbar-strong: var(--cc-text);
    --cc-neutral-bg: var(--cc-surface);
    --cc-neutral-hover-bg: var(--cc-surface-muted);
    --cc-neutral-border: #cad5e2;   /* slate-300 — secondary button border */
    --cc-input-bg: var(--cc-surface);
    --cc-input-border: var(--cc-border-control);
    --cc-input-placeholder: #62748e;
    --cc-label: var(--cc-text-secondary);
    --cc-table-head-bg: var(--cc-surface-muted);
    --cc-table-hover-bg: var(--cc-surface-muted);
    --cc-table-divider: var(--cc-border);
    --cc-code: #a01a5e;

    /* ── Type scale (T-3): size / line-height pairs in rem on a 16px root ─── */
    --cc-font-meta: 0.75rem;        --cc-lh-meta: 1rem;         /* 12/16 dates, helpers, chips, column headings */
    --cc-font-body: 0.875rem;       --cc-lh-body: 1.25rem;      /* 14/20 body, table data, labels, actions */
    --cc-font-body-lg: 1rem;        --cc-lh-body-lg: 1.5rem;    /* 16/24 compact card headings, mobile fields */
    --cc-font-section: 1.125rem;    --cc-lh-section: 1.5rem;    /* 18/24 section headings */
    --cc-font-page: 1.25rem;        --cc-lh-page: 1.75rem;      /* 20/28 page title */
    --cc-font-metric: 1.5rem;       --cc-lh-metric: 2rem;       /* 24/32 KPI values */

    /* ── Radius / elevation (T-5) ─────────────────────────────────────────── */
    --cc-radius: 12px;              /* card / dialog */
    --cc-radius-sm: 8px;            /* control / tab container */
    --cc-radius-xs: 4px;            /* checkbox / small inset */
    --cc-radius-lg: 16px;           /* auth container */
    --cc-shadow: none;              /* ordinary workspace cards: border only */
    --cc-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
    --cc-shadow-lg: 0 8px 24px rgba(15, 23, 42, 0.16);   /* overlays only */

    /* ── BlazorMHD.UI token bridge ──────────────────────────────────────────
       mhd-theme.css re-points the library's Tailwind palette vars at these
       --mhd-* tokens, so setting them here re-brands every Mhd* component
       (buttons, tags, dialogs, focus rings…) to the same roles. */
    --mhd-color-primary: var(--cc-primary);
    --mhd-color-primary-hover: var(--cc-primary-hover);
    --mhd-color-primary-pressed: var(--cc-primary-pressed);
    --mhd-color-on-primary: var(--cc-on-primary);
    --mhd-color-primary-subtle: var(--cc-primary-soft);
    --mhd-color-on-danger: var(--cc-on-danger);
    --mhd-color-danger-pressed: var(--cc-danger-pressed);
    --mhd-focus-ring: var(--cc-focus);
    --mhd-color-success: #007a55;   /* emerald-700 — white text 4.8:1 */
    --mhd-color-success-hover: #006045;
    --mhd-color-danger: var(--cc-danger);
    --mhd-color-danger-hover: var(--cc-danger-hover);
    --mhd-color-info: #0069a8;      /* sky-700 */
    --mhd-color-info-hover: #00598a;
    --mhd-radius-sm: 0.25rem;
    --mhd-radius-md: 0.5rem;
    --mhd-radius-lg: 0.5rem;
    --mhd-radius-xl: 0.75rem;
    --mhd-surface: var(--cc-surface);
    --mhd-surface-muted: var(--cc-surface-muted);
    --mhd-surface-raised: var(--cc-surface-raised);
    --mhd-border: var(--cc-border);
    --mhd-text: var(--cc-text);
    --mhd-text-muted: var(--cc-muted);
    --mhd-overlay-scrim: var(--cc-overlay);
    --mhd-tone-success-fg: var(--cc-tone-success-fg);  --mhd-tone-success-bg: var(--cc-tone-success-bg);
    --mhd-tone-warning-fg: var(--cc-tone-warning-fg);  --mhd-tone-warning-bg: var(--cc-tone-warning-bg);
    --mhd-tone-danger-fg:  var(--cc-tone-danger-fg);   --mhd-tone-danger-bg:  var(--cc-tone-danger-bg);
    --mhd-tone-info-fg:    var(--cc-tone-info-fg);     --mhd-tone-info-bg:    var(--cc-tone-info-bg);
    --mhd-tone-neutral-fg: var(--cc-tone-neutral-fg);  --mhd-tone-neutral-bg: var(--cc-tone-neutral-bg);
    --mhd-font-sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* Root stays 16px (T-3): Bootstrap's `.small`, `em` badges and nested headings multiplied a 15px
   root into 25 fractional sizes (12.9px, 13.125px, 11.48px…). Body text is the 14/20 workspace role. */
html {
    font-size: 16px;
}

body {
    font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
    background-color: var(--cc-bg);
    color: var(--cc-text);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
}

/* Bootstrap's `.small`/`small` is `.875em` — an em that compounds inside every nested `.small`.
   It is the metadata role, so it is rem-based and never multiplies. */
small, .small {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
}

/* `.small` on prose, table data and form labels was only ever "a bit smaller than 15px"; those
   are body roles (T-3: never metadata as the sole size for labels or table data). Secondary
   lines in a <div>/<span> keep the metadata size. */
p.small, td.small, th.small, label.small, li.small {
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
}

/* Bootstrap's responsive font-size utilities and headings use calc(rem + vw) below 1200px, which
   yields fractional pixels on every laptop. Pin them to the scale: fs-3/fs-4 are the KPI metric,
   fs-5 the page title, h5/h6 section headings. */
.fs-3, .fs-4 { font-size: var(--cc-font-metric) !important; line-height: var(--cc-lh-metric); }
.fs-5 { font-size: var(--cc-font-page) !important; line-height: var(--cc-lh-page); }
.fs-6 { font-size: var(--cc-font-body-lg) !important; line-height: var(--cc-lh-body-lg); }
h3, .h3 { font-size: var(--cc-font-section); line-height: var(--cc-lh-section); font-weight: 600; }
h4, .h4 { font-size: var(--cc-font-body-lg); line-height: var(--cc-lh-body-lg); font-weight: 600; }
h5, .h5 { font-size: var(--cc-font-body-lg); line-height: var(--cc-lh-body-lg); font-weight: 600; }
h6, .h6 { font-size: var(--cc-font-body); line-height: var(--cc-lh-body); font-weight: 600; }

/* Weights are 400 / 500 / 600 / 700 only. */
.fw-semibold { font-weight: 600 !important; }
.fw-bold { font-weight: 700 !important; }
.fw-medium { font-weight: 500 !important; }

/* Keyboard focus (T-6): 2px solid ring, 2px offset, on every interactive element; a Highlight
   outline survives forced-colours mode so focus never depends on a box-shadow alone. */
:focus-visible {
    outline: 2px solid var(--cc-focus);
    outline-offset: 2px;
}

@media (forced-colors: active) {
    :focus-visible {
        outline-color: Highlight;
    }
}

/* Reduced motion (WCAG 2.3.3). Nothing here animates to convey meaning — the movement is hover
   feedback, the button spinner and a few fades — so an operator who asks the OS for stillness gets
   it, everywhere, including inside BlazorMHD components this file cannot enumerate.
   Near-zero durations rather than `none`: `animation: none` never fires animationend, and script
   (the library's dialogs, the reconnect overlay) can wait on that event forever. */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

kbd {
    font-size: var(--cc-font-meta);
    border-radius: var(--cc-radius-xs);
}

/* ---------------------------------------------------------------------------
   Typography — page titles and section headings shared by all pages.
   ------------------------------------------------------------------------- */

/* Content-first AND consistent: every page title is the same size and leaves the
   SAME gap below it — whether the title stands alone or shares its row with an
   action button (.page-header). This removes the old per-page mb-2/mb-3/none mix. */
h1, h1.h3 {
    font-size: var(--cc-font-page);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--cc-text);
    margin: 0 0 0.5rem;
    line-height: var(--cc-lh-page);
    min-width: 0;
    overflow-wrap: anywhere;
}

h1:focus {
    outline: none;
}

/* Title row that shares its line with an action (button/link) on the right.
   Use this instead of ad-hoc `d-flex … mb-2/mb-3` so the header gap is uniform. */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.page-header h1 {
    margin-bottom: 0;
}

/* Lead paragraph/subtitle directly under a page title — tight to the title, then
   the same gap to the content below on every page. */
h1 + p, h1 + .text-muted, .page-header + p, .page-header + .text-muted {
    margin-top: -0.25rem;
    margin-bottom: 1rem;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
}

h2.h5, h2 {
    font-size: var(--cc-font-body-lg);
    line-height: var(--cc-lh-body-lg);
    font-weight: 600;
    color: var(--cc-text);
    margin-top: 0.25rem;
    margin-bottom: 0.5rem;
}

.text-muted {
    color: var(--cc-muted) !important;
}

/* ---------------------------------------------------------------------------
   Content area — comfortable padding, capped line length on huge monitors.
   ------------------------------------------------------------------------- */

/* The cap used to live here as max-width: 1500px on the whole content area. With no auto margin the
   block stayed hard left, so every viewport wider than the sidebar + 1500 px piled the remainder into
   one empty band down the right-hand side — and .top-row, which has no cap, ran past the content edge,
   which is what made the gap read as a mistake rather than as margin. Centring it would have kept the
   same wasted width, just split in two. This console is table-heavy (Organizations alone is ten
   columns), so the width is worth using; only running prose actually needs a measure, and it gets one
   below rather than the whole page paying for it. */
.content {
    padding-top: 1rem;
    padding-bottom: 2rem;
}

/* Intro and explanatory paragraphs keep a readable measure instead of stretching into a single
   2500 px line on an ultrawide monitor. Tables, cards and grids are free to use the full width. */
.content > p {
    max-width: 80ch;
}

/* A Bootstrap .table is width: 100%, so in a full-width content area it shares its slack out across
   every column in proportion — which made a column of ten-character dates as wide as the name beside
   it. Here the slack is CLAIMED by the one column that can use it rather than refused by the nine that
   cannot: width: 100% on a cell in an auto-layout table means "take whatever is left over", which drops
   every other column to its own content width. (Marking the others 1% instead leaves the distribution
   to the browser's judgement, and across ten columns it kept handing width to a date or a single digit.)

   Opt in per table, then mark the column(s) worth widening with .col-flex on their th AND td. Two
   flexible columns simply share the slack between them. Selectors are qualified with .table so they
   outrank the .table > thead th block further down regardless of source order. */
.table.table-fit-cols th.col-flex,
.table.table-fit-cols td.col-flex {
    width: 100%;
    white-space: normal;
}

/* Every other data cell keeps its single line: a date or a tag breaking in two is exactly what the
   fit is for. Prose lives in a .col-flex column, which is excluded here and wraps freely. */
.table.table-fit-cols > tbody td:not(.col-flex) {
    white-space: nowrap;
}

/* The floor a column cannot shrink past is its widest unbreakable box — and for these columns that is
   the HEADER, not the data. Letting a multi-word label stack puts the data back in charge of the width;
   bottom alignment keeps one- and two-line labels on the same baseline. */
.table.table-fit-cols > thead th {
    white-space: normal;
    vertical-align: bottom;
}

/* Sortable headers wrap with the label they sit in rather than forcing it back onto one line. */
.table.table-fit-cols > thead th .btn {
    white-space: normal;
    text-align: left;
}

/* The page title now lives in the top bar, so the first content element sits
   directly under it — don't let a leading paragraph/heading add its own top gap. */
.content > :first-child {
    margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Links & buttons (C-1 … C-3).
   ------------------------------------------------------------------------- */

a, .btn-link {
    color: var(--cc-link);
    text-decoration: none;
}

a:hover, .btn-link:hover {
    color: var(--cc-link-hover);
}

/* Inline links inside running text must be distinguishable without colour (axe
   link-in-text-block): underline them. Standalone links in nav/tables/cards keep the clean look. */
p a, li a, .alert a, .mhd-alert a, td a, .text-muted a {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* Bootstrap .btn is the host-side expression of the shared button contract: 14/20 semibold,
   8px radius, four variants (primary / secondary = outline-secondary / ghost = link / danger),
   three sizes — 32px (.btn-sm) · 36px (default) · 44px (.btn-lg). Heights are minimums, labels wrap. */
.btn {
    --bs-btn-font-size: var(--cc-font-body);
    --bs-btn-line-height: var(--cc-lh-body);
    --bs-btn-font-weight: 600;
    --bs-btn-border-radius: var(--cc-radius-sm);
    --bs-btn-padding-y: 0.4375rem;   /* 7px + 20px line + 2×1px border = 36px */
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-focus-box-shadow: none;
    --bs-btn-disabled-opacity: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 2.25rem;
    box-shadow: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.btn-sm {
    --bs-btn-font-size: var(--cc-font-body);
    --bs-btn-border-radius: var(--cc-radius-sm);
    --bs-btn-padding-y: 0.3125rem;   /* 5px → 32px */
    --bs-btn-padding-x: 0.5rem;
    min-height: 2rem;
}

.btn-lg {
    --bs-btn-font-size: var(--cc-font-body);
    --bs-btn-border-radius: var(--cc-radius-sm);
    --bs-btn-padding-y: 0.6875rem;   /* 11px → 44px */
    --bs-btn-padding-x: 1rem;
    min-height: 2.75rem;
}

.btn-primary {
    --bs-btn-color: var(--cc-on-primary);
    --bs-btn-bg: var(--cc-primary);
    --bs-btn-border-color: var(--cc-primary);
    --bs-btn-hover-color: var(--cc-on-primary);
    --bs-btn-hover-bg: var(--cc-primary-hover);
    --bs-btn-hover-border-color: var(--cc-primary-hover);
    --bs-btn-active-color: var(--cc-on-primary);
    --bs-btn-active-bg: var(--cc-primary-pressed);
    --bs-btn-active-border-color: var(--cc-primary-pressed);
    --bs-btn-disabled-color: var(--cc-disabled-text);
    --bs-btn-disabled-bg: var(--cc-disabled-bg);
    --bs-btn-disabled-border-color: var(--cc-disabled-bg);
}

.btn-danger {
    --bs-btn-color: var(--cc-on-danger);
    --bs-btn-bg: var(--cc-danger);
    --bs-btn-border-color: var(--cc-danger);
    --bs-btn-hover-color: var(--cc-on-danger);
    --bs-btn-hover-bg: var(--cc-danger-hover);
    --bs-btn-hover-border-color: var(--cc-danger-hover);
    --bs-btn-active-color: var(--cc-on-danger);
    --bs-btn-active-bg: var(--cc-danger-pressed);
    --bs-btn-active-border-color: var(--cc-danger-pressed);
    --bs-btn-disabled-color: var(--cc-disabled-text);
    --bs-btn-disabled-bg: var(--cc-disabled-bg);
    --bs-btn-disabled-border-color: var(--cc-disabled-bg);
}

/* Secondary: surface, secondary text, control border. */
.btn-outline-secondary, .btn-secondary, .btn-light, .btn-outline-primary {
    --bs-btn-color: var(--cc-text-secondary);
    --bs-btn-bg: var(--cc-neutral-bg);
    --bs-btn-border-color: var(--cc-neutral-border);
    --bs-btn-hover-color: var(--cc-text);
    --bs-btn-hover-bg: var(--cc-neutral-hover-bg);
    --bs-btn-hover-border-color: var(--cc-border-control);
    --bs-btn-active-color: var(--cc-text);
    --bs-btn-active-bg: var(--cc-neutral-hover-bg);
    --bs-btn-active-border-color: var(--cc-border-control);
    --bs-btn-disabled-color: var(--cc-disabled-text);
    --bs-btn-disabled-bg: var(--cc-disabled-bg);
    --bs-btn-disabled-border-color: var(--cc-border);
}

/* Outline-primary keeps its indigo text so an existing "secondary but branded" action still reads
   as such; the geometry and hover follow the secondary contract. */
.btn-outline-primary {
    --bs-btn-color: var(--cc-link);
    --bs-btn-hover-color: var(--cc-link-hover);
    --bs-btn-active-color: var(--cc-link-hover);
}

/* Ghost: transparent, secondary text, subtle hover. Bootstrap's .btn-link is the nearest host class. */
.btn-link {
    --bs-btn-color: var(--cc-text-secondary);
    --bs-btn-hover-color: var(--cc-text);
    --bs-btn-hover-bg: var(--cc-neutral-hover-bg);
    --bs-btn-active-bg: var(--cc-neutral-hover-bg);
    --bs-btn-active-color: var(--cc-text);
    --bs-btn-disabled-color: var(--cc-disabled-text);
    --bs-btn-font-weight: 600;
    text-decoration: none;
}

.btn-outline-danger {
    --bs-btn-color: var(--cc-tone-danger-fg);
    --bs-btn-bg: var(--cc-neutral-bg);
    --bs-btn-border-color: var(--cc-neutral-border);
    --bs-btn-hover-color: var(--cc-on-danger);
    --bs-btn-hover-bg: var(--cc-danger);
    --bs-btn-hover-border-color: var(--cc-danger);
    --bs-btn-active-color: var(--cc-on-danger);
    --bs-btn-active-bg: var(--cc-danger-pressed);
    --bs-btn-active-border-color: var(--cc-danger-pressed);
}

/* Bootstrap's focus ring is a box-shadow; the shared contract is the 2px outline above. */
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-check-input:focus {
    box-shadow: none;
}

.btn-close:focus {
    box-shadow: none;
}

/* ---------------------------------------------------------------------------
   Cards (C-9) — 12px radius, 1px decorative border, 16px padding, no lift.
   Stat tiles on the dashboard and detail panels everywhere pick this up automatically.
   ------------------------------------------------------------------------- */

.card {
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius);
    box-shadow: var(--cc-shadow);
    background-color: var(--cc-surface);
}

.card-body {
    padding: 1rem;
}

.card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--cc-border);
    font-weight: 600;
    padding: 0.75rem 1rem;
}

.card-title, .card-header {
    font-size: var(--cc-font-body-lg);
    line-height: var(--cc-lh-body-lg);
}

/* ---------------------------------------------------------------------------
   Tables (C-11) — every list page renders a bare <table class="table">; give it a
   card-like surface (rounded, bordered, white) without extra markup.
   Header 12/16 semibold on the subtle surface, min 36px; body 14/20; rows min 40px;
   cells vertically centred; numbers tabular.
   ------------------------------------------------------------------------- */

.table {
    --bs-table-bg: var(--cc-surface);
    --bs-table-hover-bg: var(--cc-table-hover-bg);
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius);
    box-shadow: var(--cc-shadow);
    overflow: hidden;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    margin-bottom: 1rem;
    font-variant-numeric: tabular-nums;
}

.table > thead th {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    font-weight: 600;
    /* Sentence case (C-11): uppercase + tracking made every header wider than its data and read
       as shouting next to the sentence-case labels the rest of the console uses. */
    color: var(--cc-muted);
    background-color: var(--cc-table-head-bg);
    border-bottom: 1px solid var(--cc-border);
    padding: 0.625rem 0.75rem;   /* 10 + 16 + 10 = 36px */
    white-space: nowrap;
    vertical-align: middle;
}

.table > tbody td {
    padding: 0.625rem 0.75rem;   /* 10 + 20 + 10 = 40px */
    border-bottom: 1px solid var(--cc-table-divider);
    color: var(--cc-text);
    vertical-align: middle;
}

.table > tbody tr:last-child td {
    border-bottom: none;
}

.table.table-sm > thead th,
.table.table-sm > tbody td {
    padding: 0.5rem 0.75rem;
}

/* Rounded corners on the actual corner cells (overflow:hidden alone is not
   reliable for table elements in all browsers). */
.table > thead tr:first-child th:first-child { border-top-left-radius: calc(var(--cc-radius) - 1px); }
.table > thead tr:first-child th:last-child  { border-top-right-radius: calc(var(--cc-radius) - 1px); }
.table > tbody tr:last-child td:first-child  { border-bottom-left-radius: calc(var(--cc-radius) - 1px); }
.table > tbody tr:last-child td:last-child   { border-bottom-right-radius: calc(var(--cc-radius) - 1px); }

/* ---------------------------------------------------------------------------
   Badges (C-8) — 12/16 semibold pills, 24px minimum, five tones.
   ------------------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    font-weight: 600;
    letter-spacing: 0;
    padding: 0.25rem 0.5rem;   /* 4 + 16 + 4 = 24px */
    border-radius: 9999px;
}

.badge.text-bg-success   { color: var(--cc-tone-success-fg) !important; background-color: var(--cc-tone-success-bg) !important; }
.badge.text-bg-danger    { color: var(--cc-tone-danger-fg) !important;  background-color: var(--cc-tone-danger-bg) !important; }
.badge.text-bg-warning   { color: var(--cc-tone-warning-fg) !important; background-color: var(--cc-tone-warning-bg) !important; }
.badge.text-bg-info      { color: var(--cc-tone-info-fg) !important;    background-color: var(--cc-tone-info-bg) !important; }
.badge.text-bg-secondary,
.badge.text-bg-light,
.badge.text-bg-primary,
.badge.text-bg-dark      { color: var(--cc-tone-neutral-fg) !important; background-color: var(--cc-tone-neutral-bg) !important; }

/* ---------------------------------------------------------------------------
   Tabs (C-14) — one underline strip: 14/20, 36px minimum, 2px selected indicator.
   ------------------------------------------------------------------------- */

.nav-tabs {
    border-bottom: 1px solid var(--cc-border);
    gap: 0.25rem;
}

/* One scrolling row (C-14): the row never wraps into a grid; the thin scrollbar and the fade at
   the trailing edge are the affordance that more tabs exist. Wrap a .nav-tabs in .tab-scroll. */
.tab-scroll {
    overflow-x: auto;
    scrollbar-width: thin;
    scroll-snap-type: x proximity;
    mask-image: linear-gradient(to right, black calc(100% - 2rem), transparent);
    padding-inline-end: 2rem;
}

.tab-scroll .nav-tabs {
    flex-wrap: nowrap;
    min-width: max-content;
}

.tab-scroll .nav-item {
    scroll-snap-align: start;
}

.nav-tabs .nav-link {
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--cc-muted);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 500;
    padding: 0.5rem 0.75rem;
    margin-bottom: -1px;
    white-space: nowrap;
    min-height: 2.25rem;
}

.nav-tabs .nav-link:hover {
    color: var(--cc-text);
    border-bottom-color: var(--cc-neutral-border);
}

.nav-tabs .nav-link.active {
    color: var(--cc-link);
    background-color: transparent;
    border-bottom-color: var(--cc-primary);
    font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Forms (C-4 … C-7) — 36px controls (32px .form-control-sm), 8px radius,
   essential control border, 14/20 text, labels 14/20 medium.
   ------------------------------------------------------------------------- */

.form-control, .form-select {
    border-radius: var(--cc-radius-sm);
    border-color: var(--cc-input-border);
    background-color: var(--cc-input-bg);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    padding: 0.4375rem 0.75rem;   /* 7 + 20 + 7 + 2 = 36px */
    min-height: 2.25rem;
    color: var(--cc-text);
}

.form-control-sm, .form-select-sm {
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    padding: 0.3125rem 0.5rem;     /* 5 + 20 + 5 + 2 = 32px */
    min-height: 2rem;
    border-radius: var(--cc-radius-sm);
}

/* Keep room for the dropdown chevron Bootstrap paints on the right. */
.form-select {
    padding-right: 2.25rem;
}

.form-control::placeholder {
    color: var(--cc-input-placeholder);
}

.form-control:hover:not(:disabled):not([readonly]), .form-select:hover:not(:disabled) {
    border-color: var(--cc-text-secondary);
}

.form-control:focus, .form-select:focus {
    border-color: var(--cc-primary);
    box-shadow: 0 0 0 0.2rem var(--cc-primary-ring);
    outline: none;
}

.form-control:disabled, .form-control[readonly], .form-select:disabled {
    background-color: var(--cc-disabled-bg);
    color: var(--cc-disabled-text);
    border-color: var(--cc-border);
}

.form-label {
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 500;
    color: var(--cc-label);
    margin-bottom: 0.25rem;
}

.form-text {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    color: var(--cc-muted);
}

.form-check-input {
    width: 1.125rem;
    height: 1.125rem;
    margin-top: 0.0625rem;
    border-color: var(--cc-border-control);
    border-radius: var(--cc-radius-xs);
}

.form-check-input:checked {
    background-color: var(--cc-primary);
    border-color: var(--cc-primary);
}

.form-check-input:focus {
    border-color: var(--cc-primary);
}

.form-switch .form-check-input {
    width: 2.25rem;
    height: 1.25rem;
    border-radius: 9999px;
}

/* ---------------------------------------------------------------------------
   Alerts (C-15) — five tones, 8px radius, 3px start accent, 12/16px padding.
   ------------------------------------------------------------------------- */

.alert {
    border-radius: var(--cc-radius-sm);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    border-width: 1px;
    border-inline-start-width: 3px;
    padding: 0.75rem 1rem;
}

.alert.py-2 {
    padding-top: 0.75rem !important;
    padding-bottom: 0.75rem !important;
}

.alert-warning   { color: var(--cc-tone-warning-fg); background-color: var(--cc-tone-warning-bg); border-color: var(--cc-tone-warning-fg); }
.alert-danger    { color: var(--cc-tone-danger-fg);  background-color: var(--cc-tone-danger-bg);  border-color: var(--cc-tone-danger-fg); }
.alert-success   { color: var(--cc-tone-success-fg); background-color: var(--cc-tone-success-bg); border-color: var(--cc-tone-success-fg); }
.alert-info      { color: var(--cc-tone-info-fg);    background-color: var(--cc-tone-info-bg);    border-color: var(--cc-tone-info-fg); }
.alert-secondary { color: var(--cc-text);            background-color: var(--cc-surface-muted);   border-color: var(--cc-border-control); }

/* Only the start edge carries the tone; the other three edges stay decorative. */
.alert-warning, .alert-danger, .alert-success, .alert-info, .alert-secondary {
    border-top-color: var(--cc-border);
    border-bottom-color: var(--cc-border);
    border-inline-end-color: var(--cc-border);
}

.alert a {
    color: inherit;
}

/* ---------------------------------------------------------------------------
   Modals & pagination (confirm dialogs, log pagers).
   ------------------------------------------------------------------------- */

.modal-content {
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius);
    box-shadow: var(--cc-shadow-lg);
    background-color: var(--cc-surface-raised);
}

.pagination .page-link {
    color: var(--cc-link);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    min-height: 2.25rem;
    min-width: 2.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-color: var(--cc-border);
}

.pagination .page-item.active .page-link {
    background-color: var(--cc-primary);
    border-color: var(--cc-primary);
    color: var(--cc-on-primary);
}

/* ---------------------------------------------------------------------------
   Validation + framework chrome (unchanged behaviors, refreshed colors).
   ------------------------------------------------------------------------- */

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--cc-tone-success-fg);
}

.invalid {
    outline: 1px solid var(--cc-tone-danger-fg);
}

.validation-message {
    color: var(--cc-tone-danger-fg);
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
    border-radius: var(--cc-radius-sm);
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.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;
}

/* ---------------------------------------------------------------------------
   Auth pages (login + forgot password) — centered card on a soft indigo-tinted
   backdrop, rendered inside EmptyLayout. Shared by both pages, hence global.
   ------------------------------------------------------------------------- */

.auth-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background:
        radial-gradient(1100px 560px at 100% -10%, rgba(97, 95, 255, 0.12), transparent 60%),
        radial-gradient(880px 480px at -10% 110%, rgba(79, 57, 246, 0.09), transparent 55%),
        var(--cc-bg);
}

.auth-card {
    width: 100%;
    max-width: 24rem;
    background: var(--cc-surface);
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius-lg);
    box-shadow: var(--cc-shadow-lg);
    padding: 2rem 1.75rem;
}

.auth-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
    text-align: center;
}

.auth-mark {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--cc-radius);
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--cc-primary), #615fff);
    color: #fff;
    font-weight: 700;
    font-size: var(--cc-font-page);
    letter-spacing: -0.03em;
    box-shadow: 0 8px 22px rgba(79, 57, 246, 0.35);
}

.auth-title {
    font-size: var(--cc-font-page);
    font-weight: 600;
    color: var(--cc-text);
    margin: 0;
    line-height: var(--cc-lh-page);
}

.auth-sub {
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    color: var(--cc-muted);
    margin: 0.125rem 0 0;
}

.auth-field {
    margin-bottom: 1rem;
}

.auth-field .form-label {
    display: block;
}

/* Password input + inline reveal button. */
.pw-field {
    position: relative;
}

.pw-field .form-control {
    padding-right: 2.75rem;
}

.pw-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--cc-muted);
    cursor: pointer;
    border-radius: 0 var(--cc-radius-sm) var(--cc-radius-sm) 0;
}

.pw-toggle:hover {
    color: var(--cc-primary);
}

.pw-toggle:focus-visible {
    outline: 2px solid var(--cc-focus);
    outline-offset: -2px;
}

/* Two icons; show the "eye" by default, swap to "eye-off" when revealed. */
.pw-toggle .icon-on {
    display: inline-flex;
}

.pw-toggle .icon-off {
    display: none;
}

.pw-toggle.revealed .icon-on {
    display: none;
}

.pw-toggle.revealed .icon-off {
    display: inline-flex;
}

.auth-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
}

.auth-link {
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 500;
    color: var(--cc-link);
    text-decoration: none;
}

.auth-link:hover {
    color: var(--cc-link-hover);
    text-decoration: underline;
}

.btn-auth {
    width: 100%;
    border: none;
    border-radius: var(--cc-radius-sm);
    background: var(--cc-primary);
    color: var(--cc-on-primary);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 600;
    min-height: 2.75rem;
    padding: 0.75rem 1rem;
    cursor: pointer;
    transition: background-color 120ms ease;
}

.btn-auth:hover {
    background: var(--cc-primary-hover);
}

.btn-auth:active {
    background: var(--cc-primary-pressed);
}

.btn-auth:focus-visible {
    outline: 2px solid var(--cc-focus);
    outline-offset: 2px;
}

.auth-error {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    background: var(--cc-tone-danger-bg);
    border: 1px solid var(--cc-border);
    border-inline-start: 3px solid var(--cc-tone-danger-fg);
    color: var(--cc-tone-danger-fg);
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    border-radius: var(--cc-radius-sm);
    padding: 0.75rem;
    margin-bottom: 1rem;
}

.auth-note {
    font-size: var(--cc-font-body);
    color: var(--cc-text);
    line-height: var(--cc-lh-body);
}

.auth-note code {
    background: var(--cc-surface-muted);
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius-xs);
    padding: 0.05rem 0.35rem;
    font-size: var(--cc-font-meta);
    color: var(--cc-text);
}

.field-error {
    color: var(--cc-tone-danger-fg);
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    margin-top: 0.25rem;
}

/* Inline checkbox row on the auth card (e.g. the 2FA "recovery code" toggle). */
.auth-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    color: var(--cc-text);
    margin-bottom: 1rem;
    cursor: pointer;
    min-height: 2rem;
}

.auth-check .form-check-input {
    margin: 0;
    cursor: pointer;
}

/* Shared width for the search/filter inputs on the InvoiceCraft app-detail pages
   (a `form-control-sm w-auto` box, previously an inline min-width on each page).
   Search flexes from 240px (C-12); `-wide` is for the GUID company-id filters. */
.ic-filter {
    min-width: 240px;
}

.ic-filter-wide {
    min-width: 280px;
}

/* ===========================================================================
   BlazorMHD.UI component host CSS.
   The library carries the tag contract itself (5.1.x: 12/16 semibold, 24px, the five
   tones from the --mhd-tone-* roles bridged above), so a MhdTag and a .badge that
   report the same state read as the same state with no host copy. The status dot
   and card rules below remain host-side because the console's card is the Bootstrap
   .card. Scoped to .mhd-scope (the app shell wrapper) exactly like the library's own
   utilities.
   =========================================================================== */

/* MhdStatusDot — dot + label. */
.mhd-scope .mhd-status-root {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 500;
    color: var(--cc-text);
}

.mhd-scope .mhd-status-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    flex-shrink: 0;
}

.mhd-scope .mhd-status-dot-success { background-color: var(--cc-tone-success-fg); box-shadow: 0 0 0 3px var(--cc-tone-success-bg); }
.mhd-scope .mhd-status-dot-danger  { background-color: var(--cc-tone-danger-fg);  box-shadow: 0 0 0 3px var(--cc-tone-danger-bg); }
.mhd-scope .mhd-status-dot-warning { background-color: var(--cc-tone-warning-fg); box-shadow: 0 0 0 3px var(--cc-tone-warning-bg); }
.mhd-scope .mhd-status-dot-info    { background-color: var(--cc-tone-info-fg);    box-shadow: 0 0 0 3px var(--cc-tone-info-bg); }
.mhd-scope .mhd-status-dot-primary { background-color: var(--cc-primary);         box-shadow: 0 0 0 3px var(--cc-primary-soft); }
.mhd-scope .mhd-status-dot-neutral { background-color: var(--cc-tone-neutral-fg); box-shadow: 0 0 0 3px var(--cc-tone-neutral-bg); }

.mhd-scope .mhd-status-text { color: inherit; }

/* MhdCard is styled by the library (5.1.x card contract: 12px radius, 1px border, 16px padding, no
   lift) from the --mhd-surface / --mhd-border / --mhd-text roles bridged above, so it looks like the
   Bootstrap .card below without a host copy. */

/* Settings/detail forms that read better constrained rather than full-width. */
.mhd-scope .card-narrow { max-width: 640px; }

/* A flush body (padding:0) for cards whose content is a table meant to reach the card edges —
   the Bootstrap equivalent was `card-body p-0`. Targets only the body pad div, never the
   title/header/footer (which share the mhd-card-pad-regular class). */
.mhd-scope .card-flush-body > .mhd-card-pad-regular:not(.mhd-card-title):not(.mhd-card-header):not(.mhd-card-footer) {
    padding: 0;
}

/* Bootstrap's reboot ships an un-layered `button { border-radius: 0 }`, which
   outranks BlazorMHD's `@layer utilities` .rounded-* classes (layered CSS always
   loses to un-layered CSS). The result: every MhdButton (a <button> styled only by
   Tailwind utilities) renders with square corners, unlike our <a class="btn">
   links. Re-assert the library radii for buttons inside the app shell — un-layered
   and specific enough to beat the reboot rule. All control radii are 8px (T-5). */
.mhd-scope button.rounded-lg   { border-radius: var(--cc-radius-sm); }
.mhd-scope button.rounded-md   { border-radius: var(--cc-radius-sm); }
.mhd-scope button.rounded-full { border-radius: 9999px; }

/* Since 5.1.0 MhdButton renders `.mhd-btn` (rounded-lg inside @layer components) with no
   rounded-* utility, so the rule above no longer reached it and every MhdButton in the console
   was square. Re-assert the shared button geometry on the component class itself: 8px radius,
   14/20 semibold, 32 / 36 / 44px minimum heights (C-1). */
.mhd-scope .mhd-btn {
    border-radius: var(--cc-radius-sm);
}

/* MhdButton spinner (only shown when IsLoading) — give it a spin. */
.mhd-scope .mhd-btn-spinner { animation: cc-spin 0.7s linear infinite; }

@keyframes cc-spin {
    to { transform: rotate(360deg); }
}

/* WCAG 1.4.3 (AA): Bootstrap's default inline-code pink (#d63384) reaches only ~4.3:1 on the page
   background, so inline <code> in prose (e.g. plan keys on /plans) failed the contrast check.
   #a01a5e keeps the same hue family at 6.2:1 on white and 5.9:1 on --cc-bg. */
:root {
    --bs-code-color: var(--cc-code);
}

code {
    color: var(--bs-code-color);
    font-size: var(--cc-font-meta);
}

/* Bootstrap's .bg-light is a fixed #f8f9fa and sets no foreground, so the seven <pre> blocks that
   carry it — stack traces on /applications/invoicecraft/errors and /logs, the last delivery error
   on /email-logs and /stripe-webhooks, the before/after values in the audit log — painted a WHITE
   card and then let the text inherit --cc-text. In dark mode that is 1.04:1: the operator opens
   the exception detail and the exception is not there. It is a muted SURFACE now, which is what it
   was always being used as, and it carries its own ink in both themes. */
.bg-light {
    background-color: var(--cc-surface-muted) !important;
    color: var(--cc-text);
}

/* Those blocks hold an exception, a JSON property bag or a serialised column value — all of which
   arrive as one long line. Without this they widen the page instead of wrapping (the same reflow
   problem the tables had), and a stack trace is unreadable sideways anyway. */
pre {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* A <button> that must read as a link (used inside a POST form where an <a> would be wrong —
   e.g. "Sign in as someone else" on the access-denied page). */
.auth-linkbutton {
    border: none;
    background: none;
    padding: 0;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    font-weight: 500;
    color: var(--cc-link);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.auth-linkbutton:hover {
    color: var(--cc-link-hover);
}

.auth-linkbutton:focus-visible {
    outline: 2px solid var(--cc-focus);
    outline-offset: 2px;
}

/* ===========================================================================
   DARK THEME
   ===========================================================================
   Activated by `data-theme="dark"` on <html>, which wwwroot/theme.js sets BEFORE
   first paint (a render-blocking <head> script — inline script is forbidden by the
   CSP's `script-src 'self'`, so it is a real file). theme.js also adds the `dark`
   class, which is what BlazorMHD.UI's own dark variants (`&:is(.dark *)`) key off,
   so dialogs, tags and buttons from the library switch with the app.

   Precedence: `:root[data-theme="dark"]` (0,2,0) beats the plain `:root` (0,1,0)
   block at the top of this file regardless of source order.

   The dark values are the same slate/indigo palette entries InvoiceCraft's dark
   mode renders, so the two apps share one dark canvas. CONTRAST — every pair was
   MEASURED (WCAG 2.1 relative luminance): body text 17:1 · muted text 6.8:1 on a
   card, 5.6:1 on the subtle surface · links 10:1 · the dark on-primary text on the
   light indigo fill 5.7:1 (hover 8.9:1, pressed 4.7:1) · every tone pair ≥ 8.2:1.
   ========================================================================== */

:root[data-theme="dark"] {
    color-scheme: dark;

    --cc-bg: #020618;               /* slate-950 */
    --cc-surface: #0f172b;          /* slate-900 */
    --cc-surface-muted: #1d293d;    /* slate-800 */
    --cc-surface-raised: #0f172b;
    --cc-border: #1d293d;
    --cc-border-control: #62748e;
    --cc-text: #f1f5f9;             /* slate-100 */
    --cc-text-secondary: #cad5e2;   /* slate-300 */
    --cc-muted: #90a1b9;            /* slate-400 */

    /* D-B: the dark primary is a LIGHT indigo fill with DARK text — never white on pale indigo. */
    --cc-primary: #7c86ff;          /* indigo-400 */
    --cc-primary-hover: #a3b3ff;    /* indigo-300 */
    --cc-primary-pressed: #6e73ff;  /* indigo-400/500 midpoint */
    --cc-primary-soft: #1e1a4d;     /* indigo-950 */
    --cc-on-primary: #0f172b;
    --cc-primary-ring: rgba(124, 134, 255, 0.4);
    --cc-focus: #7c86ff;

    --cc-link: #a3b3ff;             /* indigo-300 — 10:1 on the canvas */
    --cc-link-hover: #c6d2ff;

    --cc-danger: #ffa1ad;           /* rose-300 fill, rose-950 text 8.2:1 */
    --cc-danger-hover: #ffccd3;
    --cc-danger-pressed: #ff637e;
    --cc-on-danger: #4d0218;

    --cc-disabled-bg: #1d293d;
    --cc-disabled-text: #90a1b9;
    --cc-overlay: rgba(0, 0, 0, 0.6);

    --cc-tone-success-fg: #5ee9b5;  --cc-tone-success-bg: #002c22;   /* emerald-300 / 950 — 10.0:1 */
    --cc-tone-warning-fg: #ffd230;  --cc-tone-warning-bg: #461901;   /* amber-300 / 950   — 10.4:1 */
    --cc-tone-danger-fg:  #ffa1ad;  --cc-tone-danger-bg:  #4d0218;   /* rose-300 / 950    — 8.2:1 */
    --cc-tone-info-fg:    #74d4ff;  --cc-tone-info-bg:    #052f4a;   /* sky-300 / 950     — 8.3:1 */
    --cc-tone-neutral-fg: #cad5e2;  --cc-tone-neutral-bg: #1d293d;   /* slate-300 / 800   — 9.8:1 */

    /* The sidebar was already dark in both themes; nudged a shade to sit under the darker page. */
    --cc-sidebar-1: #020618;
    --cc-sidebar-2: #0b1020;

    --cc-topbar-bg: rgba(15, 23, 43, 0.9);
    --cc-neutral-border: #45556c;   /* slate-600 */
    --cc-input-bg: #020618;
    --cc-input-placeholder: #90a1b9; /* 6.8:1 on the input background */
    --cc-code: #f4a8c9;              /* 9.8:1 on the page, 8.9:1 on a card */
    --cc-palette-hint: #ffd230;
    --cc-palette-selected: rgba(124, 134, 255, 0.22);

    --cc-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.24);
    --cc-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);

    /* BlazorMHD token bridge — same tokens, dark values, so library components follow. */
    --mhd-color-success: #007a55;
    --mhd-color-success-hover: #006045;
    --mhd-color-info: #0069a8;
    --mhd-color-info-hover: #00598a;
}

/* Bootstrap paints many surfaces from its own variables; re-point the handful the
   Control Center actually renders. */
:root[data-theme="dark"] body {
    --bs-body-bg: var(--cc-bg);
    --bs-body-color: var(--cc-text);
    --bs-secondary-color: var(--cc-muted);
    --bs-emphasis-color: var(--cc-text);
    --bs-border-color: var(--cc-border);
}

:root[data-theme="dark"] .card,
:root[data-theme="dark"] .modal-content,
:root[data-theme="dark"] .list-group-item,
:root[data-theme="dark"] .dropdown-menu {
    background-color: var(--cc-surface);
    color: var(--cc-text);
    border-color: var(--cc-border);
}

:root[data-theme="dark"] .table {
    --bs-table-bg: var(--cc-surface);
    --bs-table-color: var(--cc-text);
    --bs-table-hover-color: var(--cc-text);
    --bs-table-striped-color: var(--cc-text);
    --bs-table-striped-bg: var(--cc-surface-muted);
}

:root[data-theme="dark"] .form-control::placeholder,
:root[data-theme="dark"] .form-select::placeholder {
    color: var(--cc-input-placeholder);
}

/* Bootstrap's chevron for <select> is a dark inline SVG; swap it for a light one. */
:root[data-theme="dark"] .form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%2390a1b9' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

:root[data-theme="dark"] .form-check-input {
    background-color: var(--cc-input-bg);
    border-color: var(--cc-border-control);
}

:root[data-theme="dark"] .form-check-input:checked {
    background-color: var(--cc-primary);
    border-color: var(--cc-primary);
}

/* Bootstrap's check-mark SVG is white; on the light dark-mode primary it needs the dark on-primary. */
:root[data-theme="dark"] .form-check-input:checked[type="checkbox"] {
    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='%230f172b' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

:root[data-theme="dark"] .form-check-input:checked[type="radio"] {
    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='%230f172b'/%3e%3c/svg%3e");
}

/* Auth pages (login / forgot password / access denied). */
:root[data-theme="dark"] .auth-wrap {
    background:
        radial-gradient(1100px 560px at 100% -10%, rgba(124, 134, 255, 0.14), transparent 60%),
        radial-gradient(880px 480px at -10% 110%, rgba(97, 95, 255, 0.1), transparent 55%),
        var(--cc-bg);
}

:root[data-theme="dark"] .auth-mark {
    background: linear-gradient(135deg, #7c86ff, #615fff);
    color: #0f172b;
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
}

/* Dialog surfaces: the library's own dark variants fire from the `dark` class, but its
   base rules hard-code white/slate-200. Pin them to the Control Center surfaces so a
   dialog matches the page it opened over. */
:root[data-theme="dark"] .mhd-scope .mhd-dialog-surface,
:root[data-theme="dark"] .mhd-scope .mhd-dialog-header,
:root[data-theme="dark"] .mhd-scope .mhd-dialog-footer {
    background-color: var(--cc-surface-raised);
    border-color: var(--cc-border);
}

:root[data-theme="dark"] .mhd-scope .mhd-dialog-title { color: var(--cc-text); }
:root[data-theme="dark"] .mhd-scope .mhd-dialog-body { color: var(--cc-text); }
:root[data-theme="dark"] .mhd-scope .mhd-dialog-description { color: var(--cc-muted); }

/* ---------------------------------------------------------------------------
   Theme toggle (rendered in the top bar by MainLayout) — a 36px icon button.
   ------------------------------------------------------------------------- */

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border: 1px solid var(--cc-neutral-border);
    background: var(--cc-neutral-bg);
    color: var(--cc-topbar-text);
    border-radius: var(--cc-radius-sm);
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.theme-toggle:hover {
    background: var(--cc-neutral-hover-bg);
    color: var(--cc-text);
    border-color: var(--cc-border-control);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--cc-focus);
    outline-offset: 2px;
}

/* One button, two glyphs: show the moon in light mode (click -> go dark) and the sun
   in dark mode (click -> go light). Pure CSS, so it is correct on the very first paint. */
.theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: inline-flex; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ---------------------------------------------------------------------------
   Status tiles + counter groups.

   Both were introduced for the organization "Health & sync" tab, where the
   same three facts (are we in sync · is the snapshot fresh · is a push
   pending) used to be repeated as a header tag, an alert banner AND three
   meta rows abusing the desired/actual comparison table. They are stated once
   here instead, and the table went back to being only a field comparison.

   Generic on purpose — any page with a "few headline facts, then the
   evidence" shape can use them. Geometry follows the KPI tile (C-10):
   12/16 label, 16px padding, 12/16 meta.
   ------------------------------------------------------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
}

.stat-tile {
    border: 1px solid var(--cc-border);
    border-inline-start: 3px solid var(--cc-border);
    border-radius: var(--cc-radius-sm);
    background: var(--cc-surface-muted);
    padding: 0.75rem 1rem;
    min-width: 0;
}

.stat-tile-label {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    font-weight: 500;
    color: var(--cc-muted);
}

.stat-tile-value {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.25rem;
    font-weight: 600;
    color: var(--cc-text);
}

.stat-tile-meta {
    margin-top: 0.25rem;
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    color: var(--cc-muted);
    overflow-wrap: anywhere;
}

/* The accent stripe carries the verdict, so the tile is readable at a glance without
   relying on the tag's colour alone (the tag text still names the state — WCAG 1.4.1). */
.stat-tile--ok      { border-inline-start-color: var(--cc-tone-success-fg); }
.stat-tile--warn    { border-inline-start-color: var(--cc-tone-warning-fg); }
.stat-tile--danger  { border-inline-start-color: var(--cc-tone-danger-fg); }
.stat-tile--neutral { border-inline-start-color: var(--cc-border-control); }

/* Counter groups — a labelled set of "name … number" rows, for the cached tenant-health
   counters that used to run together as one wrapping line of small spans. */
.counter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.75rem;
}

.counter-group {
    border: 1px solid var(--cc-border);
    border-radius: var(--cc-radius-sm);
    background: var(--cc-surface);
    padding: 0.75rem;
}

.counter-group-title {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    font-weight: 600;
    color: var(--cc-muted);
    margin-bottom: 0.25rem;
}

.counter-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    font-size: var(--cc-font-body);
    line-height: var(--cc-lh-body);
    padding: 0.125rem 0;
}

.counter-row + .counter-row {
    border-top: 1px solid var(--cc-table-divider);
}

.counter-name { color: var(--cc-muted); }

.counter-value {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--cc-text);
}

/* A zero is the good case for every counter in this set, so it recedes; a non-zero
   count is what the operator is looking for and steps forward. */
.counter-value.is-zero   { font-weight: 500; color: var(--cc-muted); }
.counter-value.is-warn   { color: var(--cc-tone-warning-fg); }
.counter-value.is-danger { color: var(--cc-tone-danger-fg); }

/* ---------------------------------------------------------------------------
   KPI tile (design review C-10): 12/16 label → 24/32 tabular value → 12/16 context, 8px gaps,
   16px padding, on the ordinary .card surface. The Shared/KpiTile component renders it.
   ------------------------------------------------------------------------- */
.kpi-tile {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
    padding: 1rem;
}

.kpi-tile-label {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    font-weight: 500;
    color: var(--cc-muted);
}

.kpi-tile-value {
    font-size: var(--cc-font-metric);
    line-height: var(--cc-lh-metric);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--cc-text);
    overflow-wrap: anywhere;
}

.kpi-tile-value .kpi-tile-denominator {
    font-size: var(--cc-font-body);
    font-weight: 400;
    color: var(--cc-muted);
}

.kpi-tile-context {
    font-size: var(--cc-font-meta);
    line-height: var(--cc-lh-meta);
    color: var(--cc-muted);
}

/* A tile that is also a link to its work queue (dashboard "Upgrade requests pending"): the
   surrounding <a> carries the navigation, the tile only signals it on hover/focus. */
.kpi-tile-link:hover,
a:focus-visible > .kpi-tile-link {
    border-color: var(--cc-tone-info-fg);
}

.text-status-ok   { color: var(--cc-tone-success-fg); }
.text-status-info { color: var(--cc-tone-info-fg); }

/* Status foregrounds as utilities, for the odd inline phrase that must carry the same
   colour as a tile/counter. Bootstrap's own .text-danger/.text-success are re-toned to the
   same five tones so they stay legible in both themes. */
.text-status-warn   { color: var(--cc-tone-warning-fg); }
.text-status-danger { color: var(--cc-tone-danger-fg); }
.text-danger  { color: var(--cc-tone-danger-fg) !important; }
.text-success { color: var(--cc-tone-success-fg) !important; }
.text-warning { color: var(--cc-tone-warning-fg) !important; }
.text-info    { color: var(--cc-tone-info-fg) !important; }
.text-primary { color: var(--cc-link) !important; }

/* Sticky per-record context bar (organization detail). Bootstrap's .bg-body paints from
   --bs-body-bg, which the dark theme only re-points on <body> itself, so the bar stayed
   white over a dark page while content scrolled under it. Paint it from the page token. */
.org-context-bar {
    background-color: var(--cc-bg);
}

/* Outline buttons in dark mode. The library's base rule hard-codes `bg-white` and its dark
   counterpart fires from Tailwind's `dark` CLASS (which theme.js sets). Foregrounds reuse the
   tone foregrounds so an outline button matches the tag/alert of the same state. */
:root[data-theme="dark"] .mhd-scope [class*="mhd-btn-outline-"] {
    background-color: transparent;
}

:root[data-theme="dark"] .mhd-scope [class*="mhd-btn-outline-"]:hover:not(:disabled) {
    background-color: var(--cc-neutral-hover-bg);
}

:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-success { color: var(--cc-tone-success-fg); border-color: var(--cc-neutral-border); }
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-danger  { color: var(--cc-tone-danger-fg);  border-color: var(--cc-neutral-border); }
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-warning { color: var(--cc-tone-warning-fg); border-color: var(--cc-neutral-border); }
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-info    { color: var(--cc-tone-info-fg);    border-color: var(--cc-neutral-border); }
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-primary { color: var(--cc-link);            border-color: var(--cc-neutral-border); }
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-secondary,
:root[data-theme="dark"] .mhd-scope .mhd-btn-outline-neutral { color: var(--cc-text-secondary);  border-color: var(--cc-neutral-border); }

/* X-5: figures and timestamps in tables line up digit for digit. */
.table td,
.table th {
    font-variant-numeric: tabular-nums;
}

/* X-2 dark parity: pill view switches and the 2FA shared key read in both themes. */
.nav-pills .nav-link {
    color: var(--cc-text-secondary);
    border-radius: 8px;
    min-height: 2.25rem;
}

.nav-pills .nav-link:hover {
    background-color: var(--cc-neutral-hover-bg);
    color: var(--cc-text);
}

.nav-pills .nav-link.active {
    background-color: var(--cc-primary);
    color: var(--cc-on-primary);
}

.shared-key {
    background-color: var(--cc-surface-subtle, var(--cc-neutral-hover-bg));
    color: var(--cc-text);
    letter-spacing: 0.05em;
}

/* A count beside a navigation label — how many things are waiting behind that link. A link says a page
   exists; a number says somebody is waiting behind it, which is what gets the page opened. Tabular
   figures so the badge keeps its width as the number changes. Light surfaces (the tab strip); the dark
   sidebar overrides these in NavMenu.razor.css. */
.nav-badge {
    display: inline-block;
    margin-inline-start: 0.4rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.45;
    font-variant-numeric: tabular-nums;
    color: var(--cc-tone-neutral-fg);
    background-color: var(--cc-tone-neutral-bg);
}

.nav-badge-critical {
    color: var(--cc-tone-danger-fg);
    background-color: var(--cc-tone-danger-bg);
}
