/*
 * Refinery design tokens, ported from docs/design/Refinery.dc.html per
 * IMPLEMENTATION_PLAN.md's "Design system tokens" notes (Architecture
 * Decision 1: Twig + AssetMapper, no build step — plain CSS custom
 * properties, no Sass/PostCSS).
 */

:root {
    /* Typography */
    --font-body: 'Archivo', 'Helvetica Neue', Helvetica, sans-serif;
    --font-mono: 'IBM Plex Mono', monospace;

    /* Palette */
    --color-bg: #f1ecdf;
    --color-surface: #fffcf5;
    --color-sidebar-bg: #faf6ec;
    --color-header-bg: #f6f1e4;
    --color-row-hover: #f3edde;
    --color-border: #e3dac6;
    --color-border-muted: #ece4d2;
    --color-border-strong: #cfc5ae;
    --color-ink: #211a0e;
    --color-text-secondary: #46402f;
    --color-text-muted: #6f6757;
    --color-text-faint: #8c8271;
    /* Design's own dimmed/zero-state tone (`#c1b7a0` — disabled buttons,
       "not linked" labels, pagination arrows, "no overrides") — one shade
       lighter than `--color-text-faint`, distinct enough to be worth its
       own token rather than reusing that one for this specific treatment. */
    --color-text-dim: #c1b7a0;

    /* Severity */
    --color-severity-critical: #d84a31;
    --color-severity-critical-bg: #f9e2d6;
    --color-severity-high: #f76b15;
    --color-severity-high-bg: #fdeadb;
    --color-severity-medium: #a87716;
    --color-severity-medium-bg: #f6e8c8;
    --color-severity-low: #8c8271;
    --color-severity-low-bg: #e8dfcb;

    /* Status */
    --color-status-new: #3f382a;
    --color-status-new-bg: #ebe2cf;
    --color-status-acknowledged: #54718e;
    --color-status-acknowledged-bg: #e4e7e2;
    --color-status-snoozed: #9a6e14;
    --color-status-snoozed-bg: #f6e8c8;
    --color-status-accepted-risk: #6f6757;
    --color-status-accepted-risk-bg: #efe7d5;
    --color-status-ticketed: #211a0e;
    --color-status-ticketed-bg: #ebe2cf;
    --color-status-resolved: #4d7c3a;
    --color-status-resolved-bg: #e5eccf;

    /* Radius */
    --radius-panel: 2px;
    --radius-pill: 5px;

    --sidebar-width: 216px;
    --topbar-height: 52px;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--color-bg);
    font-family: var(--font-body);
    color: var(--color-ink);
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--color-ink);
    text-decoration: none;
}

a:hover {
    color: var(--color-text-secondary);
    text-decoration: underline;
}

select,
input,
textarea,
button {
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    color: inherit;
}

/* ---- App shell ---- */

.app-shell {
    display: flex;
    height: 100vh;
    min-width: 1024px;
    overflow: hidden;
}

.sidebar {
    width: var(--sidebar-width);
    flex: none;
    background: var(--color-sidebar-bg);
    border-right: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
}

.sidebar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 16px 14px;
}

.sidebar__logo {
    width: 26px;
    height: 26px;
    border-radius: var(--radius-panel);
    background: var(--color-ink);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.sidebar__logo-icon {
    width: 18px;
    height: 18px;
    display: block;
}

.sidebar__logo-mark {
    fill: none;
    stroke: var(--color-surface);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.sidebar__logo-mark--faint {
    opacity: 0.65;
}

.sidebar__brand-name {
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--color-ink);
}

.sidebar__nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 8px;
}

.sidebar__nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-panel);
    font-family: var(--font-mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    cursor: pointer;
    color: var(--color-text-muted);
    font-weight: 400;
    text-decoration: none;
}

.sidebar__nav-item:hover {
    background: rgba(0, 0, 0, 0.05);
    text-decoration: none;
    color: var(--color-text-muted);
}

.sidebar__nav-item.is-active {
    background: rgba(0, 0, 0, 0.08);
    color: var(--color-ink);
    font-weight: 600;
}

.sidebar__nav-icon {
    width: 15px;
    height: 15px;
    flex: none;
    opacity: 0.85;
}

.sidebar__nav-icon path {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.sidebar__nav-label {
    flex: 1;
}

.sidebar__nav-badge {
    background: var(--color-ink);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    padding: 1px 7px;
    border-radius: var(--radius-panel);
}

.sidebar__spacer {
    flex: 1;
}

.sidebar__footer {
    padding: 12px 16px;
    border-top: 1px solid var(--color-border);
    font-size: 11px;
    color: var(--color-text-faint);
    line-height: 1.6;
}

.app-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.topbar {
    height: var(--topbar-height);
    flex: none;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 20px;
    position: relative;
    z-index: 30;
}

.topbar__title {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.topbar__spacer {
    flex: 1;
}

.user-menu {
    position: relative;
}

.user-menu__trigger {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radius-panel);
    background: none;
    border: none;
}

.user-menu__trigger:hover {
    background: var(--color-status-accepted-risk-bg);
}

.user-menu__avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--color-border);
    color: var(--color-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
}

.user-menu__name {
    font-size: 12px;
    font-weight: 500;
}

.user-menu__caret {
    color: var(--color-text-faint);
    font-size: 10px;
}

.user-menu__dropdown {
    position: absolute;
    right: 0;
    top: 40px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    width: 210px;
    padding: 6px;
    z-index: 40;
}

.user-menu__email {
    padding: 6px 10px;
    font-size: 12px;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border-muted);
    margin-bottom: 4px;
    word-break: break-all;
}

.user-menu__signout {
    display: block;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 13px;
    color: var(--color-text-muted);
    cursor: pointer;
}

.user-menu__signout:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
    text-decoration: none;
}

.app-content {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
    padding: 20px 24px;
}

/*
 * Findings Inbox opts out of the standard padded/max-width content area —
 * per the design, its filter bar/table/hint bar fill the full remaining
 * viewport height edge-to-edge (see docs/design/Refinery.dc.html's
 * "Findings Inbox" screen).
 */
.app-content--flush {
    padding: 0;
    max-width: none;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/*
 * Fleet Dashboard/Rules Settings both go full-width as a deliberate deviation
 * from the design (which caps them at 1320px/980px respectively) — unlike
 * Findings, they keep the standard padded layout, just without the max-width
 * ceiling, so `--flush`'s padding/flex-column reset would be wrong here.
 */
.app-content--wide {
    max-width: none;
}

/* ---- Shared surfaces ---- */

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    overflow: hidden;
}

.badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    border-radius: 4px;
    padding: 1px 5px;
}

.pill {
    display: inline-block;
    font-size: 11px;
    font-weight: 500;
    border-radius: var(--radius-pill);
    padding: 2px 8px;
}

/* ---- Projects Registry ---- */

.registry__head,
.registry__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    font-size: 13px;
}

.registry__head {
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.registry__row {
    border-bottom: 1px solid var(--color-border-muted);
}

.registry__row:last-child {
    border-bottom: none;
}

.registry__row:hover {
    background: var(--color-row-hover);
}

.registry__col--name {
    flex: 1.2;
    font-weight: 600;
}

.registry__col--customer {
    flex: 1;
    color: var(--color-text-muted);
    font-size: 12px;
}

.registry__col--hoster {
    width: 130px;
    color: var(--color-text-muted);
    font-size: 12px;
}

.registry__col--version {
    width: 150px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.registry__col--uptime {
    width: 80px;
    text-align: right;
    font-size: 12px;
}

.registry__col--collector {
    width: 120px;
    text-align: right;
}

/*
 * Stage 6: "Open findings"/"Activity" columns, added between PHP and
 * Uptime per the design's exact column order. Widths match the design's
 * own `width:150px`/`width:104px` for these two columns.
 */
.registry__col--findings {
    width: 150px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.registry__severity-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 12px;
    color: var(--color-text-secondary);
}

.registry__all-clear {
    color: var(--color-status-resolved);
    font-weight: 500;
    font-size: 12px;
}

.registry__col--activity {
    width: 104px;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--color-text-muted);
}

.registry__activity-badge {
    font-size: 9px;
    font-weight: 600;
    color: var(--color-ink);
    background: var(--color-status-new-bg);
    border-radius: 4px;
    padding: 1px 5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/*
 * Stage 6: sortable column headers, same idiom `.findings__head-link`/
 * `.findings__head-arrow` already established for the Findings Inbox
 * (`App\Registry\ProjectsRegistryFilter` is this screen's counterpart of
 * `App\Findings\FindingsFilter`'s `sort`/`dir` half).
 */
.registry__head-link {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 3px;
}

.registry__head-link:hover {
    color: var(--color-ink);
}

.registry__head-link--active {
    color: var(--color-ink);
}

.registry__head-arrow {
    font-size: 8px;
}

.registry__version-value {
    white-space: nowrap;
}

.registry__empty {
    padding: 40px 16px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

.registry__project-link {
    color: inherit;
    text-decoration: none;
}

.registry__project-link:hover {
    text-decoration: underline;
}

.registry__footnote {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 12px;
}

/* ---- Customers Registry (Stage 2) ---- */

.customers__intro {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.6;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.customers__head-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 0 10px;
}

.customers__count {
    font-size: 12px;
    color: var(--color-text-faint);
}

.customers__col--name {
    flex: 1.4;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.customers__col--health {
    width: 120px;
}

.customers__col--budget {
    width: 130px;
}

.customers__col--revenue {
    width: 170px;
}

.customers__revenue-amount {
    display: block;
    font-weight: 600;
    white-space: nowrap;
}

.customers__revenue-delta {
    display: block;
    font-size: 10px;
    margin-top: 1px;
    white-space: nowrap;
}

.customers__col--lead {
    width: 110px;
    color: var(--color-text-secondary);
    font-size: 12px;
}

.customers__col--projects {
    width: 140px;
}

.customers__col--actions {
    width: 96px;
    flex: none;
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-end;
}

.customers__action-btn {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: 5px;
    padding: 0 10px;
    height: 24px;
    cursor: pointer;
    color: var(--color-text-muted);
    text-decoration: none;
}

.customers__action-btn:hover {
    border-color: #b3a98f;
    color: var(--color-ink);
}

.customers__action-btn--danger {
    padding: 0 8px;
    border-color: #f0c6b8;
    color: var(--color-severity-critical);
}

.customers__action-btn--danger:hover {
    border-color: var(--color-severity-critical);
}

.customers__delete-form {
    display: inline-flex;
}

.customers__avatar {
    width: 28px;
    height: 28px;
    flex: none;
    border-radius: 50%;
    background: var(--color-border-muted);
    color: var(--color-text-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    object-fit: contain;
}

.customers__budget-label {
    display: block;
    font-size: 11px;
    font-weight: 500;
}

.customers__budget-track {
    height: 5px;
    background: var(--color-border-muted);
    border-radius: 3px;
    margin-top: 4px;
    overflow: hidden;
}

.customers__budget-bar {
    display: block;
    height: 100%;
    background: var(--color-status-resolved);
    border-radius: 3px;
}

.customers__no-budget {
    font-size: 11px;
    color: var(--color-text-faint);
}

.customers__project-count {
    display: block;
    font-size: 12px;
}

.customers__severity-chips {
    display: flex;
    gap: 6px;
    font-size: 10px;
    flex-wrap: wrap;
    margin-top: 2px;
}

.customers__severity-chip {
    font-weight: 600;
}

.customers__all-clear {
    color: var(--color-status-resolved);
    font-weight: 500;
}

/* ---- Placeholder ("coming soon") screens ---- */

.placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 320px;
}

.placeholder__card {
    text-align: center;
    padding: 40px 48px;
}

.placeholder__eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-faint);
}

.placeholder__title {
    font-size: 20px;
    font-weight: 600;
    margin-top: 8px;
    color: var(--color-ink);
}

.placeholder__body {
    margin-top: 8px;
    font-size: 13px;
    color: var(--color-text-muted);
}

/* ---- Findings Inbox ---- */

.findings-screen {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.findings {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.severity-dot {
    width: 8px;
    height: 8px;
    flex: none;
    border-radius: 50%;
    display: inline-block;
}

.btn {
    font-size: 13px;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    border-radius: var(--radius-panel);
    padding: 8px 14px;
    cursor: pointer;
    color: var(--color-text-secondary);
}

.btn:hover {
    border-color: #b3a98f;
}

.btn--outline {
    display: inline-block;
}

.btn--muted {
    color: var(--color-text-muted);
}

.btn--stub {
    opacity: 0.55;
    cursor: not-allowed;
}

.btn--danger {
    border-color: #f0c6b8;
    color: var(--color-severity-critical);
}

.btn--danger:hover {
    border-color: var(--color-severity-critical);
}

/* QA fix: native `disabled` buttons/inputs (e.g. the ticketed Finding
   Detail overlay's Acknowledge/Snooze/Accept-risk row) don't otherwise look
   visually different from `.btn` — same treatment as `.btn--stub` above. */
.btn:disabled,
.finding-detail__note:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.findings__filterbar {
    flex: none;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 10px 20px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.findings__select {
    font-size: 12px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 5px 8px;
    background: var(--color-surface);
    color: var(--color-text-secondary);
    cursor: pointer;
}

.findings__new-only {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--color-text-secondary);
    cursor: pointer;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 5px 10px;
}

.findings__filterbar-spacer {
    flex: 1;
}

.findings__count {
    font-size: 12px;
    color: var(--color-text-faint);
}

.findings__bulkbar {
    flex: none;
    background: #ebe2cf;
    border-bottom: 1px solid var(--color-border-strong);
    padding: 7px 20px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
}

.findings__bulkbar-count {
    font-weight: 600;
    color: var(--color-text-secondary);
}

.findings__bulkbar-btn {
    font-size: 12px;
    border: 1px solid #c9bfa8;
    background: var(--color-surface);
    border-radius: 6px;
    padding: 4px 10px;
    cursor: pointer;
    color: var(--color-text-secondary);
}

.findings__bulkbar-btn:hover {
    border-color: var(--color-ink);
}

.findings__bulkbar-clear {
    color: var(--color-text-muted);
    cursor: pointer;
    margin-left: 4px;
}

.findings__bulkbar-clear:hover {
    color: var(--color-ink);
}

/*
 * QA fix: the Findings Inbox table had no column header row at all — most
 * visibly, the bare `.finding-row__occ`/`.finding-row__age` numbers had no
 * label explaining what they were. Column widths mirror the `.finding-row__*`
 * cells below so the labels line up with their values; look/feel (mono,
 * uppercase, muted-on-header-bg) matches `.registry__head`/
 * `.audit-log__col--*` elsewhere in this file.
 */
.findings__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 20px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    flex: none;
}

.findings__head-col--checkbox {
    width: 14px;
    flex: none;
}

/*
 * Stage 5: wide enough to fit the "Severity" label (the design's dot
 * column is otherwise unlabeled) while still lining up with
 * `.finding-row__severity` below, which wraps the 8px `.severity-dot` at
 * the same width rather than resizing the shared `.severity-dot` class
 * itself (used un-wrapped on several other screens).
 */
.findings__head-col--severity {
    width: 64px;
    flex: none;
}

/*
 * Stage 5: the design has no standalone "Rule" header/column — the old
 * `.findings__head-col--rule` is gone, and this "Finding" column now
 * covers both the rule-key secondary text and the title
 * (`.finding-row__finding` below), same as it did before this stage.
 */
.findings__head-col--finding {
    flex: 1;
    min-width: 0;
}

.findings__head-link {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.findings__head-link:hover {
    color: var(--color-ink);
}

.findings__head-link--active {
    color: var(--color-ink);
}

.findings__head-arrow {
    font-size: 8px;
}

.findings__head-col--project {
    flex: none;
    max-width: 140px;
}

.findings__head-col--occ {
    width: 30px;
    flex: none;
    text-align: right;
}

.findings__head-col--age {
    width: 36px;
    flex: none;
    text-align: right;
}

.findings__head-col--status {
    flex: none;
    width: 90px;
}

.findings__head-col--actions {
    flex: none;
    width: 176px;
}

.findings__rows {
    flex: 1;
    overflow-y: auto;
    background: var(--color-surface);
}

.findings__empty {
    padding: 60px 20px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

.findings__empty-reset {
    margin-top: 14px;
}

.findings__pagination {
    flex: none;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 20px;
    border-top: 1px solid var(--color-border);
    font-size: 12px;
    color: var(--color-text-muted);
}

.finding-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 20px;
    height: 40px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
    transition: opacity 260ms ease, transform 260ms ease, background-color 0.1s;
}

.finding-row:hover {
    background: var(--color-row-hover);
}

.finding-row--selected {
    background: var(--color-row-hover);
    box-shadow: inset 2px 0 0 var(--color-ink);
}

.finding-row--exiting {
    opacity: 0;
    transform: translateX(12px);
    pointer-events: none;
}

.finding-row__checkbox {
    width: 14px;
    height: 14px;
    flex: none;
    accent-color: var(--color-ink);
    cursor: pointer;
}

/*
 * Stage 5: wraps the shared `.severity-dot` at the same 64px width as
 * `.findings__head-col--severity` above so the dot lines up under its new
 * "Severity" header label — `.severity-dot` itself stays untouched since
 * it's also used un-wrapped on several other screens (Customers, Dashboard,
 * Rules, Finding Detail).
 */
.finding-row__severity {
    width: 64px;
    flex: none;
    display: flex;
    align-items: center;
}

/*
 * Stage 5: the rule key and title now share one Finding cell (no separate
 * "Rule" column) — `.finding-row__rule` lost its fixed 58px width since it
 * no longer has to line up with a header column of its own.
 */
.finding-row__finding {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
}

.finding-row__rule {
    font-size: 11px;
    font-weight: 600;
    color: var(--color-text-muted);
    flex: none;
    font-family: var(--font-mono);
}

.finding-row__title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: var(--color-ink);
}

.finding-row__project {
    font-size: 11px;
    color: var(--color-text-muted);
    background: var(--color-status-accepted-risk-bg);
    border-radius: 5px;
    padding: 2px 7px;
    flex: none;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.finding-row__occ {
    font-size: 11px;
    color: var(--color-text-faint);
    width: 30px;
    text-align: right;
    flex: none;
}

.finding-row__age {
    font-size: 12px;
    color: var(--color-text-faint);
    width: 36px;
    text-align: right;
    flex: none;
}

.finding-row__actions {
    display: flex;
    gap: 4px;
    flex: none;
    width: 176px;
    justify-content: flex-end;
}

.finding-row__actions form {
    display: contents;
}

.finding-row__action-btn {
    font-size: 11px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: 5px;
    padding: 0 8px;
    height: 22px;
    cursor: pointer;
    color: var(--color-text-muted);
    opacity: 0.8;
}

.finding-row__action-btn:hover {
    opacity: 1;
    border-color: #b3a98f;
    color: var(--color-ink);
}

a.finding-row__action-btn {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
}

/* ---- Finding Detail overlay ---- */

turbo-frame#finding-detail-frame:empty {
    display: none;
}

turbo-frame#finding-detail-frame:not(:empty) {
    position: fixed;
    inset: 0;
    z-index: 41;
    background: rgba(33, 26, 14, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
}

.finding-detail {
    width: 900px;
    max-width: 94vw;
    max-height: 88vh;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.2);
    border-radius: var(--radius-panel);
    display: flex;
    flex-direction: column;
}

.finding-detail__header {
    flex: none;
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border);
}

.finding-detail__header-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.finding-detail__sev-label {
    font-size: 12px;
    font-weight: 600;
}

.finding-detail__rule {
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--color-text-muted);
}

.finding-detail__id {
    font-size: 12px;
    color: var(--color-text-faint);
}

.finding-detail__spacer {
    flex: 1;
}

.finding-detail__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
}

.finding-detail__close:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
}

.finding-detail__title {
    font-size: 15px;
    font-weight: 600;
    margin-top: 8px;
    line-height: 1.4;
}

.finding-detail__meta {
    display: flex;
    gap: 14px;
    margin-top: 8px;
    font-size: 12px;
    color: var(--color-text-muted);
}

/*
 * QA fix: prominent link to the real GitLab issue once a Ticket exists for
 * this Finding (`ticket` in templates/findings/_detail.html.twig) — sits
 * between the header and the evidence/history body, same full-width flex
 * child treatment as `.finding-detail__header`/`.finding-detail__footer`.
 */
.finding-detail__ticket-banner {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 20px;
    background: var(--color-status-ticketed-bg);
    border-bottom: 1px solid var(--color-border);
    font-size: 12px;
}

.finding-detail__ticket-banner-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
}

.finding-detail__ticket-banner-link {
    font-weight: 600;
    color: var(--color-status-acknowledged);
}

.finding-detail__ticket-banner-link:hover {
    text-decoration: underline;
}

.finding-detail__ticket-banner-state {
    color: var(--color-text-faint);
}

.finding-detail__body {
    flex: 1;
    overflow-y: auto;
    padding: 18px 22px;
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: 26px;
    align-items: start;
}

.finding-detail__section-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 8px;
}

.finding-detail__history-row {
    display: flex;
    gap: 10px;
    font-size: 12px;
    padding: 6px 0;
    border-bottom: 1px solid var(--color-border-muted);
}

.finding-detail__history-age {
    color: var(--color-text-faint);
    width: 70px;
    flex: none;
}

.finding-detail__footer {
    flex: none;
    border-top: 1px solid var(--color-border);
    padding: 12px 20px;
    display: flex;
    gap: 8px;
    align-items: center;
}

.finding-detail__readonly {
    font-size: 12px;
    color: var(--color-text-faint);
}

.finding-detail__action-form {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
}

.finding-detail__note {
    flex: 1;
    font-size: 12px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 7px 10px;
    background: var(--color-surface);
}

/* ---- Ticket Draft Modal (Stage 3) ---- */

.ticket-draft-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.ticket-draft-modal[hidden] {
    display: none;
}

.ticket-draft-modal__panel {
    width: 640px;
    max-width: 94vw;
    max-height: 88vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-panel);
    padding: 18px 20px;
}

.ticket-draft-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 600;
    margin-bottom: 14px;
}

.ticket-draft-modal__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
}

.ticket-draft-modal__close:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
}

.ticket-draft-modal__loading {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 40px 0;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: 13px;
}

/*
 * QA fix: this unconditional `display: flex` outranked the browser's default
 * `[hidden] { display: none }` UA rule (author styles win cascade ties
 * against UA styles regardless of specificity), so the Stimulus controller
 * setting `loadingTarget.hidden = true` once loading finished never actually
 * hid the spinner — it kept rendering on top of/alongside the completed
 * draft or the error/retry message. Same fix already applied to the parent
 * `.ticket-draft-modal[hidden]` rule above; this just extends it to the
 * spinner specifically, since that's the element the controller toggles.
 */
.ticket-draft-modal__loading[hidden] {
    display: none;
}

.ticket-draft-modal__spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--color-border-strong);
    border-top-color: var(--color-ink);
    border-radius: 50%;
    animation: ticket-draft-spin 0.8s linear infinite;
}

@keyframes ticket-draft-spin {
    to {
        transform: rotate(360deg);
    }
}

.ticket-draft-modal__error {
    padding: 24px 0;
    text-align: center;
    color: var(--color-text-secondary);
    font-size: 13px;
}

.ticket-draft-modal__error p {
    margin-bottom: 10px;
}

.ticket-draft-modal__field {
    display: block;
    margin-bottom: 12px;
    font-size: 12px;
    color: var(--color-text-muted);
}

.ticket-draft-modal__field span {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
}

.ticket-draft-modal__field input,
.ticket-draft-modal__field textarea {
    width: 100%;
    font-size: 13px;
    font-family: inherit;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 8px 10px;
    background: var(--color-surface);
    color: var(--color-ink);
    resize: vertical;
}

.ticket-draft-modal__estimate {
    font-size: 12px;
    color: var(--color-text-muted);
    margin-bottom: 10px;
}

.ticket-draft-modal__similar {
    font-size: 12px;
    margin-bottom: 14px;
}

.ticket-draft-modal__similar a {
    color: var(--color-ink);
}

.ticket-draft-modal__submit-error {
    font-size: 12px;
    color: #d84a31;
    margin-bottom: 10px;
}

.ticket-draft-modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ---- Root Cause Hypothesis Modal (post-launch AI root-cause hypothesis feature) ---- */
/* Same visual treatment as the Ticket Draft Modal above, reused for
   consistency (loading spinner, error+retry, panel chrome) — see
   `App\Controller\Api\RootCauseHypothesisController`'s docblock for why this
   is a single generate-and-persist action with no separate edit/submit step,
   unlike the Ticket Draft Modal's two-step flow. */

.root-cause-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.root-cause-modal[hidden] {
    display: none;
}

.root-cause-modal__panel {
    width: 560px;
    max-width: 94vw;
    max-height: 88vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-panel);
    padding: 18px 20px;
}

.root-cause-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 600;
    margin-bottom: 14px;
}

.root-cause-modal__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
}

.root-cause-modal__close:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
}

.root-cause-modal__loading {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 40px 0;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: 13px;
}

/* QA fix: see `.ticket-draft-modal__loading[hidden]`'s comment above — same
   bug, same fix, same reason. */
.root-cause-modal__loading[hidden] {
    display: none;
}

.root-cause-modal__spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--color-border-strong);
    border-top-color: var(--color-ink);
    border-radius: 50%;
    animation: ticket-draft-spin 0.8s linear infinite;
}

.root-cause-modal__error {
    padding: 24px 0;
    text-align: center;
    color: var(--color-text-secondary);
    font-size: 13px;
}

.root-cause-modal__error p {
    margin-bottom: 10px;
}

.root-cause-modal__text {
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-ink);
    margin-bottom: 14px;
}

.root-cause-modal__commits {
    font-size: 12px;
    margin-bottom: 14px;
}

.root-cause-modal__commits a {
    color: var(--color-ink);
}

.root-cause-modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.root-cause-panel {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 12px;
    margin-bottom: 10px;
    font-size: 12px;
}

.root-cause-panel__label {
    font-weight: 600;
    margin-bottom: 6px;
}

.root-cause-panel__generated-at {
    font-weight: 400;
    color: var(--color-text-faint);
}

.root-cause-panel__text {
    color: var(--color-text-secondary);
    margin-bottom: 8px;
}

/* ---- Evidence blocks ---- */

.evidence-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 12px;
}

.evidence-kv {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 12px;
    padding: 5px 0;
}

.evidence-kv span {
    color: var(--color-text-faint);
}

.evidence-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin-top: 10px;
    font-size: 12px;
}

.evidence-cve__head {
    display: flex;
    align-items: center;
    gap: 8px;
}

.evidence-cve__id {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
}

.evidence-cve__cvss {
    font-size: 11px;
    font-weight: 600;
    color: #fff;
    border-radius: 4px;
    padding: 2px 7px;
}

.evidence-cve__summary {
    font-size: 12px;
    color: var(--color-text-secondary);
    margin-top: 8px;
    line-height: 1.55;
}

.evidence-eol {
    display: flex;
    align-items: center;
    gap: 16px;
}

.evidence-eol__ring {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    border-width: 5px;
    border-style: solid;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: none;
}

.evidence-eol__days {
    font-size: 17px;
    font-weight: 700;
}

.evidence-eol__unit {
    font-size: 9px;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.evidence-eol__meta {
    font-size: 12px;
    line-height: 1.7;
    color: var(--color-text-secondary);
}

.evidence-eol__meta span {
    color: var(--color-text-faint);
}

.evidence-dep-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11px;
}

.evidence-dep-table th {
    text-align: left;
    font-size: 10px;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    background: var(--color-header-bg);
    padding: 6px 8px;
    border-bottom: 1px solid var(--color-border);
}

.evidence-dep-table td {
    padding: 6px 8px;
    border-bottom: 1px solid var(--color-border-muted);
}

.evidence-dep-table__pkg {
    font-family: var(--font-mono);
}

.evidence-collector__head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
}

.evidence-collector__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--color-severity-high);
}

.evidence-generic__empty {
    font-size: 12px;
    color: var(--color-text-faint);
}

/*
 * QA fix: TW-001 (Tideways exception) evidence — `App\Findings\EvidenceType`
 * previously had no `TW-` case, so this fell through to the generic
 * key/value dump, rendering nested arrays (`lastStackTrace`, `transactions`,
 * `environments`) as raw `json_encode` strings. `.evidence-stacktrace`
 * mirrors `.evidence-dep-table`'s bordered/mono treatment above, but as a
 * scrollable list rather than a table, since a stack frame is a single
 * file:line + function rather than tabular columns.
 */
.evidence-tideways__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.evidence-tideways__type {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
}

.evidence-tideways__occurrences {
    font-size: 11px;
    color: var(--color-text-faint);
    flex: none;
}

.evidence-tideways__message {
    font-size: 12px;
    color: var(--color-text-secondary);
    margin-top: 8px;
    line-height: 1.55;
}

.evidence-tideways__stack-label {
    font-size: 10px;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-top: 14px;
    margin-bottom: 6px;
}

.evidence-stacktrace {
    list-style: none;
    margin: 0;
    padding: 0;
    font-family: var(--font-mono);
    font-size: 11px;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border-muted);
    border-radius: var(--radius-panel);
    max-height: 220px;
    overflow-y: auto;
}

.evidence-stacktrace__frame {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    padding: 5px 8px;
    border-bottom: 1px solid var(--color-border-muted);
    overflow: hidden;
}

.evidence-stacktrace__frame:last-child {
    border-bottom: none;
}

.evidence-stacktrace__location {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    color: var(--color-ink);
}

.evidence-stacktrace__fn {
    color: var(--color-text-faint);
    flex: none;
}

.evidence-stacktrace__more {
    padding: 5px 8px;
    color: var(--color-text-faint);
    font-style: italic;
}

/* ---- Rules Settings ---- */

/*
 * `.rules-screen` itself carries no styles — it's purely the
 * `data-controller="rule-drawer"` mount point
 * (`templates/rules/index.html.twig`). IMPLEMENTATION_PLAN.md Stage
 * 10/Decision 1 moved this screen's width to `.app-content--wide` (see that
 * class's docblock), replacing the 980px cap this selector used to carry.
 */

.rules__banner {
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 12px 16px;
    margin-bottom: 18px;
    display: flex;
    gap: 12px;
}

.rules__banner-icon {
    width: 16px;
    height: 16px;
    flex: none;
    margin-top: 1px;
    color: var(--color-text-muted);
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.rules__banner-text {
    font-size: 12px;
    line-height: 1.65;
    color: var(--color-text-secondary);
    flex: 1;
}

.rules__banner-action {
    flex: none;
    align-self: center;
    white-space: nowrap;
}

.rules__group {
    margin-bottom: 18px;
}

.rules__group-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-bottom: 8px;
}

.rules__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
}

.rules__row:last-child {
    border-bottom: none;
}

.rules__row:hover {
    background: var(--color-row-hover);
}

.rules__key {
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
    color: var(--color-ink);
    width: 70px;
    flex: none;
}

.rules__info {
    flex: 1;
    min-width: 0;
}

.rules__name {
    font-weight: 500;
}

.rules__desc {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 1px;
}

.rules__severity {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--color-text-muted);
    width: 90px;
    flex: none;
}

.rules__overrides-link,
.rules__overrides-count {
    font-size: 11px;
    width: 96px;
    text-align: right;
    flex: none;
}

.rules__overrides-link {
    color: var(--color-ink);
    cursor: pointer;
}

.rules__overrides-link:hover {
    text-decoration: underline;
}

.rules__overrides-count {
    color: var(--color-text-faint);
}

/*
 * "0 overrides" → "no overrides" (IMPLEMENTATION_PLAN.md Stage 10 fix) gets
 * the design's own dimmed treatment instead of the link/count's normal
 * color — a project with no overrides tuned is a non-event, not something
 * worth the same visual weight as one that actually has per-project tuning.
 */
.rules__overrides-link--zero,
.rules__overrides-count--zero {
    color: var(--color-text-dim);
}

.rules__toggle-form {
    flex: none;
}

.rules__toggle,
.rules__toggle--readonly {
    width: 32px;
    height: 18px;
    border-radius: 999px;
    background: var(--color-border-strong);
    position: relative;
    display: inline-block;
    flex: none;
    border: none;
    padding: 0;
    transition: background 0.15s;
}

.rules__toggle {
    cursor: pointer;
}

.rules__toggle--readonly {
    /* QA fix: was `cursor: default; opacity: 0.7`, visually near-identical
       to the interactive `.rules__toggle` — a pm/dev viewer had no clear
       cue this control isn't clickable. Reuses this app's existing
       disabled-state convention (`.btn:disabled`/`.btn--stub` above)
       instead of inventing a new one. */
    cursor: not-allowed;
    opacity: 0.55;
}

.rules__toggle.is-on,
.rules__toggle--readonly.is-on {
    background: var(--color-ink);
}

.rules__toggle-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--color-surface);
    transition: left 0.15s;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.rules__toggle.is-on .rules__toggle-knob,
.rules__toggle--readonly.is-on .rules__toggle-knob {
    left: 16px;
}

.rules__empty {
    padding: 40px 16px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

/* ---- Suggest Rule Modal (Stage 4) ---- */

.suggest-rule-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.suggest-rule-modal[hidden] {
    display: none;
}

.suggest-rule-modal__hint {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 4px;
}

/*
 * QA fix (IMPLEMENTATION_PLAN.md Stage 10): this modal reuses
 * `.customer-modal__panel`'s shell (see `templates/rules/_suggest_modal
 * .html.twig`'s docblock) but the design's own Suggest Rule Modal is 480px,
 * not the Customer/Staff Modal's 460px. Field labels no longer need a
 * per-modal override — `.wizard__label`'s own default now matches the
 * design's mono/uppercase/10px treatment everywhere it's used (QA
 * polish pass: the Customer/Staff Modal's plain-label look was the actual
 * design-fidelity gap, not this modal's mono labels).
 */
.customer-modal__panel.suggest-rule-modal__panel {
    width: 480px;
}

/* ---- Rule overrides drawer ---- */

turbo-frame#rule-overrides-drawer:empty {
    display: none;
}

turbo-frame#rule-overrides-drawer:not(:empty) {
    position: fixed;
    inset: 0;
    z-index: 44;
    background: rgba(33, 26, 14, 0.18);
    display: flex;
    justify-content: flex-end;
}

.rule-drawer {
    /* QA fix (IMPLEMENTATION_PLAN.md Stage 10): was 420px/92vw — the
       design's own "Rule Details" panel is 560px/94vw, and the Stage 10
       content this drawer grew (description/data source/schedule
       cards/thresholds/recent findings, on top of the original Stage 4
       override CRUD) genuinely needs the extra width. */
    width: 560px;
    max-width: 94vw;
    height: 100%;
    background: var(--color-surface);
    box-shadow: -12px 0 40px rgba(0, 0, 0, 0.14);
    display: flex;
    flex-direction: column;
}

.rule-drawer__header {
    flex: none;
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 8px;
}

.rule-drawer__key {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
    color: var(--color-ink);
}

.rule-drawer__name {
    font-size: 14px;
    font-weight: 600;
}

.rule-drawer__severity {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--color-text-muted);
}

.rule-drawer__enabled-badge {
    font-size: 11px;
    font-weight: 500;
    color: var(--color-text-faint);
    background: var(--color-status-accepted-risk-bg);
    border-radius: var(--radius-pill);
    padding: 2px 9px;
}

.rule-drawer__enabled-badge--on {
    color: var(--color-status-resolved);
    background: var(--color-status-resolved-bg);
}

.rule-drawer__spacer {
    flex: 1;
}

.rule-drawer__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
}

.rule-drawer__close:hover {
    background: var(--color-status-accepted-risk-bg);
}

.rule-drawer__body {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
}

.rule-drawer__overrides-label {
    margin-top: 22px;
}

.rule-drawer__description {
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--color-text-secondary);
    margin: 8px 0 0;
}

.rule-drawer__meta-cards {
    display: flex;
    gap: 8px;
    margin-top: 12px;
}

.rule-drawer__meta-card {
    flex: 1;
    background: var(--color-header-bg);
    border-radius: var(--radius-panel);
    padding: 9px 12px;
}

.rule-drawer__meta-value {
    font-size: 12px;
    font-weight: 500;
    margin-top: 3px;
}

.rule-drawer__recent-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 4px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
    color: var(--color-ink);
    text-decoration: none;
}

.rule-drawer__recent-row:hover {
    background: var(--color-row-hover);
}

.rule-drawer__recent-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rule-drawer__recent-project {
    color: var(--color-text-faint);
    font-size: 11px;
    flex: none;
}

.rule-drawer__form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}

.rule-drawer__form select {
    flex: 1;
    min-width: 120px;
    font-size: 12px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 6px 8px;
    background: var(--color-surface);
}

.rule-drawer__config {
    width: 100%;
    font-family: var(--font-mono);
    font-size: 11px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 6px 8px;
    background: var(--color-surface);
    resize: vertical;
}

.rule-drawer__config-reference {
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
    font-size: 11px;
    color: var(--color-text-muted);
}

.rule-drawer__config-reference li {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 2px 0;
}

.rule-drawer__config-reference-default {
    color: var(--color-text-faint);
}

.rule-drawer__override {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 12px;
    margin-top: 10px;
}

.rule-drawer__override-name {
    font-size: 12px;
    font-weight: 600;
}

.rule-drawer__empty {
    font-size: 12px;
    color: var(--color-text-faint);
    margin-top: 10px;
}

/* ---- Settings (IMPLEMENTATION_PLAN.md Stage 12: width fix + 5 sections) ---- */

.settings__card {
    max-width: 980px;
    padding: 20px 24px;
}

.settings__intro {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.6;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.settings__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-bottom: 14px;
}

.settings__section {
    margin-bottom: 14px;
}

/*
 * QA polish fix (IMPLEMENTATION_PLAN.md Stage 12): with the default
 * `align-items: start`, a two-column row's shorter card stopped well
 * above its taller neighbor, leaving asymmetric whitespace that broke the
 * card rhythm the rest of the page establishes. Stretching both cards to
 * the row's tallest, then pinning each card's footnote to the bottom via
 * the flex column below, keeps card *heights* equal without visually
 * padding out a card's actual content.
 */
.settings__grid .settings__section {
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
}


.settings__section-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
}

.settings__section-title {
    font-size: 13px;
    font-weight: 600;
}

.settings__section-subtitle {
    font-size: 11px;
    color: var(--color-text-faint);
}

.settings__section-actions {
    margin-left: auto;
}

.settings__section-body {
    padding: 12px 16px;
}

.settings__section-footnote {
    padding: 10px 16px 12px;
    font-size: 11px;
    color: var(--color-text-faint);
    line-height: 1.5;
    margin-top: auto;
}

.settings__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.settings__row:last-of-type {
    border-bottom: none;
}

.settings__row--head {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 8px 16px;
}

.settings__col--name {
    flex: 1;
    min-width: 0;
    font-weight: 500;
}

.settings__col--detail {
    flex: 2;
    color: var(--color-text-muted);
    font-size: 12px;
}

.settings__col--severity {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 500;
}

.settings__col--toggle {
    width: 110px;
    flex: none;
}

.settings__col--project {
    width: 170px;
    flex: none;
    color: var(--color-text-muted);
}

.settings__col--date {
    width: 110px;
    flex: none;
    color: var(--color-text-faint);
}

.settings__col--status {
    width: 90px;
    flex: none;
}

.settings__col--actions {
    width: 70px;
    flex: none;
    text-align: right;
}

.settings__col--retention-select {
    width: 110px;
    flex: none;
}

.settings__col--retention-desc {
    flex: 1;
    color: var(--color-text-muted);
    font-size: 12px;
}

.settings__retention-name {
    display: block;
    font-weight: 500;
    color: var(--color-ink);
    font-size: 12px;
    margin-bottom: 1px;
}

.settings__empty {
    padding: 12px 16px;
    font-size: 12px;
    color: var(--color-text-faint);
}

.settings__field-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    padding: 12px 16px;
}

.settings__field-label {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 500;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 5px;
}

.settings__select {
    width: 100%;
    font-size: 12px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 6px 8px;
    background: var(--color-surface);
    color: var(--color-text-secondary);
    cursor: pointer;
}

.settings__col--retention-select .settings__select {
    padding: 5px 8px;
}

.settings__toggle-form {
    flex: none;
}

.settings__toggle {
    width: 32px;
    height: 18px;
    border-radius: 999px;
    background: var(--color-border-strong);
    position: relative;
    display: inline-block;
    flex: none;
    border: none;
    padding: 0;
    cursor: pointer;
    transition: background 0.15s;
}

.settings__toggle.is-on {
    background: var(--color-ink);
}

.settings__toggle-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--color-surface);
    transition: left 0.15s;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

.settings__toggle.is-on .settings__toggle-knob {
    left: 16px;
}

.settings__channel-choice {
    display: flex;
    gap: 8px;
}

.settings__channel-btn {
    font-size: 12px;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    border-radius: var(--radius-panel);
    padding: 5px 12px;
    cursor: pointer;
    font-weight: 500;
    color: var(--color-text-secondary);
}

.settings__channel-btn.is-active {
    border-color: var(--color-ink);
    color: var(--color-ink);
    font-weight: 600;
}

.settings__form-actions {
    padding: 0 16px 10px;
}

.settings__section-body--tight {
    padding-top: 0;
}

/* ---- Audit Log ---- */

.audit-log__filter-field {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--color-text-secondary);
}

.audit-log__filter-label {
    color: var(--color-text-muted);
}

.audit-log__head,
.audit-log__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    font-size: 13px;
}

.audit-log__head {
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.audit-log__row {
    border-bottom: 1px solid var(--color-border-muted);
}

.audit-log__row:last-child {
    border-bottom: none;
}

.audit-log__row:hover {
    background: var(--color-row-hover);
}

.audit-log__col--time {
    width: 140px;
    flex: none;
    color: var(--color-text-muted);
    font-size: 12px;
    font-family: var(--font-mono);
}

.audit-log__col--actor {
    width: 140px;
    flex: none;
}

.audit-log__col--action {
    width: 160px;
    flex: none;
}

.audit-log__col--target {
    width: 220px;
    flex: none;
    display: flex;
    align-items: center;
    gap: 6px;
    overflow: hidden;
}

/*
 * QA fix: long finding titles here had no width constraint or ellipsis at
 * all, so they overflowed past this column's fixed width and visibly
 * collided mid-word with the adjacent Detail column's text. `min-width: 0`
 * is required alongside `flex: 1` for a flex child to actually shrink below
 * its content's intrinsic width instead of overflowing regardless of
 * `text-overflow`.
 */
.audit-log__entity-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.audit-log__col--detail {
    flex: 1;
    color: var(--color-text-muted);
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.audit-log__entity-type {
    background: var(--color-header-bg);
    color: var(--color-text-muted);
    flex: none;
}

/* ---- Audit Log: AI daily summaries card (Stage 11) ---- */

/*
 * Deliberately not `.card` (see `.card`'s own rule above): two `.card`
 * elements on this one screen would break every pre-existing functional
 * test that scopes an assertion to "the" `.card` (the audit-log table
 * itself) — this widget replicates the same background/border/radius
 * recipe under its own scoped class instead of sharing that generic one.
 */
.audit-log__summary-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    overflow: hidden;
    margin-bottom: 12px;
}

.audit-log__summary-head {
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 8px;
}

.audit-log__summary-title {
    font-size: 13px;
    font-weight: 600;
}

.audit-log__summary-caption {
    font-size: 11px;
    color: var(--color-text-faint);
}

.audit-log__summary-row {
    display: flex;
    gap: 14px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.audit-log__summary-row:last-child {
    border-bottom: none;
}

.audit-log__summary-day {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-secondary);
    width: 88px;
    flex: none;
    padding-top: 1px;
}

.audit-log__summary-items {
    flex: 1;
    min-width: 0;
}

.audit-log__summary-item {
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

.audit-log__summary-by {
    color: var(--color-text-faint);
}

.audit-log__summary-empty {
    padding: 12px 16px;
    font-size: 12px;
    color: var(--color-text-faint);
}

/* ---- Fleet Dashboard (Stage 4) ---- */

.dashboard__sparkline {
    width: 100%;
    height: 34px;
    display: block;
    margin-bottom: 14px;
}

@keyframes tmDraw {
    from {
        stroke-dashoffset: 1;
    }
    to {
        stroke-dashoffset: 0;
    }
}

@keyframes tmDash {
    to {
        stroke-dashoffset: -16;
    }
}

.dashboard__kpis {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 12px;
}

.dashboard__kpi-card {
    padding: 14px 16px;
}

.dashboard__kpi-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.dashboard__kpi-value {
    font-family: var(--font-body);
    font-size: 32px;
    font-weight: 600;
    letter-spacing: -0.02em;
    margin-top: 8px;
}

.dashboard__kpi-value--critical {
    color: var(--color-severity-critical);
}

.dashboard__kpi-value-suffix {
    font-size: 14px;
    color: var(--color-text-muted);
    font-weight: 400;
}

.dashboard__kpi-delta {
    font-size: 12px;
    margin-top: 2px;
}

/* Revenue KPI card's trend chart — same server-computed-SVG-path convention
   as `.business-tab__chart*` (Architecture Decision 1), just smaller since
   it lives in one `.dashboard__kpi-card` column rather than a full tab
   panel. See `App\Dashboard\FleetRevenueChartBuilder`. */
.dashboard__kpi-chart {
    width: 100%;
    display: block;
    margin-top: 10px;
}

.dashboard__kpi-chart-area {
    fill: var(--color-ink);
    opacity: 0.06;
}

.dashboard__kpi-chart-series {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.dashboard__kpi-chart-point {
    fill: var(--color-ink);
    opacity: 0.85;
}

.dashboard__kpi-chart-empty {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 10px;
}

.dashboard__kpi-sev-row {
    display: flex;
    gap: 14px;
    margin-top: 10px;
}

.dashboard__kpi-sev-count {
    display: flex;
    align-items: center;
    gap: 5px;
}

.dashboard__kpi-sev-number {
    font-size: 20px;
    font-weight: 600;
}

.dashboard__kpi-sev-label {
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 1px;
}

.dashboard__body {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 12px;
    margin-top: 12px;
    align-items: start;
}

.dashboard__col {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.dashboard__panel-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 13px;
    font-weight: 600;
}

.dashboard__panel-head-link {
    font-size: 12px;
    color: var(--color-ink);
    font-weight: 500;
}

.dashboard__attention-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
    cursor: pointer;
}

.dashboard__attention-row:last-child {
    border-bottom: none;
}

.dashboard__attention-row:hover {
    background: var(--color-row-hover);
    text-decoration: none;
}

.dashboard__attention-sev {
    font-size: 11px;
    font-weight: 600;
    width: 60px;
    flex: none;
}

.dashboard__attention-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: var(--color-ink);
}

.dashboard__attention-project {
    font-size: 11px;
    color: var(--color-text-muted);
    background: var(--color-status-accepted-risk-bg);
    border-radius: 5px;
    padding: 2px 7px;
    flex: none;
}

.dashboard__attention-age {
    font-size: 12px;
    color: var(--color-text-faint);
    width: 34px;
    text-align: right;
    flex: none;
}

.dashboard__attention-empty,
.dashboard__activity-empty,
.dashboard__matrix-empty {
    padding: 24px 16px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

.dashboard__matrix {
    padding: 10px 16px 14px;
}

.dashboard__matrix-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 0;
}

.dashboard__matrix-project {
    width: 170px;
    flex: none;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard__matrix-bar {
    flex: 1;
    height: 16px;
    display: flex;
    gap: 2px;
}

.dashboard__matrix-segment {
    border-radius: 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 600;
    text-decoration: none;
}

.dashboard__matrix-segment:hover {
    opacity: 0.85;
    text-decoration: none;
}

.dashboard__matrix-total {
    width: 30px;
    flex: none;
    text-align: right;
    font-size: 11px;
    color: var(--color-text-faint);
}

.dashboard__matrix-legend {
    display: flex;
    gap: 14px;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 10px;
}

.dashboard__matrix-legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.dashboard__matrix-legend-swatch {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    border: 1px solid;
    display: inline-block;
}

.dashboard__matrix-legend-note {
    margin-left: auto;
    color: var(--color-text-faint);
}

.dashboard__activity-row {
    display: flex;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
    line-height: 1.45;
}

.dashboard__activity-row:last-child {
    border-bottom: none;
}

.dashboard__activity-dot {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    margin-top: 5px;
}

.dashboard__activity-subject {
    font-weight: 600;
    color: var(--color-ink);
    margin-bottom: 1px;
}

.dashboard__activity-subject a {
    color: inherit;
}

.dashboard__activity-subject a:hover {
    text-decoration: underline;
}

.dashboard__activity-text {
    color: var(--color-text-secondary);
}

.dashboard__activity-meta {
    color: var(--color-text-faint);
    margin-top: 1px;
}

.dashboard__occasions {
    margin-top: 12px;
}

.dashboard__occasions-caption {
    font-size: 11px;
    color: var(--color-text-faint);
}

.dashboard__occasion-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.dashboard__occasion-row:last-child {
    border-bottom: none;
}

.dashboard__occasion-icon {
    width: 14px;
    height: 14px;
    flex: none;
    color: var(--color-text-faint);
}

.dashboard__occasion-icon path {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.dashboard__occasion-body {
    flex: 1;
    min-width: 0;
}

.dashboard__occasion-who {
    font-weight: 500;
    color: var(--color-ink);
}

.dashboard__occasion-what {
    font-weight: 400;
    color: var(--color-text-muted);
}

.dashboard__occasion-detail {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 1px;
}

.dashboard__occasion-when {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 11px;
    font-weight: 600;
    flex: none;
}

.dashboard__occasions-empty {
    padding: 12px 16px;
    font-size: 12px;
    color: var(--color-text-faint);
}

.dashboard__occasions-footer {
    padding: 8px 16px;
    font-size: 11px;
    color: var(--color-text-faint);
}

/* Analytics screen (IMPLEMENTATION_PLAN.md Stage 13 near-total rebuild) */

.analytics__filterbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

.analytics__select {
    padding: 5px 8px;
    border: 1px solid var(--color-border-strong);
    border-radius: 2px;
    background: var(--color-surface);
    color: var(--color-text-secondary);
    font-size: 12px;
    cursor: pointer;
}

.analytics__kpis {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 12px;
}

.analytics__kpi-card {
    padding: 12px 16px;
}

.analytics__kpi-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.analytics__kpi-value {
    font-size: 24px;
    font-weight: 600;
    margin-top: 6px;
}

.analytics__kpi-delta {
    font-size: 11px;
    margin-top: 2px;
}

.analytics__grid {
    display: grid;
    gap: 12px;
    align-items: start;
}

.analytics__grid--main {
    grid-template-columns: 2fr 1fr;
    margin-bottom: 12px;
}

.analytics__grid--triple {
    grid-template-columns: repeat(3, 1fr);
}

.analytics__panel {
    padding: 14px 16px;
}

.analytics__panel--wide {
    grid-column: 1 / -1;
}

.analytics__panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.analytics__panel-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-ink);
}

.analytics__panel-note {
    font-size: 11px;
    color: var(--color-text-faint);
}

.analytics__empty {
    font-size: 12px;
    color: var(--color-text-faint);
}

/* ---- weekly created-vs-closed line/area chart ---- */

.analytics__weekly-chart {
    width: 100%;
    display: block;
    margin-top: 12px;
}

.analytics__weekly-chart-grid {
    stroke: var(--color-border-muted);
    stroke-width: 1;
}

.analytics__weekly-chart-area {
    fill: var(--color-ink);
    opacity: 0.05;
}

.analytics__weekly-chart-closed {
    fill: none;
    stroke: var(--color-border-strong);
    stroke-width: 1.6;
    stroke-dasharray: 4 4;
    stroke-linejoin: round;
}

.analytics__weekly-chart-created {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: tmDraw 1.6s ease forwards;
}

.analytics__weekly-chart-end-dot {
    fill: var(--color-ink);
}

.analytics__weekly-chart-end-pulse {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 1;
    opacity: 0.4;
    animation: tmPulse 2s infinite;
}

.analytics__weekly-chart-end-label {
    font-size: 10px;
    font-weight: 600;
    fill: var(--color-ink);
    text-anchor: middle;
    font-family: var(--font-mono);
}

.analytics__weekly-chart-x-label {
    font-size: 9px;
    fill: var(--color-text-faint);
    text-anchor: middle;
    font-family: var(--font-mono);
}

@keyframes tmPulse {
    0% {
        transform: scale(0.6);
        opacity: 0.5;
    }

    70% {
        transform: scale(1.6);
        opacity: 0;
    }

    100% {
        transform: scale(1.6);
        opacity: 0;
    }
}

.analytics__chart-legend {
    display: flex;
    gap: 16px;
    margin-top: 8px;
    font-size: 11px;
    color: var(--color-text-muted);
    align-items: center;
}

.analytics__legend-line {
    display: inline-block;
    width: 14px;
    height: 2px;
    background: var(--color-ink);
    margin-right: 5px;
}

.analytics__legend-line--closed {
    background: none;
    border-top: 2px dashed var(--color-border-strong);
}

.analytics__legend-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 2px;
    margin-right: 5px;
}

.analytics__legend-dot--reactive {
    background: var(--color-severity-high);
    opacity: 0.7;
}

.analytics__legend-dot--proactive {
    background: var(--color-ink);
    opacity: 0.85;
}

/* ---- findings funnel ---- */

.analytics__funnel-row {
    margin-top: 11px;
}

.analytics__funnel-row-head {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
}

.analytics__funnel-label {
    color: var(--color-text-secondary);
}

.analytics__funnel-value {
    font-weight: 600;
}

.analytics__funnel-percent {
    color: var(--color-text-faint);
    font-weight: 400;
    font-size: 11px;
}

.analytics__funnel-bar-track {
    height: 9px;
    background: var(--color-border-muted);
    border-radius: 5px;
    margin-top: 4px;
    overflow: hidden;
}

.analytics__funnel-bar {
    display: block;
    height: 100%;
    background: var(--color-ink);
    border-radius: 5px;
}

.analytics__funnel-callout {
    margin-top: 14px;
    font-size: 12px;
    color: var(--color-text-muted);
    border-top: 1px solid var(--color-border-muted);
    padding-top: 10px;
}

/* ---- first-response / resolution SLA panels + 3D bar histograms ---- */

.analytics__sla-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 600;
    border-radius: 5px;
    padding: 2px 9px;
}

.analytics__sla-target {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 2px;
}

.analytics__bars3d {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    height: 118px;
    margin-top: 12px;
    padding: 0 4px;
}

.analytics__bar3d {
    position: relative;
    width: 34px;
    height: 96px;
    cursor: pointer;
}

.analytics__bar3d-front {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 22px;
    height: var(--bar-height, 2px);
    background: var(--color-ink);
    transition: opacity 0.15s;
}

.analytics__bar3d-side {
    position: absolute;
    bottom: 0;
    left: 22px;
    width: 7px;
    height: var(--bar-height, 2px);
    background: var(--color-border-strong);
    transform: skewY(-40deg);
    transform-origin: bottom left;
    transition: opacity 0.15s;
}

.analytics__bar3d-top {
    position: absolute;
    left: 0;
    width: 22px;
    height: 6px;
    bottom: calc(var(--bar-height, 2px) - 3px);
    background: var(--color-text-dim);
    transform: skewX(-40deg);
    transform-origin: bottom left;
    transition: opacity 0.15s;
}

.analytics__bar3d:hover .analytics__bar3d-front,
.analytics__bar3d:hover .analytics__bar3d-side,
.analytics__bar3d:hover .analytics__bar3d-top {
    opacity: 0.7;
}

.analytics__bar3d-count {
    position: absolute;
    bottom: calc(var(--bar-height, 2px) + 8px);
    left: 0;
    width: 22px;
    text-align: center;
    font-size: 10px;
    font-weight: 600;
    color: var(--color-text-secondary);
}

.analytics__bar3d-label {
    position: absolute;
    top: 100%;
    left: -6px;
    width: 40px;
    margin-top: 4px;
    text-align: center;
    font-size: 8px;
    color: var(--color-text-faint);
    font-family: var(--font-mono);
}

.analytics__sla-footnote {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 10px;
}

/* ---- aging WIP compact list ---- */

.analytics__aging-list {
    margin-top: 4px;
}

.analytics__aging-row {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
    font-size: 12px;
}

.analytics__aging-label {
    color: var(--color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.analytics__aging-age {
    font-weight: 600;
    color: var(--color-severity-high);
    flex: none;
}

.analytics__aging-footnote {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 12px;
}

/* ---- reactive vs. proactive percent-only stacked bars ---- */

.analytics__rp-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 9px;
    font-size: 12px;
}

.analytics__rp-name {
    width: 150px;
    flex: none;
    color: var(--color-text-secondary);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.analytics__rp-track {
    flex: 1;
    height: 14px;
    border-radius: 4px;
    overflow: hidden;
    display: flex;
}

.analytics__rp-segment {
    height: 100%;
}

.analytics__rp-segment--reactive {
    background: var(--color-severity-high);
    opacity: 0.7;
}

.analytics__rp-segment--proactive {
    background: var(--color-ink);
    opacity: 0.85;
}

.analytics__rp-label {
    width: 110px;
    flex: none;
    text-align: right;
    color: var(--color-text-muted);
}

/* ---- Project Detail (IMPLEMENTATION_PLAN.md Stage 5 scope: Business tab) ---- */

.project-detail__header {
    margin-bottom: 16px;
}

.project-detail__title {
    font-size: 20px;
    font-weight: 600;
    color: var(--color-ink);
}

.project-detail__meta {
    margin-top: 2px;
    font-size: 12px;
    color: var(--color-text-muted);
}

.project-detail__tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 16px;
}

.project-detail__tab {
    padding: 9px 14px;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}

.project-detail__tab.is-active {
    color: var(--color-ink);
    font-weight: 600;
    border-bottom-color: var(--color-ink);
}

.project-detail__overview-card {
    padding: 14px 16px;
    margin-bottom: 12px;
}

.project-detail__overview-row {
    display: flex;
    gap: 10px;
    padding: 6px 0;
    font-size: 13px;
    border-bottom: 1px solid var(--color-border-muted);
}

.project-detail__overview-row:last-child {
    border-bottom: none;
}

.project-detail__overview-label {
    width: 110px;
    flex: none;
    color: var(--color-text-muted);
}

.project-detail__overview-value {
    color: var(--color-text-secondary);
    font-weight: 500;
}

.project-detail__panel-title {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    margin-bottom: 10px;
}

/* ---- Project Detail Overview: retainer budget bar (Stage 7 gap #5) ---- */

.project-detail__retainer-summary {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-ink);
    margin-bottom: 8px;
}

.project-detail__retainer-track {
    height: 10px;
    background: var(--color-border-muted);
    border-radius: 5px;
    overflow: hidden;
}

.project-detail__retainer-bar {
    display: block;
    height: 100%;
    border-radius: 5px;
}

.project-detail__retainer-bar--normal {
    background: var(--color-status-ticketed);
}

.project-detail__retainer-bar--high {
    background: var(--color-severity-high);
}

.project-detail__retainer-bar--over {
    background: var(--color-severity-critical);
}

.project-detail__retainer-note {
    font-size: 12px;
    margin-top: 6px;
}

.project-detail__retainer-note--high {
    color: var(--color-severity-high);
}

.project-detail__retainer-note--over {
    color: var(--color-severity-critical);
}

/* ---- Project Detail Overview: Health / Uptime / Contract / Platform versions / Open findings (design fidelity follow-up, `pIsOverview`) ---- */

.overview-tab__stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

.overview-tab__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 12px;
    align-items: start;
}

.overview-tab__panel {
    padding: 14px 16px;
}

.overview-tab__health-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.overview-tab__health-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
}

.overview-tab__health-label {
    font-size: 16px;
    font-weight: 600;
}

.overview-tab__health-counts {
    display: flex;
    gap: 14px;
    margin-top: 12px;
}

.overview-tab__health-count-num {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 16px;
    font-weight: 600;
}

.overview-tab__health-count-label {
    font-size: 11px;
    color: var(--color-text-muted);
}

.overview-tab__uptime-value {
    font-size: 26px;
    font-weight: 600;
    margin-top: 8px;
}

.overview-tab__uptime-value--unknown {
    font-size: 13px;
    font-weight: 400;
    color: var(--color-text-faint);
}

.overview-tab__uptime-bars {
    margin-top: 8px;
}

.overview-tab__uptime-last-ping {
    margin-top: 6px;
    font-size: 11px;
    color: var(--color-text-faint);
}

.overview-tab__contract-type {
    font-size: 14px;
    font-weight: 600;
    margin-top: 8px;
}

.overview-tab__contract-meta {
    font-size: 12px;
    color: var(--color-text-muted);
    margin-top: 8px;
}

.overview-tab__contract-toggl {
    margin-top: 10px;
}

.overview-tab__version-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 0;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
}

.overview-tab__version-row:last-child {
    border-bottom: none;
}

.overview-tab__version-icon {
    width: 15px;
    height: 15px;
    flex: none;
    color: var(--color-text-faint);
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.overview-tab__version-name {
    width: 90px;
    flex: none;
    color: var(--color-text-muted);
}

.overview-tab__version-value {
    font-weight: 600;
}

.overview-tab__finding-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
    cursor: pointer;
}

.overview-tab__finding-row:last-child {
    border-bottom: none;
}

.overview-tab__finding-row:hover {
    background: var(--color-row-hover);
    text-decoration: none;
}

.overview-tab__finding-rule-key {
    font-family: var(--font-mono);
    color: var(--color-text-muted);
    font-size: 11px;
    width: 56px;
    flex: none;
}

.overview-tab__finding-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.overview-tab__finding-age {
    color: var(--color-text-faint);
    flex: none;
}

.overview-tab__finding-more {
    display: block;
    padding: 9px 16px;
    font-size: 12px;
    color: var(--color-text-muted);
}

/* ---- Project Detail Info: Running since / Contract / Customer / Project team / Linked services / Project history (design fidelity port, `docs/design/Refinery.dc.html`'s `pIsInfo` block) ---- */

.info-tab__value {
    font-size: 13px;
    font-weight: 600;
    margin-top: 6px;
}

.info-tab__anniversary {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--color-status-snoozed);
    margin-top: 2px;
}

.info-tab__anniversary-icon {
    width: 12px;
    height: 12px;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.info-tab__meta {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 2px;
}

.info-tab__contract-link {
    display: inline-block;
    font-size: 11px;
    font-weight: 500;
    color: var(--color-ink);
    margin-top: 4px;
}

.info-tab__contract-fallback {
    display: inline-block;
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 4px;
    border-bottom: 1px dashed var(--color-border-strong);
}

.info-tab__customer-card {
    cursor: pointer;
    display: block;
}

.info-tab__customer-card:hover {
    border-color: var(--color-border-strong);
    text-decoration: none;
}

.info-tab__customer-arrow {
    color: var(--color-text-faint);
    font-weight: 400;
}

.info-tab__team-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
}

.info-tab__panel-title {
    font-size: 13px;
    font-weight: 600;
}

.info-tab__team-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.info-tab__team-avatar {
    width: 30px;
    height: 30px;
    flex: none;
    font-size: 11px;
}

.info-tab__team-identity {
    flex: 1;
    min-width: 0;
}

.info-tab__team-name {
    font-size: 12.5px;
    font-weight: 600;
}

.info-tab__team-role {
    font-weight: 400;
    color: var(--color-text-muted);
}

.info-tab__services {
    padding: 12px 16px;
    border-top: 1px solid var(--color-border);
}

.info-tab__services-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    margin-top: 6px;
}

.info-tab__services-row:first-child {
    margin-top: 0;
}

.info-tab__service-name {
    font-weight: 500;
    color: var(--color-ink);
    width: 90px;
    flex: none;
}

.info-tab__service-detail {
    color: var(--color-text-faint);
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.info-tab__history-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 8px;
}

.info-tab__history-mark {
    color: var(--color-ink);
}

.info-tab__history-sub {
    font-size: 11px;
    color: var(--color-text-faint);
}

.info-tab__history-link {
    margin-left: auto;
    font-size: 11px;
    font-weight: 500;
    color: var(--color-ink);
}

.info-tab__history-week {
    display: flex;
    gap: 14px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.info-tab__history-week:last-child {
    border-bottom: none;
}

.info-tab__history-week-label {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
    width: 76px;
    flex: none;
    padding-top: 1px;
}

.info-tab__history-items {
    flex: 1;
    min-width: 0;
}

.info-tab__history-item {
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

.business-tab__empty-state {
    padding: 40px 48px;
    text-align: center;
}

.business-tab__empty {
    font-size: 12px;
    color: var(--color-text-faint);
}

.business-tab__grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 12px;
    align-items: start;
}

.business-tab__side {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.business-tab__chart-card,
.business-tab__panel {
    padding: 14px 16px;
}

.business-tab__chart-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}

.business-tab__chart-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-ink);
}

.business-tab__chart-source {
    font-size: 11px;
    color: var(--color-text-faint);
}

.business-tab__chart {
    width: 100%;
    display: block;
    margin-top: 10px;
}

.business-tab__chart-band {
    fill: var(--color-border-muted);
    stroke: none;
}

.business-tab__chart-area {
    fill: var(--color-ink);
    opacity: 0.06;
}

.business-tab__chart-baseline {
    fill: none;
    stroke: var(--color-border-strong);
    stroke-width: 1.4;
    stroke-dasharray: 4 4;
}

.business-tab__chart-series {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.business-tab__chart-point {
    fill: var(--color-ink);
    opacity: 0.85;
}

.business-tab__chart-deploy-line {
    stroke: var(--color-ink);
    stroke-width: 1.2;
    opacity: 0.45;
}

.business-tab__chart-deploy-marker {
    fill: var(--color-ink);
    opacity: 0.75;
    cursor: help;
}

.business-tab__chart-legend {
    display: flex;
    gap: 16px;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 6px;
    flex-wrap: wrap;
}

.business-tab__legend-swatch {
    display: inline-block;
    width: 12px;
    height: 8px;
    margin-right: 5px;
    border-radius: 2px;
    vertical-align: middle;
}

.business-tab__legend-swatch--series {
    background: var(--color-ink);
    height: 2px;
}

.business-tab__legend-swatch--baseline {
    border-top: 2px dashed var(--color-border-strong);
    height: 0;
}

.business-tab__legend-swatch--band {
    background: var(--color-border-muted);
}

.business-tab__legend-swatch--deploy {
    background: var(--color-ink);
    opacity: 0.75;
    width: 8px;
    height: 8px;
}

.business-tab__panel-title {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 4px;
}

.business-tab__pay-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 9px;
    font-size: 12px;
}

.business-tab__pay-name {
    width: 96px;
    flex: none;
    color: var(--color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.business-tab__pay-track {
    flex: 1;
    height: 8px;
    background: var(--color-border-muted);
    border-radius: 4px;
    overflow: hidden;
}

.business-tab__pay-bar {
    display: block;
    height: 100%;
    background: var(--color-ink);
    border-radius: 4px;
}

.business-tab__pay-pct {
    width: 40px;
    flex: none;
    text-align: right;
    color: var(--color-text-muted);
}

.business-tab__catalog-values {
    display: flex;
    gap: 18px;
    margin-top: 4px;
}

.business-tab__catalog-value {
    font-size: 17px;
    font-weight: 600;
    color: var(--color-ink);
}

.business-tab__catalog-value--drifted {
    color: var(--color-severity-high);
}

.business-tab__catalog-label {
    font-size: 11px;
    color: var(--color-text-muted);
}

.business-tab__catalog-drift {
    margin-top: 9px;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-status-resolved);
}

.business-tab__catalog-drift--warn {
    color: var(--color-severity-high);
}

/* ---- Project Detail: Infrastructure tab (merged grouped table) ---- */

.infra-tab__note {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: 16px;
    max-width: 980px;
    font-size: 11px;
    color: var(--color-text-faint);
}

.infra-tab__note-link {
    font-weight: 600;
    color: var(--color-ink);
}

.infra-tab__panel {
    margin-top: 12px;
    max-width: 980px;
}

.infra-tab__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.infra-tab__head-icon {
    width: 15px;
    flex: none;
}

.infra-tab__head-col {
    width: 110px;
    flex: none;
}

.infra-tab__head-col--flex {
    width: auto;
    flex: 1;
}

.infra-tab__head-probe {
    text-transform: none;
    letter-spacing: 0;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 11px;
    color: var(--color-text-faint);
}

.infra-tab__group-title {
    padding: 10px 16px 4px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.infra-tab__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12.5px;
}

.infra-tab__row-icon {
    width: 15px;
    height: 15px;
    flex: none;
    color: var(--color-text-faint);
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.infra-tab__row-name {
    width: 110px;
    flex: none;
    color: var(--color-text-muted);
}

.infra-tab__cell {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.infra-tab__cell-version {
    font-weight: 600;
}

.infra-tab__cell[data-environment-kind="staging"] .infra-tab__cell-version {
    font-weight: 500;
    color: var(--color-text-secondary);
}

.infra-tab__cell-badge {
    flex: none;
}

/*
 * Infrastructure tab follow-up: "be able to click a link that sends me to
 * the EOL site" — only EOL/EOL-soon badges render as a real `<a>` (see
 * `App\Registry\EolStatus::hasEolInfoLink()`), so this only needs to undo
 * the browser's default link underline/color and align the small
 * external-link icon next to the label; every other badge stays a plain,
 * non-interactive `<span>`.
 */
.infra-tab__cell-badge--link {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    text-decoration: none;
    cursor: pointer;
}

.infra-tab__cell-badge-icon {
    width: 9px;
    height: 9px;
}

.infra-tab__cell-dash,
.infra-tab__cell-empty {
    color: var(--color-text-faint);
    font-size: 12px;
}

/* ---- Project Detail: Infrastructure tab, "Cluster configuration" card ----
   Real per-server MaxCluster data (docs/plans/2026-08-16-gitlab-maxcluster-
   and-correlated-rules-design.md §2) — same row/detail-column shape as the
   fleet-wide inventory's `.maxcluster-fleet__server` below, scoped under its
   own `infra-tab__cluster-*` classes since this card lives inside the
   Infrastructure tab's own panel styling, not the fleet page's. */

.infra-tab__cluster-config {
    margin-top: 16px;
}

.infra-tab__cluster-row {
    flex-wrap: wrap;
}

.infra-tab__cluster-detail {
    color: var(--color-text-muted);
    font-size: 12px;
    flex: none;
}

.infra-tab__cluster-link {
    margin-left: auto;
    font-weight: 600;
    font-size: 12px;
    color: var(--color-ink);
    text-decoration: none;
    flex: none;
}

/* ---- MaxCluster server inventory (Settings > Collector fleet > View all servers) ---- */

.maxcluster-fleet__intro {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.6;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.maxcluster-fleet__count {
    font-size: 12px;
    color: var(--color-text-muted);
    margin-bottom: 10px;
}

.maxcluster-fleet__row {
    margin-bottom: 10px;
    padding: 12px 16px;
}

.maxcluster-fleet__row-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 8px;
}

.maxcluster-fleet__cluster-number {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
}

.maxcluster-fleet__cluster-name {
    font-weight: 600;
    font-size: 14px;
    flex: 1;
}

.maxcluster-fleet__servers {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.maxcluster-fleet__server {
    display: flex;
    align-items: baseline;
    gap: 12px;
    font-size: 12px;
    padding: 4px 0;
    border-top: 1px solid var(--color-border-muted);
}

.maxcluster-fleet__server-name {
    font-weight: 500;
    width: 70px;
    flex: none;
}

.maxcluster-fleet__server-type {
    color: var(--color-text-muted);
    width: 130px;
    flex: none;
}

.maxcluster-fleet__server-hostname {
    color: var(--color-text-faint);
    font-family: var(--font-mono);
    font-size: 11px;
    flex: 1;
}

/* ---- Project Detail: Dependencies tab ---- */

.deps-tab {
    margin-top: 16px;
}

/* `[hidden]` must win over `display: flex` below — same specificity as a
   class selector, so without this the Stimulus controller's `hidden = true`
   (native attribute) would be silently overridden by the flex rule and the
   bar would show even with nothing selected. */
.deps-tab__selection-bar[hidden] {
    display: none;
}

.deps-tab__selection-bar {
    background: #ebe2cf;
    border: 1px solid #d6cdb8;
    border-radius: var(--radius-panel);
    padding: 8px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    margin-bottom: 10px;
}

.deps-tab__selection-count {
    font-weight: 600;
    color: #3f382a;
}

.deps-tab__ticket-button {
    font-size: 12px;
    font-weight: 500;
    border: none;
    background: var(--color-ink);
    color: #fff;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-radius: 6px;
    padding: 5px 12px;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}

.deps-tab__ticket-button:hover {
    background: #362f21;
}

.deps-tab__clear-link {
    color: var(--color-text-muted);
    cursor: pointer;
}

.deps-tab__clear-link:hover {
    color: var(--color-ink);
}

/*
 * Was scoped to `.deps-tab__table--npm` only, back when there were exactly
 * two tables (Composer, then npm) — now up to four (Composer real/dev/
 * local-path, then npm), so this is a general adjacent-sibling rule
 * instead of a manager-specific one.
 */
.deps-tab__table + .deps-tab__table {
    margin-top: 12px;
}

.deps-tab__table-head {
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    justify-content: space-between;
}

.deps-tab__table-title {
    font-size: 13px;
    font-weight: 600;
}

.deps-tab__table-source {
    font-size: 11px;
    color: var(--color-text-faint);
}

.deps-tab__col-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

/*
 * Design-fidelity follow-up: "Can we make the columns sortable on the
 * dependencies tab?" — `assets/controllers/sortable_table_controller.js`.
 * `::after` carries the direction arrow so it can be swapped per
 * `[data-sort-active]` without a second DOM element; a plain `↕` hints at
 * sortability before any column is actively sorted.
 */
.deps-tab__col--sortable {
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.deps-tab__col--sortable:hover {
    color: var(--color-ink);
}

.deps-tab__col--sortable::after {
    content: '\21C5';
    font-size: 9px;
    opacity: 0.4;
}

.deps-tab__col--sortable[data-sort-active="asc"]::after {
    content: '\2191';
    opacity: 1;
}

.deps-tab__col--sortable[data-sort-active="desc"]::after {
    content: '\2193';
    opacity: 1;
}

.deps-tab__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.deps-tab__row:last-child {
    border-bottom: none;
}

.deps-tab__row--selected {
    background: var(--color-header-bg);
}

.deps-tab__col--checkbox {
    width: 14px;
    flex: none;
}

.deps-tab__col--package {
    flex: 1.6;
    min-width: 0;
}

.deps-tab__col--installed {
    width: 90px;
    flex: none;
    color: var(--color-text-muted);
}

.deps-tab__col--latest {
    width: 90px;
    flex: none;
    font-weight: 500;
}

.deps-tab__col--behind {
    width: 110px;
    flex: none;
}

/*
 * Design-fidelity follow-up: "a column that indicates whether the
 * dependency is paid or open source" — same width/treatment as
 * `.deps-tab__col--behind`, one badge per row.
 */
.deps-tab__col--license {
    width: 100px;
    flex: none;
}

.deps-tab__col--advisories {
    width: 120px;
    flex: none;
    font-size: 11px;
}

.deps-tab__checkbox {
    width: 13px;
    height: 13px;
    accent-color: var(--color-ink);
    cursor: pointer;
}

.deps-tab__pkg {
    font-family: var(--font-mono);
    font-size: 12px;
}

/*
 * "click every dependency and get linked to the github repo ... or to the
 * packagist site" — only a row with a real, verified public source
 * renders as a link (`App\ProjectDetail\DependencyPackageRow::linkUrl()`);
 * every other row keeps the plain `.deps-tab__pkg` styling above.
 */
.deps-tab__pkg--link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted var(--color-text-faint);
}

.deps-tab__pkg--link:hover {
    border-bottom-style: solid;
}

.deps-tab__behind-badge,
.deps-tab__license-badge {
    font-size: 11px;
    font-weight: 500;
    padding: 1px 7px;
}

.deps-tab__empty {
    padding: 14px 16px;
}

/*
 * "we basically need three tables ... local path (always folded)" — plain
 * native `<details>`/`<summary>`, no JS. `<summary>` isn't a flex container
 * by default like `.deps-tab__table-head`'s normal `<div>` usage, so this
 * re-applies the same flex/spacing/border look plus a visible disclosure
 * affordance (cursor, marker) `.deps-tab__table-head` itself never needed.
 */
.deps-tab__table-head--summary {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
    list-style: none;
}

.deps-tab__table--local-path[open] .deps-tab__table-head--summary {
    border-bottom-color: var(--color-border);
}

.deps-tab__table--local-path:not([open]) .deps-tab__table-head--summary {
    border-bottom: none;
}

/* ---- Project Detail: Tickets tab (design-fidelity row rebuild) ---- */

/* Panel is now a flush list of full-bleed rows, not a padded table wrapper. */
.tickets-tab__panel {
    padding: 0;
}

.tickets-tab__note {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: 16px;
    margin-bottom: 12px;
    font-size: 11px;
    color: var(--color-text-faint);
}

.tickets-tab__note-link {
    font-weight: 600;
    color: var(--color-ink);
}

.tickets-tab__empty {
    padding: 40px 48px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

/*
 * "A proper table with column sorting and a table search" — the search
 * input above the header row, same visual language as the design's own
 * filter `<select>`s (border/radius/background/color tokens lifted
 * verbatim from docs/design/Refinery.dc.html's Analytics filter bar).
 */
.tickets-tab__toolbar {
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.tickets-tab__search-input {
    width: 240px;
    font-size: 12px;
    font-family: inherit;
    border: 1px solid #cfc5ae;
    border-radius: 2px;
    padding: 5px 8px;
    background: #fffcf5;
    color: var(--color-ink);
    outline: none;
}

.tickets-tab__search-input::placeholder {
    color: var(--color-text-faint);
}

.tickets-tab__col-head {
    display: flex;
    gap: 12px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

/* Same affordance as `.deps-tab__col--sortable`/`.code-tab__col--sortable`
   — this tab's own token, per this codebase's per-tab BEM convention. */
.tickets-tab__col--sortable {
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.tickets-tab__col--sortable:hover {
    color: var(--color-ink);
}

.tickets-tab__col--sortable::after {
    content: '\21C5';
    font-size: 9px;
    opacity: 0.4;
}

.tickets-tab__col--sortable[data-sort-active="asc"]::after {
    content: '\2191';
    opacity: 1;
}

.tickets-tab__col--sortable[data-sort-active="desc"]::after {
    content: '\2193';
    opacity: 1;
}

.tickets-tab__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
}

/*
 * "The search doesn't really filter the table" — root cause: this rule's
 * own `display: flex` above is an author-stylesheet declaration, which
 * always wins over the browser's default `[hidden] { display: none }`
 * (a user-agent-origin rule — origin beats specificity in the cascade),
 * so `row.hidden = true` from `table_search_controller.js` was silently
 * doing nothing. This explicit `[hidden]` override, in the SAME (author)
 * origin and with higher specificity than the plain class alone, is what
 * actually makes hiding a row work.
 */
.tickets-tab__row[hidden] {
    display: none;
}

.tickets-tab__row:last-child {
    border-bottom: none;
}

/* Column widths — shared by the header row and every data row alike,
   same "one class controls both" convention as the Code/Dependencies
   tabs' own `--col` modifiers. */
.tickets-tab__col--id {
    width: 44px;
    flex: none;
}

.tickets-tab__col--title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

.tickets-tab__col--reporter {
    width: 130px;
    flex: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--color-text-muted);
}

.tickets-tab__col--age {
    width: 70px;
    flex: none;
    text-align: right;
    font-size: 12px;
    color: var(--color-text-faint);
}

.tickets-tab__col--activity {
    width: 90px;
    flex: none;
    text-align: right;
    font-size: 12px;
    color: var(--color-text-faint);
}

.tickets-tab__estimate--none {
    color: var(--color-text-faint);
}

/*
 * Progress bar follow-up ("show in a progress bar thingy the estimated
 * time and the time already tracked on the task") — track/bar/label
 * reuse `App\ProjectDetail\RetainerBudgetView`'s own Overview-tab budget
 * bar colour tokens (`.project-detail__retainer-bar--normal/--over`'s
 * `--color-status-ticketed`/`--color-severity-critical`) rather than
 * inventing new colours for what's the same "used vs. budgeted" concept.
 */
.tickets-tab__col--progress {
    width: 150px;
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

.tickets-tab__progress-none {
    color: var(--color-text-faint);
    font-size: 12px;
}

.tickets-tab__progress-track {
    flex: 1;
    height: 6px;
    background: var(--color-border-muted);
    border-radius: 3px;
    overflow: hidden;
}

.tickets-tab__progress-bar {
    display: block;
    height: 100%;
    border-radius: 3px;
}

.tickets-tab__progress-bar--normal {
    background: var(--color-status-ticketed);
}

.tickets-tab__progress-bar--over {
    background: var(--color-severity-critical);
}

.tickets-tab__progress-label {
    flex: none;
    font-size: 11px;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.tickets-tab__progress-label--untracked {
    color: var(--color-text-faint);
}

.tickets-tab__progress-label--over {
    color: var(--color-severity-critical);
    font-weight: 600;
}

.tickets-tab__col--comments {
    width: 100px;
    flex: none;
    display: flex;
    justify-content: flex-end;
}

.tickets-tab__id {
    font-family: var(--font-mono);
    color: var(--color-ink);
    font-weight: 600;
}

/* "Click on the title to get linked to the gitlab ticket" — the global
   `a` reset already drops the underline/keeps ink colour by default, so
   this only needs to add back the display/truncation behavior a plain
   `<span>` used to provide. */
.tickets-tab__title {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

.tickets-tab__from-finding {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
    background: #efe7d5;
    border-radius: 5px;
    padding: 2px 7px;
    flex: none;
    white-space: nowrap;
}

/*
 * Design-fidelity follow-up: "Tickets with more than 5 comments should be
 * marked yellow ... more than 10 ... red" — `.tickets-tab__comments`
 * (normal, plain muted text) vs. the `.badge` variant (warning/critical,
 * colored inline per `App\ProjectDetail\CommentSeverity` — see that
 * template's own docblock for why "normal" never gets pill treatment).
 */
.tickets-tab__comments {
    text-align: right;
    font-size: 12px;
}

.tickets-tab__comments--normal {
    color: var(--color-text-faint);
}

.badge.tickets-tab__comments {
    text-align: center;
}

/* "Add pagination to the ticket table" — hidden entirely (not just
   inert) when everything fits on one page, matching this app's own
   "don't show a useless control" convention elsewhere. */
.tickets-tab__pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 10px 16px;
    border-top: 1px solid var(--color-border-muted);
}

.tickets-tab__page-button {
    font-size: 12px;
    font-family: inherit;
    border: 1px solid #cfc5ae;
    border-radius: 2px;
    padding: 4px 10px;
    background: #fffcf5;
    color: var(--color-ink);
    cursor: pointer;
}

.tickets-tab__page-button:disabled {
    color: var(--color-text-faint);
    cursor: default;
    opacity: 0.6;
}

.tickets-tab__page-info {
    font-size: 12px;
    color: var(--color-text-muted);
}

/*
 * "Tickets created by refinery should get an extra label or a visual
 * indicator" — reuses the already-established "acknowledged"/status-blue
 * token (`App\Registry\EolStatus::UpdateAvailable`'s own color), not a new
 * hex value.
 */
.tickets-tab__refinery-badge {
    flex: none;
    white-space: nowrap;
    color: #54718e;
    background: #e4e7e2;
}

/*
 * "Add a separate component in the projects ticket tab above the ticket
 * table to highlight the high priority issues" — reuses the same
 * severity-high token every other high-severity indicator in this app
 * already uses (e.g. Findings Inbox severity pills), not a new colour.
 * Hidden entirely (see the template's own `{% if %}`) rather than shown
 * empty when there are no high-priority tickets open.
 */
.tickets-tab__priority-card {
    margin-top: 16px;
    margin-bottom: 12px;
    border-left: 3px solid var(--color-severity-high);
    padding: 0;
}

.tickets-tab__priority-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.tickets-tab__priority-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-severity-high);
}

.tickets-tab__priority-sub {
    font-size: 11px;
    color: var(--color-text-faint);
}

.tickets-tab__priority-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.tickets-tab__priority-row:last-child {
    border-bottom: none;
}

.tickets-tab__priority-link {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: var(--color-ink);
}

.tickets-tab__priority-labels {
    flex: none;
    font-size: 11px;
    color: var(--color-text-muted);
}

.tickets-tab__priority-age {
    flex: none;
    width: 70px;
    text-align: right;
    font-size: 11px;
    color: var(--color-text-faint);
}

/* ---- Public Status Page (Stage 8 follow-on: GET /status/{token}) ----
 * Deliberately outside `.app-shell`/`.app-content` (no sidebar/topbar — see
 * `templates/status_page/show.html.twig`'s docblock) but reuses this file's
 * own `:root` tokens (palette/typography/radius) for visual consistency
 * with the rest of the app.
 */

.status-page {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    padding: 48px 20px;
}

.status-page__container {
    width: 100%;
    max-width: 720px;
}

.status-page__header {
    margin-bottom: 28px;
}

.status-page__eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-text-faint);
}

.status-page__title {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--color-ink);
    margin: 6px 0 0;
}

.status-page__subtitle {
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--color-text-muted);
}

.status-page__empty {
    padding: 40px 16px;
    text-align: center;
    color: var(--color-text-faint);
    font-size: 13px;
}

.status-page__list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.status-page__card {
    padding: 16px 18px;
}

.status-page__card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.status-page__card-title {
    display: flex;
    align-items: center;
    gap: 9px;
}

.status-page__status-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: none;
}

.status-page__status-dot--up {
    background: var(--color-status-resolved);
}

.status-page__status-dot--down {
    background: var(--color-severity-critical);
}

.status-page__status-dot--unknown {
    background: var(--color-text-faint);
}

.status-page__page-type {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-ink);
}

.status-page__card-meta {
    display: flex;
    align-items: center;
    gap: 12px;
}

.status-page__status-label {
    font-size: 12px;
    font-weight: 600;
}

.status-page__status-label--up {
    color: var(--color-status-resolved);
}

.status-page__status-label--down {
    color: var(--color-severity-critical);
}

.status-page__status-label--unknown {
    color: var(--color-text-faint);
}

.status-page__uptime-pct {
    font-size: 12px;
    color: var(--color-text-muted);
}

.status-page__history {
    display: flex;
    align-items: stretch;
    gap: 2px;
    margin-top: 14px;
    height: 28px;
}

.status-page__history-bar {
    flex: 1;
    min-width: 2px;
    border-radius: 2px;
    background: var(--color-border-muted);
    cursor: default;
}

.status-page__history-bar--up {
    background: var(--color-status-resolved);
}

.status-page__history-bar--down {
    background: var(--color-severity-critical);
}

.status-page__history-bar--partial {
    background: var(--color-severity-medium);
}

.status-page__history-bar--no-data {
    background: var(--color-border-muted);
}

.status-page__history-labels {
    display: flex;
    justify-content: space-between;
    margin-top: 4px;
    font-size: 10px;
    color: var(--color-text-faint);
}

.status-page__footer {
    margin-top: 28px;
    text-align: center;
    font-size: 11px;
    color: var(--color-text-faint);
}

/* ---- Themed error pages (403/404/500) ----
 * Symfony's default `ErrorController` renders these directly (no app
 * controller involved), so - same reasoning as `.status-page` above -
 * this deliberately stands alone rather than extending
 * `templates/layout/app.html.twig` (whose sidebar needs `active_nav`/nav
 * state this context doesn't reliably have), reusing this file's own
 * `:root` tokens for visual consistency instead.
 */

.error-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 20px;
}

.error-page__card {
    width: 100%;
    max-width: 480px;
    text-align: center;
    padding: 40px 36px;
}

.error-page__code {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-text-faint);
}

.error-page__title {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--color-ink);
    margin: 10px 0 0;
}

.error-page__message {
    margin: 10px 0 0;
    font-size: 13px;
    color: var(--color-text-secondary);
    line-height: 1.6;
}

.error-page__actions {
    margin-top: 24px;
}

/* ---- Projects Registry: intro banner + "New Project" entry point ---- */

.registry__intro {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.6;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.registry__head-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 0 10px;
}

.registry__count {
    font-size: 12px;
    color: var(--color-text-faint);
}

/*
 * Stage 6: the design's dark-filled "＋ New project" CTA
 * (`background:#211a0e;color:#fff;text-transform:uppercase`) — a `.btn`
 * modifier rather than a one-off style, so the Customers Registry's own
 * "＋ New customer" button (Stage 8, same design treatment, not yet fixed)
 * can pick it up too instead of a second copy landing later.
 */
.btn--cta {
    font-size: 12px;
    font-weight: 600;
    border: none;
    background: var(--color-ink);
    color: #fff;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.btn--cta:hover {
    background: #362f21;
}

/* ---- Project Configurator wizard ---- */

.wizard {
    max-width: 760px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.wizard__card {
    padding: 24px 28px;
}

.wizard__title {
    font-size: 18px;
    font-weight: 600;
    margin: 0 0 4px;
}

.wizard__subtitle {
    font-size: 14px;
    font-weight: 600;
    margin: 20px 0 8px;
}

.wizard__intro {
    color: var(--color-text-muted);
    font-size: 13px;
    margin: 0 0 18px;
}

.wizard__fieldset {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 14px 16px 4px;
    margin: 0 0 16px;
}

.wizard__legend {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    padding: 0 4px;
}

.wizard__field {
    margin-bottom: 12px;
}

.wizard__label {
    display: block;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 4px;
}

.wizard__input {
    width: 100%;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-panel);
    padding: 7px 9px;
    font-size: 13px;
    background: var(--color-surface);
    color: var(--color-ink);
}

/*
 * QA fix: every <select> in the app (wizard/modal forms via
 * `select.wizard__input`, plus every other page's own select class) relied
 * entirely on native OS/browser chrome — no custom arrow, no consistent
 * height with sibling text inputs. One shared chevron for all of them
 * rather than duplicating the background-image per class.
 */
select.wizard__input,
.analytics__select,
.findings__select,
.settings__select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236f6757' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 28px;
    cursor: pointer;
}

.wizard__input--textarea {
    min-height: 80px;
    resize: vertical;
}

.wizard__help {
    font-size: 11px;
    color: var(--color-text-faint);
    margin: 4px 0 0;
}

.wizard__errors {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    font-size: 11px;
    color: var(--color-severity-critical);
}

.wizard__checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    cursor: pointer;
}

.wizard__checkbox-text {
    font-size: 13px;
    color: var(--color-text-secondary);
}

.wizard__actions {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;
}

.wizard__summary {
    display: grid;
    grid-template-columns: 180px 1fr;
    gap: 6px 12px;
    font-size: 13px;
    margin: 0 0 16px;
}

.wizard__summary dt {
    color: var(--color-text-muted);
}

.wizard__summary dd {
    margin: 0;
}

.wizard__connector-list {
    list-style: none;
    padding: 0;
    margin: 0 0 16px;
    font-size: 13px;
}

.wizard__connector-list li {
    padding: 4px 0;
    border-bottom: 1px solid var(--color-border-muted);
}

.wizard__connector-list li:last-child {
    border-bottom: none;
}

.wizard__flash {
    background: var(--color-severity-high-bg);
    color: var(--color-severity-high);
    padding: 10px 14px;
    border-radius: var(--radius-panel);
    font-size: 13px;
    margin-bottom: 16px;
}

.wizard__token-warning {
    background: var(--color-severity-high-bg);
    color: var(--color-severity-high);
    padding: 10px 14px;
    border-radius: var(--radius-panel);
    font-size: 13px;
    margin-bottom: 16px;
}

.wizard__token-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}

.wizard__token-value {
    flex: 1;
    font-family: var(--font-mono);
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 8px 10px;
    font-size: 13px;
    overflow-wrap: anywhere;
}

/* ---- New Project Modal (Stage 7) ----
   Same fixed-overlay/backdrop recipe as `.customer-modal` (reused idiom,
   not re-derived from the design's own literal `rgba(0,0,0,0.42)` scrim —
   see `templates/project_wizard/_modal_shell.html.twig`'s docblock), just
   its own class namespace since this dialog needs extra chrome (the
   step-pill header, a scrolling body separate from a pinned footer) none
   of the Customer/Staff/Suggest-Rule modals need. */

.project-wizard-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.project-wizard-modal[hidden] {
    display: none;
}

.project-wizard-modal__panel {
    width: 720px;
    max-width: 94vw;
    max-height: 90vh;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-panel);
    display: flex;
    flex-direction: column;
}

.project-wizard-modal__form {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.project-wizard-modal__header {
    flex: none;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 22px;
    border-bottom: 1px solid var(--color-border);
}

.project-wizard-modal__title {
    font-size: 15px;
    font-weight: 600;
}

.project-wizard-modal__header-spacer,
.project-wizard-modal__footer-spacer {
    flex: 1;
}

.project-wizard-modal__steps {
    display: flex;
    align-items: center;
    gap: 12px;
}

.project-wizard-modal__step {
    display: flex;
    align-items: center;
    gap: 6px;
}

.project-wizard-modal__step-num {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1px solid var(--color-border-strong);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 600;
    flex: none;
    color: var(--color-text-faint);
}

.project-wizard-modal__step-label {
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-faint);
}

.project-wizard-modal__step--active .project-wizard-modal__step-num {
    border-color: var(--color-ink);
    background: var(--color-ink);
    color: #fff;
}

.project-wizard-modal__step--active .project-wizard-modal__step-label {
    color: var(--color-ink);
    font-weight: 600;
}

.project-wizard-modal__step--done .project-wizard-modal__step-num {
    border-color: var(--color-status-resolved);
    color: var(--color-status-resolved);
}

.project-wizard-modal__step--done .project-wizard-modal__step-label {
    color: var(--color-status-resolved);
}

.project-wizard-modal__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
    flex: none;
}

.project-wizard-modal__close:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
}

.project-wizard-modal__body {
    flex: 1;
    overflow-y: auto;
    padding: 18px 22px;
}

/*
 * QA fix (IMPLEMENTATION_PLAN.md Stage 7 polish pass): the Basics step's
 * fields were stacked one-per-row inside bordered `<fieldset>`s — the
 * design's own Basics step is a flat 2-column grid with no section
 * dividers at all. `App\Form\ProjectBasicsType`'s field set is untouched;
 * only `templates/project_wizard/basics.html.twig`'s markup changed to
 * drop the fieldsets and wrap fields in this grid instead.
 */
.project-wizard-modal__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 18px;
}

.project-wizard-modal__grid .wizard__field {
    margin-bottom: 12px;
}

.project-wizard-modal__footer {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 22px;
    margin: 0;
    border-top: 1px solid var(--color-border);
}

/*
 * ---- Project Detail: Security tab ----
 * Two clearly separate top-level cards (the Cloudflare/WAF "not connected"
 * empty state, then the real SEC-001/SSL-001 "other security findings"
 * list) — a plain flex column with a deliberately generous gap keeps them
 * visually distinct rather than reading as one continuous panel, matching
 * `.dashboard__col`'s own "stack of unrelated panels" gap convention.
 */
.security-tab {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/*
 * Generic small "where this data comes from" / "how to configure this"
 * note box — first used on the Security tab (CVE/cert source explainer)
 * and the Configure tab's Cloudflare fieldset (token-creation
 * instructions), reusable anywhere else a short explanatory aside is
 * needed rather than inventing a new box per tab.
 */
.info-note {
    margin-top: 8px;
    padding: 9px 12px;
    font-size: 11px;
    line-height: 1.5;
    color: var(--color-text-muted);
    background: var(--color-header-bg);
    border: 1px solid var(--color-border-muted);
    border-radius: 2px;
}

.info-note a {
    font-weight: 600;
    color: var(--color-ink);
}

/*
 * ---- Project Detail: Performance tab ----
 * Same "plain flex column of clearly separate cards" convention as
 * `.security-tab` — the RUMVision "not connected" card, then whichever
 * Tideways card(s) below it (empty state, or the real chart/exceptions
 * grid + slowest-transactions gap note), never one continuous panel.
 * `.performance-tab__chart-*`/`.performance-tab__panel`/`.performance-tab
 * __grid` deliberately mirror `.business-tab__chart-*`/`.business-tab
 * __panel`/`.business-tab__grid` rather than reusing them outright: the
 * two charts differ enough (no baseline/band/deploy layer here, see
 * `App\ProjectDetail\PerformanceChartBuilder`'s docblock) that a shared
 * class would carry unused Business-tab-only rules; the *values* are kept
 * identical on purpose so both tabs' cards read as one visual system.
 */
.performance-tab {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.performance-tab__grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 12px;
    align-items: start;
}

.performance-tab__chart-card,
.performance-tab__panel {
    padding: 14px 16px;
}

.performance-tab__chart-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}

.performance-tab__chart-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-ink);
}

.performance-tab__chart-source {
    font-size: 11px;
    color: var(--color-text-faint);
}

.performance-tab__chart {
    width: 100%;
    display: block;
    margin-top: 10px;
}

.performance-tab__chart-area {
    fill: var(--color-ink);
    opacity: 0.06;
}

.performance-tab__chart-series {
    fill: none;
    stroke: var(--color-ink);
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.performance-tab__chart-point {
    fill: var(--color-ink);
    opacity: 0.85;
}

.performance-tab__chart-legend {
    display: flex;
    gap: 16px;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 6px;
}

.performance-tab__empty {
    font-size: 12px;
    color: var(--color-text-faint);
    line-height: 1.5;
}

.performance-tab__exceptions-total {
    font-size: 26px;
    font-weight: 600;
    margin-top: 4px;
    color: var(--color-ink);
}

.performance-tab__exception-row {
    margin-top: 10px;
}

.performance-tab__exception-row-head {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 11px;
}

.performance-tab__exception-name {
    font-family: var(--font-mono);
    color: var(--color-text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.performance-tab__exception-count {
    font-weight: 600;
    flex: none;
    color: var(--color-ink);
}

.performance-tab__exception-track {
    height: 5px;
    background: var(--color-border-muted);
    border-radius: 3px;
    margin-top: 3px;
    overflow: hidden;
}

.performance-tab__exception-bar {
    display: block;
    height: 100%;
    background: var(--color-severity-high);
    border-radius: 3px;
}

/*
 * RUMVision half of the Performance tab (web-vitals KPI row + "Web vitals
 * by page type" table) — `.performance-tab__vitals-*`/`.performance-tab
 * __vital-*`/`.performance-tab__pagetype-*` deliberately mirror the
 * `.performance-tab__chart-*` values (same card padding, header layout,
 * muted-source-label treatment) rather than introducing a visually
 * distinct sub-system, even though they're their own scoped class family
 * (see this file's own "Project Detail: Performance tab" comment above for
 * why tab-scoped classes aren't shared across tabs here). The KPI grid
 * uses `repeat(auto-fit, ...)` rather than the design mock's fixed
 * `repeat(4, 1fr)` since a real `App\RumVision\RumVisionApiClient::
 * CORE_METRIC_SLUGS` catalog commonly has 5 entries, not 4 — see
 * `templates/project_detail/_performance.html.twig`'s own docblock for the
 * full reasoning.
 */
.performance-tab__vitals-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
}

.performance-tab__vitals-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-ink);
}

.performance-tab__vitals-source {
    font-size: 11px;
    color: var(--color-text-faint);
}

.performance-tab__vitals-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
    margin-top: 12px;
}

.performance-tab__vital-card {
    padding: 14px 16px;
}

.performance-tab__vital-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.performance-tab__vital-label {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    letter-spacing: 0.1em;
}

.performance-tab__vital-value {
    font-size: 26px;
    font-weight: 600;
    margin-top: 8px;
    color: var(--color-ink);
}

.performance-tab__vital-unit {
    font-size: 12px;
    color: var(--color-text-faint);
    font-weight: 400;
}

.performance-tab__vital-secondary {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 3px;
}

.performance-tab__pagetype-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    justify-content: space-between;
}

.performance-tab__pagetype-columns {
    display: flex;
    gap: 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.performance-tab__pagetype-col--page {
    flex: 1;
}

.performance-tab__pagetype-col--metric {
    width: 64px;
    text-align: right;
}

.performance-tab__pagetype-col--views {
    width: 56px;
    text-align: right;
}

.performance-tab__pagetype-row {
    display: flex;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
    align-items: center;
}

.performance-tab__pagetype-name {
    flex: 1;
    font-weight: 500;
}

.performance-tab__pagetype-metric {
    width: 64px;
    text-align: right;
    font-weight: 600;
}

.performance-tab__pagetype-views {
    width: 56px;
    text-align: right;
    color: var(--color-text-faint);
    font-size: 11px;
}

/* ---- Project Detail: Configure tab ---- */

.configure__card {
    padding: 20px 24px;
    margin: 0 0 16px;
}

/*
 * "The Forms should be collapsable, so i can find my configs faster" —
 * `.configure__card` is a native `<details>`, same plain "no JS needed"
 * pattern already established for the Dependencies tab's
 * local-path-packages disclosure (see `.deps-tab__table-head--summary`).
 * Collapsed by default as of the follow-up "Can you make the entirety of
 * the configs collapsable?" (`templates/project_configure/index.html.twig`'s
 * own docblock covers the per-card "stay open on a real validation error"
 * exception). `list-style: none` suppresses the default marker in engines
 * that render `<summary>` as a list item — replaced by `.configure__card
 * -caret` below, added for "Add a little caret to indicate that its a
 * collapsable" after the title-text-alone affordance turned out not to be
 * obvious enough.
 */
.configure__card-title {
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 14px;
}

summary.configure__card-title {
    cursor: pointer;
    list-style: none;
}

.configure__card-caret {
    display: inline-block;
    font-size: 10px;
    color: var(--color-text-faint);
    transition: transform 0.15s ease;
}

.configure__card[open] > summary .configure__card-caret {
    transform: rotate(90deg);
}

.configure__actions {
    justify-content: flex-end;
}

.configure__flash {
    background: var(--color-status-resolved-bg);
    color: var(--color-status-resolved);
    padding: 10px 14px;
    border-radius: var(--radius-panel);
    font-size: 13px;
    margin: 0 0 16px;
}

.configure__empty {
    color: var(--color-text-faint);
    font-size: 13px;
    margin: 0 0 14px;
}

.configure__token-list {
    margin: 0 0 20px;
}

.configure__token-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-border-muted);
}

.configure__token-row:last-child {
    border-bottom: none;
}

.configure__token-label {
    font-weight: 500;
    flex: 1;
}

.configure__token-detail {
    font-size: 12px;
    color: var(--color-text-muted);
}

.configure__token-revoke-form {
    margin: 0;
}

.configure__token-create {
    border-top: 1px solid var(--color-border-muted);
    padding-top: 16px;
}

/* ---- Project Detail Configure tab: Danger zone ---- */

.configure__card--danger {
    border-color: var(--color-severity-critical-bg);
}

.configure__danger-warning {
    color: var(--color-text-faint);
    font-size: 13px;
    margin: 0 0 14px;
}

/* ---- Delete Project Modal ----
   Same fixed-overlay/backdrop recipe as `.customer-modal`/`.staff-modal`/
   `.suggest-rule-modal` (this app's established per-modal duplicated-rule
   idiom, not a shared class — see those rules' own comments), reusing
   `.customer-modal__panel`'s chrome directly since no feature-specific
   sizing/label override is needed here. */

.delete-project-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.delete-project-modal[hidden] {
    display: none;
}

.delete-project-modal__warning {
    font-size: 13px;
    margin: 0 0 14px;
}

/* ---- Customer Modal (Stage 2) ---- */

.customer-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.customer-modal[hidden] {
    display: none;
}

.customer-modal__panel {
    width: 460px;
    max-width: 94vw;
    max-height: 88vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-panel);
    padding: 18px 20px;
}

.customer-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 600;
    margin-bottom: 14px;
}

.customer-modal__close {
    cursor: pointer;
    color: var(--color-text-faint);
    font-size: 16px;
    padding: 2px 6px;
    border-radius: 5px;
    background: none;
    border: none;
}

.customer-modal__close:hover {
    background: var(--color-status-accepted-risk-bg);
    color: var(--color-ink);
}

.customer-modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    border-top: 1px solid var(--color-border);
    padding-top: 14px;
    margin-top: 6px;
}

/* ---- Customer Detail (Stage 2) ---- */

.customer-detail__top {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
}

.customer-detail__back {
    font-size: 12px;
    color: var(--color-text-muted);
    text-decoration: none;
}

.customer-detail__back:hover {
    color: var(--color-ink);
}

.customer-detail__top-spacer {
    flex: 1;
}

.customer-detail__header {
    display: flex;
    align-items: center;
    gap: 14px;
}

.customer-detail__avatar {
    width: 52px;
    height: 52px;
    flex: none;
    border-radius: 50%;
    background: var(--color-border-muted);
    color: var(--color-text-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    font-weight: 700;
    object-fit: contain;
}

.customer-detail__header-info {
    flex: 1;
    min-width: 0;
}

.customer-detail__logo-form {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
}

.customer-detail__logo-input {
    font-size: 11px;
    max-width: 200px;
}

.customer-detail__logo-input::file-selector-button {
    font-size: 11px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: 5px;
    padding: 0 10px;
    height: 24px;
    cursor: pointer;
    color: var(--color-text-secondary);
    margin-right: 8px;
}

.customer-detail__logo-input::file-selector-button:hover {
    border-color: #b3a98f;
    color: var(--color-ink);
}

.customers__avatar--logo,
.customer-detail__avatar--logo {
    object-fit: cover;
}

.customer-detail__logo-submit {
    font-size: 11px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: 5px;
    padding: 0 10px;
    height: 24px;
    cursor: pointer;
    color: var(--color-text-muted);
}

.customer-detail__logo-submit:hover {
    border-color: #b3a98f;
    color: var(--color-ink);
}

.customer-detail__name {
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.customer-detail__contact-line {
    font-size: 12px;
    color: var(--color-text-faint);
    margin-top: 2px;
    display: flex;
    align-items: center;
    gap: 5px;
}

.customer-detail__email-copy {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.customer-detail__copy {
    font-size: 10px;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    border-radius: var(--radius-panel);
    padding: 1px 6px;
    cursor: pointer;
    color: var(--color-text-muted);
}

.customer-detail__copy:hover {
    border-color: #b3a98f;
    color: var(--color-ink);
}

.customer-detail__stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-top: 16px;
}

.customer-detail__stat {
    padding: 12px 16px;
}

.customer-detail__stat-label {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 500;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.customer-detail__stat-value {
    font-size: 13px;
    font-weight: 600;
    margin-top: 6px;
}

.customer-detail__stat-value--muted {
    font-weight: 400;
    color: var(--color-text-faint);
}

.customer-detail__contract-link {
    display: inline-block;
    font-size: 11px;
    color: var(--color-ink);
    font-weight: 500;
    margin-top: 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.customer-detail__projects {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    flex-wrap: wrap;
}

.customer-detail__project-chip {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 5px 10px;
    background: var(--color-surface);
    color: inherit;
    text-decoration: none;
}

.customer-detail__project-chip:hover {
    border-color: var(--color-ink);
}

.customer-detail__project-chip-name {
    font-weight: 500;
}

.customer-detail__project-chip-open {
    color: var(--color-text-faint);
    font-size: 11px;
}

.customer-detail__no-projects {
    font-size: 12px;
    color: var(--color-text-faint);
}

.customer-detail__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 16px;
    align-items: start;
}

.customer-detail__panel {
    padding: 0;
}

.customer-detail__panel-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    font-size: 13px;
    font-weight: 600;
}

.customer-detail__history-form {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-header-bg);
}

.customer-detail__history-form-actions {
    display: flex;
    justify-content: flex-end;
}

.customer-detail__history-row {
    display: flex;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.customer-detail__history-row:last-child {
    border-bottom: none;
}

.customer-detail__history-date {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-faint);
    width: 56px;
    flex: none;
}

.customer-detail__history-kind {
    font-size: 10px;
    font-weight: 600;
    border-radius: 4px;
    padding: 1px 7px;
    flex: none;
    height: fit-content;
    text-transform: uppercase;
}

.customer-detail__history-kind--note {
    color: var(--color-text-muted);
    background: var(--color-status-accepted-risk-bg);
}

.customer-detail__history-kind--project {
    color: var(--color-status-acknowledged);
    background: var(--color-status-acknowledged-bg);
}

.customer-detail__history-kind--incident {
    color: var(--color-severity-high);
    background: var(--color-severity-high-bg);
}

.customer-detail__history-kind--contract {
    color: var(--color-status-resolved);
    background: var(--color-status-resolved-bg);
}

.customer-detail__history-text {
    flex: 1;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

.customer-detail__contact-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.customer-detail__contact-row:last-child {
    border-bottom: none;
}

.customer-detail__contact-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--color-border-muted);
    color: var(--color-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    flex: none;
}

.customer-detail__contact-info {
    flex: 1;
    min-width: 0;
}

.customer-detail__contact-name {
    font-size: 12.5px;
    font-weight: 600;
}

.customer-detail__contact-role {
    font-weight: 400;
    color: var(--color-text-muted);
}

.customer-detail__contact-note {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 1px;
}

.customer-detail__contact-email {
    font-size: 11px;
    color: var(--color-text-muted);
    flex: none;
}

/* ---- Staff Registry & Detail (Stage 3) ---- */

.staff__intro {
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.6;
    background: var(--color-header-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 10px 14px;
    margin-bottom: 14px;
}

.staff__head-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 0 12px;
}

.staff__count {
    font-size: 12px;
    color: var(--color-text-faint);
}

.staff__row {
    margin-bottom: 10px;
    padding: 14px 16px;
}

.staff__row-top {
    display: flex;
    align-items: center;
    gap: 12px;
}

.staff__avatar {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: 50%;
    background: var(--color-border-muted);
    color: var(--color-text-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
}

.staff__row-identity {
    width: 220px;
    flex: none;
    color: inherit;
    text-decoration: none;
}

.staff__row-identity:hover .staff__row-name {
    text-decoration: underline;
}

.staff__row-name {
    display: block;
    font-size: 14px;
    font-weight: 600;
}

.staff__row-role {
    display: block;
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 1px;
}

.staff__row-workload {
    flex: 1;
    min-width: 0;
}

.staff__row-workload-labels {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.staff__workload-track {
    height: 8px;
    background: var(--color-border-muted);
    border-radius: 4px;
    overflow: hidden;
}

.staff__workload-bar {
    display: block;
    height: 100%;
    background: var(--color-status-resolved);
    border-radius: 4px;
}

.staff__row-panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border-muted);
}

.staff__row-panel-header {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 500;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 6px;
}

.staff__row-panel-header--split {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
}

.staff__row-panel-header-note {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 400;
    color: var(--color-text-faint);
    text-transform: none;
    letter-spacing: normal;
}

.staff__delete-form {
    display: inline-flex;
}

.staff__no-tickets {
    font-size: 12px;
    color: var(--color-status-acknowledged);
}

.staff-modal {
    position: fixed;
    inset: 0;
    z-index: 51;
    background: rgba(33, 26, 14, 0.28);
    display: flex;
    align-items: center;
    justify-content: center;
}

.staff-modal[hidden] {
    display: none;
}

.staff-detail__top {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
}

.staff-detail__back {
    font-size: 12px;
    color: var(--color-text-muted);
    text-decoration: none;
}

.staff-detail__back:hover {
    color: var(--color-ink);
}

.staff-detail__top-spacer {
    flex: 1;
}

.staff-detail__header {
    display: flex;
    align-items: center;
    gap: 14px;
}

.staff-detail__avatar {
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 50%;
    background: var(--color-border-muted);
    color: var(--color-text-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    font-weight: 700;
}

.staff-detail__header-info {
    flex: 1;
    min-width: 0;
}

.staff-detail__name {
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.staff-detail__sub {
    font-size: 12px;
    color: var(--color-text-faint);
    margin-top: 2px;
}

.staff-detail__workload {
    width: 220px;
    flex: none;
}

.staff-detail__workload-labels {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.staff-detail__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 16px;
    align-items: start;
}

.staff-detail__panel-col {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.staff-detail__panel {
    padding: 0;
}

.staff-detail__panel-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    font-size: 13px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.staff-detail__panel-header-note {
    font-size: 11px;
    font-weight: 400;
    color: var(--color-text-faint);
}

.staff-detail__panel-header-link {
    font-size: 11px;
    font-weight: 500;
    color: var(--color-ink);
    text-decoration: none;
}

.staff-detail__panel-header-link:hover {
    text-decoration: underline;
}

.staff-detail__panel-empty {
    padding: 12px 16px;
    font-size: 12px;
    color: var(--color-status-acknowledged);
}

/*
 * ---- Project Detail: Code tab ---- (2026-08-11 design refresh,
 * `templates/project_detail/_code.html.twig` + `assets/controllers/
 * code_quality_controller.js`). Replaces the previous pass's CC-vs-MI
 * cartesian-scatter styling wholesale — every rule below is new/rewritten
 * for the packed-circle bubble chart, 5-card summary, class-inspector
 * panel, collapsible package/class table and README audit table. Colour/
 * threshold values are computed server-side (`App\ProjectDetail\
 * CodeQualityColors`) and applied via inline `style` attributes in the
 * template — same convention as `App\Registry\InfrastructureCellView`'s
 * badge colouring elsewhere in this app — so these rules only ever carry
 * layout/typography, never a data-tied colour.
 */
.code-tab {
    margin-top: 16px;
    max-width: 1050px;
}

.code-tab__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 12px;
}

.code-tab__header-note,
.code-tab__last-run {
    font-size: 11px;
    color: var(--color-text-faint);
}

.code-tab__header-right {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex: none;
}

.code-tab__scan-form,
.deps-tab__scan-form {
    margin: 0;
}

.deps-tab__header {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 12px;
}

.code-tab__path {
    font-family: var(--font-mono);
    color: var(--color-text-secondary);
    font-weight: 500;
}

.code-tab__gitlab-link {
    font-weight: 600;
    color: var(--color-ink);
}

.code-tab__summary {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 12px;
}

.code-tab__summary-card {
    padding: 14px 16px;
}

.code-tab__summary-label {
    display: block;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.code-tab__summary-value {
    display: block;
    font-family: var(--font-body);
    font-size: 26px;
    font-weight: 600;
    margin-top: 8px;
}

.code-tab__summary-unknown {
    font-size: 13px;
    font-weight: 400;
    color: var(--color-text-faint);
}

.code-tab__summary-sub {
    display: block;
    font-size: 11px;
    color: var(--color-text-muted);
    margin-top: 4px;
}

.code-tab__summary-bar {
    display: block;
    height: 6px;
    background: var(--color-severity-low-bg);
    border-radius: 3px;
    margin-top: 8px;
    overflow: hidden;
}

.code-tab__summary-bar-fill {
    display: block;
    height: 100%;
    border-radius: 3px;
}

.code-tab__chart-row {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: 12px;
    margin-top: 12px;
    align-items: stretch;
}

.code-tab__chart-head,
.code-tab__table-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.code-tab__chart-title,
.code-tab__table-title,
.code-tab__detail-head {
    font-size: 13px;
    font-weight: 600;
}

.code-tab__chart-sub,
.code-tab__table-sub {
    font-size: 11px;
    color: var(--color-text-faint);
}

.code-tab__chart-body {
    padding: 10px 12px;
}

.code-tab__chart-svg {
    width: 100%;
    height: auto;
    display: block;
}

/*
 * Default (no selection yet) bubble treatment ported verbatim from the
 * design mock's own `op:sel?(...):0.92` branch — once any class has been
 * selected, `code_quality_controller.js#highlightBubbles` takes over and
 * sets stroke/stroke-width/opacity on every bubble directly (1 for the
 * selected one, 0.55 for the rest), matching the mock's `sel` branch.
 */
.code-tab__bubble {
    stroke: #fffcf5;
    stroke-width: 1;
    opacity: 0.92;
    cursor: pointer;
}

.code-tab__chart-legend {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 16px 12px;
    font-size: 11px;
    color: var(--color-text-muted);
}

.code-tab__legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.code-tab__legend-swatch {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
}

.code-tab__legend-spacer {
    flex: 1;
}

/*
 * Class-inspector side panel (design's "click a bubble → class detail",
 * now also reachable by clicking a class-table row — see
 * `code_quality_controller.js#select`). 280px-wide sibling of the bubble
 * chart card, not a modal — a bubble's detail is a small, glanceable
 * amount of data, not a full page of content.
 */
.code-tab__detail-card {
    display: flex;
    flex-direction: column;
}

.code-tab__detail-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
}

.code-tab__detail-placeholder {
    padding: 12px 16px;
    font-size: 12px;
    color: var(--color-text-faint);
    line-height: 1.6;
}

.code-tab__detail-body {
    padding: 12px 16px;
}

.code-tab__detail-file {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
    line-height: 1.5;
    word-break: break-all;
}

.code-tab__detail-file-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted var(--color-text-faint);
}

.code-tab__detail-file-link:hover {
    border-bottom-style: solid;
}

.code-tab__detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-top: 12px;
}

.code-tab__detail-metric-label {
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.code-tab__detail-metric-value {
    font-size: 17px;
    font-weight: 600;
}

.code-tab__detail-note {
    font-size: 12px;
    color: var(--color-text-secondary);
    line-height: 1.6;
    margin-top: 12px;
}

.code-tab__detail-meta {
    font-size: 11px;
    color: var(--color-text-faint);
    margin-top: 10px;
}

.code-tab__packages {
    margin-top: 12px;
}

.code-tab__col-head {
    display: flex;
    gap: 12px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

/*
 * Shared column classes reused across the top-level package rows, the
 * nested per-class drill-down rows, AND the README audit table — the
 * template applies the exact same `.code-tab__col--*` class regardless of
 * which of those three tables it is in (see `_code.html.twig`), so a
 * column's exact width/colour here is scoped to its containing table
 * (`.code-tab__packages`/`.code-tab__readme`) rather than the shared class
 * alone, matching each table's own distinct widths from the design.
 */
.code-tab__col--num {
    flex: none;
    text-align: right;
}

.code-tab__col--mi {
    font-weight: 600;
}

.code-tab__col--coverage {
    width: 170px;
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

/*
 * "Add column sortings for the tables in the code tab" — same
 * `assets/controllers/sortable_table_controller.js` the Dependencies tab
 * already uses, one instance per table (the "Coverage by package" table,
 * each package's own nested per-class drill-down, and the README audit
 * table are 3+ independent instances). Identical visual language to
 * `.deps-tab__col--sortable` on purpose — same affordance, different tab.
 */
.code-tab__col--sortable {
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.code-tab__col--sortable:hover {
    color: var(--color-ink);
}

.code-tab__col--sortable::after {
    content: '\21C5';
    font-size: 9px;
    opacity: 0.4;
}

.code-tab__col--sortable[data-sort-active="asc"]::after {
    content: '\2191';
    opacity: 1;
}

.code-tab__col--sortable[data-sort-active="desc"]::after {
    content: '\2193';
    opacity: 1;
}

/*
 * Package/class table: Package|Class name column is 1.4, and the 4 numeric
 * columns that follow (Classes/Methods, LoC, CC, MI) are fixed 70/70/60/50
 * — the template gives all four the same `.code-tab__col--num` class, so
 * their distinct widths are addressed positionally (`nth-of-type`) rather
 * than by a modifier class.
 */
.code-tab__packages .code-tab__col--package {
    flex: 1.4;
    min-width: 0;
}

.code-tab__packages .code-tab__col--num:nth-of-type(2) {
    width: 70px;
    color: var(--color-text-muted);
}

.code-tab__packages .code-tab__col--num:nth-of-type(3) {
    width: 70px;
}

.code-tab__packages .code-tab__col--num:nth-of-type(4) {
    width: 60px;
}

.code-tab__packages .code-tab__col--num:nth-of-type(5) {
    width: 50px;
}

.code-tab__package-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 13px;
    cursor: pointer;
    background: transparent;
}

.code-tab__package-row:hover {
    background: var(--color-row-hover);
}

.code-tab__package-cell {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.code-tab__package-caret {
    display: inline-block;
    width: 8px;
    flex: none;
    font-size: 9px;
    color: var(--color-text-faint);
}

.code-tab__package-name {
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 500;
}

.code-tab__class-group {
    background: #f9f5ea;
    border-bottom: 1px solid var(--color-border-muted);
}

.code-tab__class-col-head {
    display: flex;
    gap: 12px;
    padding: 7px 16px 7px 40px;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.code-tab__class-empty {
    padding-left: 40px;
}

.code-tab__class-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 16px 8px 40px;
    border-top: 1px solid #efe7d5;
    font-size: 12px;
    cursor: pointer;
    background: transparent;
}

.code-tab__class-row:hover {
    background: var(--color-row-hover);
}

/* Design's own `c.bg: sel?...'#efe7d5':'transparent'` — kept and highlighted
   in sync with the matching bubble by `code_quality_controller.js#select`. */
.code-tab__class-row--selected {
    background: #efe7d5;
}

.code-tab__class-name {
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.code-tab__coverage-track {
    flex: 1;
    height: 6px;
    background: var(--color-severity-low-bg);
    border-radius: 3px;
    overflow: hidden;
}

.code-tab__coverage-track--sm {
    height: 5px;
}

.code-tab__coverage-bar {
    display: block;
    height: 100%;
    border-radius: 3px;
}

.code-tab__coverage-pct {
    width: 34px;
    text-align: right;
    font-size: 12px;
    font-weight: 500;
}

.code-tab__readme {
    margin-top: 12px;
    margin-bottom: 8px;
}

/* README table: Package column is 1.2 here (vs. 1.4 on the package/class
   table above) and its one numeric column (Words) is 80px, not 70/70/60/50
   — both scoped to `.code-tab__readme` for the same reason noted above. */
.code-tab__readme .code-tab__col--package {
    flex: 1.2;
    min-width: 0;
    font-family: var(--font-mono);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.code-tab__readme .code-tab__col--num {
    width: 80px;
    color: var(--color-text-muted);
}

.code-tab__col--file {
    width: 80px;
    flex: none;
    font-size: 11px;
    font-weight: 500;
}

.code-tab__col--desc {
    width: 96px;
    flex: none;
}

.code-tab__col--verdict {
    flex: 1.3;
    color: var(--color-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Design's badge sizing for the README "Description" column (5px radius,
   2px 8px padding, 11px/500) differs from this app's generic `.badge`
   (4px/1px 5px/10px/600) — scoped to this one column so no other badge
   usage in the app is affected. */
.code-tab__col--desc .badge {
    font-size: 11px;
    font-weight: 500;
    border-radius: 5px;
    padding: 2px 8px;
}

.code-tab__readme-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
    font-size: 12px;
}

.code-tab__readme-footnote {
    padding: 10px 16px;
    font-size: 11px;
    color: var(--color-text-faint);
    line-height: 1.5;
}

/* ==========================================================================
   Landing (`/`) & login (`/login`) — the only two screens that extend
   base.html.twig directly instead of layout/app.html.twig's sidebar chrome.
   No design-prototype coverage exists for these (confirmed against
   docs/design/Refinery.dc.html before building this), so they lean on the
   same tokens/components as the rest of the app rather than inventing a
   separate visual language. Motion is intentionally restrained - one
   ambient ticker drift, a one-time staggered fade-in, a hover-only glow -
   and gated behind prefers-reduced-motion so it never fights a visitor who
   has asked for less.
   ========================================================================== */

.landing,
.login {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

.landing__ticker {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 0.16;
    mask-image: linear-gradient(to bottom, transparent, black 15%, black 85%, transparent);
    -webkit-mask-image: linear-gradient(to bottom, transparent, black 15%, black 85%, transparent);
}

.landing__ticker-scroll {
    display: flex;
    flex-direction: column;
}

.landing__ticker-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 10px 0;
    font-size: 13px;
    white-space: nowrap;
}

.landing__ticker-code {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
    min-width: 52px;
}

.landing__ticker-text {
    color: var(--color-text-secondary);
}

.landing__ticker-time {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-faint);
}

.landing__hero {
    position: relative;
    z-index: 1;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
}

.landing__wordmark,
.login__wordmark {
    font-family: var(--font-mono);
    font-size: 28px;
    font-weight: 600;
    letter-spacing: 0.35em;
    color: var(--color-ink);
    /* balances the trailing letter-spacing so the wordmark optically centers */
    padding-left: 0.35em;
}

.landing__tagline {
    margin: 0;
    font-size: 16px;
    color: var(--color-text-secondary);
}

.landing__cta,
.login__gitlab-btn {
    text-decoration: none;
}

.landing__cta:hover,
.login__gitlab-btn:hover {
    text-decoration: none;
}

.landing__cta {
    margin-top: 8px;
    font-family: var(--font-mono);
}

/* Login card */

.login__card {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-panel);
    padding: 48px 56px;
}

.login__wordmark {
    font-size: 20px;
    padding-left: 0.35em;
}

.login__subhead {
    margin: 0;
    font-size: 14px;
    color: var(--color-text-muted);
}

.login__gitlab-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 500;
    padding: 11px 22px;
    transition: box-shadow 0.3s ease, transform 0.2s ease;
}

.login__gitlab-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 18px rgba(33, 26, 14, 0.12);
}

@media (prefers-reduced-motion: no-preference) {
    .landing__ticker-scroll {
        animation: refinery-ticker-drift 48s linear infinite;
    }

    .landing__hero > *,
    .login__card > * {
        opacity: 0;
        animation: refinery-fade-rise 0.7s ease-out forwards;
    }

    .landing__hero > *:nth-child(1),
    .login__card > *:nth-child(1) { animation-delay: 0.05s; }

    .landing__hero > *:nth-child(2),
    .login__card > *:nth-child(2) { animation-delay: 0.15s; }

    .landing__hero > *:nth-child(3),
    .login__card > *:nth-child(3) { animation-delay: 0.25s; }
}

@keyframes refinery-ticker-drift {
    from { transform: translateY(0); }
    to { transform: translateY(-50%); }
}

@keyframes refinery-fade-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
