/* ============================================================================
   Product Codes — management console theme (dark)
   A single global stylesheet: design tokens, app shell, and component styles
   (including overrides of the Bootstrap classes still used by some pages).
   ========================================================================== */

:root {
    --bg: #0c0f17;
    --surface: #141926;
    --surface-2: #1a2030;
    --surface-3: #10151f;
    --border: #262d3d;
    --border-strong: #333c4f;

    --text: #e7ebf3;
    --text-soft: #b6bdcc;
    --muted: #7f8899;

    --sidebar: #0a0d14;
    --sidebar-2: #0e121c;
    --sidebar-text: #9aa3b5;
    --sidebar-text-dim: #616b80;

    --accent: #6366f1;
    --accent-hover: #7c7ef5;
    --accent-soft: rgba(99, 102, 241, 0.16);
    --accent-ring: rgba(99, 102, 241, 0.40);

    --success: #34d399;
    --success-soft: rgba(52, 211, 153, 0.14);
    --danger: #f87171;
    --danger-soft: rgba(248, 113, 113, 0.14);
    --warn: #fbbf24;

    --radius: 12px;
    --radius-sm: 8px;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.30);
    --shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    /* Chevron used for every native <select> (light stroke for dark UI). */
    --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%237f8899' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E");
}

html, body {
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    color-scheme: dark;
}

h1, h2, h3, h4 { color: var(--text); }
a { color: var(--accent-hover); text-decoration: none; }
a:hover { text-decoration: underline; }
code, .mono { font-family: var(--mono); }

/* ── App shell ──────────────────────────────────────────────────────────── */
.app-shell { display: flex; min-height: 100vh; }

.app-sidebar {
    width: 258px;
    flex-shrink: 0;
    background: var(--sidebar);
    background-image: linear-gradient(180deg, var(--sidebar-2), var(--sidebar));
    color: var(--sidebar-text);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    border-right: 1px solid var(--border);
}

.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.app-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    height: 60px;
    background: rgba(12, 15, 23, 0.80);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 24px;
}

.app-content { padding: 28px 32px 48px; max-width: 1180px; width: 100%; }

/* ── Sidebar: brand ─────────────────────────────────────────────────────── */
.sidebar-brand {
    display: flex; align-items: center; gap: 10px;
    padding: 18px 18px 14px;
}
.brand-mark {
    width: 30px; height: 30px; border-radius: 8px;
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--accent), #8b8cf7);
    color: #fff; font-weight: 700; font-size: 12px; letter-spacing: .3px;
    box-shadow: 0 2px 10px rgba(99, 102, 241, .5);
}
.brand-text { color: #fff; font-weight: 600; font-size: 15px; letter-spacing: .2px; }

/* ── Sidebar: application switcher ──────────────────────────────────────── */
.appsw { padding: 6px 16px 16px; border-bottom: 1px solid var(--border); margin-bottom: 8px; }
.appsw-label {
    display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
    color: var(--sidebar-text-dim); margin: 0 0 6px 2px; font-weight: 600;
}
.appsw-control { position: relative; }
.appsw-select {
    width: 100%;
    appearance: none; -webkit-appearance: none;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #fff;
    border-radius: var(--radius-sm);
    padding: 9px 32px 9px 11px;
    font-size: 13.5px; font-weight: 500;
    cursor: pointer;
}
.appsw-select:hover { background: rgba(255, 255, 255, 0.08); }
.appsw-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.appsw-select option { color: #e7ebf3; background: #10131c; }
.appsw-muted { color: var(--sidebar-text-dim); cursor: default; }
.appsw-caret {
    position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
    width: 12px; height: 12px; color: var(--sidebar-text); pointer-events: none;
}

/* ── Sidebar: nav ───────────────────────────────────────────────────────── */
.nav-groups { padding: 4px 12px 20px; }
.nav-group { margin-bottom: 18px; }
.nav-group-title {
    font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
    color: var(--sidebar-text-dim); font-weight: 600;
    padding: 0 10px; margin-bottom: 6px;
}
.nav-item {
    display: flex; align-items: center; gap: 11px;
    padding: 8px 10px; margin: 1px 0;
    border-radius: var(--radius-sm);
    color: var(--sidebar-text);
    font-size: 13.5px; font-weight: 500;
    text-decoration: none;
    transition: background .12s, color .12s;
}
.nav-item:hover { background: rgba(255, 255, 255, 0.05); color: #fff; text-decoration: none; }
.nav-item.active { background: var(--accent); color: #fff; box-shadow: 0 2px 12px rgba(99,102,241,.45); }
.nav-item.active .nav-ico { color: #fff; opacity: 1; }
.nav-ico { width: 18px; height: 18px; display: inline-flex; opacity: .82; }
.nav-ico svg { width: 18px; height: 18px; }

/* ── Topbar bits ────────────────────────────────────────────────────────── */
.topbar-context { display: flex; align-items: center; gap: 10px; }
.ctx-chip {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--accent-soft); color: var(--accent-hover);
    border: 1px solid rgba(99,102,241,.30);
    padding: 5px 12px; border-radius: 999px; font-size: 13px; font-weight: 600;
}
.ctx-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

.topbar-user { display: flex; align-items: center; gap: 12px; }
.user-name { font-size: 13.5px; font-weight: 600; color: var(--text); }
.user-role {
    font-size: 11px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
    color: var(--text-soft); background: var(--surface-2); border: 1px solid var(--border);
    padding: 2px 8px; border-radius: 6px;
}
.logout-form { margin: 0; }
.btn-signout {
    background: transparent; border: 1px solid var(--border-strong); color: var(--text-soft);
    padding: 6px 12px; border-radius: var(--radius-sm); font-size: 13px; font-weight: 500; cursor: pointer;
}
.btn-signout:hover { background: var(--surface-2); color: var(--text); border-color: var(--muted); }

/* ── Page primitives ────────────────────────────────────────────────────── */
.page-head { margin-bottom: 22px; }
.page-head h1 { font-size: 22px; font-weight: 700; margin: 0 0 4px; letter-spacing: -.01em; }
.page-sub { color: var(--muted); font-size: 14px; margin: 0; }
.page-sub strong { color: var(--text-soft); font-weight: 600; }

.empty-state {
    background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius);
    padding: 40px 24px; text-align: center; color: var(--muted); font-size: 14.5px;
}

/* ── Cards ──────────────────────────────────────────────────────────────── */
.card, .panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    margin-bottom: 20px;
}
.card-header, .panel-header {
    padding: 14px 18px; border-bottom: 1px solid var(--border);
    font-weight: 600; font-size: 14.5px; color: var(--text);
    background: var(--surface-2); border-radius: var(--radius) var(--radius) 0 0;
}
.card-body, .panel-body { padding: 18px; }

.toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.toolbar .grow { flex: 1; min-width: 160px; }

/* ── Forms ──────────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 5px; }
.field-label, .form-label {
    font-size: 12.5px; font-weight: 600; color: var(--text-soft); margin: 0;
}
.input, .form-control, .form-select, textarea.input, textarea.form-control {
    background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    padding: 9px 12px; font-size: 14px; color: var(--text); width: 100%;
    transition: border-color .12s, box-shadow .12s;
}
.input:focus, .form-control:focus, .form-select:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring);
}
.input::placeholder, .form-control::placeholder { color: #6a7385; }
textarea.input, textarea.form-control { min-height: 90px; resize: vertical; }

/* Every native dropdown gets an explicit chevron so it reads as a select. */
select, select.form-select, select.input {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    background-image: var(--caret);
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 34px;
    cursor: pointer;
}
select option { background: var(--surface-3); color: var(--text); }

.form-check { display: inline-flex; align-items: center; gap: 7px; }
.form-check-input {
    width: 16px; height: 16px; border: 1px solid var(--border-strong); border-radius: 4px;
    accent-color: var(--accent); cursor: pointer; background: var(--surface-3);
}
.form-check-label { font-size: 13.5px; color: var(--text-soft); cursor: pointer; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    border: 1px solid transparent; border-radius: var(--radius-sm);
    padding: 9px 16px; font-size: 14px; font-weight: 600; cursor: pointer;
    transition: background .12s, border-color .12s, color .12s, box-shadow .12s;
    line-height: 1.1; white-space: nowrap;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* Bootstrap's .btn sets color to its own --bs-body-color, which is #212529 - a LIGHT-theme
   near-black. app.css loads after Bootstrap but never set a color here, so any .btn that did not
   also carry one of the variants below inherited that near-black onto a dark surface and became
   unreadable. A .btn class also outranks the `a` rule, so anchors styled as buttons were hit too.
   Setting a themed default means a variant that is missing or misspelled degrades to readable
   rather than invisible. The variants below all set their own color and still win on order. */
.btn { color: var(--text-soft); background: transparent; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }
.btn-ghost, .btn-outline, .btn-secondary, .btn-outline-secondary {
    background: var(--surface-2); border-color: var(--border-strong); color: var(--text-soft);
}
.btn-ghost:hover, .btn-outline:hover:not(:disabled), .btn-secondary:hover:not(:disabled), .btn-outline-secondary:hover:not(:disabled) { border-color: var(--muted); color: var(--text); background: var(--surface-2); }
.btn-danger, .btn-outline-danger {
    background: var(--danger-soft); border-color: rgba(248,113,113,.35); color: var(--danger);
}
.btn-danger:hover:not(:disabled), .btn-outline-danger:hover:not(:disabled) { background: rgba(248,113,113,.22); border-color: var(--danger); color: #fff; }
.btn-sm { padding: 6px 11px; font-size: 12.5px; }
/* Bootstrap's own red, which its dark theme does not lighten. Readable, but not this
   palette's red - map it so the Error page matches everything else. */
.text-danger { color: var(--danger) !important; }
.btn-link { background: none; border: none; color: var(--accent-hover); font-weight: 600; cursor: pointer; padding: 6px 8px; }

/* ── Tables ─────────────────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
table.table, table.data { width: 100%; border-collapse: collapse; font-size: 14px; margin: 0; }
.table thead th, .data thead th {
    text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .05em;
    color: var(--muted); font-weight: 600; padding: 11px 16px;
    background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.table tbody td, .data tbody td { padding: 12px 16px; border-bottom: 1px solid var(--border); color: var(--text-soft); vertical-align: middle; }
.table tbody tr:last-child td, .data tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover td, .data tbody tr:hover td { background: rgba(255,255,255,0.02); }
.table td code, .data td code { font-size: 12.5px; color: var(--text); background: var(--surface-3); padding: 2px 6px; border-radius: 5px; border: 1px solid var(--border); }

/* ── Alerts / result blocks ─────────────────────────────────────────────── */
.alert { border-radius: var(--radius-sm); padding: 12px 15px; font-size: 14px; margin-top: 16px; border: 1px solid transparent; }
.alert-danger { background: var(--danger-soft); border-color: rgba(248,113,113,.3); color: #fca5a5; }
.alert-success { background: var(--success-soft); border-color: rgba(52,211,153,.3); color: #6ee7b7; }
.alert-info { background: var(--accent-soft); border-color: rgba(99,102,241,.3); color: var(--accent-hover); }

.result {
    margin-top: 16px; background: var(--surface-2); border: 1px solid var(--border);
    border-radius: var(--radius-sm); padding: 14px 16px;
}
.result-label { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 600; margin-bottom: 6px; }
.code-block {
    font-family: var(--mono); font-size: 12.5px; background: #080b11; color: #cdd6e6;
    border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 14px; overflow-x: auto;
    white-space: pre-wrap; word-break: break-all; margin: 8px 0 0;
}

/* ── Badges / pills ─────────────────────────────────────────────────────── */
.badge-pill {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; font-weight: 600; padding: 2px 9px; border-radius: 999px;
    background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border);
    /* A pill is a label, not a paragraph. Without this the text wraps INSIDE the pill when
       the column is narrow, which turned two-word labels ("PM approval", "Auto-publish",
       "Not scanned") into tall lumpy blobs and gave every row a different height. Let the
       column widen instead. */
    white-space: nowrap;
}
.badge-admin { background: var(--accent-soft); color: var(--accent-hover); border-color: rgba(99,102,241,.3); }
.badge-dev { background: rgba(56,140,220,.16); color: #86bdf2; border-color: rgba(56,140,220,.3); }
.badge-ok { background: var(--success-soft); color: #6ee7b7; border-color: rgba(52,211,153,.3); }
.badge-off { background: var(--surface-2); color: var(--text-soft); }
.tag-list { display: flex; flex-wrap: wrap; gap: 5px; }
.text-muted { color: var(--muted) !important; }

/* dashboard cards */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }
.tile {
    display: block; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); padding: 18px; text-decoration: none; color: inherit; transition: box-shadow .14s, transform .14s, border-color .14s;
}
.tile:hover { text-decoration: none; box-shadow: var(--shadow); transform: translateY(-1px); border-color: var(--border-strong); }
.tile-ico { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent-hover); margin-bottom: 12px; }
.tile-ico svg { width: 19px; height: 19px; }
.tile-title { font-weight: 600; font-size: 15px; margin: 0 0 3px; color: var(--text); }
.tile-desc { font-size: 13px; color: var(--muted); margin: 0; line-height: 1.45; }

/* Navigation on the overview, now that the page leads with figures. The same links carrying the
   same weight as the numbers made the page read as two competing halves, and the sidebar already
   lists all of them - so these are a compact strip, not a second set of cards. */
.tiles-compact { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; }
.tiles-compact .tile { padding: 12px 14px; display: flex; align-items: center; gap: 10px; }
.tiles-compact .tile-ico { width: 26px; height: 26px; border-radius: 7px; margin: 0; flex: 0 0 auto; }
.tiles-compact .tile-ico svg { width: 15px; height: 15px; }
.tiles-compact .tile-title { margin: 0; font-size: 13.5px; }

/* ── Overview KPIs ──────────────────────────────────────────────────────── */
.kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; margin-bottom: 8px; }
.kpi {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 14px 16px; box-shadow: var(--shadow-sm);
}
.kpi-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0 0 6px; }
/* Tabular figures so a column of numbers lines up on the decimal rather than shimmering. */
.kpi-value { font-size: 26px; font-weight: 650; color: var(--text); line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-sub { font-size: 12px; color: var(--muted); margin: 5px 0 0; }
.kpi-value.is-warn { color: var(--warn); }
.kpi-value.is-ok { color: var(--success); }

/* Sparkline. Bars rather than a line: the series is a count per day, and a line between two
   integer counts implies values in between that were never measured. */
.spark { display: flex; align-items: flex-end; gap: 3px; height: 46px; margin-top: 10px; }
.spark-bar { flex: 1 1 0; background: var(--accent-soft); border-radius: 2px 2px 0 0; min-height: 2px; }
.spark-bar.is-peak { background: var(--accent); }
.section-head { display: flex; align-items: baseline; gap: 10px; margin: 22px 0 10px; }
.section-head h2 { font-size: 15px; margin: 0; color: var(--text); }
.section-head .text-muted { font-size: 12.5px; }

/* ── Error overlay (kept from template) ─────────────────────────────────── */
#blazor-error-ui {
    color-scheme: light only; background: lightyellow; bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); box-sizing: border-box; display: none;
    left: 0; padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; z-index: 1000;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; }

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 820px) {
    .app-shell { flex-direction: column; }
    .app-sidebar { width: 100%; height: auto; position: static; flex-direction: column; }
    .nav-groups { display: flex; flex-wrap: wrap; gap: 4px 14px; }
    .nav-group { margin-bottom: 8px; }
    .app-content { padding: 20px 18px 40px; }
}

.checks { display: flex; flex-wrap: wrap; gap: 10px 22px; padding: 4px 0 2px; align-items: center; }

/* ── Neutralize Bootstrap's light table painting (dark mode) ────────────── */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-soft);
    --bs-table-accent-bg: transparent;
    --bs-table-striped-bg: transparent;
    --bs-table-striped-color: var(--text-soft);
    --bs-table-hover-bg: rgba(255, 255, 255, 0.03);
    --bs-table-hover-color: var(--text);
    --bs-table-border-color: var(--border);
    color: var(--text-soft);
    background-color: transparent;
}
.table > :not(caption) > * > * {
    background-color: transparent;
    box-shadow: none;
    color: inherit;
}
.table thead th { background: var(--surface-2); color: var(--muted); }
.table tbody tr:hover td { background: rgba(255, 255, 255, 0.03); }

a.user-name { color: var(--text); text-decoration: none; cursor: pointer; }
a.user-name:hover { color: var(--accent-hover); text-decoration: underline; }
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(1200px 600px at 50% -10%, #1c2233 0%, #0e1119 60%);
    padding: 24px;
}
.login-card {
    width: 340px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 34px 32px;
    border-radius: 16px;
    background: #171d2b;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
}
.login-card h1 {
    margin: 4px 0 0;
    font-size: 22px;
    color: #fff;
    font-weight: 700;
    letter-spacing: -.01em;
}
.login-card .sub { margin: 0 0 10px; color: #8a95ab; font-size: 13px; }
.login-card input {
    padding: 11px 13px;
    border-radius: 9px;
    border: 1px solid #2b3346;
    background: #10141f;
    color: #e6ecf5;
    font-size: 14px;
    outline: none;
    transition: border-color .12s, box-shadow .12s;
}
.login-card input::placeholder { color: #5d6880; }
.login-card input:focus { border-color: #4f46e5; box-shadow: 0 0 0 3px rgba(79, 70, 229, .3); }
.login-card button {
    margin-top: 6px;
    padding: 11px 13px;
    border: 0;
    border-radius: 9px;
    background: #4f46e5;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background .12s;
}
.login-card button:hover { background: #4338ca; }
.login-card .err { margin: 0; color: #ff8080; font-size: 13px; }

/* Passkey sign-in. Deliberately quieter than the primary submit button: it sits above the password
   fields, and two solid indigo buttons stacked would read as two ways of doing the same thing
   rather than a recommended route and a fallback. */
.login-card .passkey-btn {
    margin-top: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    background: #1d2435;
    border: 1px solid #2b3346;
    color: #e6ecf5;
}
.login-card .passkey-btn:hover:not(:disabled) { background: #232b40; border-color: #3a4459; }
.login-card .passkey-btn:disabled { opacity: .6; cursor: default; }
.passkey-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #5d6880;
    font-size: 12px;
}
.passkey-divider::before,
.passkey-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: #2b3346;
}


/* Recovery codes — shown once at enrolment, in both the forced-setup page and the profile.
   Visually distinct from the surrounding cards because scrolling past them is the mistake. */
.recovery-block {
    border: 1px solid #3a3050;
    background: #1a1626;
    border-radius: 10px;
    padding: 12px 14px;
}
.recovery-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}
.recovery-head strong { color: #c9a2ff; font-size: 14px; }
.recovery-note { margin: 0 0 10px; color: #8a95ab; font-size: 12.5px; line-height: 1.5; }
.recovery-list {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.7;
    letter-spacing: .04em;
    color: #e6ecf5;
    white-space: pre;
    overflow-x: auto;
}

/* ── Permission picker (Roles page) ──────────────────────────────────────────
   Thirty-odd permissions of wildly different label lengths. A wrapping flex row
   (.checks) turns that into ragged columns that cannot be scanned — so this is a
   fixed grid, one permission per cell, each a target you can click anywhere on. */
.perm-groups { display: flex; flex-direction: column; gap: 24px; margin-top: 20px; }

.perm-group-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding-bottom: 7px; margin-bottom: 12px; border-bottom: 1px solid var(--border);
}
.perm-group-title {
    font-size: 11.5px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--text-soft);
}
.perm-group-count { font-size: 12px; color: var(--muted); white-space: nowrap; }

.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 8px; }

.perm {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px;
    background: var(--surface-3); cursor: pointer;
    transition: border-color .12s, background .12s;
}
.perm:hover { border-color: var(--border-strong); background: var(--surface-2); }
.perm.is-on { border-color: var(--accent); background: var(--accent-soft); }
.perm input { margin: 2px 0 0; flex: 0 0 auto; }
.perm-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.perm-name { font-size: 13.5px; line-height: 1.35; color: var(--text-soft); }
.perm.is-on .perm-name { color: var(--text); }
.perm-code {
    font-size: 11px; color: var(--muted); letter-spacing: .01em;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Role-level switches: one per line, each with its own explanation. Previously
   inline, so the two ran together mid-sentence. */
.role-switches { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 4px; }
.role-switch { display: flex; gap: 10px; align-items: flex-start; }
.role-switch input { margin: 2px 0 0; flex: 0 0 auto; }
.role-switch-text { display: flex; flex-direction: column; gap: 2px; }
.role-switch-title { font-size: 13.5px; font-weight: 600; color: var(--text); }
.role-switch-note { font-size: 12.5px; color: var(--muted); line-height: 1.45; }

/* ============================================================================
   Repository browsing: header, diffs, rendered markdown.

   Built on the console's own tokens rather than a second palette. The reference
   is GitHub's information architecture, not its colors -- a repository page
   that looked like GitHub inside this console would read as an embedded iframe,
   which is the exact thing the plan rules out.
   ========================================================================= */

/* ---- repo header ---- */
.repo-head { margin: 0 0 18px; }
.repo-id { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 21px; }
.repo-owner { color: var(--text-soft); font-weight: 500; }
.repo-name { color: var(--text); font-weight: 700; }
.repo-sep { color: var(--muted); font-weight: 400; }
.repo-vis {
    font-size: 11.5px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
    color: var(--muted); border: 1px solid var(--border-strong);
    border-radius: 999px; padding: 2px 9px; margin-left: 4px;
}
.repo-vis-warn { color: var(--warn); border-color: var(--warn); }
.repo-desc { margin: 8px 0 0; color: var(--text-soft); font-size: 13.5px; max-width: 70ch; }

/* The tab strip is the spine of the whole section: adding Pull requests later is one more <a>. */
.repo-tabs { display: flex; gap: 2px; margin: 16px 0 0; border-bottom: 1px solid var(--border); }
.repo-tab {
    padding: 9px 14px; font-size: 13.5px; color: var(--text-soft);
    border-bottom: 2px solid transparent; margin-bottom: -1px; text-decoration: none;
}
.repo-tab:hover { color: var(--text); background: var(--surface-2); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.repo-tab.is-active { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }

.repo-bar {
    display: flex; gap: 14px; align-items: center; justify-content: space-between;
    flex-wrap: wrap; margin: 14px 0 0;
}
.ref-switch { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.ref-current {
    font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: var(--text);
    background: var(--accent-soft); border: 1px solid var(--accent-ring);
    border-radius: var(--radius-sm); padding: 4px 10px;
}
.ref-pill {
    font-family: var(--mono); font-size: 12px; color: var(--text-soft); text-decoration: none;
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: var(--radius-sm); padding: 3px 9px;
}
.ref-pill:hover { color: var(--text); border-color: var(--border-strong); }
.ref-pill-tag { color: var(--warn); }

.clone-box { display: flex; align-items: center; gap: 8px; }
.clone-label { font-size: 12.5px; color: var(--muted); }
.clone-url {
    font-family: var(--mono); font-size: 12px; color: var(--text-soft);
    background: var(--surface-3); border: 1px solid var(--border);
    border-radius: var(--radius-sm); padding: 5px 9px; width: 340px; max-width: 46vw;
}
.clone-hint { font-size: 12px; color: var(--muted); }

.repo-crumbs { display: flex; align-items: center; gap: 5px; font-size: 13px; }
.repo-crumb-right { margin-left: auto; font-size: 12.5px; }
.blob-meta {
    display: flex; gap: 14px; align-items: center;
    font-size: 12.5px; color: var(--muted); margin-bottom: 10px;
}
.commit-link { font-weight: 600; }
/* The repository list's way into the browser. Sized up because it is the primary action of that
   whole page, and it spent a release as a <span> that looked like a heading and did nothing. */
.repo-list-link { font-weight: 600; font-size: 14px; }

/* ---- commit ---- */
.commit-subject { margin: 0 0 8px; font-size: 17px; }
.commit-body {
    margin: 0 0 12px; font-family: var(--mono); font-size: 12.5px; line-height: 1.55;
    color: var(--text-soft); white-space: pre-wrap; word-break: break-word;
}
.commit-meta {
    display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
    font-size: 12.5px; color: var(--muted);
}
.commit-sha { font-family: var(--mono); font-size: 12px; color: var(--text-soft); }

/* ---- diff ---- */
.diff-summary {
    display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
    font-size: 13px; color: var(--text-soft); margin: 0 0 12px;
}
.diff-add { color: var(--success); font-family: var(--mono); font-size: 12.5px; }
.diff-del { color: var(--danger); font-family: var(--mono); font-size: 12.5px; }
.diff-trunc { color: var(--warn); font-size: 12.5px; }

.diff-file {
    border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface); box-shadow: var(--shadow-sm);
    margin-bottom: 14px; overflow: hidden;
}
.diff-file-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 9px 14px; background: var(--surface-2); border-bottom: 1px solid var(--border);
    font-size: 12.5px;
}
.diff-path { font-family: var(--mono); color: var(--text); word-break: break-all; }
.diff-old-path { color: var(--muted); }
.diff-counts { display: flex; gap: 7px; }
.diff-view { margin-left: auto; font-size: 12.5px; }
.diff-status {
    font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em;
    border-radius: 999px; padding: 2px 8px;
    color: var(--muted); background: var(--surface-3); border: 1px solid var(--border);
}
.diff-status-added { color: var(--success); border-color: var(--success); }
.diff-status-deleted { color: var(--danger); border-color: var(--danger); }
.diff-status-renamed { color: var(--warn); border-color: var(--warn); }
.diff-note { margin: 0; padding: 12px 14px; font-size: 12.5px; color: var(--muted); }

/* One table, four columns: old number, new number, marker, text. The marker is a real column
   rather than a ::before, so copying a diff out of the page keeps the +/- that makes it a diff. */
.diff { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12.5px; }
.diff td { padding: 0 8px; line-height: 1.5; vertical-align: top; }
.dl-num {
    width: 1%; min-width: 44px; text-align: right; color: var(--muted);
    user-select: none; border-right: 1px solid var(--border);
}
.dl-mark { width: 1%; text-align: center; color: var(--muted); user-select: none; }
/* pre-wrap, not pre: a long line has to wrap or the whole table scrolls sideways on one outlier. */
.dl-text { white-space: pre-wrap; word-break: break-word; color: var(--text-soft); }
.dl-add { background: var(--success-soft); }
.dl-add .dl-text, .dl-add .dl-mark { color: var(--success); }
.dl-remove { background: var(--danger-soft); }
.dl-remove .dl-text, .dl-remove .dl-mark { color: var(--danger); }
.dl-hunk { background: var(--surface-3); }
.dl-hunk .dl-text { color: var(--muted); font-size: 12px; }

/* ---- rendered markdown ---- */
.markdown { color: var(--text-soft); font-size: 14px; line-height: 1.65; max-width: 76ch; }
.markdown .md-h { color: var(--text); line-height: 1.3; margin: 26px 0 10px; }
.markdown .md-h:first-child { margin-top: 0; }
.markdown h1.md-h, .markdown h2.md-h { border-bottom: 1px solid var(--border); padding-bottom: 7px; }
.markdown h1.md-h { font-size: 25px; }
.markdown h2.md-h { font-size: 20px; }
.markdown h3.md-h { font-size: 16.5px; }
.markdown h4.md-h, .markdown h5.md-h, .markdown h6.md-h { font-size: 14px; }
.markdown .md-p { margin: 0 0 14px; }
.markdown .md-list { margin: 0 0 14px; padding-left: 24px; }
.markdown .md-list li { margin: 4px 0; }
.markdown .md-quote {
    margin: 0 0 14px; padding: 2px 0 2px 14px;
    border-left: 3px solid var(--border-strong); color: var(--muted);
}
.markdown .md-quote p { margin: 6px 0; }
.markdown .md-code {
    background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-sm);
    padding: 12px 14px; margin: 0 0 14px; overflow-x: auto;
    font-family: var(--mono); font-size: 12.5px; line-height: 1.5;
}
.markdown .md-inline-code {
    background: var(--surface-3); border: 1px solid var(--border); border-radius: 5px;
    padding: 1px 5px; font-family: var(--mono); font-size: 12.5px; color: var(--text);
}
.markdown .md-table-wrap { overflow-x: auto; margin: 0 0 14px; }
.markdown .md-table { border-collapse: collapse; font-size: 13px; }
.markdown .md-table th, .markdown .md-table td {
    border: 1px solid var(--border); padding: 6px 12px; text-align: left;
}
.markdown .md-table th { background: var(--surface-2); color: var(--text); font-weight: 600; }
.markdown .md-img { max-width: 100%; border-radius: var(--radius-sm); }
.markdown hr { border: 0; border-top: 1px solid var(--border); margin: 22px 0; }
.markdown del { color: var(--muted); }

/* ---- branches and tags ---- */
.ref-name { font-family: var(--mono); font-size: 13px; font-weight: 600; }
.ref-name-tag { color: var(--warn); }
.ref-pill-more { color: var(--muted); font-family: var(--font); font-style: italic; }

/* Behind on the left, ahead on the right, split at the centre -- the shape GitHub uses, because it
   makes "stale" and "unmerged" two different silhouettes rather than two numbers to read. */
.divergence { display: flex; align-items: center; gap: 7px; font-family: var(--mono); font-size: 12px; }
.divergence-behind { color: var(--danger); min-width: 24px; text-align: right; }
.divergence-ahead { color: var(--success); min-width: 24px; }
.divergence-bar { display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.divergence-bar-behind, .divergence-bar-ahead { height: 6px; border-radius: 2px; }
.divergence-bar-behind { background: var(--danger); }
.divergence-bar-ahead { background: var(--success); }
.divergence-split { width: 1px; height: 12px; background: var(--border-strong); margin: 0 2px; flex: 0 0 auto; }

/* ---- compare ---- */
/* A plain GET form: picking two refs stays a link, so the page needs no circuit like the rest. */
.compare-pick { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.compare-pick .field { min-width: 190px; }
.compare-dots { color: var(--muted); font-family: var(--mono); padding-bottom: 9px; }
.compare-summary { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; font-size: 14px; }
.compare-basis { font-size: 12.5px; }
.compare-basis code { font-family: var(--mono); }

/* ---- repository settings ---- */
/* Bordered in red because everything inside it is irreversible from the product's side. */
.danger-zone { border-color: var(--danger); }
.danger-zone .card-header { color: var(--danger); }
.danger-row {
    display: flex; align-items: center; justify-content: space-between; gap: 18px;
    flex-wrap: wrap; padding: 14px 0; border-bottom: 1px solid var(--border);
}
.danger-row:last-child { border-bottom: 0; padding-bottom: 0; }
.danger-row:first-child { padding-top: 0; }
.danger-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 3px; }
.danger-confirm { display: flex; gap: 8px; align-items: center; }
.danger-confirm .input { width: 240px; font-family: var(--mono); font-size: 12.5px; }

/* ---- build cache ---- */
/* Headline numbers first: the questions this page answers are "how big is it" and "how much of it
   is dead", and both should be readable without parsing a table. */
.cache-stats { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.stat {
    flex: 1 1 150px; padding: 14px 16px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.stat-value { font-size: 21px; font-weight: 700; color: var(--text); line-height: 1.2; }
.stat-label { font-size: 12px; color: var(--muted); margin-top: 3px; }
.stat-warn { border-color: var(--warn); }
.stat-warn .stat-value { color: var(--warn); }
.cache-name { font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--text); }
/* Dimmed rather than hidden: a stale entry is still servable, just a purge candidate. */
.row-stale { opacity: .62; }

/* Monospace so a hash reads as one, and nowrap because a truncated one must not wrap anyway. */
.cache-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.chip { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted);
        border-radius: 999px; padding: 5px 13px; font-size: .86em; cursor: pointer; }
.chip:hover { border-color: var(--accent); color: var(--text); }
.chip-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip-count { opacity: .7; margin-left: 6px; font-variant-numeric: tabular-nums; }

.cache-hash { font-family: ui-monospace, Consolas, monospace; font-size: .78em; white-space: nowrap; }

/* View-as banner. Deliberately loud: mistaking an impersonated session for your own turns every
   hidden control into a false conclusion about authorisation. */
.viewas-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 10px 22px; background: #7a4a00; color: #fff; font-size: .9em;
    border-bottom: 1px solid #a86400;
}
.viewas-banner strong { font-weight: 600; }
.viewas-banner form { margin: 0; }
.viewas-banner .btn { background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.4); color: #fff; }
.viewas-banner .btn:hover { background: rgba(255,255,255,.28); }

/* Upload progress. One row per file, several moving at once. */
.upload-row { margin-bottom: 10px; }
.upload-head { display: flex; justify-content: space-between; gap: 12px; font-size: .86em; margin-bottom: 4px; }
.upload-track { height: 6px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.upload-fill { height: 100%; background: var(--accent); transition: width .15s linear; }
.upload-fill.is-failed { background: #b04242; }
.upload-failed { color: #e08585; }

/* Check state. Colour carries the same three answers the rollup does, and never alone: the state
   word sits beside every dot, because a red/green dot is invisible to a colourblind reader. */
.check-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 8px; }
.check-success { background: #3fb950; }
.check-failure, .check-error { background: #d1414b; }
.check-pending { background: #d29922; }
.check-annotation { font-size: .82em; margin-top: 4px; padding-left: 10px; border-left: 2px solid var(--border); }
