/* ============================================================================
   M365 Auto Renew — Design System
   Border-first, neutral, token-driven. See docs/DESIGN_SYSTEM.md.
   Layered on top of Bootstrap 5.3.2 via the --bs-* bridge in section 2.
   ========================================================================== */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */

:root {
    /* Neutral ramp — cool-leaning, chroma kept under 0.014 */
    --background: oklch(0.985 0.002 265);
    --foreground: oklch(0.21 0.012 265);
    --card: oklch(1 0 0);
    --card-foreground: var(--foreground);
    --popover: oklch(1 0 0);
    --muted: oklch(0.968 0.004 265);
    --muted-foreground: oklch(0.50 0.014 265);
    --accent: oklch(0.955 0.006 265);
    --accent-foreground: var(--foreground);
    --border: oklch(0.922 0.005 265);
    --border-strong: oklch(0.86 0.007 265);
    --input: oklch(0.90 0.006 265);

    /* Single brand accent */
    --primary: oklch(0.55 0.20 262);
    --primary-hover: oklch(0.49 0.20 262);
    --primary-foreground: oklch(0.99 0.005 262);
    --primary-muted: oklch(0.96 0.03 262);
    --ring: var(--primary);

    /* Functional status hues — identical L and C, hue only varies */
    --success: oklch(0.55 0.15 150);
    --warning: oklch(0.55 0.15 75);
    --danger: oklch(0.55 0.19 25);
    --info: oklch(0.55 0.13 240);

    --success-bg: oklch(0.96 0.035 150);
    --success-border: oklch(0.88 0.06 150);
    --success-fg: oklch(0.42 0.13 150);
    --warning-bg: oklch(0.96 0.045 75);
    --warning-border: oklch(0.88 0.08 75);
    --warning-fg: oklch(0.42 0.12 75);
    --danger-bg: oklch(0.96 0.030 25);
    --danger-border: oklch(0.88 0.06 25);
    --danger-fg: oklch(0.44 0.16 25);
    --info-bg: oklch(0.96 0.030 240);
    --info-border: oklch(0.88 0.055 240);
    --info-fg: oklch(0.42 0.12 240);
    --neutral-bg: var(--muted);
    --neutral-border: var(--border);
    --neutral-fg: var(--muted-foreground);

    /* Radius — one root, everything derives */
    --radius: 0.5rem;
    --radius-sm: 0.25rem;
    --radius-md: 0.375rem;
    --radius-lg: var(--radius);
    --radius-full: 9999px;

    /* Spacing — 8 steps, 4px base */
    --sp-1: 0.25rem;
    --sp-2: 0.5rem;
    --sp-3: 0.75rem;
    --sp-4: 1rem;
    --sp-5: 1.25rem;
    --sp-6: 1.5rem;
    --sp-7: 2rem;
    --sp-8: 3rem;

    /* Type scale */
    --text-xs: 0.75rem;    /* 12 */
    --text-sm: 0.8125rem;  /* 13 */
    --text-base: 0.875rem; /* 14 */
    --text-md: 1rem;       /* 16 */
    --text-lg: 1.125rem;   /* 18 */
    --text-xl: 1.375rem;   /* 22 */
    --text-2xl: 1.75rem;   /* 28 */
    --text-3xl: 2.25rem;   /* 36 */

    /* Elevation — overlays only, never flat surfaces */
    --shadow-overlay: 0 4px 6px -1px oklch(0 0 0 / 0.08), 0 2px 4px -2px oklch(0 0 0 / 0.06);
    --shadow-modal: 0 16px 32px -8px oklch(0 0 0 / 0.16);

    /* Control heights */
    --h-sm: 2rem;    /* 32 */
    --h-base: 2.25rem; /* 36 */
    --h-lg: 2.5rem;  /* 40 */

    --sidebar-width: 260px;
    --topbar-height: 3.5rem;
    --motion: 150ms ease-out;

    /* Legacy aliases — kept so older inline styles keep resolving */
    --color-primary: var(--primary);
    --color-primary-strong: var(--primary-hover);
    --color-primary-soft: var(--primary-muted);
    --color-page: var(--background);
    --color-surface: var(--card);
    --color-surface-subtle: var(--muted);
    --color-ink: var(--foreground);
    --color-muted: var(--muted-foreground);
    --color-border: var(--border);
    --color-border-strong: var(--border-strong);
    --color-success: var(--success);
    --color-warning: var(--warning);
    --color-danger: var(--danger);
    --color-info: var(--info);

    color-scheme: light;
}

:root[data-theme="dark"] {
    --background: oklch(0.16 0.008 265);
    --foreground: oklch(0.95 0.004 265);
    --card: oklch(0.205 0.010 265);
    --popover: oklch(0.225 0.011 265);
    --muted: oklch(0.25 0.010 265);
    --muted-foreground: oklch(0.71 0.012 265);
    --accent: oklch(0.27 0.012 265);
    --border: oklch(0.30 0.012 265);
    --border-strong: oklch(0.38 0.014 265);
    --input: oklch(0.34 0.014 265);

    --primary: oklch(0.66 0.17 262);
    --primary-hover: oklch(0.72 0.15 262);
    --primary-foreground: oklch(0.18 0.02 262);
    --primary-muted: oklch(0.30 0.06 262);

    --success: oklch(0.72 0.15 150);
    --warning: oklch(0.78 0.14 75);
    --danger: oklch(0.68 0.17 25);
    --info: oklch(0.72 0.12 240);

    --success-bg: oklch(0.28 0.05 150);
    --success-border: oklch(0.38 0.07 150);
    --success-fg: oklch(0.83 0.11 150);
    --warning-bg: oklch(0.29 0.05 75);
    --warning-border: oklch(0.39 0.07 75);
    --warning-fg: oklch(0.85 0.11 75);
    --danger-bg: oklch(0.28 0.06 25);
    --danger-border: oklch(0.38 0.08 25);
    --danger-fg: oklch(0.82 0.10 25);
    --info-bg: oklch(0.28 0.05 240);
    --info-border: oklch(0.38 0.07 240);
    --info-fg: oklch(0.83 0.09 240);

    --shadow-overlay: 0 4px 6px -1px oklch(0 0 0 / 0.4), 0 2px 4px -2px oklch(0 0 0 / 0.3);
    --shadow-modal: 0 16px 32px -8px oklch(0 0 0 / 0.55);

    color-scheme: dark;
}

/* ── 2. Bootstrap bridge ─────────────────────────────────────────────────── */

:root {
    --bs-body-bg: var(--background);
    --bs-body-color: var(--foreground);
    --bs-body-font-family: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
    --bs-body-font-size: var(--text-base);
    --bs-body-line-height: 1.5;
    --bs-emphasis-color: var(--foreground);
    --bs-secondary-color: var(--muted-foreground);
    --bs-tertiary-color: var(--muted-foreground);
    --bs-secondary-bg: var(--muted);
    --bs-tertiary-bg: var(--muted);
    --bs-border-color: var(--border);
    --bs-border-color-translucent: var(--border);
    --bs-border-radius: var(--radius-md);
    --bs-border-radius-sm: var(--radius-sm);
    --bs-border-radius-lg: var(--radius-lg);
    --bs-border-radius-xl: var(--radius-lg);
    --bs-primary: var(--primary);
    --bs-link-color: var(--primary);
    --bs-link-hover-color: var(--primary-hover);
    --bs-link-color-rgb: initial;
    --bs-heading-color: var(--foreground);
    --bs-code-color: var(--foreground);
    --bs-highlight-bg: var(--warning-bg);
    --bs-focus-ring-color: transparent;
    --bs-focus-ring-width: 0;
}

/* ── 3. Base ─────────────────────────────────────────────────────────────── */

html {
    min-height: 100%;
}

body {
    background: var(--background);
    color: var(--foreground);
    font-family: var(--bs-body-font-family);
    font-size: var(--text-base);
    line-height: 1.5;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
}

::selection {
    background: var(--primary-muted);
    color: var(--foreground);
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--foreground);
    font-weight: 600;
    letter-spacing: -0.011em;
    line-height: 1.25;
    text-wrap: pretty;
}

h1, .h1 { font-size: var(--text-2xl); }
h2, .h2 { font-size: var(--text-xl); }
h3, .h3 { font-size: var(--text-lg); }
h4, .h4 { font-size: var(--text-md); }
h5, .h5 { font-size: var(--text-md); }
h6, .h6 { font-size: var(--text-base); }

p { text-wrap: pretty; }

a {
    color: var(--primary);
    text-decoration: none;
    transition: color var(--motion);
}

a:hover {
    color: var(--primary-hover);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

code,
.font-monospace {
    font-family: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace !important;
    font-size: 0.925em;
}

code {
    background: var(--muted);
    border-radius: var(--radius-sm);
    color: var(--foreground);
    padding: 0.1em 0.35em;
}

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

/* One focus treatment for everything. outline-offset is flipped inward inside
   scroll containers so the ring is never clipped. */
:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
}

.table-responsive :focus-visible,
.tp24-list :focus-visible {
    outline-offset: -2px;
}

.btn:focus,
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.page-link:focus {
    box-shadow: none;
}

/* ── 4. App shell ────────────────────────────────────────────────────────── */

.sidebar {
    background: var(--card);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    height: 100vh;
    left: 0;
    overflow-y: auto;
    position: fixed;
    top: 0;
    width: var(--sidebar-width);
    z-index: 1000;
}

.sidebar-header {
    align-items: center;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex: 0 0 auto;
    min-height: var(--topbar-height);
    padding: 0 var(--sp-4);
}

.sidebar-header h4 {
    align-items: center;
    color: var(--foreground);
    display: flex;
    font-size: var(--text-md);
    font-weight: 600;
    gap: var(--sp-3);
    margin: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-header h4 > i {
    align-items: center;
    background: var(--primary);
    border-radius: var(--radius-md);
    color: var(--primary-foreground);
    display: inline-flex;
    flex: 0 0 auto;
    font-size: var(--text-base);
    height: 1.75rem;
    justify-content: center;
    width: 1.75rem;
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--sp-3);
}

.sidebar-nav .nav-link {
    align-items: center;
    border-radius: var(--radius-md);
    color: var(--muted-foreground);
    display: flex;
    font-size: var(--text-base);
    font-weight: 500;
    gap: var(--sp-3);
    min-height: var(--h-base);
    padding: var(--sp-2) var(--sp-3);
    position: relative;
    text-decoration: none;
    transition: background-color var(--motion), color var(--motion);
}

.sidebar-nav .nav-link:hover {
    background: var(--accent);
    color: var(--foreground);
    text-decoration: none;
}

.sidebar-nav .nav-link.active {
    background: var(--accent);
    color: var(--foreground);
    font-weight: 600;
}

.sidebar-nav .nav-link.active::before {
    background: var(--primary);
    border-radius: var(--radius-full);
    bottom: var(--sp-2);
    content: "";
    left: 0;
    position: absolute;
    top: var(--sp-2);
    width: 2px;
}

.sidebar-nav .nav-link i {
    flex: 0 0 auto;
    font-size: var(--text-md);
    text-align: center;
    width: 1.125rem;
}

.sidebar-nav .nav-link.text-danger {
    color: var(--danger) !important;
}

.sidebar-nav .nav-link.text-danger:hover {
    background: var(--danger-bg);
}

.sidebar-nav hr {
    margin: var(--sp-2) var(--sp-1);
}

.app-logo {
    border-radius: var(--radius-sm);
    flex: 0 0 auto;
    height: 1.75rem;
    width: auto;
}

.main-content {
    margin-left: var(--sidebar-width);
    min-height: 100vh;
}

.main-content.no-sidebar {
    align-items: center;
    background: var(--background);
    display: flex;
    justify-content: center;
    margin-left: 0;
}

.main-content > .container-fluid {
    max-width: 1400px;
}

/* Pages built around a data table take the whole window. Capping them left
   ~650px of empty page on a wide monitor while app.js was busy hiding columns
   to fit the table into 1350px. Text-first pages keep the cap, where a long
   measure is genuinely harder to read. */
body:has(.responsive-priority-table) .main-content > .container-fluid {
    max-width: none;
}

.main-content > .container-fluid.py-3 {
    padding: var(--sp-6) var(--sp-6) var(--sp-8) !important;
}

.main-content > .container-fluid.mt-3 {
    margin-top: 0 !important;
    padding: 0 var(--sp-6);
}

.main-content > .container-fluid.mt-3:has(.alert) {
    padding-top: var(--sp-4);
}

.top-navbar {
    align-items: center;
    background: var(--background);
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: var(--sp-3);
    justify-content: space-between;
    min-height: var(--topbar-height);
    padding: 0 var(--sp-6);
    position: sticky;
    top: 0;
    z-index: 900;
}

.top-navbar h5 {
    color: var(--foreground);
    font-size: var(--text-md);
    font-weight: 600;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Beats Bootstrap's `.btn { display: inline-flex }`, which sits later in the
   cascade at equal specificity and used to leak the toggle onto desktop. */
.top-navbar .sidebar-toggle {
    align-items: center;
    color: var(--foreground);
    display: none;
    height: var(--h-base);
    justify-content: center;
    padding: 0;
    width: var(--h-base);
}

.sidebar-backdrop {
    display: none;
}

/* `text-overflow` does nothing on a flex container — it only clipped the role
   badge mid-word. The username is the part that should give way, so it gets
   its own truncating box and the badge stays whole. */
.app-user-chip {
    align-items: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--muted-foreground);
    display: inline-flex;
    font-size: var(--text-sm);
    font-weight: 500;
    gap: var(--sp-2);
    max-width: 16rem;
    min-height: var(--h-base);
    min-width: 0;
    padding: 0 var(--sp-3);
    white-space: nowrap;
}

.app-user-chip > i {
    flex: 0 0 auto;
}

.app-user-chip__name {
    min-width: 2ch;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-user-chip .badge {
    flex: 0 0 auto;
}

.theme-toggle {
    align-items: center;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--muted-foreground);
    display: inline-flex;
    flex: 0 0 auto;
    font-size: var(--text-sm);
    height: var(--h-base);
    justify-content: center;
    min-width: var(--h-base);
    padding: 0 var(--sp-2);
    transition: background-color var(--motion), color var(--motion), border-color var(--motion);
}

.theme-toggle:hover {
    background: var(--accent);
    color: var(--foreground);
    text-decoration: none;
}

/* ── 5. Page header & toolbar ────────────────────────────────────────────── */

.page-header {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    justify-content: space-between;
    margin-bottom: var(--sp-6);
}

.page-header__text {
    min-width: 0;
}

.page-header__title {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    font-size: var(--text-xl);
    font-weight: 600;
    gap: var(--sp-3);
    letter-spacing: -0.011em;
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

.page-header__desc {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    margin: var(--sp-1) 0 0;
    max-width: 60ch;
    overflow-wrap: anywhere;
}

.page-header__actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.toolbar {
    align-items: flex-end;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-bottom: var(--sp-5);
    padding-bottom: var(--sp-4);
}

.toolbar__field {
    display: flex;
    flex: 1 1 9.5rem;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
}

.toolbar__field--grow {
    flex: 2 1 15rem;
}

.toolbar__field--search {
    flex: 1 1 20rem;
    max-width: 26rem;
}

.toolbar__field--narrow {
    flex: 0 1 6.5rem;
}

.bulk-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-bottom: var(--sp-4);
    padding: var(--sp-2) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

.toolbar__field > .form-label {
    margin-bottom: 0;
}

.toolbar__actions {
    display: flex;
    flex: 0 0 auto;
    gap: var(--sp-2);
    margin-left: auto;
}

.section-label {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ── Form pages ──────────────────────────────────────────────────────────── */

/* Centred, because the page container is itself centred with a max-width --
   left-aligning a narrow column inside it leaves all the slack on one side. */
.form-layout {
    margin-inline: auto;
    max-width: 56rem;
}

.form-section + .form-section {
    border-top: 1px solid var(--border);
    margin-top: var(--sp-6);
    padding-top: var(--sp-6);
}

.form-section > .section-label {
    display: block;
    margin: 0 0 var(--sp-4);
}

.form-grid {
    display: grid;
    gap: var(--sp-5);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 767.98px) {
    .form-grid { grid-template-columns: minmax(0, 1fr); }
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    min-width: 0;
}

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

.form-field > .form-label,
.form-field > .form-text {
    margin: 0;
}

.form-field > .form-label {
    align-items: center;
    display: block;
}

.form-label--with-action {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    justify-content: flex-end;
}

.form-layout--narrow {
    max-width: 40rem;
}

.stacked-action {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    justify-content: space-between;
}

.stacked-action__title {
    font-size: var(--text-sm);
    font-weight: 600;
    margin: 0 0 var(--sp-1);
}

.inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.inline-form > .form-control {
    flex: 1 1 12rem;
    min-width: 0;
}

.inline-form > .btn {
    flex: 0 0 auto;
}

.totp-qr {
    display: flex;
    justify-content: center;
}

.totp-qr img {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--sp-3);
}

/* ── 6. Card ─────────────────────────────────────────────────────────────── */

.card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: none;
    color: var(--card-foreground);
    /* deliberately not overflow:hidden so focus rings inside are never clipped */
    overflow: visible;
}

.card > :first-child {
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
}

.card > :last-child {
    border-bottom-left-radius: inherit;
    border-bottom-right-radius: inherit;
}

.card-header {
    align-items: center;
    background: transparent;
    border-bottom: 1px solid var(--border);
    color: var(--foreground);
    display: flex;
    flex-wrap: wrap;
    font-size: var(--text-base);
    font-weight: 600;
    gap: var(--sp-3);
    padding: var(--sp-4) var(--sp-5);
}

.card-header > .card-title {
    font-size: var(--text-base);
    font-weight: 600;
    margin: 0;
    margin-right: auto;
}

/* Headers that still wrap their content in a single flex row keep working */
.card-header > *:only-child {
    flex: 1 1 auto;
    min-width: 0;
}

.card-header h5,
.card-header h6,
.card-header .h5,
.card-header .h6 {
    color: var(--foreground);
    font-size: var(--text-base);
    font-weight: 600;
    margin: 0;
}

.card-header .card-desc {
    color: var(--muted-foreground);
    display: block;
    font-size: var(--text-sm);
    font-weight: 400;
    margin-top: var(--sp-1);
}

.card-body {
    padding: var(--sp-5);
}

.card-footer {
    background: var(--muted);
    border-top: 1px solid var(--border);
    font-size: var(--text-sm);
    padding: var(--sp-3) var(--sp-5);
}

/* Table sits flush against the card edges */
.card-body.is-flush {
    padding: 0;
}

.card-body.is-flush > .table-responsive {
    border: 0;
    border-radius: inherit;
}

/* Sticky table header, two shapes chosen by app.js:
   - `can-stick`: the table fits the card, so the wrapper can give up its
     overflow and the header pins to the viewport under the topbar.
   - `can-stick-inner`: the table is wider than the card and must keep its
     horizontal scroll, so the wrapper becomes its own scroll box and the
     header pins to the top of that box instead. */
@media (min-width: 1200px) {
    .card-body.is-flush > .table-responsive.can-stick {
        overflow: visible;
    }

    .card-body.is-flush > .table-responsive.can-stick > .table > thead > tr > th {
        position: sticky;
        top: var(--topbar-height);
        z-index: 3;
    }

    .card-body.is-flush > .table-responsive.can-stick-inner {
        max-height: calc(100vh - var(--topbar-height) - 8rem);
    }

    .card-body.is-flush > .table-responsive.can-stick-inner > .table > thead > tr > th {
        position: sticky;
        top: 0;
        z-index: 3;
    }

    .card-body.is-flush > .table-responsive.can-stick > .table > thead > tr > th:first-child,
    .card-body.is-flush > .table-responsive.can-stick-inner > .table > thead > tr > th:first-child {
        border-top-left-radius: var(--radius-lg);
    }

    .card-body.is-flush > .table-responsive.can-stick > .table > thead > tr > th:last-child,
    .card-body.is-flush > .table-responsive.can-stick-inner > .table > thead > tr > th:last-child {
        border-top-right-radius: var(--radius-lg);
    }

    .card-body.is-flush:last-child > .table-responsive.can-stick > .table > tbody > tr:last-child > td:first-child {
        border-bottom-left-radius: var(--radius-lg);
    }

    .card-body.is-flush:last-child > .table-responsive.can-stick > .table > tbody > tr:last-child > td:last-child {
        border-bottom-right-radius: var(--radius-lg);
    }
}

/* ── 7. Table ────────────────────────────────────────────────────────────── */

.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--foreground);
    border-color: var(--border);
    color: var(--foreground);
    font-size: var(--text-base);
    margin-bottom: 0;
}

.table thead th {
    background: var(--muted);
    border-bottom: 1px solid var(--border);
    border-top: 0;
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: var(--sp-2) var(--sp-3);
    vertical-align: middle;
    white-space: nowrap;
}

.table tbody td {
    border-color: var(--border);
    padding: var(--sp-3);
    vertical-align: middle;
}

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

.table-hover tbody tr {
    transition: background-color var(--motion);
}

.table-hover > tbody > tr:hover > * {
    --bs-table-accent-bg: transparent;
    background: var(--muted);
    color: var(--foreground);
}

.table-sm thead th,
.table-sm tbody td {
    padding: var(--sp-2) var(--sp-3);
}

.table-borderless tbody td {
    border: 0;
}

.table-responsive {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    container-type: inline-size;
    overflow: auto;
}

/* Lists must never scroll sideways: the table shrinks to its wrapper, sheds
   low-priority columns (see § 22) and finally wraps the survivors. */
.table-responsive > .table {
    min-width: 0;
    width: 100%;
}

/* `anywhere` rather than `break-word` on purpose — only `anywhere` lets the
   wrap opportunity shrink the cell's min-content width, which is what the
   table's intrinsic sizing measures. */
.table th,
.table td {
    overflow-wrap: anywhere;
}

/* Opt-in hard wrap for cells holding unbroken identifiers. The floor keeps an
   email on one line while the column survives; once it can't, the column is
   shed rather than squeezed into a mid-word break. */
.cell-break {
    max-width: 16rem;
    min-width: 11rem;
    overflow-wrap: anywhere;
}

.cell-nowrap {
    white-space: nowrap;
}

.cell-datetime {
    white-space: nowrap;
}

/* The row's identifying cell — keeps names on one or two lines instead of
   collapsing to min-content next to long unbreakable identifiers. */
.cell-primary {
    max-width: 22rem;
    overflow-wrap: anywhere;
}

/* Once a table has shed everything it can, the survivors have to give up
   their nowrap floors rather than push a scrollbar out. */
.table.is-cramped .cell-nowrap,
.table.is-cramped .cell-datetime,
.table.is-cramped .badge {
    white-space: normal;
}

.table.is-cramped .cell-break {
    min-width: 0;
}

.table.is-cramped {
    font-size: var(--text-xs);
}

.table.is-cramped > thead > tr > th,
.table.is-cramped > tbody > tr > td {
    padding-inline: var(--sp-2);
}

.link-cell {
    color: var(--foreground);
    font-weight: 500;
}

.link-cell:hover {
    color: var(--primary);
}

.log-details {
    margin-top: var(--sp-1);
}

/* The log message is the widest free-text column; cap it so it wraps instead
   of stretching the table past the card. */
.cell-message {
    max-width: 32rem;
}

.log-details > summary {
    color: var(--muted-foreground);
    cursor: pointer;
    font-size: var(--text-xs);
}

.log-details > pre {
    background: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    font-size: var(--text-xs);
    margin: var(--sp-2) 0 0;
    max-height: 16rem;
    overflow: auto;
    padding: var(--sp-2);
    white-space: pre-wrap;
    word-break: break-word;
}

td[data-priority="actions"],
th[data-priority="actions"] {
    text-align: right;
    white-space: nowrap;
}

td[data-priority="actions"] .btn-group,
td[data-priority="actions"] .btn {
    white-space: nowrap;
}

/* ── 8. Badge ────────────────────────────────────────────────────────────── */

.badge {
    align-items: center;
    background: var(--neutral-bg) !important;
    border: 1px solid var(--neutral-border);
    border-radius: var(--radius-sm);
    color: var(--neutral-fg) !important;
    display: inline-flex;
    font-size: var(--text-xs);
    font-weight: 500;
    gap: var(--sp-1);
    letter-spacing: 0;
    line-height: 1.35;
    padding: 0.125rem var(--sp-2);
    white-space: nowrap;
}

.badge.bg-primary {
    background: var(--primary-muted) !important;
    border-color: var(--primary);
    color: var(--primary) !important;
}

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

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

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

.badge.bg-info {
    background: var(--info-bg) !important;
    border-color: var(--info-border);
    color: var(--info-fg) !important;
}

.badge.bg-secondary,
.badge.bg-light,
.badge.bg-dark {
    background: var(--neutral-bg) !important;
    border-color: var(--neutral-border);
    color: var(--neutral-fg) !important;
}

/* Status dot — pair with a badge to encode state without relying on colour */
.status-dot {
    background: currentColor;
    border-radius: var(--radius-full);
    display: inline-block;
    flex: 0 0 auto;
    height: 0.375rem;
    width: 0.375rem;
}

/* ── 9. Forms ────────────────────────────────────────────────────────────── */

.form-label {
    color: var(--foreground);
    font-size: var(--text-sm);
    font-weight: 500;
    margin-bottom: var(--sp-2);
}

.form-control,
.form-select {
    background-color: var(--card);
    border: 1px solid var(--input);
    border-radius: var(--radius-md);
    color: var(--foreground);
    font-size: var(--text-base);
    min-height: var(--h-base);
    padding: var(--sp-2) var(--sp-3);
    transition: border-color var(--motion);
}

.form-control:focus,
.form-select:focus {
    background-color: var(--card);
    border-color: var(--border-strong);
    color: var(--foreground);
}

.form-control::placeholder {
    color: var(--muted-foreground);
    opacity: 1;
}

.form-control:disabled,
.form-select:disabled {
    background-color: var(--muted);
    color: var(--muted-foreground);
}

.form-control-sm,
.form-select-sm,
.input-group-sm > .form-control,
.input-group-sm > .form-select {
    font-size: var(--text-sm);
    min-height: var(--h-sm);
    padding: var(--sp-1) var(--sp-2);
}

textarea.form-control {
    line-height: 1.55;
    min-height: 5rem;
}

.form-text,
small.text-muted,
.text-muted {
    color: var(--muted-foreground) !important;
}

.form-text {
    font-size: var(--text-xs);
    margin-top: var(--sp-1);
}

.input-group-text {
    background: var(--muted);
    border-color: var(--input);
    border-radius: var(--radius-md);
    color: var(--muted-foreground);
    font-size: var(--text-base);
}

.form-check-input {
    background-color: var(--card);
    border-color: var(--border-strong);
}

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

.form-check-label {
    font-size: var(--text-base);
}

.form-switch .form-check-input {
    height: 1.25rem;
    width: 2.25rem;
}

.form-switch .form-check-label {
    padding-left: var(--sp-2);
}

/* Give bare switches inside tables a real 44px touch area without moving them */
.table .form-check.form-switch {
    margin: 0;
    min-height: 0;
    position: relative;
}

.table .form-switch .form-check-input {
    cursor: pointer;
}

.form-select {
    background-position: right var(--sp-3) center;
}

/* ── 10. Buttons ─────────────────────────────────────────────────────────── */

.btn {
    --bs-btn-focus-box-shadow: none;
    align-items: center;
    border-radius: var(--radius-md);
    display: inline-flex;
    font-size: var(--text-base);
    font-weight: 500;
    gap: var(--sp-2);
    justify-content: center;
    line-height: 1.25;
    min-height: var(--h-base);
    padding: var(--sp-2) var(--sp-4);
    transition: background-color var(--motion), border-color var(--motion), color var(--motion);
    white-space: nowrap;
}

.btn i {
    font-size: 1em;
    line-height: 1;
}

.btn-primary {
    --bs-btn-bg: var(--primary);
    --bs-btn-border-color: var(--primary);
    --bs-btn-color: var(--primary-foreground);
    --bs-btn-hover-bg: var(--primary-hover);
    --bs-btn-hover-border-color: var(--primary-hover);
    --bs-btn-hover-color: var(--primary-foreground);
    --bs-btn-active-bg: var(--primary-hover);
    --bs-btn-active-border-color: var(--primary-hover);
    --bs-btn-disabled-bg: var(--primary);
    --bs-btn-disabled-border-color: var(--primary);
    --bs-btn-disabled-color: var(--primary-foreground);
}

.btn-secondary,
.btn-light,
.btn-dark {
    --bs-btn-bg: var(--card);
    --bs-btn-border-color: var(--input);
    --bs-btn-color: var(--foreground);
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--input);
    --bs-btn-hover-color: var(--foreground);
    --bs-btn-active-bg: var(--accent);
    --bs-btn-active-border-color: var(--input);
    --bs-btn-active-color: var(--foreground);
}

.btn-danger {
    --bs-btn-bg: var(--danger);
    --bs-btn-border-color: var(--danger);
    --bs-btn-color: oklch(0.99 0.005 25);
    --bs-btn-hover-bg: oklch(0.48 0.19 25);
    --bs-btn-hover-border-color: oklch(0.48 0.19 25);
    --bs-btn-hover-color: oklch(0.99 0.005 25);
    --bs-btn-active-bg: oklch(0.48 0.19 25);
}

.btn-success {
    --bs-btn-bg: var(--success);
    --bs-btn-border-color: var(--success);
    --bs-btn-color: oklch(0.99 0.005 150);
    --bs-btn-hover-bg: oklch(0.48 0.14 150);
    --bs-btn-hover-border-color: oklch(0.48 0.14 150);
    --bs-btn-hover-color: oklch(0.99 0.005 150);
}

.btn-warning {
    --bs-btn-bg: var(--warning);
    --bs-btn-border-color: var(--warning);
    --bs-btn-color: oklch(0.99 0.005 75);
    --bs-btn-hover-bg: oklch(0.48 0.14 75);
    --bs-btn-hover-border-color: oklch(0.48 0.14 75);
    --bs-btn-hover-color: oklch(0.99 0.005 75);
}

.btn-info {
    --bs-btn-bg: var(--info);
    --bs-btn-border-color: var(--info);
    --bs-btn-color: oklch(0.99 0.005 240);
    --bs-btn-hover-bg: oklch(0.48 0.13 240);
    --bs-btn-hover-border-color: oklch(0.48 0.13 240);
    --bs-btn-hover-color: oklch(0.99 0.005 240);
}

/* Outline family collapses to one neutral shape; the hue only shows on hover
   and in the icon, which keeps dense toolbars from turning into a rainbow. */
.btn-outline-primary,
.btn-outline-secondary,
.btn-outline-success,
.btn-outline-danger,
.btn-outline-warning,
.btn-outline-info,
.btn-outline-light,
.btn-outline-dark {
    --bs-btn-bg: var(--card);
    --bs-btn-border-color: var(--input);
    --bs-btn-color: var(--foreground);
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--border-strong);
    --bs-btn-hover-color: var(--foreground);
    --bs-btn-active-bg: var(--accent);
    --bs-btn-active-border-color: var(--border-strong);
    --bs-btn-active-color: var(--foreground);
    --bs-btn-disabled-bg: var(--card);
    --bs-btn-disabled-border-color: var(--border);
    --bs-btn-disabled-color: var(--muted-foreground);
}

.btn-outline-primary { --bs-btn-color: var(--primary); }
.btn-outline-primary:hover { color: var(--primary); }
.btn-outline-success { --bs-btn-color: var(--success-fg); }
.btn-outline-success:hover { color: var(--success-fg); }
.btn-outline-danger { --bs-btn-color: var(--danger-fg); }
.btn-outline-danger:hover {
    background: var(--danger-bg);
    border-color: var(--danger-border);
    color: var(--danger-fg);
}
.btn-outline-warning { --bs-btn-color: var(--warning-fg); }
.btn-outline-warning:hover { color: var(--warning-fg); }
.btn-outline-info { --bs-btn-color: var(--info-fg); }
.btn-outline-info:hover { color: var(--info-fg); }

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

.btn-sm,
.btn-group-sm > .btn {
    font-size: var(--text-sm);
    gap: var(--sp-1);
    min-height: var(--h-sm);
    padding: var(--sp-1) var(--sp-3);
}

.btn-lg {
    font-size: var(--text-md);
    min-height: var(--h-lg);
    padding: var(--sp-2) var(--sp-5);
}

.btn-group > .btn:not(:first-child),
.btn-group > .btn:not(:last-child) {
    border-radius: 0;
}

.btn-group > .btn:first-child {
    border-bottom-left-radius: var(--radius-md);
    border-top-left-radius: var(--radius-md);
}

.btn-group > .btn:last-child {
    border-bottom-right-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
}

.btn-group > .btn + .btn {
    margin-left: -1px;
}

.btn-group > .btn:hover,
.btn-group > .btn:focus-visible {
    z-index: 2;
}

.btn-close {
    border-radius: var(--radius-sm);
}

/* ── 11. Alerts ──────────────────────────────────────────────────────────── */

.alert {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: none;
    font-size: var(--text-base);
    padding: var(--sp-3) var(--sp-4);
}

.alert-info,
.alert-primary {
    background: var(--info-bg);
    border-color: var(--info-border);
    color: var(--info-fg);
}

.alert-warning {
    background: var(--warning-bg);
    border-color: var(--warning-border);
    color: var(--warning-fg);
}

.alert-danger,
.alert-error {
    background: var(--danger-bg);
    border-color: var(--danger-border);
    color: var(--danger-fg);
}

.alert-success {
    background: var(--success-bg);
    border-color: var(--success-border);
    color: var(--success-fg);
}

.alert-secondary,
.alert-light,
.alert-dark {
    background: var(--muted);
    border-color: var(--border);
    color: var(--foreground);
}

.alert a {
    color: inherit;
    font-weight: 500;
    text-decoration: underline;
}

/* Multi-line technical detail inside an alert (e.g. a stored error message) */
.alert-detail {
    font-size: var(--text-sm);
    margin: var(--sp-1) 0 0;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}

/* Raw API payloads shown in a details/summary block */
.code-block {
    background: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    margin: var(--sp-2) 0 0;
    max-height: 20rem;
    overflow: auto;
    overflow-wrap: anywhere;
    padding: var(--sp-3);
    white-space: pre-wrap;
}

/* ── 12. Overlays ────────────────────────────────────────────────────────── */

.modal-content {
    background: var(--popover);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-modal);
    color: var(--foreground);
}

.modal-header,
.modal-footer {
    border-color: var(--border);
    padding: var(--sp-4) var(--sp-5);
}

.modal-title {
    font-size: var(--text-md);
    font-weight: 600;
}

.modal-body {
    padding: var(--sp-5);
}

.modal-footer {
    gap: var(--sp-2);
}

.modal-footer > * {
    margin: 0;
}

.dropdown-menu {
    background: var(--popover);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-overlay);
    color: var(--foreground);
    font-size: var(--text-base);
    padding: var(--sp-1);
}

.dropdown-item {
    border-radius: var(--radius-sm);
    color: var(--foreground);
    padding: var(--sp-2) var(--sp-3);
}

.dropdown-item:hover,
.dropdown-item:focus {
    background: var(--accent);
    color: var(--foreground);
}

.toast {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-overlay);
}

.tooltip-inner {
    background: var(--foreground);
    border-radius: var(--radius-md);
    color: var(--background);
    font-size: var(--text-sm);
    padding: var(--sp-1) var(--sp-2);
}

.tooltip .tooltip-arrow::before {
    border-top-color: var(--foreground);
    border-bottom-color: var(--foreground);
    border-left-color: var(--foreground);
    border-right-color: var(--foreground);
}

/* ── 13. Page primitives ─────────────────────────────────────────────────── */

.breadcrumb {
    --bs-breadcrumb-divider-color: var(--muted-foreground);
    --bs-breadcrumb-item-padding-x: var(--sp-2);
    background: transparent;
    font-size: var(--text-sm);
    margin-bottom: var(--sp-4);
}

.breadcrumb a {
    color: var(--muted-foreground);
    font-weight: 400;
}

.breadcrumb a:hover {
    color: var(--foreground);
}

.breadcrumb-item.active {
    color: var(--foreground);
    font-weight: 500;
}

.breadcrumb-item {
    min-width: 0;
    overflow-wrap: anywhere;
}

.progress {
    background-color: var(--muted);
    border-radius: var(--radius-full);
    height: 0.5rem;
}

.progress-bar {
    background: var(--primary);
}

.pagination {
    --bs-pagination-bg: var(--card);
    --bs-pagination-border-color: var(--border);
    --bs-pagination-color: var(--foreground);
    --bs-pagination-hover-bg: var(--accent);
    --bs-pagination-hover-border-color: var(--border);
    --bs-pagination-hover-color: var(--foreground);
    --bs-pagination-focus-bg: var(--accent);
    --bs-pagination-focus-box-shadow: none;
    --bs-pagination-active-bg: var(--primary);
    --bs-pagination-active-border-color: var(--primary);
    --bs-pagination-active-color: var(--primary-foreground);
    --bs-pagination-disabled-bg: var(--card);
    --bs-pagination-disabled-border-color: var(--border);
    --bs-pagination-disabled-color: var(--muted-foreground);
    --bs-pagination-border-radius: var(--radius-md);
    font-size: var(--text-sm);
    margin-bottom: 0;
}

.page-link {
    font-weight: 500;
    min-width: var(--h-sm);
    padding: var(--sp-1) var(--sp-2);
    text-align: center;
}

.nav-tabs {
    border-bottom: 1px solid var(--border);
    gap: var(--sp-1);
}

.nav-tabs .nav-link {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--muted-foreground);
    font-size: var(--text-base);
    font-weight: 500;
    margin-bottom: -1px;
    padding: var(--sp-2) var(--sp-3);
}

.nav-tabs .nav-link:hover {
    color: var(--foreground);
}

.nav-tabs .nav-link.active {
    background: transparent;
    border-bottom-color: var(--primary);
    color: var(--foreground);
}

.accordion {
    --bs-accordion-bg: var(--card);
    --bs-accordion-color: var(--foreground);
    --bs-accordion-border-color: var(--border);
    --bs-accordion-border-radius: var(--radius-lg);
    --bs-accordion-btn-color: var(--foreground);
    --bs-accordion-btn-bg: var(--card);
    --bs-accordion-active-bg: var(--muted);
    --bs-accordion-active-color: var(--foreground);
    --bs-accordion-btn-focus-box-shadow: none;
}

/* ── 14. Detail rows (key / value) ───────────────────────────────────────── */

/* Two-column detail layout: content on the left, summary rail on the right.
   Templates set the DOM order they want with Bootstrap's `order-*` classes. */
.detail-grid {
    display: grid;
    gap: var(--sp-5);
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 992px) {
    .detail-grid {
        align-items: start;
        grid-template-columns: minmax(0, 1fr) 21.25rem;
    }

    /* The summary rail reads first on narrow screens but sits to the right
       once there is room for two columns. */
    .detail-grid__main {
        grid-column: 1;
        grid-row: 1;
    }

    .detail-grid__side {
        grid-column: 2;
        grid-row: 1;
        position: sticky;
        top: calc(var(--topbar-height) + var(--sp-5));
    }
}

.detail-grid__main,
.detail-grid__side {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    min-width: 0;
}

/* Stacked on narrow screens the summary rail reads first */
.detail-grid__side {
    order: -1;
}

/* Two detail lists side by side inside one card */
.detail-columns {
    display: grid;
    gap: 0 var(--sp-8);
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 992px) {
    .detail-columns {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.detail-list {
    display: flex;
    flex-direction: column;
}

.detail-row {
    align-items: baseline;
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: var(--sp-4);
    padding: var(--sp-3) 0;
}

.detail-row:first-child { padding-top: 0; }
.detail-row:last-child { border-bottom: 0; padding-bottom: 0; }

.detail-row > dt,
.detail-row__label {
    color: var(--muted-foreground);
    flex: 0 0 8.75rem;
    font-size: var(--text-sm);
    font-weight: 400;
    margin: 0;
}

.detail-row > dd,
.detail-row__value {
    flex: 1 1 auto;
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Inline controls that sit next to a value need breathing room */
.detail-row > dd > .btn {
    margin-left: var(--sp-2);
    vertical-align: middle;
}

/* Tenant summary rail is narrow; a shorter label column and tighter gap
   keep values (e.g. the user count and its details button) on one line */
@media (min-width: 992px) {
    .tenant-detail-layout .detail-grid__side .detail-row {
        gap: var(--sp-3);
    }

    .tenant-detail-layout .detail-grid__side .detail-row > dt {
        flex-basis: 7.5rem;
    }
}

/* Legacy detail tables keep the same rhythm until every page is migrated */
.tenant-detail-table td {
    border-bottom: 1px solid var(--border);
    padding: var(--sp-3) 0;
}

.tenant-detail-table tr:last-child td {
    border-bottom: 0;
}

.tenant-detail-table td:first-child {
    color: var(--muted-foreground) !important;
    font-weight: 400;
    padding-right: var(--sp-4);
    white-space: nowrap;
    width: 8.75rem;
}

.tenant-detail-table td:last-child {
    min-width: 0;
    overflow-wrap: anywhere;
}

.tenant-detail-actions {
    gap: var(--sp-2) !important;
}

.tenant-detail-actions .btn {
    justify-content: flex-start;
    white-space: normal;
}

.marketplace-purchase-form .input-group {
    flex-wrap: wrap;
}

.marketplace-purchase-form .form-control {
    min-width: 13rem;
}

.marketplace-purchase-form__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
}

.marketplace-purchase-form__actions .btn {
    flex: 1 1 auto;
}

/* Live TOTP readout on the tenant detail page */
.totp-readout {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.totp-readout__code {
    color: var(--success-fg);
    font-family: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: 0.08em;
}

/* ── 15. KPI grid (dashboard) ────────────────────────────────────────────── */

.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.kpi-grid--5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

.kpi-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (min-width: 768px) {
    .kpi-grid--3 > .kpi:nth-child(3n) { border-right: 0; }
    .kpi-grid--3 > .kpi:nth-child(4n) { border-right: 1px solid var(--border); }
    .kpi-grid--3 > .kpi:nth-child(n + 4) { border-top: 1px solid var(--border); }
}

@media (min-width: 768px) {
    .kpi-grid--5 > .kpi:nth-child(4n) { border-right: 1px solid var(--border); }
    .kpi-grid--5 > .kpi:nth-child(5n) { border-right: 0; }
    .kpi-grid--5 > .kpi:nth-child(n + 5) { border-top: 0; }
    .kpi-grid--5 > .kpi:nth-child(n + 6) { border-top: 1px solid var(--border); }
}

.kpi {
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
    padding: var(--sp-4) var(--sp-5);
}

.kpi:last-child,
.kpi:nth-child(4n) {
    border-right: 0;
}

.kpi-grid > .kpi:nth-child(n + 5) {
    border-top: 1px solid var(--border);
}

.kpi__label {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    font-weight: 500;
}

.kpi__value {
    color: var(--foreground);
    font-feature-settings: "tnum";
    font-size: var(--text-2xl);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.15;
}

.kpi__meta {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
}

.kpi__meta--danger { color: var(--danger-fg); }
.kpi__meta--warning { color: var(--warning-fg); }

.health-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1);
}

.chart-frame {
    height: 16.25rem;
    position: relative;
}

/* Narrow dashboard tables live in half-width columns: opt out of the
   scroll floor so they wrap instead of clipping. */
.table-responsive > .table.table-fit {
    min-width: 0;
}

.card-header__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.facts-grid {
    display: grid;
    gap: var(--sp-5);
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 991.98px) {
    .facts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 575.98px) {
    .facts-grid { grid-template-columns: minmax(0, 1fr); }
}

.fact {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    min-width: 0;
}

.fact__label {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
}

.fact__value {
    font-size: var(--text-base);
    font-weight: 500;
    overflow-wrap: anywhere;
}

.steps-list {
    color: var(--foreground);
    font-size: var(--text-base);
    margin: 0;
    padding-left: var(--sp-5);
}

.steps-list li + li,
.steps-list ul {
    margin-top: var(--sp-2);
}

.steps-list ul {
    color: var(--muted-foreground);
    padding-left: var(--sp-5);
}

/* ── 16. Empty state ─────────────────────────────────────────────────────── */
.empty-state {
    align-items: center;
    display: flex;
    flex-direction: column;
    padding: var(--sp-8) var(--sp-5);
    text-align: center;
}

.empty-state__icon {
    align-items: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--muted-foreground);
    display: flex;
    font-size: var(--text-lg);
    height: 2.75rem;
    justify-content: center;
    margin-bottom: var(--sp-4);
    width: 2.75rem;
}

.empty-state__title {
    font-size: var(--text-md);
    font-weight: 600;
    margin: 0;
}

.empty-state__desc {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    margin: var(--sp-2) 0 var(--sp-4);
    max-width: 44ch;
}

/* ── 17. Auth pages ──────────────────────────────────────────────────────── */

.auth-shell {
    align-items: center;
    background: var(--background);
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 100vh;
    padding: var(--sp-6);
    width: 100%;
}

.auth-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    max-width: 25rem;
    padding: var(--sp-7);
    width: 100%;
}

.auth-brand {
    align-items: center;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    margin-bottom: var(--sp-6);
    text-align: center;
}

.auth-brand__mark {
    align-items: center;
    background: var(--primary);
    border-radius: var(--radius-lg);
    color: var(--primary-foreground);
    display: flex;
    font-size: var(--text-lg);
    height: 2.75rem;
    justify-content: center;
    width: 2.75rem;
}

.auth-brand__mark img {
    border-radius: var(--radius-sm);
    max-height: 1.75rem;
    max-width: 1.75rem;
}

/* The bundled mark carries its own tile and colour, so it replaces the
   container's swatch rather than sitting on top of it. */
.auth-brand__mark--default {
    background: none;
}

.auth-brand__mark--default img {
    border-radius: 0;
    max-height: 2.75rem;
    max-width: 2.75rem;
}

.auth-brand__name {
    font-size: var(--text-lg);
    font-weight: 600;
    margin: 0;
}

.auth-brand__desc {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    margin: 0;
}

.auth-footer {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    margin-top: var(--sp-5);
    text-align: center;
}

.auth-topbar {
    display: flex;
    gap: var(--sp-2);
    justify-content: flex-end;
    margin-bottom: var(--sp-5);
    max-width: 25rem;
    width: 100%;
}

.auth-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    min-height: 100vh;
}

.auth-aside {
    display: none;
}

@media (min-width: 992px) {
    .auth-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

    .auth-aside {
        background: var(--muted);
        border-right: 1px solid var(--border);
        display: flex;
        align-items: center;
        padding: var(--sp-8);
    }
}

.auth-aside__inner {
    max-width: 26rem;
}

.auth-aside__title {
    font-size: var(--text-2xl);
    font-weight: 600;
    letter-spacing: -0.015em;
    margin: 0 0 var(--sp-3);
}

.auth-aside__lead {
    color: var(--muted-foreground);
    font-size: var(--text-sm);
    line-height: 1.6;
    margin: 0 0 var(--sp-6);
    text-wrap: pretty;
}

.auth-points {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    list-style: none;
    margin: 0;
    padding: 0;
}

.auth-points li {
    align-items: flex-start;
    color: var(--foreground);
    display: flex;
    font-size: var(--text-sm);
    gap: var(--sp-3);
    line-height: 1.55;
}

.auth-points i {
    color: var(--muted-foreground);
    flex: 0 0 auto;
    font-size: 1rem;
    line-height: 1.55;
}

.auth-field {
    margin-bottom: var(--sp-4);
}

.auth-field > .form-label {
    display: block;
    margin-bottom: var(--sp-2);
}

.password-field {
    position: relative;
}

.password-field > .form-control {
    padding-right: 2.75rem;
}

.toggle-password {
    align-items: center;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--muted-foreground);
    display: flex;
    height: 2rem;
    justify-content: center;
    position: absolute;
    right: 0.35rem;
    top: 50%;
    transform: translateY(-50%);
    width: 2rem;
}

.toggle-password:hover { color: var(--foreground); }

.auth-code-input {
    font-family: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;
    font-size: var(--text-xl);
    letter-spacing: 0.4em;
    text-align: center;
    text-indent: 0.4em;
}

/* ── 18. Time picker ─────────────────────────────────────────────────────── */

.time-picker-24 {
    position: relative;
}

.time-picker-24 .tp24-toggle {
    align-items: center;
    border-color: var(--input);
    display: flex;
    justify-content: center;
    width: 2.75rem;
}

.tp24-pop {
    background: var(--popover);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-overlay);
    display: flex;
    overflow: hidden;
    position: absolute;
    right: 0;
    top: calc(100% + var(--sp-1));
    z-index: 1060;
}

.tp24-col {
    display: flex;
    flex-direction: column;
    width: 4.25rem;
}

.tp24-col + .tp24-col {
    border-left: 1px solid var(--border);
}

.tp24-col-head {
    background: var(--muted);
    border-bottom: 1px solid var(--border);
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: var(--sp-1) 0;
    text-align: center;
    text-transform: uppercase;
}

.tp24-list {
    max-height: 12.5rem;
    overflow-y: auto;
    scrollbar-width: thin;
}

.tp24-item {
    color: var(--foreground);
    cursor: pointer;
    font-size: var(--text-base);
    font-variant-numeric: tabular-nums;
    padding: var(--sp-1) 0;
    text-align: center;
}

.tp24-item:hover {
    background: var(--accent);
}

.tp24-item.active {
    background: var(--primary);
    color: var(--primary-foreground);
    font-weight: 500;
}

/* ── 19. Renewal calendar ────────────────────────────────────────────────── */

.renewal-calendar .cal-toolbar {
    align-items: center;
    display: flex;
    gap: var(--sp-2);
}

.renewal-calendar .cal-title {
    font-weight: 600;
    min-width: 11rem;
    text-align: center;
}

.cal-grid {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    overflow: hidden;
}

.cal-dow {
    background: var(--muted);
    border-bottom: 1px solid var(--border);
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: var(--sp-2);
    text-align: center;
    text-transform: uppercase;
}

.cal-day {
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
    min-height: 6.25rem;
    padding: var(--sp-2);
}

.cal-day:nth-child(7n) {
    border-right: 0;
}

.cal-grid > .cal-day:nth-last-child(-n + 7) {
    border-bottom: 0;
}

.cal-day .cal-date {
    color: var(--muted-foreground);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    margin-bottom: var(--sp-1);
}

.cal-day.cal-outside {
    background: var(--muted);
}

.cal-day.cal-outside .cal-date {
    opacity: 0.5;
}

.cal-day.cal-today .cal-date {
    color: var(--primary);
    font-weight: 600;
}

.cal-day.cal-today {
    background: var(--primary-muted);
}

.cal-chip {
    border-radius: var(--radius-sm);
    cursor: pointer;
    display: block;
    font-size: var(--text-xs);
    font-weight: 500;
    margin-bottom: 2px;
    overflow: hidden;
    padding: 2px var(--sp-1);
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
}

.cal-chip.cal-chip-run {
    background: var(--info-bg);
    border: 1px solid var(--info-border);
    color: var(--info-fg);
}

.cal-chip.cal-chip-expiry {
    background: var(--warning-bg);
    border: 1px solid var(--warning-border);
    color: var(--warning-fg);
}

.cal-legend {
    align-items: center;
    color: var(--muted-foreground);
    display: flex;
    flex-wrap: wrap;
    font-size: var(--text-sm);
    gap: var(--sp-3);
    margin-top: var(--sp-4);
}

.cal-legend .cal-chip {
    cursor: default;
    display: inline-block;
    margin-bottom: 0;
    width: auto;
}

/* ── 20. Utilities ───────────────────────────────────────────────────────── */

.text-xs { font-size: var(--text-xs); }
.text-sm { font-size: var(--text-sm); }
.small, small { font-size: var(--text-sm); }

.font-weight-bold { font-weight: 600 !important; }
.fw-bold { font-weight: 600 !important; }

.text-primary { color: var(--primary) !important; }
.text-success { color: var(--success-fg) !important; }
.text-danger { color: var(--danger-fg) !important; }
.text-warning { color: var(--warning-fg) !important; }
.text-info { color: var(--info-fg) !important; }
.text-secondary { color: var(--muted-foreground) !important; }
.text-gray-300 { color: var(--muted-foreground) !important; }

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

.min-w-0 {
    min-width: 0;
}

.shadow-soft { box-shadow: var(--shadow-overlay) !important; }

.bg-light { background-color: var(--muted) !important; }
.bg-white { background-color: var(--card) !important; }
.border { border-color: var(--border) !important; }

/* Icon-only controls keep a 44px touch area via a transparent overlay so the
   visual size stays compact while the hit target meets the guideline. */
.hit-target {
    position: relative;
}

.hit-target::after {
    content: "";
    inset: 50% auto auto 50%;
    min-height: 44px;
    min-width: 44px;
    position: absolute;
    transform: translate(-50%, -50%);
}

.fade-in {
    animation: fadeIn 150ms ease-out;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ── 21. Scrollbar ───────────────────────────────────────────────────────── */

::-webkit-scrollbar {
    height: 10px;
    width: 10px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border: 3px solid transparent;
    background-clip: content-box;
    border-radius: var(--radius-full);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--muted-foreground);
    background-clip: content-box;
}

/* ── 22. Responsive ──────────────────────────────────────────────────────── */

/* Progressive column shedding. static/js/app.js measures every table against
   its wrapper and adds shed-p2 … shed-p8 one tier at a time until the table
   fits, so no list ever produces a horizontal scrollbar. Hand-tuned
   breakpoints were replaced by measurement because the Vietnamese labels are
   far longer than the English ones and no fixed threshold suits both. Priority
   1 and the actions column are never shed. */
.shed-p8 [data-priority="8"],
.shed-p7 [data-priority="7"],
.shed-p6 [data-priority="6"],
.shed-p5 [data-priority="5"],
.shed-p4 [data-priority="4"],
.shed-p3 [data-priority="3"],
.shed-p2 [data-priority="2"] {
    display: none;
}

@media (max-width: 1199.98px) {
    .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kpi:nth-child(2n) { border-right: 0; }
    .kpi:nth-child(4n) { border-right: 0; }
    .kpi-grid > .kpi:nth-child(n + 3) { border-top: 1px solid var(--border); }
}

/* The sidebar costs 248px of content width — more than any table can spare on
   a small screen — so it collapses behind the toggle well before the phone
   breakpoint. */
@media (max-width: 991.98px) {
    :root { --sidebar-width: 248px; }
    .main-content > .container-fluid.py-3 { padding: var(--sp-5) var(--sp-4) var(--sp-7) !important; }
    .main-content > .container-fluid.mt-3 { padding-inline: var(--sp-4); }
    .top-navbar { padding-inline: var(--sp-4); }

    .sidebar {
        transform: translateX(-100%);
        transition: transform var(--motion);
    }

    .sidebar.show {
        box-shadow: var(--shadow-modal);
        transform: translateX(0);
    }

    .main-content { margin-left: 0; }

    .top-navbar .sidebar-toggle { display: inline-flex; }

    body.sidebar-open { overflow: hidden; }

    .sidebar-backdrop {
        background: rgb(0 0 0 / 45%);
        display: block;
        inset: 0;
        opacity: 0;
        pointer-events: none;
        position: fixed;
        transition: opacity var(--motion);
        z-index: 999;
    }

    .sidebar-backdrop.show {
        opacity: 1;
        pointer-events: auto;
    }
}

@media (max-width: 767.98px) {
    :root {
        --h-sm: 2.5rem;
        --h-base: 2.75rem;
        --h-lg: 2.75rem;
    }

    .btn-sm,
    .btn-group-sm > .btn { padding: var(--sp-2) var(--sp-3); }

    .kpi-grid { grid-template-columns: minmax(0, 1fr); }
    .kpi { border-right: 0; }
    .kpi-grid > .kpi:nth-child(n + 2) { border-top: 1px solid var(--border); }
}

@media (max-width: 575.98px) {
    .top-navbar {
        gap: var(--sp-2);
        padding-inline: var(--sp-3);
    }

    .main-content > .container-fluid.py-3 { padding-inline: var(--sp-3) !important; }
    .main-content > .container-fluid.mt-3 { padding-inline: var(--sp-3); }

    .card-body { padding: var(--sp-4); }
    .card-header { padding: var(--sp-3) var(--sp-4); }

    .app-user-chip {
        max-width: 9rem;
    }

    .app-user-chip__name {
        min-width: 0;
    }

    .auth-card { padding: var(--sp-5); }

    .detail-row {
        flex-direction: column;
        gap: var(--sp-1);
    }

    .detail-row > dt,
    .detail-row__label { flex-basis: auto; }

    .tenant-detail-table,
    .tenant-detail-table tbody,
    .tenant-detail-table tr,
    .tenant-detail-table td {
        display: block;
        width: 100%;
    }

    .tenant-detail-table td:first-child {
        border-bottom: 0;
        padding-bottom: 0;
        width: 100%;
    }

    .tenant-detail-table td:last-child { padding-top: var(--sp-1); }

    .marketplace-purchase-form .input-group > .form-control,
    .marketplace-purchase-form .input-group > .btn {
        border-radius: var(--radius-md) !important;
        flex: 1 0 100%;
        margin-top: var(--sp-1);
    }

    .tenant-responsive-table thead { display: none; }

    /* Card-shaped rows stop being a table, so the scroll floor no longer applies */
    .table-responsive > .tenant-responsive-table { min-width: 0; }

    /* Card-shaped rows need the padding the flush table body gave up */
    .card-body.is-flush > .table-responsive > .tenant-responsive-table {
        padding: var(--sp-4);
    }

    .tenant-responsive-table,
    .tenant-responsive-table tbody,
    .tenant-responsive-table tr,
    .tenant-responsive-table td {
        display: block;
        width: 100%;
    }

    .tenant-responsive-table tr {
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        margin-bottom: var(--sp-3);
        padding: var(--sp-3);
    }

    .tenant-responsive-table td {
        border: 0;
        display: flex;
        gap: var(--sp-3);
        justify-content: space-between;
        padding: var(--sp-1) 0;
    }

    .tenant-responsive-table td::before {
        color: var(--muted-foreground);
        content: attr(data-label);
        flex: 0 0 6.5rem;
        font-size: var(--text-xs);
        font-weight: 500;
    }

    .tenant-responsive-table td > *:not(form) { min-width: 0; }

    .tenant-responsive-table .form-check {
        margin-bottom: 0;
        min-height: auto;
        padding-left: 0;
    }
}

/* Touch targets. Desktop keeps the compact admin density (WCAG 2.2 AA only
   asks for 24x24, which the base sizes already clear). On touch pointers every
   genuinely tappable control is grown to 44x44. */
@media (pointer: coarse) {
    .btn,
    .btn-sm,
    .btn-group-sm > .btn,
    .page-link,
    .dropdown-item,
    .form-control,
    .form-select,
    .nav-link,
    [role="button"] {
        min-height: 44px;
    }

    .table .btn,
    .btn-group-sm > .btn,
    .page-link {
        min-width: 44px;
    }

    .btn,
    .btn-sm,
    .btn-group-sm > .btn {
        align-items: center;
        display: inline-flex;
        justify-content: center;
    }

    .dropdown-item {
        align-items: center;
        display: flex;
    }

    .form-switch .form-check-input {
        height: 1.75rem;
        margin-top: 0;
        width: 3.25rem;
    }

    /* Plain checkboxes stay square; 24px clears WCAG 2.2 AA (2.5.8) and the
       surrounding row spacing keeps them from crowding each other. */
    .form-check-input:not(.form-switch .form-check-input) {
        height: 1.5rem;
        margin-top: 0;
        width: 1.5rem;
    }

    .form-check.form-switch {
        align-items: center;
        display: flex;
        min-height: 44px;
    }

    /* The row's primary link is the main way to open a record on touch. */
    .link-cell {
        align-items: center;
        display: flex;
        min-height: 44px;
    }

    .toggle-password {
        min-height: 44px;
        min-width: 44px;
    }

    /* A checkbox is small by nature; extend its target through the label. */
    .form-check:not(.form-switch) > .form-check-label {
        align-items: center;
        display: inline-flex;
        min-height: 44px;
    }
}

@media (max-width: 399.98px) {
    /* Last resort: the avatar and the role badge carry the meaning, the
       username does not fit at all. With the name gone the controls have a
       fixed width, so the page title absorbs the remaining squeeze. */
    .app-user-chip { max-width: none; }
    .app-user-chip__name { display: none; }
    .top-navbar__actions { flex: 0 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
        transition-duration: 0.01ms !important;
    }
}

@media print {
    .sidebar,
    .top-navbar,
    .page-header__actions { display: none !important; }

    .main-content { margin-left: 0; }
    .card { break-inside: avoid; }
}
