﻿/* Operator-surface styles using shared design tokens (Goal 5 / Phase 1).
   Component-level styling lives alongside each <NeoX> component in
   Components/Shared/*.razor.css. Page-specific styling below this header
   is being migrated to tokens incrementally as each page is redesigned
   in Phase 2; until then, the new --color-* + --space-* tokens defined
   in design-tokens.css transparently back the existing var() references. */

body { margin: 0; font-family: 'Inter', -apple-system, 'Segoe UI', Roboto, sans-serif; color: var(--color-text); background: var(--color-bg); }

.page { display: flex; flex-direction: column; min-height: 100vh; }
.page-main { flex: 1; padding: var(--space-6); }
.page-content { max-width: 1200px; margin: 0 auto; }

/* Audit detail (/runtime/decisions/{id}). Iter-3 #10 introduces the side-by-side
   comparison; the audit-label/audit-value/audit-json refs from Goal 5's audit
   redesign were never given styles - filling them in here too. */
.audit-label { font-size: var(--text-sm); color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.audit-value { font-size: var(--text-md); font-weight: 600; color: var(--color-text); margin-top: 2px; }
.audit-actions { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-4) 0; }
.audit-replay-meta { font-size: var(--text-sm); color: var(--color-muted); }
.audit-section-h { font-size: var(--text-md); font-weight: 600; margin-top: var(--space-6); margin-bottom: var(--space-2); color: var(--color-text); }
.audit-json {
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    font-family: Consolas, 'Courier New', monospace;
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--color-text-soft);
    max-height: 480px;
    overflow: auto;
    margin: 0;
}
.audit-compare { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.audit-compare-col { display: flex; flex-direction: column; }
.audit-compare-h { font-size: var(--text-sm); font-weight: 600; color: var(--color-text-soft); margin-bottom: var(--space-2); padding-bottom: var(--space-2); border-bottom: var(--border-thin); }
.audit-compare-empty {
    padding: var(--space-4);
    background: var(--color-bg);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-sm);
    color: var(--color-muted);
    font-size: var(--text-sm);
    text-align: center;
}
@media (max-width: 768px) {
    .audit-compare { grid-template-columns: 1fr; }
}

/* Iter-4 #8 — dispatcher override form + trail. */
.audit-override-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-4);
    max-width: 32rem;
}
.audit-override-field { display: flex; flex-direction: column; gap: var(--space-1); }
.audit-override-field label { font-size: var(--text-sm); font-weight: 600; color: var(--color-text-soft); }
/* P3-13: the picker-source hint under the load/driver typeahead fields. */
.audit-override-hint { font-size: var(--text-sm); color: var(--color-muted); }
.audit-override-row {
    padding: var(--space-3) 0;
    border-bottom: var(--border-thin);
}
.audit-override-row:last-child { border-bottom: none; }
.live-override-hint { font-size: var(--text-sm); color: var(--color-muted); }

/* Decision audit story (D S6 #64). The narrative leads (headline + assignments + unassigned reasons);
   the raw JSON collapses into the Raw disclosures below. */
.audit-story { margin-bottom: var(--space-6); }
.audit-story-eyebrow { font-size: var(--text-sm); color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.audit-story-headline { font-size: var(--text-md); font-weight: 600; color: var(--color-text); margin: var(--space-1) 0 0; line-height: var(--leading-md); }
.audit-replay-result { margin-top: var(--space-3); }

/* Left-off-the-plan list: each load beside its own recorded reason. */
.audit-unassigned-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.audit-unassigned-row {
    display: flex;
    gap: var(--space-3);
    align-items: baseline;
    padding: var(--space-2) var(--space-3);
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
}
.audit-unassigned-load { font-weight: 600; color: var(--color-text); min-width: 7rem; }
.audit-unassigned-reason { color: var(--color-text-soft); }

/* Cancelled section: loads the brain took out of planning entirely, distinct from left-off-the-plan. */
.audit-cancelled-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.audit-cancelled-row {
    display: flex;
    gap: var(--space-3);
    align-items: baseline;
    padding: var(--space-2) var(--space-3);
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
}
.audit-cancelled-load { font-weight: 600; color: var(--color-text); }

/* Raw disclosures: the request + response + replay JSON, each opened on demand. */
.audit-raw-group { display: flex; flex-direction: column; gap: var(--space-2); }
.audit-raw { border: var(--border-thin); border-radius: var(--radius-sm); background: var(--color-bg); }
.audit-raw-summary {
    cursor: pointer;
    padding: var(--space-3);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-text-soft);
}
.audit-raw .audit-json { border: none; border-top: var(--border-thin); border-radius: 0; }

.skip-link {
    position: absolute;
    top: -40px;
    left: var(--space-3);
    z-index: 1000;
    padding: var(--space-2) var(--space-3);
    background: var(--color-accent-fill); /* decision 7: AA-safe under white text */
    color: var(--neo-white);
    border-radius: var(--radius-sm);
    text-decoration: none;
    font-weight: 600;
    transition: top 0.15s ease-in-out;
}
.skip-link:focus { top: var(--space-2); outline: var(--focus-ring); }
main:focus { outline: none; }
/* P2-13 (three-lens): Blazor's enhanced-nav focus handoff programmatically focuses the H1;
   the stock template ships exactly this suppression and the app.css rewrite dropped it,
   leaving a focus ring on every first paint. */
h1:focus, h1:focus-visible { outline: none; box-shadow: none; }

/* One-row header on the spruce chrome band: brand, primary rail, right cluster. The rail is four
   items wide (Home plus three group disclosures), so it fits beside the brand and the right cluster
   at the laptop viewport with room to spare; eleven flat links did not, which is what forced the
   old stacked second row. */
.top-nav { display: flex; flex-direction: column; gap: var(--space-2); background: var(--color-chrome); border-bottom: 1px solid rgba(255, 255, 255, 0.08); box-shadow: var(--shadow-sm); padding: var(--space-2) var(--space-6) var(--space-2); }
.top-nav .nav-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
/* The rail sits between the brand and the right cluster and never wraps: its items are few and
   short, and a wrap here would resurrect the two-row header. */
.top-nav .nav-primary { flex-wrap: nowrap; font-size: var(--text-sm); gap: var(--space-1); margin-right: auto; margin-left: var(--space-5); }
/* The brand slot: the dark emblem left of the wordmark. The emblem's own margin carries the
   gap so the tenant indicator's spacing is untouched. */
.top-nav .brand { display: flex; align-items: center; }
.top-nav .brand-emblem { margin-right: var(--space-2); }
.brand-name { font-weight: 600; }
.brand-name .brand-accent { color: var(--color-accent-on-dark); }
.brand-name .brand-rest { color: var(--neo-white); }
.tenant-indicator {
    margin-left: var(--space-3);
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-accent-soft);
    color: var(--color-accent-strong);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.4;
}
.nav-links { list-style: none; display: flex; gap: var(--space-4); margin: 0; padding: 0; }
.nav-links a { color: var(--color-text); text-decoration: none; }
/* The base nav-link accent governs the account-menu panel items on their white surface
   (the primary rail is re-skinned on-dark separately); the AA-safe green accent-text token
   is the P2-20 link standard, so the account-menu links stay legible on white. */
.nav-links a:hover { color: var(--color-accent-text); }
.nav-links a.active { color: var(--color-accent-text); font-weight: 600; }
.nav-placeholder { color: var(--color-muted); font-style: italic; }

/* PW1 - primary-rail chip affordance: each item is a padded tab with a hover fill. Home is the only
   direct link in the rail; the inline-flex + centered items match the group <summary> box beside it,
   so Home is sized like the group triggers rather than reading as a plain line of text. Scoped to
   the primary rail so the right-cluster account menu keeps its own treatment. */
.top-nav .nav-primary a {
    display: inline-flex; align-items: center;
    padding: 3px var(--space-1);
    border-radius: var(--radius-sm);
    color: rgba(255, 255, 255, 0.82);
    line-height: var(--leading-sm);
    transition: background 0.12s ease, color 0.12s ease;
}
.top-nav .nav-primary a:hover { background: rgba(255, 255, 255, 0.08); color: var(--neo-white); }
/* The current-page marker is one treatment: the accent text plus an accent bottom edge. No filled
   background (the earlier fill stacked on the accent text and read as a double highlight); the edge
   alone marks the active page and shares the rail's own accent, so Home and a group trigger could
   wear the same mark. */
.top-nav .nav-primary a.active { background: transparent; color: var(--color-accent-on-dark); font-weight: 600; box-shadow: inset 0 -2px 0 var(--color-accent-on-dark); }

/* The primary rail's group dropdowns. Same mechanism as the account menu below (a native <details>,
   the only disclosure that works under static SSR), styled for the on-dark rail: the trigger reads
   as one more rail chip, and the panel is the forest popup tier so it sits a value-step above the
   spruce chrome rather than being separated by a line alone. */
.nav-menu-wrap { display: flex; align-items: center; }
.nav-menu { position: relative; }
.nav-menu > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: var(--space-1);
    padding: 3px var(--space-1);
    border-radius: var(--radius-sm);
    color: rgba(255, 255, 255, 0.82);
    line-height: var(--leading-sm);
    white-space: nowrap;
    transition: background 0.12s ease, color 0.12s ease;
}
.nav-menu > summary::-webkit-details-marker { display: none; }
.nav-menu > summary::marker { content: ""; }
.nav-menu > summary:hover { background: rgba(255, 255, 255, 0.08); color: var(--neo-white); }
.nav-menu > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.nav-menu[open] > summary { background: rgba(255, 255, 255, 0.12); color: var(--neo-white); }
.nav-menu-caret { font-size: 0.6rem; line-height: 1; }
.nav-menu-panel {
    position: absolute; left: 0; top: calc(100% + var(--space-1)); z-index: 30;
    min-width: 12rem; display: flex; flex-direction: column;
    background: var(--color-chrome-popup); border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg); padding: var(--space-1);
}
.nav-menu-panel .nav-menu-item {
    display: block; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
    color: rgba(255, 255, 255, 0.88); font-size: var(--text-sm); text-decoration: none;
    white-space: nowrap;
}
.nav-menu-panel .nav-menu-item:hover { background: rgba(255, 255, 255, 0.10); color: var(--neo-white); }
.nav-menu-panel .nav-menu-item:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.nav-menu-panel .nav-menu-item.active { background: rgba(255, 255, 255, 0.14); color: var(--color-accent-on-dark); font-weight: 600; }

/* PW2 - the account/utility dropdown. A native <details> disclosure (works under static SSR);
   the trigger is a quiet chip, the panel a right-aligned card of the collapsed links. */
.account-menu-wrap { display: flex; align-items: center; }
.account-menu { position: relative; }
.account-menu > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border: var(--border-thin); border-radius: var(--radius-sm);
    background: var(--color-surface); color: var(--color-text-soft);
    font-size: var(--text-sm); font-weight: 600;
}
.account-menu > summary::-webkit-details-marker { display: none; }
.account-menu > summary::marker { content: ""; }
.account-menu > summary:hover { background: var(--neo-grey-100); color: var(--color-text); }
.account-menu > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.account-menu[open] > summary { background: var(--neo-grey-100); color: var(--color-text); border-color: var(--color-border-strong); }
.account-menu-caret { font-size: 0.6rem; line-height: 1; }
.account-menu-panel {
    position: absolute; right: 0; top: calc(100% + var(--space-1)); z-index: 30;
    min-width: 12rem; display: flex; flex-direction: column;
    background: var(--color-surface); border: var(--border-thin); border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg); padding: var(--space-1);
}
.account-menu-item {
    display: block; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
    color: var(--color-text); font-size: var(--text-sm); text-decoration: none;
}
.account-menu-item:hover { background: var(--neo-grey-100); color: var(--color-text); }
.account-menu-sep { height: 1px; background: var(--color-border); margin: var(--space-1) 0; }
.account-menu-signout { padding: var(--space-1); }
.account-menu-signout button { width: 100%; }

/* The house grid grammar (the stops-grid standard): one container border, a grey uppercase head
   band, horizontal row separators, row-scale type. Grids run full width; a table that reads better
   narrow opts in with .data-table-capped.
   Borders are separate with the spacing zeroed rather than collapsed, so the container's radius
   survives and a sticky head keeps its own band. In the separate model a border on a <tr> is
   ignored, so the row separators live on the cells. */
.data-table {
    border-collapse: separate; border-spacing: 0;
    width: 100%; margin-top: var(--space-3);
    border: var(--border-thin); border-radius: var(--radius-md);
    background: var(--color-surface);
}
.data-table th, .data-table td { padding: var(--space-2) var(--space-3); text-align: left; }
.data-table thead th {
    background: var(--neo-grey-100); border-bottom: var(--border-thin);
    font-size: var(--text-xs); font-weight: 600; color: var(--color-text-soft);
    text-transform: uppercase; letter-spacing: 0.03em;
}
/* The head band carries the container's top corners itself: its opaque fill would otherwise
   square off the rounding it sits inside. */
.data-table thead th:first-child { border-top-left-radius: var(--radius-md); }
.data-table thead th:last-child { border-top-right-radius: var(--radius-md); }
.data-table tbody td { border-bottom: var(--border-thin); font-size: var(--text-sm); }
.data-table tbody tr:last-child > td { border-bottom: none; }
/* The opt-in reading cap for the small catalog tables that read better narrow than full-bleed. */
.data-table-capped { max-width: 800px; }
/* Rule-1 grid density: tight row rhythm for scan-heavy grids (mirrors NeoDataTable's Tight). */
.data-table-tight th, .data-table-tight td { padding: var(--space-1) var(--space-2); }
/* The loads/drivers grid is footprint-constrained: it scrolls internally instead of growing the
   page, with a sticky header so columns stay labeled. The wrapper is the container here, so the
   table inside drops its own border and corners. */
.data-grid-scroll { max-height: 60vh; overflow: auto; border: var(--border-thin); border-radius: var(--radius-md); }
.data-grid-scroll .data-table { margin-top: 0; border: none; border-radius: 0; }
.data-grid-scroll .data-table thead th { position: sticky; top: 0; z-index: 1; border-radius: 0; }

.page-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2) var(--space-4); margin-top: 0; }
/* P3-2: the live board's right-side header cluster — freshness stamp + Recompute. */
.live-header-actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
/* Carries the close-out trigger's hint while the trigger is disabled; a disabled control fires no
   mouse events, so its own title cannot show. Laid out as the button it wraps. */
.close-out-hint { display: inline-flex; }
.error { color: var(--color-error); }

/* The button convention (decided 2026-07-09): every button speaks uppercase; filled green for
   actions, outlined white for opposing choices (Cancel / Back), text tertiary. */
.btn { display: inline-block; padding: var(--space-2) var(--space-4); border: var(--border-strong); background: var(--color-surface); color: var(--color-text); text-decoration: none; border-radius: var(--radius-sm); cursor: pointer; font: inherit; font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.btn:hover { background: var(--neo-grey-100); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
/* Filled primary buttons ride the AA-safe fill step (deep green #0F6E56, white text
   6.20:1); hover steps one darker (#0B5742, 8.55:1). */
.btn-primary { background: var(--color-accent-fill); color: var(--neo-white); border-color: var(--color-accent-fill); }
.btn-primary:hover { background: var(--color-accent-fill-hover); }
/* On-dark fill step: for a filled action sitting on the spruce chrome or pine dark surfaces,
   where the deep-green primary fill reads soft. Mint fill (#35E0A6) with spruce text (#08211B)
   clears 9.94:1. Hover holds the mint so the shared .btn:hover grey does not override it. */
.btn-on-dark { background: var(--color-accent-on-dark); color: var(--color-chrome); border-color: var(--color-accent-on-dark); }
.btn-on-dark:hover { background: var(--color-accent-on-dark); }
/* P0-7: the operator .btn-secondary (design-direction §6). marketing.css's dark-hero
   variant used to leak in globally and paint these white-on-white. */
.btn-secondary { background: var(--neo-white); color: var(--color-text); border-color: var(--color-border-strong); }
.btn-secondary:hover { background: var(--neo-grey-50); }
/* The accent tier: outlined green for additive / disclosure actions (Add stop, Show details) -
   pops against the grey neutrals without competing with the filled-green primary commit. */
.btn-accent { background: var(--color-surface); color: var(--color-accent-strong); border-color: var(--color-accent-strong); }
.btn-accent:hover { background: var(--color-accent-soft); }
.btn-danger { color: var(--color-error); border-color: var(--color-error); }
.btn-danger:hover { background: var(--color-error-soft); }
/* Walk-E S5 - the billing entitlement-override row: "Reactivate (Active)" is a visibly longer label
   than "Grace (Pilot)" or "Force-suspend", so the three buttons auto-size unevenly by default. A
   shared min-width reads the row as one uniform button group instead of a ragged stretch. */
.override-btn { min-width: 170px; text-align: center; }

/* Lightened from the heavy surface card: a quiet bordered group so Name + Description
   no longer dominate the editor. */
.metadata-panel { background: var(--color-bg); padding: 10px 12px; border: var(--border-thin); border-radius: 4px; margin-bottom: 16px; }
.form-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.form-row:last-child { margin-bottom: 0; }
.form-row label { font-weight: 600; font-size: 13px; color: var(--neo-forest-700); text-transform: uppercase; letter-spacing: 0.5px; }
.form-input { padding: 10px 12px; border: 1px solid var(--color-border-strong); border-radius: 4px; font: inherit; background: var(--color-surface); color: var(--color-text); }
.form-input:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-soft); }
.form-hint { font-size: var(--text-xs); font-style: italic; color: var(--color-muted); }
.form-textarea { resize: vertical; min-height: 60px; }
.lineage-badge { display: inline-block; padding: 4px 8px; background: var(--neo-grey-100); border-radius: 4px; font-size: 12px; color: var(--color-muted); margin-top: 4px; }

.components-table-wrap { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.components-table-wrap h2 { margin-top: 0; }
/* The wrap is the card, so the table inside drops its own border and corners. */
.components-table-wrap .data-table { border: none; border-radius: 0; }
.empty-state {
    color: var(--color-muted);
    font-size: var(--text-sm);
    padding: var(--space-4);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-bg);
    margin: var(--space-3) 0;
    text-align: center;
}
.row-actions { display: flex; gap: 8px; justify-content: flex-end; }
.selected-row { background: var(--color-accent-soft); }
.add-component-row { margin-top: 12px; }

.component-editor { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.component-editor h3 { margin-top: 0; }
.form-row-inline { display: flex; gap: 16px; }
.form-row-inline > .form-row { flex: 1; }
.monaco-shell { border: 1px solid var(--color-border); border-radius: 4px; overflow: hidden; height: 240px; }
/* BlazorMonaco wraps the editor in a child .monaco-editor-container with no intrinsic height; without this
   it collapses to ~5px inside the shell, hiding the script and exposing Monaco's ime-text-area. */
.monaco-shell > .monaco-editor-container { height: 100%; }

.preview-pane { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.preview-pane h2 { margin-top: 0; }
/* The pane is the card, so the table inside drops its own border and corners. */
.preview-pane .data-table { border: none; border-radius: 0; }
.preview-table code { font-size: 12px; }
.error-badge { display: inline-block; padding: 2px 6px; background: var(--color-error-soft); color: var(--color-error-text); border-radius: 3px; font-size: 12px; }

/* Walk-E S2 - the tenant drill-down triage band: the eight health signals as pill-shaped links
   leading the page, each an anchor into its diagnostic <details> section. An issue chip carries the
   danger accent; a quiet chip reads muted green; an unknown chip (its read failed) reads warning, so
   a failed read never masquerades as clear. The count-pill renders a signal's count or state as a
   pill inside its section summary rather than bare parentheses. */
.triage-band { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0; }
.triage-chip { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); border: var(--border-thin); border-radius: 999px; font-size: var(--text-sm); font-weight: 600; text-decoration: none; }
.triage-chip-ok { background: var(--color-accent-soft); color: var(--color-accent-text); border-color: var(--color-accent); }
.triage-chip-issue { background: var(--color-error-soft); color: var(--color-error-text); border-color: var(--color-error); }
.triage-chip-unknown { background: var(--color-warning-soft); color: var(--color-warning-text); border-color: var(--color-warning); }
.triage-chip:hover { filter: brightness(0.97); }
.triage-chip:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.triage-chip-value { font-weight: 700; }
.count-pill { display: inline-block; min-width: 1.25em; padding: 0 var(--space-2); border-radius: 999px; background: var(--neo-grey-100); color: var(--color-text-soft); font-size: var(--text-xs); font-weight: 600; text-align: center; }
.count-pill-issue { background: var(--color-error-soft); color: var(--color-error-text); }

.action-bar { display: flex; gap: 8px; }
.dataset-picker { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; display: flex; flex-wrap: wrap; align-items: end; gap: 12px; }
.dataset-picker label { font-weight: 600; font-size: 13px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.dataset-picker > select { flex: 1; }
.dataset-picker .empty-state { margin: 0; }
/* S17: the collapsed scenario line shown while the auto-default is selected. Full-width row so
   the sentence breathes; the action buttons flow beneath it. */
.scenario-default-summary { margin: 0; flex: 1 1 100%; font-size: var(--text-sm); color: var(--color-text-soft); }
.scenario-default-summary strong { color: var(--color-text); }
.scenario-change-link { background: none; border: none; padding: 0; margin-left: var(--space-2); font: inherit; font-size: var(--text-xs); color: var(--color-accent-strong); text-decoration: underline; cursor: pointer; }
/* S5 (#40): the purpose line explaining what picking a scenario here does; forced onto its
   own row (flex-basis 100%) above the label/select/button row. */
.dataset-picker-purpose { flex-basis: 100%; margin: 0 0 4px; font-size: var(--text-sm); color: var(--color-text-soft); }

/* Goal 9 / Phase 4-ui + S5 (#40): the historical-score readout as a bordered panel matching
   the editor's other card surfaces (dataset picker, component editor), not a raw table dump. */
/* The context band: setup (metadata + dataset picker) left, the score story (historical panel +
   seed badge) right - one screen row for the informational layer, the factor editor below. */
.editor-context-band { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--space-3) var(--space-6); align-items: start; }
/* No score story to pair with: the setup column takes the whole band rather than sitting squeezed
   beside an empty gutter. */
.editor-context-band-single { grid-template-columns: minmax(0, 1fr); }
.editor-context-side { min-width: 0; }
@media (max-width: 1100px) {
    .editor-context-band { grid-template-columns: 1fr; }
}

/* Compact by design: the panel is context for the factor editor below it, never the destination.
   One line of summary, then a bar per factor (name + description / contribution bar / score).
   Width is bounded by the context band's side column. */
.live-score-panel { background: var(--color-surface); padding: var(--space-2) var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-sm); margin-bottom: var(--space-3); }
/* The summary line is the panel's whole resting state. It declares no display of its own, so the
   browser's default `summary { display: list-item }` stands and draws the disclosure marker; the
   inner row carries the flex layout instead. Overriding display here removes that marker. */
.live-score-summary { cursor: pointer; }
.live-score-summary-row { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.live-score-panel[open] .live-score-summary { margin-bottom: 6px; }
.live-score-label { font-weight: 600; font-size: 13px; color: var(--neo-forest-700); text-transform: uppercase; letter-spacing: 0.5px; }
.live-score-total { font-size: 16px; font-weight: 700; color: var(--color-accent-text); font-family: Consolas, monospace; }
.live-score-purpose { font-size: var(--text-xs); font-style: italic; color: var(--color-muted); }
.live-score-row { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(70px, 1fr) 84px; align-items: center; gap: var(--space-2); padding: 2px 0; }
.live-score-row-text { min-width: 0; line-height: 1.25; }
.live-score-row-name { display: block; font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-score-row-desc { display: block; font-size: var(--text-xs); color: var(--color-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The coverage note under a factor. It wraps where the description truncates: the note explains why
   a number is what it is, so losing its tail to an ellipsis would lose the point of it. */
.live-score-row-coverage { display: block; font-size: var(--text-xs); color: var(--color-muted); line-height: 1.3; }
.live-score-row-bar { display: block; height: 8px; background: var(--neo-grey-100); border-radius: 2px; overflow: hidden; }
.live-score-bar { display: block; height: 100%; background: var(--color-accent-fill); border-radius: 2px; }
.live-score-bar-negative { background: var(--color-error); }
.live-score-row-value { text-align: right; font-family: Consolas, monospace; font-size: var(--text-xs); }

.gantt-wrap { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.gantt-wrap h2 { margin-top: 0; }
.gantt-scroller { overflow-x: auto; max-width: 100%; }
.gantt-grid { position: relative; min-height: 60px; }
/* P3-15: the axis shares the driver rows' column template so tick positions align
   with the bar tracks (they previously sat 148px left of every bar). */
.gantt-axis-row { display: grid; grid-template-columns: 140px 1fr; gap: 8px; }
/* The axis names its own zone in the label column, in the tick grammar so it reads as part of the scale. */
.gantt-axis-zone { font-size: 11px; color: var(--color-muted); white-space: nowrap; }
.gantt-time-axis { position: relative; height: 24px; border-bottom: 1px solid var(--color-border); margin-bottom: 8px; }
.gantt-hour-tick { position: absolute; top: 0; font-size: 11px; color: var(--color-muted); border-left: 1px dashed var(--color-border); padding-left: 2px; height: 24px; white-space: nowrap; }
.gantt-driver-row { display: grid; grid-template-columns: 140px 1fr; gap: 8px; align-items: center; padding: 4px 0; border-bottom: 1px solid var(--color-border); }
.gantt-driver-label { font-size: 12px; }
.gantt-driver-label strong { display: block; font-family: monospace; }
.gantt-driver-name { color: var(--color-muted); font-size: 11px; }
.gantt-driver-track { position: relative; height: 28px; }
.load-bar { position: absolute; height: 22px; top: 3px; background: var(--color-accent); color: var(--neo-white); border: none; border-radius: 3px; font-size: 11px; padding: 0 6px; cursor: pointer; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.load-bar:hover { background: var(--color-accent-strong); }
.load-bar-late { background: var(--color-error); }
.load-bar-late:hover { background: var(--color-error); }

/* The "vs your manual board" delta chip. The text always carries the real signed value.
   A tint signals direction ONLY where the numbers are a fresh same-dataset re-evaluation
   (the dispatch-review surface); an untinted chip carries a training-time delta, which is
   frozen history and makes no standing verdict about the board today (run detail). */
.baseline-delta-chip { display: inline-block; padding: 2px 8px; border-radius: 3px; font-size: 12px; font-weight: 600; white-space: nowrap; background: var(--color-surface); color: var(--color-text-soft); }
.baseline-delta-ahead { background: var(--color-success-soft); color: var(--color-success-text); }
.baseline-delta-behind { background: var(--color-warning-soft); color: var(--color-warning-text); }
/* The chip doubles as the door into the dispatch-review surface when a winning schedule
   exists: a link affordance that keeps whatever tint the chip carries. */
a.baseline-delta-chip { text-decoration: none; }
a.baseline-delta-door { cursor: pointer; border: 1px solid var(--color-accent); }
a.baseline-delta-door:hover { box-shadow: var(--shadow-sm); text-decoration: underline; }

/* Score decomposition layout (shared by ScorePane and DecompositionDeltaTable). */
.decomposition-wrap { background: var(--color-surface); padding: 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.decomposition-wrap h2 { margin-top: 0; }
.decomposition-wrap .data-table { border: none; border-radius: 0; }
.total-score-banner { display: flex; align-items: baseline; gap: 12px; background: var(--color-accent-soft); padding: 12px 16px; border-radius: 4px; margin-bottom: 12px; }
.total-score-label { font-size: 13px; color: var(--color-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.total-score-value { font-size: 28px; font-weight: 600; color: var(--color-accent-text); font-family: monospace; }
.errors-block { background: var(--color-error-soft); color: var(--color-error-text); padding: 12px 16px; border-radius: 4px; margin-bottom: 12px; font-size: 13px; }
.errors-block ul { margin: 4px 0 0 24px; padding: 0; }

/* P2-16 (three-lens): the Loads & Drivers tab strip (TrainingDataTabBar) had ZERO CSS
   anywhere — the tabs rendered as bare inline links. Underline-style tab bar on tokens;
   the active state tracks the URL via the P0-5 query-param re-bind. */
.evaluation-tabs {
    display: flex;
    gap: var(--space-1);
    border-bottom: var(--border-thin);
    margin: var(--space-4) 0 0;
}
.evaluation-tabs .tab {
    padding: var(--space-2) var(--space-4);
    margin-bottom: -1px;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-text-soft);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.evaluation-tabs .tab:hover {
    color: var(--color-text);
    background: var(--neo-grey-100);
}
.evaluation-tabs .tab:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}
.evaluation-tabs .tab-active {
    color: var(--color-accent-text);
    border-bottom-color: var(--color-accent);
}
.evaluation-tab-content {
    padding-top: var(--space-4);
}

/* The TrainingData tabs' filter strip. */
.filter-strip { display: flex; align-items: end; gap: 16px; flex-wrap: wrap; background: var(--color-surface); padding: 12px 16px; border: 1px solid var(--color-border); border-radius: 4px; margin-bottom: 24px; }
.filter-strip .filter-row { display: flex; flex-direction: column; gap: 4px; }
.filter-strip .filter-row label { font-size: 12px; color: var(--color-muted); }

/* DecompositionDeltaTable */
.total-banner-row { display: flex; gap: 12px; margin-bottom: 16px; }
.total-banner-row .total-score-banner { flex: 1; }
.total-delta-banner { background: var(--color-warning-soft); }
.delta-positive { color: var(--color-success); font-weight: 600; }
.delta-negative { color: var(--color-error); font-weight: 600; }

/* Compare Page */
.compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 24px; }
@media (max-width: 1100px) {
    .compare-grid { grid-template-columns: 1fr; }
}
.compare-stack { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 24px; }

/* Walk-D S5: the single-overlay compare adopts the review surface. The layout toggle
   (overlay leads; side-by-side + stacked demote) and the A/B highlight sit above it. */
.compare-controls { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.compare-layout-toggle, .compare-highlight-toggle { display: flex; align-items: center; gap: 6px; }
.compare-highlight-cap { color: var(--color-muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
.compare-overlay { margin-bottom: 24px; }

/* A/B highlight: highlighting the comparand (A) un-mutes its stacked line; highlighting
   NEO (B) is the surface's default emphasis. Compound selectors outrank the scoped rule. */
.compare-overlay.compare-highlight-a .review-theirs { color: var(--color-text); font-weight: 600; }

/* The board's on-demand compare picker (Schedule/Index). */
.schedule-compare-strip { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.schedule-compare-label { color: var(--color-muted); font-size: 12px; }
.schedule-compare-error { color: var(--color-error); font-size: 12px; margin-top: 6px; }

.preview-actions { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.preview-actions-hint { color: var(--color-muted); font-size: 12px; }


/* Subsystem #9 P1 + operator-polish pass - dashboard. ---------------------
   The classes below back /dashboard (Components/Pages/Home.razor). Goal 5
   redesigned the count cards (NeoCard / NeoCardGrid) but left dash-section-h,
   dash-links, stat-label, stat-value, empty-state without real styles - the
   browser was falling back to defaults which made the operator pages feel
   bare. This block defines them token-first. */

.dash-tiles { display: flex; gap: var(--space-4); flex-wrap: wrap; margin: var(--space-4) 0; }
.dash-tile { border: var(--border-thin); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); min-width: 7rem; background: var(--color-surface); }
.dash-num { font-size: var(--text-xl); font-weight: 700; color: var(--color-text); letter-spacing: -0.01em; }
.dash-cap { font-size: var(--text-sm); color: var(--color-text-soft); margin-top: var(--space-1); }
.dash-next { margin: var(--space-2) 0 var(--space-4); }
.dash-recent { list-style: none; padding: 0; margin: var(--space-3) 0 var(--space-8); }
.dash-recent li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--color-surface); border: var(--border-thin); border-radius: var(--radius-md); margin-bottom: var(--space-2); }
.dash-recent li a { color: var(--color-accent-text); text-decoration: none; font-weight: 600; }
.dash-recent li a:hover { text-decoration: underline; }
.dash-unavailable { color: var(--color-error); }
/* Iter-4 #4 (/today) — sub-line under a tile number (e.g. "2 hour(s) ago last activity")
   and the warning emphasis applied to the "Running late" count when it is greater than zero. */
.dash-sub { font-size: var(--text-sm); color: var(--color-text-soft); margin-top: var(--space-1); }
.dash-warning { color: var(--color-warning); }

/* Section headings within the dashboard (and reused by anyone who reaches for it). */
.dash-section-h {
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--color-text);
    margin: var(--space-8) 0 var(--space-3);
    letter-spacing: -0.005em;
}

/* Quick-link tile row. The .dash-links container holds a series of <a> chips
   that should read as actionable tiles, not bare browser-blue links. */
.dash-links {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--space-3);
    margin: var(--space-3) 0 var(--space-6);
}
.dash-links a {
    display: block;
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface);
    border: var(--border-thin);
    border-left: 3px solid var(--color-accent);
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--text-sm);
    line-height: var(--leading-base);
    transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.dash-links a:hover,
.dash-links a:focus-visible {
    border-color: var(--color-accent);
    border-left-color: var(--color-accent-strong);
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
    outline: none;
}

/* Walk-D S7 (#47-51): the run-detail completion band. Every post-run CTA (view the schedule,
   compare vs your board, make NEO live) renders together beside the run's done status, instead
   of three separate callouts scattered down the page. */
.completion-band {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-4);
    background: var(--color-success-soft);
    border: var(--border-thin);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin-bottom: var(--space-4);
}
.completion-band-head { display: flex; flex-direction: column; gap: var(--space-1); }
.completion-band-tag { font-weight: 700; color: var(--color-success-text); }
.completion-band-copy { margin: 0; color: var(--color-text-soft); font-size: var(--text-sm); }
.completion-band-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }

/* The cycles table collapses behind a native disclosure - the score graph above already tells
   this story, so the summary reads as a plain section label, not a broken heading. */
.cycles-details > summary { font-size: var(--text-md); font-weight: 600; margin: var(--space-6) 0 var(--space-2); cursor: pointer; color: var(--color-text); }
/* W24: the score columns right-align on tabular figures so the digits line up column-wise the way
   the house grid reads numbers. */
.cycles-details .cycles-num { text-align: right; font-variant-numeric: tabular-nums; }
/* W21: the "Started ..." stamp beside the warming copy reads as quiet meta, not part of the sentence. */
.training-warming-stamp { display: inline-block; margin-left: var(--space-1); color: var(--color-text-soft); }
/* W24: the support run-config drill-down (AdminPortal training-runs browser). The pretty-printed
   NEAT JSON wraps and scrolls inside a bounded block rather than stretching the row to one long line. */
.run-config-pre { max-height: 20rem; overflow: auto; white-space: pre-wrap; word-break: break-word; margin: var(--space-2) 0 0; padding: var(--space-2); background: var(--color-bg); border: var(--border-thin); border-radius: var(--radius-sm); font-size: var(--text-xs); }
/* W27(c): the standing "not pulling from a TMS yet" line - quiet muted meta, not a warning callout. */
.tms-roadmap-notice { margin: var(--space-3) 0; font-size: var(--text-sm); color: var(--color-muted); }
.tms-roadmap-notice a { margin-left: var(--space-1); color: var(--color-accent-text); white-space: nowrap; }

/* Generic stat label / value pair used on TrainingRuns/Detail + likely
   anywhere else operator code wants a "small caption + big number" pattern. */
.stat-label {
    display: block;
    font-size: var(--text-xs);
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: var(--space-1);
}
.stat-value {
    display: block;
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-text);
    line-height: var(--leading-lg);
    letter-spacing: -0.01em;
}

/* Iter-3 #15 — Runtime fleet-posture rollup tile. Lays four "stat-label /
   stat-value" pairs across one row at desktop widths; collapses to a 2x2
   grid below the typical-tablet breakpoint. */
.runtime-rollup-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4);
}
.runtime-rollup-cell {
    padding: var(--space-2) 0;
}
@media (max-width: 720px) {
    .runtime-rollup-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Batch 2 — decision-origin badge on the /runtime Recent-decisions tile. A small
   muted pill (the .lineage-badge shape on tokens) so machine recomputes read
   differently from manual decisions at a glance. */
.decision-source-badge {
    display: inline-block;
    padding: 2px var(--space-2);
    background: var(--color-surface);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    color: var(--color-muted);
    white-space: nowrap;
}

/* Iter-3 #14 — Plain-English decision summary above each audit JSON column.
   Matches the info-callout aesthetic (accent-soft bg + accent-strong border)
   so the eye reads it as a hint not body copy. */
.audit-decision-summary {
    margin: var(--space-2) 0 var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--color-accent-soft);
    border-left: 3px solid var(--color-accent-strong);
    font-size: var(--text-sm);
    color: var(--color-text);
    line-height: var(--leading-md);
}

/* Subsystem #9 P2 - Dispatch grid. */
.dispatch-table { width:100%; }
.dispatch-group-row { background:var(--color-accent-soft); cursor:pointer; }
.dispatch-load-row { cursor:pointer; }
.dispatch-stop-row { font-size:.82rem; color:var(--color-text-soft); background:var(--color-bg); }
.dispatch-row-ok { background:var(--color-success-soft); }
.dispatch-row-idle { background:var(--color-warning-soft); }
.dispatch-row-unassigned { background:var(--color-error-soft); }
.dispatch-row-late { background:var(--color-warning-soft); }
.dispatch-row-failure { background:var(--color-error-soft); }
/* token-gap: selection outline needs a strong affordance blue - var(--color-accent) is too
   light against the row tints and no AA-safe accent affordance token exists yet. */
.dispatch-selected { outline:2px solid #36c; }
.dispatch-badge { font-size:.66rem; padding:1px 5px; border-radius:3px; margin-left:6px; }
.dispatch-badge-idle { background:var(--color-success-soft); }
.dispatch-badge-unassigned { background:var(--color-error); }
.dispatch-badge-failure { background:var(--color-error); color:var(--neo-white); }
.dispatch-badge-late { background:var(--color-warning); color:var(--neo-white); }
/* replan §4 — a committed/dispatched load (IsCommitted). */
.dispatch-badge-committed { background:var(--color-success); color:var(--neo-white); }
.dispatch-rollup { font-size:.72rem; color:var(--color-text-soft); margin-left:8px; }
/* Section 4 — requested-window annotation below the projected time. */
.dispatch-requested { font-size:.68rem; color:var(--color-text-soft); }

/* S3 - per-load + per-driver fitness score chips and the lightweight breakdown they open (a pure
   attribution lookup, never a compare). */
.dispatch-score-chip { margin-left:6px; font-size:.66rem; font-weight:600; padding:0 6px; border-radius:3px; border:var(--border-thin); background:var(--color-accent-soft); color:var(--color-accent-text); cursor:pointer; }
.dispatch-score-row td { background:var(--color-bg); }
.dispatch-score-breakdown { padding:4px 2px; }
.dispatch-score-breakdown-head { display:flex; gap:8px; align-items:baseline; margin-bottom:3px; }
.dispatch-score-breakdown-label { color:var(--color-text-soft); text-transform:uppercase; letter-spacing:.4px; font-size:.62rem; }
.dispatch-score-breakdown-total { color:var(--color-accent-text); font-family:monospace; font-weight:600; font-size:.78rem; }
.dispatch-score-table { width:auto; border-collapse:collapse; font-size:.72rem; }
.dispatch-score-table td { padding:1px 10px 1px 0; }
.dispatch-score-num { text-align:right; font-family:monospace; }
.dispatch-score-empty { font-size:.7rem; color:var(--color-muted); }
/* S3 - the air-mile estimate marker on the Mi column: the settled road figure has not been computed. */
.dispatch-est { margin-left:4px; font-size:.6rem; font-weight:600; color:var(--color-muted); }

/* S4 (#61 rework) - the row-anchored "queue for push" tag + the changed-since-last-push pin. The tag lives
   in the Load # cell so a dispatch is queued from its own visible row (never a detached list). */
.dispatch-push-toggle { margin-left:6px; font-size:.64rem; font-weight:600; padding:0 6px; border-radius:3px; border:var(--border-thin); background:var(--color-bg); color:var(--color-text-soft); cursor:pointer; }
.dispatch-push-toggle.dispatch-push-queued { background:var(--color-accent-fill); color:var(--neo-white); border-color:var(--color-accent-fill); }
.dispatch-push-changed { margin-left:4px; font-size:.6rem; font-weight:600; color:var(--color-warning-text); }
/* S4 - the bottom push tray's queued-set summary (the count equals the tagged-rows count). */
.write-back-tray-count { font-weight:600; margin:4px 0; }

/* SP2 §5 / S4 - the per-row Correction|Update label (now on the assignment it amends, in the actions cell). */
.dispatch-edit-label { display:inline-flex; gap:8px; align-items:center; margin-right:8px; font-size:.68rem; }
.dispatch-edit-label-opt { display:inline-flex; gap:3px; align-items:center; }
.dispatch-drop-target { outline-offset:-2px; }
.dispatch-actions { white-space:nowrap; }
.dispatch-actions .btn { font-size:.68rem; padding:1px 6px; margin-left:3px; }
.dispatch-act-panel { margin-top:4px; padding:6px; border:var(--border-thin); border-radius:5px; background:var(--color-bg); }
.dispatch-act-field { display:flex; gap:6px; align-items:center; margin:3px 0; }
.dispatch-act-field label { font-size:.7rem; color:var(--color-text-soft); min-width:7rem; }
.dispatch-act-field .form-control { max-width:12rem; }
.dispatch-reorder-note { font-size:.68rem; color:var(--color-text-soft); margin:2px 0 6px; }

/* The board's Status filter. It is a select rather than a NeoGridFilter input, so it carries its own
   copy of that primitive's label-over-control layout and grid-chrome scale. */
.dispatch-filter-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.dispatch-filter-label {
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-muted);
}
.dispatch-filter-status {
    width: 9rem;
    min-width: 0;
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-sm);
}

/* The active-filter pill above the board: what is narrowing the rows, and the way out of it. */
.dispatch-filter-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    padding: var(--space-1) var(--space-3);
    border: var(--border-thin);
    border-radius: var(--radius-lg);
    background: var(--color-accent-soft);
    color: var(--color-accent-text);
    font-size: var(--text-sm);
    font-weight: 600;
}
.dispatch-filter-clear {
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Subsystem #9 P2 - Schedule panes. The score band's own rules, including its exception treatment,
   live in ScoreBand.razor.css: the band's base button rule is CSS-isolated, so a competing rule here
   would lose to it on specificity no matter the source order. */
.score-scope { font-size:.78rem; color:var(--color-text-soft); margin-bottom:4px; }
/* SP3 score breakdown - the schedule -> driver -> load drill. */
.score-section-label { font-size:.72rem; text-transform:uppercase; letter-spacing:0.5px; color:var(--color-muted); margin:var(--space-3) 0 var(--space-1); }
.score-drill { margin-top:var(--space-2); }
.score-schedule-level, .score-driver, .score-load { border:var(--border-thin); border-radius:4px; margin-bottom:var(--space-2); padding:var(--space-2) var(--space-3); }
.score-load { margin-left:var(--space-3); background:var(--color-bg); }
.score-driver.selected, .score-load.selected { border-color:var(--color-accent); background:var(--color-accent-soft); }
.score-schedule-level > summary, .score-driver > summary, .score-load > summary { display:flex; justify-content:space-between; align-items:baseline; gap:12px; cursor:pointer; font-weight:600; }
.score-drill-value { font-family:monospace; }
.score-loads { margin-top:var(--space-2); }
.score-component-name { display:inline-block; }
.score-component-key { margin-left:6px; font-size:.72rem; color:var(--color-muted); }
/* The fill-rate divergence warning's data-point lines, inside the callout. */
.fill-drift-list { margin:var(--space-2) 0 0; padding-left:20px; }
.fill-drift-list li { margin-bottom:2px; }
/* "NEO could not check". Muted and unadorned: it reports the absence of a check, which is not a
   finding about the plan, so it must not wear the warning callout's weight. */
.fill-drift-unchecked { margin:0 0 var(--space-3); font-size:var(--text-xs); color:var(--color-muted); font-style:italic; }
/* The per-component coverage note: its own line under the component name, so a statement about the
   population sits apart from the component's identity rather than reading as part of its name. */
.score-component-coverage { display:block; margin-top:2px; font-size:.72rem; color:var(--color-muted); }
.neo-stop-badge span { display:flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:50%; color:var(--neo-white); font-size:.7rem; border:2px solid var(--neo-white); }
.schedule-map-el { height:420px; border:var(--border-thin); }
.map-prompt { padding:18px; color:var(--color-muted); }
/* §8 HERE routing — schedule map legend. */
.neo-map-legend { background:rgba(255,255,255,0.92); border:var(--border-strong); border-radius:4px; padding:8px 10px; font-size:.78rem; line-height:1.6; }
.neo-map-legend strong { display:block; margin-bottom:4px; font-size:.8rem; }
.neo-map-legend-row { display:flex; align-items:center; gap:6px; }
.neo-map-legend-source { margin-top:4px; font-size:.72rem; color:var(--color-text-soft); }
.neo-map-legend-dot { display:inline-block; width:8px; height:8px; border-radius:50%; }

/* Subsystem #9 P2 - Schedule shell. */
.schedule-band { border:var(--border-thin); border-radius:6px; padding:8px; margin:8px 0; }
.schedule-mid { display:flex; gap:8px; }
.schedule-mid .schedule-dispatch { flex:2; }
.schedule-mid .schedule-score { flex:1; }
/* Narrow viewports (2026-06-11): the mid row's min-content width (dispatch table +
   score banner) pushed the score band past the viewport edge. Panes may shrink below
   content width and scroll inside their own band; under 900px the row stacks. */
.schedule-mid .schedule-band { min-width:0; overflow-x:auto; }
/* Effort 8 (F34): each block is footprint-constrained so the dispatch grid can't grow
   unbounded and shove the Score pane + Map - the whole result stays on one screen, each
   pane scrolling internally. The dispatch grid scrolls inside NeoDataTable's own
   .neo-data-table-scroll wrapper (already footprint-bound); the Score pane has no inner
   scroll, so cap + scroll it here so a long by-driver drill can't push the layout. */
.schedule-mid .schedule-score [id^="pane-score"] { max-height:60vh; overflow:auto; }
@media (max-width: 900px) {
    .schedule-mid { flex-direction:column; }
    .schedule-mid .schedule-dispatch, .schedule-mid .schedule-score { flex:none; }
}

/* Effort 8 (F34): the make-it-live result banner - the surfaced Promote/make-live action at the top of
   the result, no longer a buried button. */
.result-promote-banner { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-3); border:var(--border-thin); border-left:4px solid var(--color-accent); border-radius:6px; background:var(--color-accent-soft); padding:var(--space-3) var(--space-4); margin:var(--space-3) 0; }
.result-promote-copy { min-width:14rem; flex:1; }
.result-promote-heading { font-size:var(--text-md); font-weight:600; color:var(--color-text); }
.result-promote-subtitle { font-size:var(--text-sm); color:var(--color-text-soft); margin-top:2px; }
.result-promote-actions { display:flex; flex-direction:column; align-items:flex-end; gap:4px; }
.result-promote-activation-link { font-size:var(--text-sm); color:var(--color-accent-text); text-decoration:none; }
.result-promote-activation-link:hover { text-decoration:underline; }
.result-promote-result { width:100%; margin:0; }

/* Effort 8 (F34): the Map pane is expandable + lockable - a taller, fuller footprint when expanded. */
.map-pane-controls { display:flex; justify-content:flex-end; margin-bottom:4px; }
.schedule-map-el.map-expanded, .schedule-flowmap-el.map-expanded { height:78vh; }

/* Subsystem #9 P2-4 - flow map. */
.schedule-flowmap-el { height:420px; border:var(--border-thin); }

.empty-state-note { color: var(--color-text-soft); font-size: var(--text-sm); }

/* Shared filter strip used above operator data tables (Schedules, Brains, etc.). */
.filter-bar {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    flex-wrap: wrap;
    margin: var(--space-3) 0 var(--space-4);
    padding: var(--space-3);
    background: var(--color-surface);
    border: var(--border-thin);
    border-radius: var(--radius-md);
}
.filter-bar .form-input,
.filter-bar select {
    max-width: 14rem;
}
.page-header.sub-header { margin-top:24px; padding:0; border-bottom:none; }
.page-header.sub-header h2 { font-size:18px; margin:0; }

/* Plan 9-P3-1 task 4 - template strip on /algorithms/new. S5 (#40): a neutral invite card, not
   a warning band - yellow stays reserved for actual warnings. The six cards (five starter
   models + Start blank) sit on a CSS grid so every card in a row renders one uniform width. */

/* Plan 9-P3-1 task 5 - two-pane component editor with always-visible reference pane. */
.component-editor-two-pane { display:grid; grid-template-columns:1fr 280px; gap:16px; align-items:flex-start; }
.component-editor-left { min-width:0; }
.component-editor-right { position:sticky; top:16px; max-height:calc(100vh - 80px); overflow-y:auto; }
.ref-pane { background:var(--color-bg); border:var(--border-thin); border-radius:6px; padding:10px 12px; font-size:12px; }
/* P2-20 (2026-06-10): migrated to var(--color-accent-text), the minted AA-safe accent
   for text (4.69:1 on accent-soft). */
.ref-pane .ref-concept { background:var(--color-accent-soft); color:var(--color-accent-text); padding:6px 8px; border-radius:4px; font-size:11.5px; margin-bottom:10px; }
.ref-pane .ref-label { font-size:10px; text-transform:uppercase; letter-spacing:0.4px; color:var(--color-muted); margin:8px 0 4px 0; }
.ref-pane .ref-cat { font-size:10px; font-weight:600; color:var(--color-text-soft); margin-top:6px; }
.ref-pane .ref-field-btn { display:flex; justify-content:space-between; gap:6px; background:transparent; border:none; padding:2px 0; cursor:pointer; width:100%; text-align:left; }
.ref-pane .ref-field-btn:hover { background:var(--neo-grey-100); }
.ref-pane .ref-field-btn code { background:var(--neo-grey-100); padding:1px 5px; border-radius:2px; font-size:11px; }
.ref-pane .ref-type { font-size:10px; color:var(--color-muted); }
.ref-pane .ref-field-desc { font-size:10px; color:var(--color-muted); padding:0 0 4px 8px; }
.ref-pane .ref-snippet-btn { display:block; background:var(--color-surface); border:var(--border-thin); border-radius:3px; padding:4px 7px; margin-top:4px; font-size:11px; cursor:pointer; width:100%; text-align:left; }
.ref-pane .ref-snippet-btn:hover { background:var(--color-accent); color:var(--neo-white); border-color:var(--color-accent); }
.ref-pane .ref-search { font-size:11px; padding:4px 7px; margin-bottom:8px; }
.ref-pane .ref-field-dynamic code { background:var(--color-success-soft); }
.ref-pane .ref-empty { font-size:10.5px; color:var(--color-muted); font-style:italic; padding:2px 0; }

/* Feature-designs workbench (#13): the grid (left) and the design editor (right) sit side by side
   as a persistent master-detail pair. The list column stays pinned near the top of the viewport as
   the page scrolls, so a tall open editor never carries the grid off screen. Below the breakpoint the
   two columns stack (detail under list) and the list returns to normal document flow. */
.feature-designs-workbench { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--space-6); align-items: start; }
.fdw-list { position: sticky; top: var(--space-4); align-self: start; }
@media (max-width: 900px) {
    .feature-designs-workbench { grid-template-columns: 1fr; }
    .fdw-list { position: static; }
}

/* Walk-E S4 - AdminPortal CSS grounding (#2): OperatorLayout and the /admin hub referenced
   classes that were never authored (the assets loaded fine; the rules were simply never
   written), so the operator plane fell back to bare browser defaults in these spots. */

/* /admin hub (Admin/Index.razor): the five NeoCard console links tile and reflow instead of
   stacking as one column. */
.operator-hub-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-4);
    margin: var(--space-3) 0 var(--space-8);
}

/* Walk-E S8 (#88 bonus) - Overview.razor intake count badges: two clickable badges (demo/support
   request counts) linking to their queues. .intake-badge-count-unknown mutes the figure to a "-"
   when the access-log-free count read failed. */
.intake-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: var(--space-4) 0;
}
.intake-badge {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    text-decoration: none;
    color: var(--color-text);
}
.intake-badge:hover {
    border-color: var(--color-accent);
}
.intake-badge-count {
    font-size: var(--text-lg);
    font-weight: 700;
}
.intake-badge-count-unknown {
    color: var(--color-muted);
}
.intake-badge-label {
    font-size: var(--text-sm);
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Overview.razor top-line totals strip: a wrapping row of dl/dt/dd stat items, each a muted
   uppercase label over a bold figure. */
.adoption-totals {
    margin: var(--space-4) 0 var(--space-6);
}
.adoption-totals-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-6);
    margin: 0;
}
.adoption-totals-item {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.adoption-totals-item dt {
    font-size: var(--text-sm);
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.adoption-totals-item dd {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-text);
}

/* The same audit turned up these AdminPortal-specific classes unstyled too; filled in here
   the same way the audit-label/audit-value gap above was closed. */

/* Shared text helper: a muted, small-type line under a heading, used across both the customer
   Web pages and the AdminPortal surfaces (e.g. .provenance .subtitle below). */
.subtitle { font-size: var(--text-sm); color: var(--color-text-soft); }

/* Overview.razor stuck-provisioning callout: tenant name + stuck-duration pairs, no bullets. */
.stuck-provisioning-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Billing.razor entitlement legend: the four EntitlementState values as term/description pairs
   inside a NeoCallout, so a state name reads bold above its plain-English meaning. */
.entitlement-legend {
    margin: 0 0 var(--space-2);
}
.entitlement-legend dt {
    font-weight: 700;
    margin-top: var(--space-2);
}
.entitlement-legend dt:first-child {
    margin-top: 0;
}
.entitlement-legend dd {
    margin: 0 0 0 var(--space-1);
    color: var(--color-text-soft);
}

/* FeatureDesigns.razor editor: the originating-tenant / submitter / stage metadata for a
   customer pipeline request, set off as a quiet bordered group (mirrors .metadata-panel). */
.provenance {
    padding: var(--space-3) var(--space-4);
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    margin: var(--space-3) 0;
}
.provenance .subtitle {
    margin: 0 0 var(--space-1);
}
.provenance .subtitle:last-child {
    margin-bottom: 0;
}

/* FeatureDesigns.razor: the raw customer request text and the agent-authored design/plan,
   each a bounded wrapped readout so a long submission scrolls internally instead of
   stretching the page. */
.request-text, .design-text {
    background: var(--color-bg);
    border: var(--border-thin);
    border-radius: var(--radius-sm);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--color-text);
    max-height: 480px;
    overflow: auto;
    margin: var(--space-2) 0;
}

/* FeatureDesigns.razor / FeatureToggles.razor: a form label not nested in .form-row, so it
   needs its own copy of the .form-row label treatment. */
.form-label {
    display: block;
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin: var(--space-3) 0 var(--space-1);
}

/* Plan 9-P3-2 task 4 - visual composer. */
.visual-composer { display:grid; grid-template-columns:170px 1fr 280px; gap:12px; align-items:flex-start; }
.vc-palette { background:var(--color-bg); border:var(--border-thin); border-radius:6px; padding:8px; }
.vc-canvas { background:var(--color-surface); border:var(--border-thin); border-radius:6px; padding:8px; min-height:280px; }
.vc-preview { background:var(--color-bg); border:var(--border-thin); border-radius:6px; padding:8px; }

.ingredient-palette h5, .canvas-area h5, .mini-preview h5 { margin:0 0 6px 0; font-size:10px; text-transform:uppercase; letter-spacing:0.4px; color:var(--color-muted); }

/* The click-to-add signpost above the cards, at the palette's own small scale. */
.palette-signpost { margin:0 0 8px 0; font-size:10px; line-height:1.4; color:var(--color-muted); }
.palette-group { margin-bottom:8px; }
.palette-group-head { font-size:9px; text-transform:uppercase; color:var(--color-muted); margin-bottom:3px; }
.ingredient-card { display:block; width:100%; background:var(--color-surface); border:var(--border-thin); border-radius:4px; padding:5px 7px; margin-bottom:4px; cursor:pointer; text-align:left; }
.ingredient-card:hover { border-color:var(--color-success); }
/* token-gap: wildcard purple - deliberately outside every status/accent ramp so the
   wildcard ingredient reads as "different in kind"; no purple token family exists. */
.ingredient-card.ingredient-wildcard { background:#faf5ff; border-color:#d8b4fe; }
.ingredient-name { font-weight:600; font-size:11px; }
.ingredient-desc { font-size:9.5px; color:var(--color-muted); }

.canvas-empty { text-align:center; padding:60px 10px; color:var(--color-muted); font-size:11px; border:2px dashed var(--color-border); border-radius:6px; }
.canvas-row { display:flex; align-items:center; gap:6px; background:var(--color-bg); border:var(--border-thin); border-radius:4px; padding:6px 8px; margin-bottom:6px; }
/* S5 (#40): a custom (non-ingredient) script gets a neutral highlight, not the warning-yellow
   band - yellow stays reserved for actual warnings like the lossy-conversion banner below. */
.canvas-row.canvas-row-custom { background:var(--neo-grey-100); border-color:var(--color-border-strong); }
.canvas-row .cn { font-weight:600; font-size:11px; flex:0 0 130px; }
/* S5 (#40): the fill/thumb/active track ride the green accent, not the browser default. */
.canvas-row input[type=range] { flex:1; accent-color:var(--color-accent); }
/* P2-20 (2026-06-10): accent-colored text rides the minted AA-safe token. S5 (#40): a fixed
   flex-basis (not a min-width) holds this column's width constant regardless of the number's
   length, so the slider beside it always claims the same remaining space. */
.canvas-row .cval { font-size:10.5px; color:var(--color-accent-text); font-weight:600; flex:0 0 34px; text-align:right; }
.canvas-row .crem { color:var(--color-error); font-size:11px; cursor:pointer; background:transparent; border:none; }
/* S5 (#40): fixed flex-basis so the seed marker beside the value - or its absence - never
   changes how much width the slider track claims; see CanvasArea.razor's always-rendered
   wrapper span. */
.canvas-row .cmark { flex:0 0 108px; text-align:right; }
/* token-gap: gold custom badge - the "custom ingredient" gold sits outside the
   warning ramp on purpose; no gold/brand token exists. */
.canvas-row .custom-badge { background:#e6c200; color:var(--neo-white); font-size:10px; padding:1px 6px; border-radius:6px; flex:1; }

/* The composite live preview: total up top, factor bars (the shared ScoreBars grammar), and a
   one-line fleet roll-up - never per-driver/per-load rows, which don't survive a 300-load week. */
.mini-preview .ms-head { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.mini-preview .ms-source { font-size:9.5px; color:var(--color-muted); margin-bottom:6px; font-style:italic; }
.mini-preview .ms-total { font-size:13px; font-weight:600; font-family:Consolas,monospace; }
.mini-preview .ms-scale { font-size:10px; color:var(--color-muted); margin-top:6px; }
.mini-preview .ms-custom-note { font-size:9.5px; color:var(--color-muted); margin-top:6px; font-style:italic; }
.mini-preview .live-score-row-value { font-size:10.5px; }
.mini-preview .live-score-row-name { font-size:11px; }
.mini-preview .live-score-row-desc { display:none; }
/* The mini preview drops the per-row prose to stay compact, and the coverage note is prose of the
   same kind: keeping it while the description is hidden would leave the densest surface carrying
   the longest line. The full note stays on the historical panel and the score pane. */
.mini-preview .live-score-row-coverage { display:none; }

/* Plan 9-P3-2 task 5 - editor mode toggle. */
.editor-mode-toggle { margin:8px 0; }
.mode-tabs { display:inline-flex; background:var(--color-surface); border:var(--border-thin); border-radius:5px; overflow:hidden; }
.mode-tab { padding:6px 14px; font-size:12px; cursor:pointer; background:transparent; border:none; }
.mode-tab.active { background:var(--color-accent); color:var(--neo-white); }
.lossy-banner { background:var(--color-warning-soft); border:1px solid var(--color-warning); border-radius:4px; padding:6px 10px; margin-top:6px; font-size:11px; color:var(--color-warning-text); }

/* Plan 9-P3-3 task 2 - sample-datasets two-path cards. */
.scenario-paths { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:16px 0; }
.scenario-path { display:block; background:var(--color-surface); border:var(--border-thin); border-radius:6px; padding:14px 16px; text-decoration:none; color:inherit; }
.scenario-path:hover { border-color:var(--color-accent); }
/* P2-20 (2026-06-10): accent-colored text rides the minted AA-safe token. */
.scenario-path-name { font-weight:600; font-size:14px; color:var(--color-accent-text); margin-bottom:6px; }
.scenario-path-desc { font-size:12px; color:var(--color-text-soft); line-height:1.5; }

/* Plan 9-P3-3 task 3 - shared page-hint banner. */
.page-hint-banner {
    background: var(--color-accent-soft);
    border-left: 3px solid var(--color-accent);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    margin: var(--space-2) 0 var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-accent-strong);
}
.page-hint-banner strong { font-weight: 600; margin-right: var(--space-1); }

/* Inside a page header's band the strips are laid out by the band's own gap, so each one drops the
   standalone margin it carries when it renders as a full-width band of its own. */
.neo-page-header-band .page-hint-banner,
.neo-page-header-band .data-points-default-set,
.neo-page-header-band .data-points-default-set-demoted {
    margin: 0;
}

/* Goal 6 - actionable CTA on PageHint banners. */
.page-hint-cta {
    display: inline-block;
    margin-left: var(--space-2);
    padding: 3px var(--space-2);
    background: var(--color-accent-fill); /* decision 7: AA-safe under white text */
    color: var(--neo-white);
    text-decoration: none;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.page-hint-cta:hover { background: var(--color-accent-fill-hover); }
.next-step-arrow { margin-left:6px; font-family:Consolas,monospace; }

/* NavMenu next-step indicator dot. Mint reads as the next-step highlight on the spruce bar,
   matching the active-item accent. */
.nav-links .js-next-step::after {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-accent-on-dark);
    margin-left: 8px;
    vertical-align: middle;
}

/* Owner page sections (iteration-2 U6). ------------------------------- */
.form-section {
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.form-section h2 {
    font-size: 18px;
    margin: 0 0 6px;
}

.owner-list {
    list-style: none;
    padding-left: 0;
    margin: 12px 0 0;
}

.owner-list li {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    margin-bottom: 6px;
    background: var(--color-surface);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

/* token-gap: gold raw-key callout - "copy this now, it will not be shown again" needs
   to read more urgent than the warning ramp; no gold token family exists. */
.raw-key-callout {
    margin: 12px 0;
    padding: 12px 16px;
    background: #fffbea;
    border: 1px solid #f0c000;
    border-radius: 4px;
}

.raw-key-callout p {
    margin: 0 0 6px;
}

.raw-key-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.raw-key-row .raw-key-value {
    flex: 1;
    margin: 0;
}

.btn-copy-key {
    flex: 0 0 auto;
}

/* V12: the one truncate+copy treatment for a bare GUID on an operator surface. */
.neo-short-id {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
}

.neo-short-id-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    color: var(--color-muted);
}

.neo-short-id-copy {
    flex: 0 0 auto;
    padding: 1px 6px;
    font-size: 11px;
    background: var(--color-surface);
    color: var(--color-text-soft);
    border: 1px solid var(--color-border);
    border-radius: 3px;
    cursor: pointer;
}

.raw-key-value {
    display: block;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    word-break: break-all;
    padding: 6px 8px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 3px;
}

.btn-revoke {
    margin-left: auto;
}

/* Auth pages (Login / Setup / Logout) - Goal 5 P3 T26. ------------------ */

.auth-form-header {
    margin-bottom: var(--space-6);
}

.auth-form-h {
    margin: 0 0 var(--space-2);
    font-size: var(--text-lg);
    line-height: var(--leading-lg);
    font-weight: 700;
    color: var(--color-chrome);
    letter-spacing: -0.01em;
}

.auth-form-sub {
    margin: 0;
    font-size: var(--text-sm);
    line-height: var(--leading-sm);
    color: var(--neo-grey-500);
}

.auth-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.auth-field {
    display: flex;
    flex-direction: column;
}

.auth-label {
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: var(--space-1);
    text-transform: none;
    letter-spacing: 0;
}

.auth-input {
    height: 36px;
    padding: 0 var(--space-3);
    font-size: var(--text-sm);
    line-height: var(--leading-sm);
    border: 1px solid var(--neo-grey-200);
    border-radius: var(--radius-md);
    background: var(--neo-white);
    color: var(--color-text);
    font-family: inherit;
}

/* P1-8 (three-lens): why-we-ask trust copy under the SCAC/DOT fields on /signup. */
.auth-field-hint {
    margin: var(--space-1) 0 0;
    font-size: var(--text-xs);
    line-height: var(--leading-sm);
    color: var(--neo-grey-500);
}

/* #85 - show/hide password toggle. The wrap holds the input and an overlaid reveal button;
   the input reserves right padding so its text never runs under the button. */
.auth-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

.auth-input-wrap .auth-input {
    flex: 1 1 auto;
    padding-right: 3.75rem;
}

.auth-reveal {
    position: absolute;
    right: var(--space-2);
    background: transparent;
    border: none;
    padding: 0 var(--space-1);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--color-accent-text);
    cursor: pointer;
    font-family: inherit;
}

.auth-reveal:hover {
    text-decoration: underline;
}

.auth-reveal:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* P1-12 (three-lens): operator-shell 404 body. */
.nf-operator {
    max-width: 560px;
    margin: var(--space-16) auto;
    text-align: center;
    color: var(--color-text);
}

.auth-input:focus {
    outline: 2px solid var(--color-accent);
    outline-offset: 0;
    border-color: var(--color-accent);
}

.auth-submit {
    margin-top: var(--space-2);
    height: 44px;
    padding: 0 var(--space-6);
    background: var(--color-accent-fill); /* decision 7: AA-safe under white text */
    color: var(--neo-white);
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: background 120ms ease;
}

.auth-submit:hover {
    background: var(--color-accent-fill-hover);
}

.auth-submit:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.auth-form-footer {
    margin-top: var(--space-5);
    font-size: var(--text-sm);
    color: var(--neo-grey-500);
    text-align: center;
}

.auth-form-footer a {
    color: var(--color-accent-text);
}

/* P0-1 — /setting-up provisioning progress (indeterminate). */
.setup-progress {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.setup-progress-track {
    height: 6px;
    border-radius: var(--radius-md);
    background: var(--neo-grey-200);
    overflow: hidden;
}

.setup-progress-fill {
    width: 40%;
    height: 100%;
    border-radius: var(--radius-md);
    background: var(--color-accent);
    animation: setup-progress-slide 1.4s ease-in-out infinite;
}

@keyframes setup-progress-slide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}

.setup-progress-note {
    margin: 0;
    font-size: var(--text-sm);
    line-height: var(--leading-sm);
    color: var(--neo-grey-500);
}

/* Plan 11-4 - Live Operations page. */
.ops-grid { display:flex; flex-direction:column; gap:16px; margin-top:12px; }
.ops-form-row { display:flex; flex-direction:column; gap:4px; margin-bottom:10px; max-width:520px; }
.ops-form-row label { font-size:12px; font-weight:600; }

/* P2-21 - inline field error under the Webhook URL input. */
.ops-field-error {
    color: var(--color-error-text);
    font-size: 11.5px;
    margin-top: 4px;
}

/* P2-24 - the Integration-settings disclosure on /live/operations. */
.ops-integrations {
    border: var(--border-thin);
    border-radius: 6px;
    background: var(--color-surface);
}

.ops-integrations-summary {
    cursor: pointer;
    padding: 12px 16px;
    font-weight: 600;
    font-size: 13px;
}

.ops-integrations[open] > .ops-integrations-summary {
    border-bottom: var(--border-thin);
}

.ops-integrations-failures {
    margin-left: 8px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--color-error-soft);
    color: var(--color-error-text);
    font-size: 11px;
    font-weight: 600;
}

.ops-integrations-body {
    display: grid;
    gap: 16px;
    padding: 12px 16px 16px;
}

/* P3-10 - upload tab 4-step strip. */
.upload-steps { display:flex; gap:8px; list-style:none; margin:0 0 16px 0; padding:0; }
.us-step { display:flex; align-items:center; gap:6px; padding:6px 12px; border:var(--border-thin); border-radius:var(--radius-sm); background:var(--color-bg); color:var(--color-muted); font-size:var(--text-sm); }
.us-step.us-current { background:var(--color-accent-soft); border-color:var(--color-accent); color:var(--color-text); font-weight:600; }
.us-step.us-done { background:var(--color-success-soft); border-color:var(--color-success); color:var(--color-text); }
.us-num { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:50%; background:var(--color-surface); border:var(--border-thin); font-size:11px; font-weight:600; }

/* P3-10 - field reference + template download. */
.field-ref-table code { font-size:12px; }
.template-download-row { display:flex; align-items:center; gap:12px; margin:12px 0 16px 0; }

/* #42 - the field reference groups into Required/Optional native disclosures, mirroring the
   .ops-integrations collapsible-summary treatment used elsewhere. Required opens by default; the
   Optional summary is the collapse target that keeps the rest of the reference out of the way. */
.field-ref-groups { display:flex; flex-direction:column; gap:var(--space-3); }
.field-ref-group { border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); }
.field-ref-group-summary { cursor:pointer; padding:var(--space-2) var(--space-3); font-weight:600; font-size:var(--text-sm); }
.field-ref-group[open] > .field-ref-group-summary { border-bottom:var(--border-thin); }
.field-ref-group .field-ref-table { margin:0; width:100%; }
.field-ref-group .data-table { border: none; border-radius: 0; }

/* /today "no live data yet" callout: the import CTA beside a quiet hand-entry link. */
.today-empty-actions { display:flex; gap:12px; flex-wrap:wrap; align-items:center; margin-top:12px; }
.today-empty-handentry { font-size:var(--text-sm); color:var(--color-text-soft); }
.today-empty-handentry:hover { color:var(--color-text); }

/* P3-8 - inline add-load / add-driver forms on the Loads & Drivers tabs. */
.add-entity-form { margin:12px 0 16px 0; padding:14px 16px; border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); max-width:900px; }
.add-entity-form h3 { margin-top:0; }

/* P3-9 - scenario create form on /sample-datasets. */
.scenario-create-form { margin:16px 0; padding:14px 16px; border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); max-width:720px; }
.scenario-create-heading { margin:0 0 4px 0; font-size:var(--text-lg); }

/* P3-11 - "Finish setting up (N of M)" nav chip (right cluster, dismissible). */
.setup-chip { display:inline-flex; align-items:center; gap:4px; padding:2px 4px 2px 10px; border:1px solid var(--color-accent); border-radius:999px; background:var(--color-accent-soft); }
.setup-chip .setup-chip-link { font-size:var(--text-sm); font-weight:600; color:var(--color-accent-text); }
.setup-chip .setup-chip-dismiss { border:none; background:transparent; cursor:pointer; color:var(--color-text-soft); font-size:var(--text-base); line-height:1; padding:2px 6px; border-radius:50%; }
.setup-chip .setup-chip-dismiss:hover { color:var(--color-text); background:var(--color-bg); }

/* P3-11 - onboarding wizard stepper (/onboarding). */
.onb-steps { list-style:none; margin:16px 0 0 0; padding:0; display:flex; flex-direction:column; gap:12px; max-width:860px; }
.onb-step { padding:14px 16px; border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-bg); }
.onb-step.onb-current { background:var(--color-surface); border-color:var(--color-accent); }
.onb-step.onb-done { background:var(--color-success-soft); border-color:var(--color-success); }
.onb-step.onb-locked { color:var(--color-text-soft); }
.onb-step-head { display:flex; align-items:center; gap:10px; }
.onb-num { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:50%; background:var(--color-surface); border:var(--border-thin); font-size:var(--text-sm); font-weight:600; flex:none; }
/* White text rides the AA-safe fill (decision 7), never the raw brand accent. */
.onb-step.onb-current .onb-num { background:var(--color-accent-fill); color:var(--neo-white); border-color:var(--color-accent-fill); }
.onb-step-title { font-weight:600; font-size:var(--text-md); }
.onb-step-state { margin-left:auto; font-size:var(--text-sm); font-weight:600; color:var(--color-text-soft); }
.onb-step.onb-done .onb-step-state { color:var(--color-success); }
.onb-step-desc { margin:8px 0 0 34px; max-width:72ch; }
.onb-step-actions { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0 0 34px; }
.onb-step-note { margin:10px 0 0 34px; font-size:var(--text-sm); color:var(--color-text-soft); max-width:72ch; }
.onb-shortcut-actions { margin-top:10px; }
.onb-shortcut-result { font-size:var(--text-sm); margin:8px 0 0 0; }

/* The /data-points visual system: each block of the page sits in its own card, and the
   seeded-mapping delete follow-ups render as callouts anchored under their row. */
.data-points-section-heading { font-size:var(--text-md); font-weight:600; color:var(--color-text); margin:0 0 var(--space-2); }
.data-points-default-set,
.data-points-create {
    background:var(--color-surface); border:var(--border-thin); border-radius:var(--radius-md);
    padding:var(--space-4) var(--space-5); margin-bottom:var(--space-5); max-width:960px;
}
/* The default set is the recommended quick path - a soft accent band + rule marks it. */
.data-points-default-set { background:var(--color-accent-soft); border-color:var(--color-accent); border-left:3px solid var(--color-accent); }
.data-points-create .data-points-section-heading { margin-top:0; }

/* Once the catalog holds any data point (#18), the default-set callout demotes to a calm one-line
   restore link so a populated workspace is not nagged to seed a starter set again. */
.data-points-default-set-demoted { margin-bottom:var(--space-4); }
.data-points-default-set-demoted .btn-restore-default-set {
    background:none; border:none; padding:0; font-size:var(--text-sm);
    color:var(--color-accent-strong); text-decoration:underline; cursor:pointer;
}
.data-points-default-set-demoted .btn-restore-default-set:disabled { color:var(--color-text-soft); cursor:default; }

/* The two entity catalogs, each a neutral panel. The tabs and the section heading carry which
   entity the catalog belongs to, so the panel itself stays out of the way. */
.dp-entity {
    border:var(--border-thin); border-left:3px solid var(--color-border-strong); border-radius:var(--radius-md);
    padding:var(--space-4) var(--space-5); margin-bottom:var(--space-5); background:var(--color-surface);
}
/* The wizard lane walks the two catalogs in sequence rather than behind the tab bar: a lead names
   the screen the operator is on, and the confirm block names what each entity ends up tracking. */
.dp-sequence-lead { font-size:var(--text-base); line-height:1.6; color:var(--color-text-soft); margin:0 0 var(--space-4); }
.dp-sequence-confirm {
    border:var(--border-thin); border-left:3px solid var(--color-border-strong); border-radius:var(--radius-md);
    padding:var(--space-4) var(--space-5); margin-bottom:var(--space-5); background:var(--color-surface);
}
.dp-sequence-confirm .data-points-section-heading { margin-top:0; }
.dp-sequence-counts { list-style:none; margin:0 0 var(--space-2); padding:0; display:flex; gap:var(--space-5); flex-wrap:wrap; }
.dp-sequence-counts li { font-size:var(--text-base); color:var(--color-text); }

/* The section head carries the title and the tab's "New data point" affordance. */
.dp-entity-head { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); flex-wrap:wrap; margin-bottom:var(--space-3); }
.dp-entity-head .data-points-section-heading { margin-bottom:0; }

/* The built-in fields are read-only + NEO-managed - a quiet muted reference panel that fills its
   container like the catalog above it, so the Drivers tab reads at one width. */
.data-points-base-fields {
    border:var(--border-thin); border-radius:var(--radius-md); padding:var(--space-4) var(--space-5);
    background:var(--color-bg); margin-bottom:var(--space-5);
}
.data-points-base-fields-head { display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-2); }
.data-points-base-fields-head .data-points-section-heading { margin-bottom:0; }

/* The create editor's form uses the full-screen editor's width: the short fields (Code / Name /
   Type) share one row, Description spans the full width as a multi-line field. */
.dp-create-form {
    display:grid; grid-template-columns:repeat(3, minmax(0, 1fr));
    gap:var(--space-4) var(--space-5); align-items:start; max-width:1080px;
}
.dp-create-form .form-row { margin-bottom:0; }
.dp-create-form .dp-create-desc, .dp-create-form .error { grid-column:1 / -1; }
.dp-create-form textarea.form-input { resize:vertical; min-height:96px; }
@media (max-width: 900px) {
    .dp-create-form { grid-template-columns:1fr; }
}

/* The seeded-mapping delete follow-ups (S7), anchored under the row: the confirm reads as a warning
   callout, the refusal as an error callout, so each is clearly the row's own state. */
[data-delete-confirm] > td { background:var(--color-warning-soft); border-left:3px solid var(--color-warning); }
[data-delete-confirm] [data-delete-confirm-text] { color:var(--color-warning-text); font-weight:600; margin:0 0 var(--space-2); }
[data-delete-error] > td { background:var(--color-error-soft); border-left:3px solid var(--color-error); }
[data-delete-error] [data-delete-error-text] { color:var(--color-error-text); margin:0; }

/* load-editor Section 1 - the consolidated load editor. A FULL-SCREEN, two-pane modal (the grid
   stays mounted + visible behind the dimmed backdrop, no full-page navigation). The left pane is
   the data entry (it scrolls); the right pane is the map. Replaces the old half-width side drawer
   whose fixed width forced a horizontal + vertical scroll-fight on the wide multi-column form. */
.modal-backdrop { position:fixed; inset:0; background:rgba(8, 33, 27, 0.40); z-index:40; }
.modal-shell {
    position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); z-index:41;
    width:95vw; height:92vh; max-width:1600px;
    display:flex; flex-direction:column;
    background:var(--color-surface);
    border:var(--border-strong);
    border-radius:var(--radius-lg);
    box-shadow:var(--shadow-lg);
    overflow:hidden;
}
/* Editor headers wear the forest popup-chrome tier - the popup's own green banner, visibly
   lighter than the near-black spruce/pine site tiers behind it, darker than the button green.
   The dismiss is a light icon X (.modal-close-x). */
.modal-header { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); padding:var(--space-4) var(--space-5); background:var(--color-chrome-popup); }
.modal-header h2 { margin:0; font-size:var(--text-md); color:var(--neo-white); text-transform:uppercase; letter-spacing:0.04em; }
.modal-close-x {
    background:none; border:none; font-size:24px; line-height:1;
    color:rgba(255, 255, 255, 0.72); cursor:pointer;
    padding:var(--space-1) var(--space-2); border-radius:var(--radius-sm);
}
.modal-close-x:hover { color:var(--neo-white); background:rgba(255, 255, 255, 0.10); }
/* The two-pane body fills the space between header + footer; each pane manages its own scroll.
   load-editor Section 3: the data pane is widened to ~1.4:1 over the map so the stop columns
   (Location / City, ST) stop truncating now the real map lives beside them. */
.modal-body-grid { flex:1 1 auto; display:grid; grid-template-columns:minmax(0, 1.4fr) minmax(0, 1fr); gap:0; min-height:0; }
/* The data pane joins the tinted-body convention so white cards and fields separate by value. */
.modal-pane-data { min-width:0; overflow-y:auto; overflow-x:hidden; padding:var(--space-4) var(--space-5); background:var(--color-bg); }
.modal-pane-map { min-width:0; border-left:var(--border-thin); padding:var(--space-4) var(--space-5); position:sticky; top:0; align-self:start; height:100%; }
.map-placeholder {
    display:flex; align-items:center; justify-content:center;
    height:100%; min-height:240px;
    border:2px dashed var(--color-border-strong); border-radius:var(--radius-md);
    color:var(--color-muted); background:var(--color-bg);
}
/* Footer actions sit bottom-right, primary action rightmost (the NeoConfirmDialog grammar).
   One grey step darker than the tinted body so the action band reads as its own layer. */
.modal-footer { display:flex; justify-content:flex-end; gap:var(--space-2); padding:var(--space-4) var(--space-5); border-top:var(--border-thin); background:var(--neo-grey-200); }
/* The RCL .neo-button joins the uppercase convention where it appears in popup footers. */
.modal-footer .neo-button { text-transform:uppercase; letter-spacing:0.04em; font-size:13px; font-weight:600; }
.modal-shell .form-section { margin-bottom:var(--space-5); }
.modal-shell .form-section h3 { margin-top:0; margin-bottom:var(--space-3); }
/* The multi-column rows must shrink to fit the pane: clear the flex item's intrinsic min-width and
   let each input fill its cell so a wide row (4 stop-address fields) never forces a horizontal
   scroll, the root cause of the side-drawer overflow this modal replaces. */
.modal-shell .form-row-inline > .form-row { min-width:0; }
.modal-shell .form-input { width:100%; min-width:0; }

/* load-editor Section 1 - field-ownership sections: NEO "Core fields" (neutral) vs "Your custom
   fields" (teal, the customer's catalog inputs). The accent + chip make "fields you created"
   unmistakable. */
.editor-section { padding:var(--space-4); border:var(--border-thin); border-radius:var(--radius-md); border-left-width:3px; }
.editor-section-core { border-left-color:var(--color-border-strong); background:var(--color-surface); }
.editor-section-custom { border-left-color:var(--color-accent); background:var(--color-accent-soft); }
.editor-section-head { display:flex; align-items:center; gap:var(--space-3); margin-bottom:var(--space-3); padding-bottom:var(--space-2); border-bottom:var(--border-thin); }
/* Section headers speak the uppercase convention (labels, popup titles, grid heads). */
.editor-section-head h3, .drawer-section-head h3 { margin:0; font-size:var(--text-sm); text-transform:uppercase; letter-spacing:0.04em; color:var(--neo-forest-700); }
/* The quiet corner link in a section head (e.g. "Manage your data points"). */
.editor-section-link { margin-left:auto; font-size:var(--text-xs); color:var(--color-accent-strong); }
.editor-section-note { margin:0 0 var(--space-3) 0; }
/* W14: Core and Custom take the same compact row grammar the Stops grid uses (smaller inputs,
   tighter labels), so all three sections read at one scale rather than Core/Custom towering over
   the compact Stops rows. */
.editor-section .form-row { margin-bottom:var(--space-2); gap:2px; }
.editor-section .form-row label { font-size:var(--text-xs); }
.editor-section .form-input { padding:6px var(--space-2); font-size:var(--text-sm); }
/* Custom fields flow as a responsive multi-column grid - most values are short, and a long
   catalog would otherwise scroll as a single tall column. The compact inputs let the auto-fill grid
   pack more columns, so a 15-field catalog lands in roughly three rows rather than a tall stack. */
.custom-fields-editor { display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:var(--space-2) var(--space-4); align-items:start; }
.custom-fields-editor .form-row { margin-bottom:0; }
.editor-tag { display:inline-flex; align-items:center; font-size:var(--text-xs); font-weight:600; line-height:1; padding:4px 8px; border-radius:var(--radius-sm); white-space:nowrap; }
.editor-tag-core { background:var(--color-border); color:var(--color-text-soft); }
.editor-tag-custom { background:var(--color-accent-fill); color:var(--neo-white); }

/* The "Starter" provenance pill (#22) sits beside a seeded row's name; a small gap keeps it off the
   name it annotates. */
.dp-starter-badge { margin-left:var(--space-2); }

/* load-editor Section 2 - the compact stops grid. One row per stop (# / type / location /
   City, ST / window) so 5+ stops fit without the vertical scroll-fight; the full per-stop fields
   live in a row expander. A small button variant keeps the row dense. */
.btn-sm { padding:2px var(--space-2); font-size:var(--text-xs); border-radius:var(--radius-sm); }
/* No overflow:hidden here - the pick-list dropdown must overlay past the grid's edge; the head
   band carries its own top rounding instead. */
.stops-grid { border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); }
.stops-grid-head, .stops-grid-row {
    display:grid;
    /* The actions column is FIXED so the head grid (whose last cell is empty) resolves the same
       fr tracks as the rows - auto would let the two grids drift apart. */
    /* The window column's floor clears its own content (the Early/Late tag plus a
       "7/4 08:30"-shaped field) and no more, so the width it does not need goes to the
       location column. */
    grid-template-columns:28px 92px minmax(0, 2fr) minmax(132px, 0.9fr) minmax(60px, auto) 104px;
    align-items:center; gap:var(--space-2);
    padding:var(--space-2) var(--space-3);
}
.stops-grid-head { background:var(--neo-grey-100); border-bottom:var(--border-thin); border-radius:var(--radius-md) var(--radius-md) 0 0; font-size:var(--text-xs); font-weight:600; color:var(--color-text-soft); text-transform:uppercase; letter-spacing:0.03em; }
.stops-grid-line { border-bottom:var(--border-thin); }
.stops-grid-line:last-child { border-bottom:none; }
.stops-grid-row > span { min-width:0; }
/* One row-scale font: the sequence number, location name, and cells all read at the same size
   as the compact controls. */
.stops-grid-row { font-size:var(--text-sm); }
/* Row controls stay compact - the row's data, not its chrome, should carry the width. */
.stops-grid-row .form-input { padding:6px var(--space-2); font-size:var(--text-sm); }
.stops-grid-row .btn-sm { padding:2px 6px; font-size:11px; }
/* An expanded stop is marked by a forest rule + a thick divider band so adjacent expanded
   stops read as separate blocks instead of blurring together. */
.stops-grid-line:has(.stops-grid-detail) { border-left:3px solid var(--neo-forest-700); border-bottom:4px solid var(--color-border-strong); }
.stops-col-seq { text-align:center; }
.stops-col-city, .stops-col-window { font-size:var(--text-sm); color:var(--color-text-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Icon actions stagger into a tight 3-across block so they stay a small corner of the row:
   reorder + remove on the first line, Details (double-width, worded) + map beneath. */
.stops-col-actions { display:grid; grid-template-columns:repeat(3, minmax(0, auto)); gap:2px; justify-content:end; align-content:center; }
/* ch-based minimum so Show/Hide render the same width and still scale with the user's font. */
.stops-col-actions .stops-action-wide { grid-column:span 2; min-width:10ch; text-align:center; }
.stops-grid .form-input { width:100%; min-width:0; }
.stops-grid-detail { padding:var(--space-2) var(--space-3); background:var(--color-bg); border-top:var(--border-thin); }
/* walk-F #36: slim the expanded per-stop details to a denser grammar (tighter rows, smaller labels +
   inputs) so the full field set reads compact under the row rather than as a heavy stacked form. */
.stops-grid-detail .form-row-inline { gap:var(--space-3); }
.stops-grid-detail .form-row { margin-bottom:var(--space-2); gap:2px; }
.stops-grid-detail .form-row label { font-size:var(--text-xs); }
.stops-grid-detail .form-input { padding:6px var(--space-2); font-size:var(--text-sm); }
/* S7a: the Add stop affordance below the grid so the stops list grows downward, right-aligned
   per the action-corner convention. */
.stops-grid-foot { margin-top:var(--space-3); display:flex; justify-content:flex-end; }

/* Effort 3 - search-first stop entry. The location cell leads with a "Search for location..." field;
   the ranked candidates render as an inline pick-list directly under it, and a picked stop collapses
   to a clean compact label with a Change affordance. */
/* The search bar reads as one row (field + button side by side); the pick-list and note wrap
   to full width beneath it. */
.stop-search { position:relative; display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1); }
.stop-search > .form-input { flex:1 1 160px; width:auto; }
.stop-search > .stop-search-note { flex-basis:100%; }
.stop-located { display:flex; align-items:center; gap:var(--space-2); min-width:0; }
/* Name + City, ST stack as one merged location cell; regular weight, city as the muted meta line.
   The text claims the cell's free space, which lands the Change control in a fixed trailing action
   slot: every row's pencil sits at the same x, forming one column clear of the Leg column. */
.stop-located-text { display:flex; flex-direction:column; min-width:0; flex:1 1 auto; }
.stop-located > .btn-sm { flex:none; }
.stop-located-name { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.stop-located-city { font-size:var(--text-xs); color:var(--color-text-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* The candidate pick-list is a dropdown OVERLAY under the search field - wider than the column,
   floating over the rows below - so results never inflate the stop row or re-center its fields. */
.stop-picklist {
    list-style:none; margin:0; padding:0;
    position:absolute; top:calc(100% + 4px); left:0; z-index:6;
    min-width:320px; max-width:520px; width:max-content;
    max-height:320px; overflow-y:auto;
    border:var(--border-strong); border-radius:var(--radius-md);
    background:var(--color-surface); box-shadow:var(--shadow-lg);
}
.stop-picklist li { border-bottom:var(--border-thin); }
.stop-picklist li:last-child { border-bottom:none; }
.stop-picklist-item {
    display:flex; flex-direction:column; gap:2px; width:100%; text-align:left;
    padding:var(--space-2) var(--space-3); border:none; background:none; cursor:pointer;
    font-size:var(--text-sm); color:var(--color-text);
}
.stop-picklist-item:hover, .stop-picklist-item:focus { background:var(--color-accent-fill); color:var(--neo-white); }
/* walk-F #36: a candidate row leads with its label, then a muted meta line (place type + City, ST ZIP).
   The meta inherits the row color (so it flips to white on hover) at reduced opacity for the muted read. */
.stop-picklist-label { font-weight:600; }
.stop-picklist-meta { font-size:var(--text-xs); opacity:0.75; }
.stop-search-note { margin:0; font-size:var(--text-xs); color:var(--color-text-soft); }

/* The inline quick-entry arrival window: two tagged lines (Early / Late) stacked to the same
   height as the two-row action block, so the row stays even. */
.stop-window-quick { display:flex; flex-direction:column; gap:2px; }
.stop-window-line { display:flex; align-items:center; gap:4px; }
.stop-window-tag { flex:none; width:32px; font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.03em; color:var(--color-text-soft); }
.stop-window-line .stop-window-input { flex:1 1 0; min-width:0; }
.stops-grid-row .stop-window-input { font-size:var(--text-xs); padding:2px 4px; }
/* The leg figures read as quiet row metadata: miles over drive time, two compact lines. */
.stops-col-leg { display:flex; flex-direction:column; font-size:var(--text-xs); color:var(--color-text-soft); white-space:nowrap; }
.stop-window-read { font-size:var(--text-sm); color:var(--color-text-soft); }

/* load-editor Section 2 - freight on the stops grammar: a compact grid with the working fields
   inline in the row; the reference numbers behind the Show expander. */
.freight-grid { border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); }
.freight-grid-head, .freight-grid-row {
    display:grid;
    /* Fixed actions column for head/row track parity (the stops-grid rule). */
    grid-template-columns:28px minmax(0, 1.2fr) 150px 64px 150px minmax(150px, 1fr) 36px;
    align-items:center; gap:var(--space-2);
    padding:var(--space-2) var(--space-3);
}
.freight-grid-head { background:var(--neo-grey-100); border-bottom:var(--border-thin); border-radius:var(--radius-md) var(--radius-md) 0 0; font-size:var(--text-xs); font-weight:600; color:var(--color-text-soft); text-transform:uppercase; letter-spacing:0.03em; }
.freight-grid-line { border-bottom:var(--border-thin); }
.freight-grid-line:last-child { border-bottom:none; }
.freight-grid-row { font-size:var(--text-sm); }
.freight-grid-row > span { min-width:0; }
.freight-grid-row .form-input { width:100%; min-width:0; padding:6px var(--space-2); font-size:var(--text-sm); }
.freight-grid-row .btn-sm { padding:2px 6px; font-size:11px; }
.freight-col-seq { text-align:center; }
/* The hazmat cell: the checkbox, then the class field that appears only when the flag is on. */
.freight-col-hazmat { display:flex; align-items:center; gap:6px; }
.freight-hazmat-class { max-width:110px; }
.freight-weight, .freight-volume { display:flex; gap:4px; }
.freight-weight select.form-input, .freight-volume select.form-input { flex:0 0 60px; width:auto; }
.freight-col-actions { display:flex; gap:2px; justify-content:flex-end; }
.freight-grid-foot { margin-top:var(--space-3); display:flex; justify-content:flex-end; }
/* Add stop / Add freight read as a matched column going down the pane. */
.stops-grid-foot .btn, .freight-grid-foot .btn { min-width:14ch; text-align:center; }

/* load-editor Section 3 - the reusable HERE map pane. The map element needs an explicit height to
   render (HERE Maps sizes to its container); the toolbar floats the Map/Satellite/Hybrid toggle. The
   "map unavailable" state mirrors the old dashed placeholder so an absent key reads as a clear,
   non-broken degradation. */
.heremap-wrap { display:flex; flex-direction:column; height:100%; min-height:320px; gap:var(--space-2); }
.heremap-toolbar { display:flex; gap:var(--space-1); flex-wrap:wrap; }
.heremap-el { flex:1 1 auto; min-height:280px; border:var(--border-thin); border-radius:var(--radius-md); overflow:hidden; background:var(--color-bg); }
.heremap-geocode-note { margin:0; font-size:var(--text-sm); }
.heremap-geocode-note.is-ok { color:var(--color-success, var(--color-accent)); }
.heremap-geocode-note.is-warn { color:var(--color-warning, var(--color-text-soft)); }
.heremap-unavailable {
    display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
    height:100%; min-height:280px; gap:var(--space-2);
    border:2px dashed var(--color-border-strong); border-radius:var(--radius-md);
    color:var(--color-muted); background:var(--color-bg); padding:var(--space-4);
}
.heremap-unavailable-title { margin:0; font-weight:600; color:var(--color-text-soft); }

/* The side-drawer overlay (still used by the schedule CloseOutDrawer; the load editor and the driver
   editor moved to the full-screen modal above). An overlay panel; the grid stays mounted + visible
   behind it, no full-page navigation. */
.drawer-backdrop { position:fixed; inset:0; background:rgba(8, 33, 27, 0.32); z-index:40; }
.drawer {
    position:fixed; top:0; right:0; bottom:0; z-index:41;
    width:min(720px, 96vw);
    display:flex; flex-direction:column;
    background:var(--color-surface);
    border-left:var(--border-strong);
    box-shadow:var(--shadow-lg);
}
/* Side drawers follow the popup convention: forest banner, uppercase title, banded footer. */
.drawer-header { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); padding:var(--space-4) var(--space-5); background:var(--color-chrome-popup); }
.drawer-header h2 { margin:0; font-size:var(--text-md); color:var(--neo-white); text-transform:uppercase; letter-spacing:0.04em; }
.drawer-body { flex:1 1 auto; overflow-y:auto; padding:var(--space-4) var(--space-5); }
.drawer-footer { display:flex; justify-content:flex-end; gap:var(--space-2); padding:var(--space-4) var(--space-5); border-top:var(--border-thin); background:var(--neo-grey-200); }
.drawer-footer .btn { text-transform:uppercase; letter-spacing:0.04em; font-size:13px; font-weight:600; }
.drawer .form-section { margin-bottom:var(--space-5); }
.drawer .form-section h3 { margin-top:0; margin-bottom:var(--space-3); }
.drawer-section-head { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); margin-bottom:var(--space-3); }
.drawer-section-head h3 { margin:0; }
.drawer-line { padding:var(--space-3); border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-bg); margin-bottom:var(--space-3); }
.drawer-line-head { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); margin-bottom:var(--space-2); }
.drawer-line-actions { display:flex; gap:var(--space-2); }
.form-row-check { flex-direction:row; align-items:center; gap:var(--space-2); }

/* Below ~960px the two panes stack (map under the data) so neither pane crushes. */
@media (max-width: 960px) {
    .modal-body-grid { grid-template-columns:minmax(0, 1fr); }
    .modal-pane-map { border-left:none; border-top:var(--border-thin); position:static; height:auto; min-height:240px; }
}

/* Effort 6 (F33): the activation step, from the confirmed mockup. The CTA rides the accent
   fill (deep green #0F6E56, white text 6.20:1); everything else maps to the committed token system. */
.activation-cta {
    display:inline-block; background:var(--color-accent-fill); color:var(--neo-white); border:none; border-radius:var(--radius-md);
    padding:var(--space-3) var(--space-5); font:inherit; font-weight:500; cursor:pointer; text-decoration:none;
}
.activation-cta:hover { background:var(--color-accent-fill-hover); }
.activation-cta:disabled { opacity:0.6; cursor:default; }

.activation-card { background:var(--color-surface); border:var(--border-thin); border-radius:var(--radius-lg); padding:var(--space-6); margin-inline:auto; }

.activation-step-row { display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-5); }
.activation-step-badge { font-size:var(--text-xs); font-weight:500; color:var(--color-accent-text); background:var(--color-accent-soft); padding:var(--space-1) var(--space-3); border-radius:999px; }
.activation-step-label { font-size:var(--text-sm); color:var(--color-text-soft); }

.activation-ready-row { display:flex; align-items:center; gap:var(--space-4); padding-bottom:var(--space-5); border-bottom:var(--border-thin); }
.activation-ready-icon { width:48px; height:48px; flex:none; border-radius:50%; background:var(--color-accent-soft); color:var(--color-accent-text); display:flex; align-items:center; justify-content:center; font-size:24px; }
.activation-ready-copy { flex:1; }
.activation-ready-heading { font-size:var(--text-md); font-weight:500; color:var(--color-text); }
.activation-ready-subtitle { font-size:var(--text-sm); color:var(--color-text-soft); }
.activation-live-pill { flex:none; font-size:var(--text-sm); font-weight:500; color:var(--color-success-text); background:var(--color-success-soft); padding:var(--space-2) var(--space-4); border-radius:999px; }

.activation-no-neo { font-size:var(--text-sm); color:var(--color-text-soft); margin-top:var(--space-3); }

.activation-connect-prompt { font-size:var(--text-sm); font-weight:500; color:var(--color-text-soft); margin:var(--space-5) 0 var(--space-3); }

.activation-connect-card { border:2px solid var(--color-accent); border-radius:var(--radius-lg); padding:var(--space-5); background:var(--color-bg); }
.activation-connect-body { display:flex; align-items:flex-start; gap:var(--space-4); }
.activation-connect-icon { width:44px; height:44px; flex:none; border-radius:var(--radius-lg); background:var(--color-accent-soft); display:flex; align-items:center; justify-content:center; font-size:22px; }
.activation-connect-copy { flex:1; }
.activation-connect-heading-row { display:flex; align-items:center; gap:var(--space-2); }
.activation-connect-heading { font-size:var(--text-base); font-weight:500; color:var(--color-text); }
.activation-connect-badge { font-size:var(--text-xs); font-weight:500; color:var(--color-text-soft); background:var(--neo-grey-100); padding:2px var(--space-2); border-radius:999px; }
.activation-connect-description { font-size:var(--text-sm); line-height:1.6; color:var(--color-text-soft); margin:var(--space-2) 0 var(--space-3); }
.activation-connect-hint { font-size:var(--text-xs); color:var(--color-muted); margin-left:var(--space-3); }

/* The forward door inside the success band: a block-level link under the confirmation sentence, so
   the destination reads as the band's next move rather than as part of the sentence. */
.activation-live-board-link { display:inline-block; margin-top:var(--space-2); font-weight:600; }

.activation-loop { display:grid; grid-template-columns:1fr 1fr 1fr; gap:var(--space-3); margin-top:var(--space-4); }
.activation-loop-item { display:flex; gap:var(--space-2); align-items:flex-start; padding:2px var(--space-1); }
.activation-loop-mark { color:var(--color-accent-text); margin-top:1px; }
.activation-loop-text { font-size:var(--text-sm); line-height:1.45; color:var(--color-text-soft); }
.activation-loop-label { color:var(--color-text); font-weight:500; }

.activation-fallback { font-size:var(--text-sm); color:var(--color-muted); margin-top:var(--space-5); padding-top:var(--space-4); border-top:var(--border-thin); text-align:center; }

@media (max-width: 720px) {
    .activation-loop { grid-template-columns:1fr; }
}

/* G S6 (#74): the orientation spine (/how-neo-works). A sticky anchor TOC rides beside the
   two-half manual (setup + daily loop); each section is a NeoCard with copy, "go there" links,
   and a reused marketing step-shot illustration (the dark shell hosts the on-dark hero board).
   scroll-margin keeps a deep-linked section clear of the viewport edge. */
.how-neo-works { display:grid; grid-template-columns:200px minmax(0,1fr); gap:var(--space-8); align-items:start; max-width:1080px; }
.how-neo-toc { position:sticky; top:var(--space-6); }
.how-neo-toc-group { font-size:var(--text-xs); font-weight:600; text-transform:uppercase; letter-spacing:0.04em; color:var(--color-muted); margin:var(--space-4) 0 var(--space-1); }
.how-neo-toc-group:first-child { margin-top:0; }
.how-neo-toc ul { list-style:none; margin:0; padding:0; }
.how-neo-toc a { display:block; padding:var(--space-1) 0; font-size:var(--text-sm); color:var(--color-text-soft); text-decoration:none; }
.how-neo-toc a:hover { color:var(--color-accent-text); }
.how-neo-half + .how-neo-half { margin-top:var(--space-8); }
.how-neo-half-kicker { font-size:var(--text-lg); font-weight:600; color:var(--color-text); margin:0 0 var(--space-1); }
.how-neo-half-lede { font-size:var(--text-base); line-height:1.6; color:var(--color-text-soft); margin:0 0 var(--space-4); }
.how-neo-step { margin-bottom:var(--space-4); scroll-margin-top:var(--space-6); }
.how-neo-step-inner { display:grid; grid-template-columns:minmax(0,1fr) 240px; gap:var(--space-6); align-items:center; }
.how-neo-step-heading { font-size:var(--text-md); font-weight:500; color:var(--color-text); margin:0 0 var(--space-2); }
.how-neo-step-body { font-size:var(--text-base); line-height:1.6; color:var(--color-text-soft); margin:0; }
.how-neo-step-links { display:flex; flex-wrap:wrap; gap:var(--space-4); margin:var(--space-3) 0 0; font-size:var(--text-sm); }
.how-neo-step-art svg { display:block; width:100%; height:auto; }
.how-neo-step-art-dark { background:var(--color-surface-dark); border-radius:var(--radius-md); padding:var(--space-3); }
@media (max-width: 900px) {
    .how-neo-works { grid-template-columns:1fr; }
    .how-neo-toc { position:static; }
    .how-neo-step-inner { grid-template-columns:1fr; }
}

/* Effort 6 (F21): the historical-schedule upload prompt on the scoring editor (dual value). */
.historical-upload-prompt { display:flex; align-items:flex-start; gap:var(--space-2); margin:var(--space-3) 0; padding:var(--space-3); border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-accent-soft); }
.historical-upload-icon { color:var(--color-accent-text); margin-top:1px; }
.historical-upload-copy { font-size:var(--text-sm); line-height:1.5; color:var(--color-text-soft); }

/* Fitness-elicitation S2 (SEED-Y): the fit-confidence badge over a seeded draft (a quiet panel,
   the band as a small chip, the framing as soft body copy) and the per-ingredient review markers
   on canvas rows - "kept default" where the derivation could not fit, "showed signal" where the
   starting weight was fitted from the carrier's own data (walk-B S4). */
.seed-badge { display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-2); margin:var(--space-3) 0; padding:var(--space-3); border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-accent-soft); }
.seed-badge-heading { font-size:var(--text-sm); font-weight:500; color:var(--color-text); }
.seed-badge-band { font-size:var(--text-xs); font-weight:500; color:var(--color-accent-text); border:1px solid var(--color-accent); border-radius:999px; padding:1px 8px; cursor:help; }
.seed-badge-framing { font-size:var(--text-sm); line-height:1.5; color:var(--color-text-soft); flex-basis:100%; }
.seed-badge-nudge { font-size:var(--text-sm); line-height:1.5; color:var(--color-text-soft); flex-basis:100%; }
/* The two per-field review states read as chips, not as one run of italic text: a shared pill
   shape carries the shared job (where this weight came from) and the fill separates the cases -
   an accent chip where the carrier's own history set the weight, a quiet outline where the
   default stands. Both explain themselves on hover. */
.seed-marker { display:inline-block; font-size:var(--text-xs); font-weight:500; line-height:1.4; padding:1px 7px; border-radius:999px; white-space:nowrap; cursor:help; }
.seed-marker-default { color:var(--color-text-soft); border:1px solid var(--color-border-strong); background:transparent; }
.seed-marker-signal { color:var(--color-accent-text); border:1px solid var(--color-accent); background:var(--color-accent-soft); }

/* The wizard-lane orientation strip: three beats on one row, wrapping to a stack when the page
   narrows. Each beat's lead word carries the weight; the body reads as running text. */
.priorities-orientation { display:flex; flex-wrap:wrap; gap:var(--space-2) var(--space-5); margin:var(--space-3) 0; padding:var(--space-3); border:var(--border-thin); border-radius:var(--radius-md); background:var(--color-surface); }
.priorities-orientation .orientation-beat { flex:1 1 220px; font-size:var(--text-sm); line-height:1.5; color:var(--color-text-soft); }
.priorities-orientation .orientation-beat strong { display:block; font-weight:600; color:var(--color-text); }

/* Effort 7: the guided first-run wizard - the shell, the card fork (two branches, three on the
   priorities step), and the persistent progress timeline. The mockup's generic CDS tokens map onto
   the committed --color-* /
   --space-* system: surface-2 -> --color-surface, bg-accent -> --color-accent-soft, text-accent ->
   --color-accent-text, text-primary -> --color-text, text-secondary -> --color-text-soft, border ->
   --color-border. The icon font is not shipped, so each card glyph is an inline character. */
.wizard-shell { max-width:880px; margin-inline:auto; }
.wizard-step { background:var(--color-surface); border:var(--border-thin); border-radius:var(--radius-lg); padding:var(--space-6); margin-top:var(--space-4); }
.wizard-step-explanation { font-size:var(--text-base); line-height:1.6; color:var(--color-text-soft); margin:0 0 var(--space-5); }

/* The TMS question leading step 2: a quiet framed aside, not a choice card - it asks a question and
   opens the support page, and nothing on it routes into an integration. */
.wizard-tms-question {
    border:var(--border-thin); border-left:3px solid var(--color-border-strong); border-radius:var(--radius-md);
    padding:var(--space-4) var(--space-5); margin:0 0 var(--space-5); background:var(--color-surface);
}
.wizard-tms-question-heading { margin:0 0 var(--space-2); font-size:var(--text-base); font-weight:600; color:var(--color-text); }
.wizard-tms-question-body { margin:0 0 var(--space-3); font-size:var(--text-sm); line-height:1.6; color:var(--color-text-soft); }
.wizard-tms-question-link { font-size:var(--text-sm); font-weight:600; color:var(--color-accent-strong); }

/* The card fork (PW8): large side-by-side choice cards as a single-select group - two by default,
   three on the priorities step (walk-B S4). Clicking a card highlights it (all stay visible); the
   host owns the Continue. Each card sits in a wrap with its optional "What's this?" disclosure
   below it. */
.wizard-fork-prompt { font-size:var(--text-sm); color:var(--color-text-soft); margin-bottom:var(--space-5); }
.wizard-fork-cards { display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4); align-items:start; }
.wizard-fork-cards-three { grid-template-columns:1fr 1fr 1fr; }
.wizard-fork-card-wrap { display:flex; flex-direction:column; gap:var(--space-2); }
.wizard-fork-card {
    position:relative; text-align:left; cursor:pointer; width:100%;
    background:var(--color-surface); border:2px solid var(--color-border); border-radius:var(--radius-lg);
    padding:var(--space-6); min-height:180px; display:flex; flex-direction:column; gap:var(--space-3); font:inherit;
    transition:border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.wizard-fork-card:hover { border-color:var(--color-border-strong); box-shadow:var(--shadow-md); }
.wizard-fork-card:focus-visible { outline:none; box-shadow:var(--focus-ring); }
/* Selected: the highlighted choice - a soft accent band + rule, so the pick carries meaning. */
.wizard-fork-card-selected,
.wizard-fork-card-selected:hover { border-color:var(--color-recommended-rule); background:var(--color-recommended-band); }
.wizard-fork-card-icon {
    width:44px; height:44px; flex:none; border-radius:var(--radius-lg); background:var(--color-accent-soft);
    color:var(--color-accent-text); display:flex; align-items:center; justify-content:center; font-size:22px;
}
.wizard-fork-card-title { font-size:var(--text-md); font-weight:600; color:var(--color-text); }
.wizard-fork-card-desc { font-size:var(--text-sm); line-height:1.6; color:var(--color-text-soft); flex:1; }
/* The "Recommended" tag on the guided-default card (PW5). */
.wizard-fork-card-tag {
    position:absolute; top:var(--space-3); right:var(--space-3);
    font-size:var(--text-xs); font-weight:600; color:var(--color-accent-text);
    background:var(--color-accent-soft); border-radius:999px; padding:2px var(--space-2);
}
/* The selected-state marker inside the card. */
.wizard-fork-card-check { display:inline-flex; align-items:center; gap:var(--space-1); font-size:var(--text-sm); font-weight:600; color:var(--color-accent-text); }
/* Per-card "What's this?" disclosure (PW9): depth on demand, quiet by default. */
.wizard-fork-whats-this { font-size:var(--text-sm); }
.wizard-fork-whats-this-summary { cursor:pointer; color:var(--color-accent-text); font-weight:500; padding:var(--space-1) 0; list-style:none; }
.wizard-fork-whats-this-summary::-webkit-details-marker { display:none; }
.wizard-fork-whats-this-summary::marker { content:""; }
.wizard-fork-whats-this-summary:hover { text-decoration:underline; }
.wizard-fork-whats-this-body { font-size:var(--text-sm); line-height:1.6; color:var(--color-text-soft); padding:var(--space-1) 0 var(--space-2); }
/* The fork-level "Learn how NEO works" deep-link (PW9). */
.wizard-fork-learn-more { display:inline-block; margin-top:var(--space-4); font-size:var(--text-sm); font-weight:500; color:var(--color-accent-text); text-decoration:none; }
.wizard-fork-learn-more:hover { text-decoration:underline; }

/* S6: the wizard sub-page chrome - a bottom action bar on a step's work page (Back to setup left,
   Continue right) shown only while setup is incomplete. */
.wizard-step-chrome { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); margin-top:var(--space-6); }
.wizard-step-chrome [data-wizard-chrome-continue] { margin-left:auto; }

/* The persistent progress timeline (F28 + PW3): a full-width connected stepper spanning the
   content column. Each node stacks a marker over its label; a connector line runs node-to-node
   behind the markers, carrying a green "done" path up to the current step and grey beyond. Five
   equal-width columns fit the ~880px shell on one line, so the row never wraps (the PW3 defect). */
.wizard-progress { margin-top:var(--space-4); }
.wizard-progress-counter { font-size:var(--text-xs); font-weight:500; color:var(--color-accent-text); background:var(--color-accent-soft); display:inline-block; padding:var(--space-1) var(--space-3); border-radius:999px; margin-bottom:var(--space-4); }
.wizard-progress-steps { list-style:none; display:flex; margin:0; padding:0; }
.wizard-progress-step { flex:1 1 0; min-width:0; position:relative; display:flex; flex-direction:column; align-items:center; }
/* The connector from this node's centre to the next node's centre, drawn behind the markers. */
.wizard-progress-step:not(:last-child)::after {
    content:""; position:absolute; top:14px; left:50%; width:100%; height:2px;
    background:var(--color-border-strong); z-index:0;
}
.wizard-step-completed:not(:last-child)::after { background:var(--color-success); }
.wizard-progress-node {
    position:relative; z-index:1; width:100%; display:flex; flex-direction:column; align-items:center;
    gap:var(--space-2); padding:0 var(--space-1); text-decoration:none; color:inherit;
}
a.wizard-progress-node { cursor:pointer; }
a.wizard-progress-node:hover .wizard-progress-label { color:var(--color-accent-text); }
a.wizard-progress-node:hover .wizard-progress-marker { border-color:var(--color-accent); }
a.wizard-progress-node:focus-visible { outline:none; }
a.wizard-progress-node:focus-visible .wizard-progress-marker { box-shadow:var(--focus-ring); }
.wizard-progress-marker {
    width:28px; height:28px; flex:none; border-radius:50%; display:flex; align-items:center; justify-content:center;
    font-size:var(--text-sm); font-weight:600; border:var(--border-strong); color:var(--color-muted); background:var(--color-surface);
    transition:border-color 0.12s ease, box-shadow 0.12s ease;
}
.wizard-progress-label { font-size:var(--text-xs); line-height:var(--leading-sm); text-align:center; color:var(--color-text-soft); }
/* The per-node state word stays for assistive tech; the colour carries it visually. */
.wizard-progress-state { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.wizard-step-completed .wizard-progress-marker { border-color:var(--color-success); background:var(--color-success); color:var(--neo-white); }
.wizard-step-completed .wizard-progress-label { color:var(--color-text); }
.wizard-step-current .wizard-progress-marker { border-color:var(--color-accent); background:var(--color-accent-soft); color:var(--color-accent-text); box-shadow:0 0 0 4px var(--color-accent-soft); }
.wizard-step-current .wizard-progress-label { color:var(--color-text); font-weight:600; }

/* The all-done state: the wizard hands back to the day-to-day landing. */
.wizard-all-done { text-align:center; background:var(--color-surface); border:var(--border-thin); border-radius:var(--radius-lg); padding:var(--space-8) var(--space-6); margin-top:var(--space-4); }
.wizard-all-done-icon { display:inline-flex; align-items:center; justify-content:center; width:48px; height:48px; border-radius:50%; background:var(--color-success-soft); color:var(--color-success-text); font-size:24px; margin-bottom:var(--space-3); }
.wizard-all-done-heading { font-size:var(--text-lg); font-weight:600; color:var(--color-text); margin:0 0 var(--space-2); }
.wizard-all-done-body { font-size:var(--text-base); color:var(--color-text-soft); margin:0 0 var(--space-5); }

@media (max-width: 720px) {
    .wizard-fork-cards { grid-template-columns:1fr; }
}
