:root {
      color-scheme: light;
      --background: #FFFFFF;
      --surface: #FAFAFA;
      --surface-raised: #FFFFFF;
      --border-hairline: #E4E4E7;
      --border-strong: #A1A1AA;
      --text-primary: #18181B;
      --text-secondary: #52525B;
      --text-muted: #71717A;
      --accent: #2563EB;
      --success: #15803D;
      --warning: #B45309; /* Reserved for data uncertainty, never performance. */
      --danger: #B91C1C;
      --border-control: #71717A;
      --border-header: var(--border-strong);
      --focus-ring: var(--accent);
      --selection-indicator: var(--accent);
    }
    :root[data-theme="dark"] {
      color-scheme: dark;
      --background: #0C0C0D;
      --surface: #131315;
      --surface-raised: #1A1A1D;
      --border-hairline: #26262A;
      --border-strong: #52525B;
      --text-primary: #F4F4F5;
      --text-secondary: #A1A1AA;
      --text-muted: #A1A1AA;
      --accent: #6D9BFF;
      --success: #4ADE80;
      --warning: #FBBF24;
      --danger: #F87171;
    }
    *, *::before, *::after { box-sizing: border-box; font-feature-settings: "tnum" 1; }
    [hidden] { display: none !important; }
    body { margin: 0; background: var(--background); color: var(--text-primary); font-family: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif; font-size: 13px; line-height: 20px; }
    button, a { -webkit-tap-highlight-color: transparent; }
    button { font: inherit; color: inherit; cursor: pointer; border-radius: 0; }
    :focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
    html, body { height: 100%; overflow: hidden; }
    .app-shell { display: grid; grid-template-columns: 200px minmax(0, 1fr); height: 100dvh; }
    .sidebar { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; overflow-x: hidden; background: var(--surface); border-right: 1px solid var(--border-hairline); }
    /* Header row: wordmark plus the collapse toggle, right-aligned beside it (owner review, item
       1) — the toggle is a quiet 28px icon control, never a full-width row. */
    .sidebar-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; height: 56px; flex-shrink: 0; padding: 0 12px 0 20px; border-bottom: 1px solid var(--border-hairline); }
    .wordmark { display: flex; align-items: center; margin: 0; min-width: 0; font-size: 14px; line-height: 20px; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; }
    .wordmark-compact { display: none; }
    /* Quiet icon-only control: text-secondary at rest, text-primary + surface-raised on
       hover/focus, ~28x28px hit target, never full width (owner review, item 1). */
    .sidebar-toggle { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 2px; background: transparent; color: var(--text-secondary); cursor: pointer; position: relative; }
    .sidebar-toggle:hover, .sidebar-toggle:focus-visible { color: var(--text-primary); background: var(--surface-raised); }
    .sidebar nav { flex: 1; padding: 8px 0; }
    /* Shared grid for every remaining sidebar row — nav links and the theme control — so icons
       and labels line up on one consistent column regardless of element type (item 4). */
    .side-item { display: flex; align-items: center; gap: 10px; width: 100%; height: 36px; padding: 0 16px; border: 0; box-sizing: border-box; background: transparent; color: var(--text-secondary); text-decoration: none; text-align: left; font: inherit; cursor: pointer; border-radius: 0; position: relative; }
    .side-item .nav-icon { display: flex; align-items: center; justify-content: center; width: 18px; height: 18px; flex-shrink: 0; }
    .side-item .nav-icon svg { width: 100%; height: 100%; }
    .side-item .nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    /* Fixed, not absolute: .sidebar scrolls vertically (overflow-y: auto), which per spec also
       computes its overflow-x to auto — that would clip an absolutely-positioned tooltip before
       it ever reaches the main content. Fixed positioning escapes that clip; app.js sets left/top
       from the trigger's own rect on hover/focus. Generic (not scoped to .side-item) because the
       header's icon-only collapse toggle carries one too. */
    .nav-tooltip { position: fixed; left: 0; top: 0; transform: translateY(-50%); padding: 4px 8px; background: var(--surface-raised); border: 1px solid var(--border-hairline); border-radius: 2px; color: var(--text-primary); font-size: 12px; font-weight: 400; line-height: 16px; white-space: nowrap; opacity: 0; pointer-events: none; z-index: 20; }
    /* The collapse toggle is icon-only in every state, so its tooltip is not gated to the
       collapsed sidebar the way nav-link/theme-toggle tooltips are below. */
    .sidebar-toggle:hover .nav-tooltip, .sidebar-toggle:focus-visible .nav-tooltip { opacity: 1; }
    .nav-link { border-left: 2px solid transparent; }
    .nav-link:hover, .theme-toggle:hover { background: var(--surface-raised); }
    .nav-link[aria-current="page"] { border-left-color: var(--accent); color: var(--text-primary); background: var(--surface-raised); }
    /* Theme control is chrome for the chrome — a hairline separates it from the nav list above,
       distinct from the header's hairline below the wordmark (item 4). */
    .sidebar-bottom { margin-top: auto; flex-shrink: 0; padding: 8px 0; border-top: 1px solid var(--border-hairline); display: flex; flex-direction: column; }
    .main-scroll { min-width: 0; overflow: auto; display: flex; flex-direction: column; }
    /* Collapsible sidebar (item 3) — scoped entirely to >=700px so none of it can leak into the
       phone top-bar layout below, regardless of the persisted localStorage attribute. */
    @media (min-width: 700px) {
      html[data-sidebar-collapsed="true"] .app-shell { grid-template-columns: 56px minmax(0, 1fr); }
      /* Collapsed: wordmark shrinks to a compact mark and the header stacks so the toggle stays
         visible, centred beneath it — it must never become unreachable (owner review, item 1). */
      html[data-sidebar-collapsed="true"] .sidebar-header { flex-direction: column; align-items: center; justify-content: center; height: auto; padding: 12px 0; gap: 8px; }
      html[data-sidebar-collapsed="true"] .wordmark-full { display: none; }
      html[data-sidebar-collapsed="true"] .wordmark-compact { display: inline; }
      html[data-sidebar-collapsed="true"] .side-item { justify-content: center; padding: 0 8px; }
      /* Label stays in the DOM and reachable by screen readers — only visually hidden, same
         technique as .sr-only above — never removed. */
      html[data-sidebar-collapsed="true"] .nav-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
      html[data-sidebar-collapsed="true"] .side-item:hover .nav-tooltip,
      html[data-sidebar-collapsed="true"] .side-item:focus-visible .nav-tooltip { opacity: 1; }
    }
    @media (min-width: 700px) and (prefers-reduced-motion: no-preference) {
      .app-shell { transition: grid-template-columns 0.18s ease; }
      .sidebar-header, .side-item { transition: padding 0.18s ease, justify-content 0.18s ease; }
    }
    main { max-width: 1200px; width: 100%; margin: 0 auto; padding: 20px 24px; flex: 1 0 auto; display: flex; flex-direction: column; min-height: 100%; }
    #dashboard { display: flex; flex-direction: column; flex: 1; min-height: 0; }
    main:focus { outline: none; }
    .back-link { display: inline-block; margin-bottom: 12px; }
    .rep-meta { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 0 0 24px; color: var(--text-secondary); }
    .rep-meta div { display: flex; gap: 6px; }
    .rep-meta dt { color: var(--text-muted); }
    .rep-meta dd { margin: 0; }
    .compact-table { min-width: 720px; }
    .compact-table th:first-child { width: 150px; }
    .range-controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
    .range-controls button, .range-controls input { font: inherit; font-size: 13px; line-height: 20px; color: var(--text-secondary); background: var(--surface-raised); border: 1px solid var(--border-hairline); border-radius: 0; height: 28px; min-height: 28px; padding: 3px 8px; }
    .range-controls button[aria-pressed="true"] { color: var(--text-primary); border-color: var(--accent); }
    .range-controls label { display: flex; align-items: center; gap: 8px; color: var(--text-secondary); }
    .range-controls .range-preset-mobile-label { display: none; }
    .range-note { color: inherit; font: inherit; }
    .range-note.is-invalid { color: var(--text-primary); }
    .summary { margin-bottom: 12px; }
    .summary-note { margin: 6px 0 0; font-size: 11px; line-height: 16px; color: var(--text-secondary); }
    .rank-list { list-style: none; margin: 0; padding: 0; }
    .rank-list li { border-bottom: 1px solid var(--border-hairline); }
    .rank-list a { display: grid; grid-template-columns: 140px minmax(40px, 1fr) 64px; align-items: center; gap: 12px; padding: 8px 12px; text-decoration: none; color: var(--text-primary); }
    .rank-list a:hover { background: var(--surface); }
    .rank-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .rank-track { height: 12px; }
    .rank-bar { height: 12px; background: var(--border-strong); }
    .rank-bar.is-unverified { background: transparent; border: 1px dashed var(--warning); min-width: 12px; }
    .rank-list .numeric { font-size: 12px; }
    /* Two bands, stacked: band 1 (title + range controls) is a row; meta-line is one quiet secondary line. */
    .global-bar { display: flex; flex-direction: column; gap: 4px; }
    .header-band { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; }
    h1 { margin: 0; font-size: 16px; font-weight: 600; line-height: 24px; }
    .meta-line { margin: 0; font-size: 11px; line-height: 16px; color: var(--text-secondary); }
    .refresh-button { display: inline; background: none; border: 0; padding: 0; margin: 0; font: inherit; font-size: inherit; color: var(--text-secondary); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
    .refresh-button:hover, .refresh-button:focus-visible { color: var(--accent); }
    .refresh-button:disabled { text-decoration: none; }
    .close-button { background: var(--surface); border: 1px solid var(--border-control); padding: 8px 12px; min-height: 40px; white-space: nowrap; }
    .section-title { font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; margin: 0; }
    .banner { width: 100%; padding: 8px 12px; margin-bottom: 24px; border-left: 4px solid var(--warning); border-radius: 0; color: var(--warning); background: var(--surface); }
    .stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; border: 1px solid var(--border-hairline); }
    .stat { min-width: 0; min-height: 80px; padding: 12px; border-right: 1px solid var(--border-hairline); background: var(--surface); }
    .stat:last-child { border-right: 0; }
    .stat-value { display: block; font-size: 20px; line-height: 24px; font-weight: 600; }
    .stat-label { margin: 4px 0 0; font-size: 11px; line-height: 16px; font-weight: 500; color: var(--text-secondary); }
    .stat-note { margin: 0; font-size: 11px; line-height: 12px; color: var(--text-secondary); }
    .stat-caption { font-size: 11px; line-height: 14px; color: var(--text-secondary); }
    .warning, .uncertainty { color: var(--warning); }
    .uncertainty { font-size: inherit; font-weight: inherit; }
    .section-heading { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 16px; margin-bottom: 8px; }
    .section-heading p { margin: 0; color: var(--text-secondary); font-size: 12px; line-height: 16px; }
    .table-region { width: 100%; max-height: 560px; overflow: auto; border: 1px solid var(--border-hairline); scroll-padding: 40px 8px; }
    table { width: 100%; min-width: 1152px; table-layout: fixed; border-spacing: 0; border-collapse: separate; }
    caption { text-align: left; padding: 12px; color: var(--text-secondary); font-size: 12px; line-height: 16px; background: var(--background); }
    th, td { padding: 4px 8px; height: 40px; border-bottom: 1px solid var(--border-hairline); text-align: left; vertical-align: middle; background: var(--background); }
    thead th { position: sticky; top: 0; z-index: 3; height: 36px; padding: 2px 8px; background: var(--surface); border-bottom: 1px solid var(--border-header); font-size: 12px; font-weight: 600; line-height: 16px; }
    thead th:first-child { z-index: 4; }
    th:first-child { position: sticky; left: 0; z-index: 2; border-right: 1px solid var(--border-hairline); }
    thead th:first-child { z-index: 4; }
    tbody th { font-weight: 400; }
    tbody tr:last-child > * { border-bottom: 0; }
    tbody tr:hover > * { background: var(--surface); }
    tbody tr.is-selected > * { background: var(--surface-raised); }
    tbody tr.is-selected th::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 2px; background: var(--selection-indicator); }
    .numeric { text-align: right; font-weight: 500; }
    thead .numeric { font-weight: 600; }
    .name-col { width: 156px; }
    .lead-col { width: 88px; }
    .week-col { width: 96px; }
    .total-col { width: 88px; }
    .rep-button { display: block; width: 100%; padding: 4px 0; border: 0; background: transparent; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    #rep-table tbody > tr > * { height: 44px; }
    #rep-table .rep-button { padding: 0; }
    .row-note { display: block; min-height: 12px; font-size: 11px; line-height: 12px; color: var(--text-secondary); white-space: nowrap; }
    .cell-note { display: block; font-size: 11px; line-height: 12px; font-weight: 400; color: var(--text-secondary); }
    .trend-arrow { display: inline-block; margin-left: 6px; font-weight: 600; }
    .trend-arrow.trend-up { color: var(--success); }
    .trend-arrow.trend-down { color: var(--danger); }
    .trend-arrow.trend-flat { color: var(--text-secondary); font-weight: 400; }
    td.break-flag { border-left: 2px solid var(--border-strong); }
    .lead { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .lead.unassigned { color: var(--text-muted); }
    .status-label { display: block; font-size: 11px; line-height: 12px; font-weight: 400; color: var(--text-secondary); }
    .status-label.warning { color: var(--warning); }
    .week-col-cell { vertical-align: middle; }
    .week-spark { display: inline-flex; align-items: flex-end; gap: 2px; height: 24px; }
    .week-bar { display: flex; align-items: flex-end; justify-content: center; width: 7px; height: 24px; padding: 0; border: 0; background: transparent; }
    .week-bar-fill { display: block; width: 100%; min-height: 2px; background: var(--text-secondary); }
    .week-bar-fill.is-off-fill { height: 2px !important; background: var(--border-strong); }
    .week-bar-fill.is-partial { border-top: 1px dashed var(--warning); }
    .week-bar:hover .week-bar-fill, .week-bar:focus-visible .week-bar-fill { background: var(--accent); }
    .week-bar.is-unknown { position: relative; }
    .week-bar.is-unknown::after { content: ""; display: block; width: 7px; height: 7px; margin-bottom: 2px; border: 1.5px solid var(--warning); transform: rotate(45deg); background: var(--background); box-sizing: border-box; }
    .data-note { color: var(--text-secondary); font-size: 12px; line-height: 20px; margin: 12px 0 0; }
    .chart-section { margin-top: 24px; }
    .chart-region { overflow-x: auto; border: 1px solid var(--border-hairline); background: var(--background); }
    .hours-chart { width: 100%; max-width: none; height: 248px; }
    svg { display: block; font-family: inherit; }
    svg text { fill: var(--text-secondary); font-size: 11px; }
    .grid-line { stroke: var(--border-hairline); stroke-width: 1; }
    .baseline { stroke: var(--border-control); stroke-width: 1; }
    .bar { fill: var(--border-strong); fill-opacity: .85; }
    /* Item 3: Tier stays the neutral default bar; Ramp is the one other token already in the
       locked palette used chromatically (accent) — position (left/right) carries the same
       distinction redundantly, so colour is never the only encoding. */
    .bar-ramp { fill: var(--accent); fill-opacity: .85; }
    /* Item 1: week-over-week delta bars — colour reinforces the sign the value label already states. */
    .delta-bar.is-up { fill: var(--success); fill-opacity: .85; }
    .delta-bar.is-down { fill: var(--danger); fill-opacity: .85; }
    .delta-bar.is-flat { fill: var(--border-strong); fill-opacity: .85; }
    .rep-series.is-selected .bar { fill: var(--accent); }
    .rep-series.is-selected .rep-label { fill: var(--accent); font-weight: 600; }
    .rep-label { fill: var(--text-primary); font-size: 12px; }
    .chart-hit { fill: transparent; }
    .chart-rep { cursor: pointer; }
    .chart-day { cursor: pointer; }
    .rep-series.chart-day .rep-label { fill: var(--text-secondary); font-weight: 400; }
    .rep-series.chart-day:hover .rep-label, .rep-series.chart-day:focus-visible .rep-label { fill: var(--accent); text-decoration: underline; }
    .chart-day:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
    .missing-marker { fill: var(--background); stroke: var(--warning); stroke-width: 2; }
    .partial-cap { stroke: var(--warning); stroke-width: 2; stroke-dasharray: 2 2; }
    .chart-zero { fill: var(--text-primary); font-weight: 500; }
    .chart-zero, text.chart-status { paint-order: stroke; stroke: var(--background); stroke-width: 3px; stroke-linejoin: round; }
    .chart-status { fill: var(--warning); }
    .limit-ramp { stroke: var(--text-primary); stroke-width: 1.5; stroke-dasharray: 10 5; }
    .limit-tier { stroke: var(--text-secondary); stroke-width: 1.5; stroke-dasharray: 2 3 8 3; }
    .limit-casing { stroke: var(--background); stroke-width: 3; pointer-events: none; }
    .limit-label { fill: var(--text-primary); font-size: 11px; }
    .limit-label-background { fill: var(--background); }
    .legend { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 8px 12px; border-top: 1px solid var(--border-hairline); color: var(--text-secondary); font-size: 12px; line-height: 16px; }
    .legend-item { display: inline-flex; align-items: center; gap: 8px; }
    .legend-bar { display: inline-block; width: 12px; height: 12px; background: var(--border-strong); }
    .legend-bar.selected { background: var(--accent); opacity: .85; }
    .legend-marker { width: 10px; height: 10px; border: 2px solid var(--warning); transform: rotate(45deg); margin: 0 2px; }
    .legend-swatch { display: inline-block; width: 12px; height: 12px; background: var(--border-strong); opacity: .85; }
    .legend-swatch.is-ramp { background: var(--accent); }
    .legend-swatch.is-up { background: var(--success); }
    .legend-swatch.is-down { background: var(--danger); }
    .selection-note { color: var(--text-secondary); font-size: 12px; margin: 12px 0 0; }
    footer { margin-top: auto; padding-top: 16px; border-top: 1px solid var(--border-hairline); }
    footer p { margin: 0 0 8px; color: var(--text-secondary); }
    .meta { color: var(--text-muted); font-size: 11px; line-height: 14px; }
    .empty-state { padding: 32px 16px; text-align: center; border: 1px solid var(--border-hairline); color: var(--text-secondary); }
    .empty-state p { margin: 0 0 8px; }
    a { color: var(--accent); text-underline-offset: 2px; }
    dialog { max-width: 480px; width: calc(100% - 32px); max-height: calc(100% - 48px); padding: 24px; border: 1px solid var(--border-control); border-radius: 2px; background: var(--surface-raised); color: var(--text-primary); }
    dialog::backdrop { background: rgb(0 0 0 / .55); }
    dialog h2 { margin: 0 0 12px; font-size: 16px; line-height: 24px; font-weight: 600; }
    dialog p { margin: 0 0 12px; }
    dialog dl { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; margin: 16px 0 24px; }
    dialog dt { color: var(--text-secondary); overflow-wrap: anywhere; }
    dialog dd { margin: 0; text-align: right; font-weight: 500; }
    .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
    /* The global `table` rule below sets min-width: 1152px so the visible data tables scroll
       horizontally on phone instead of squeezing columns illegibly — but that min-width also wins
       over this table's own width: 1px, forcing the sr-only block-time-range table (day-panel-
       blocks-table) to a 1152px box that, despite being visually clipped, still pushed the whole
       page into horizontal scroll at phone width. Override both so this table actually collapses. */
    table.sr-only { min-width: 0; width: 1px; table-layout: fixed; }
    @media print {
      :root, :root[data-theme="dark"] {
        color-scheme: light;
        --background: #FFFFFF; --surface: #FAFAFA; --surface-raised: #FFFFFF;
        --border-hairline: #E4E4E7; --border-strong: #A1A1AA;
        --text-primary: #18181B; --text-secondary: #52525B; --text-muted: #71717A;
        --accent: #2563EB; --success: #15803D; --warning: #B45309; --danger: #B91C1C;
        --border-control: #71717A;
      }
      @page { size: A4 landscape; margin: 10mm; }
      html, body { height: auto; overflow: visible; }
      .app-shell { display: block; height: auto; }
      .main-scroll { overflow: visible; }
      .sidebar, .range-controls, .back-link { display: none !important; }
      body { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
      main { max-width: none; padding: 0; }
      .theme-toggle, dialog, .screen-help { display: none !important; }
      .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
      .stat, .banner { break-inside: avoid; }
      .stat:nth-child(-n+2) { border-bottom: 0; }
      .stat:not(:last-child) { border-right: 1px solid var(--border-hairline); }
      .table-region { overflow: visible; max-height: none; }
      table { min-width: 0; font-size: 10px; }
      .name-col { width: 13%; } .lead-col { width: 8%; } .week-col { width: 15%; } .total-col { width: 10%; }
      th, td { padding: 4px; }
      thead { display: table-header-group; }
      thead th, th:first-child { position: static; }
      tr { break-inside: avoid; }
      .rep-button, .lead { white-space: normal; overflow: visible; overflow-wrap: anywhere; }
      .status-label { font-size: 9px; }
      .chart-region { overflow: visible; }
      .hours-chart { width: 100%; min-width: 0 !important; max-width: none; height: auto; }
      .missing-marker { stroke: #18181B; fill: #FFFFFF; }
      .legend-marker { border-color: #18181B; }
      .uncertainty, .chart-status { color: #18181B; fill: #18181B; }
      .week-bar.is-unknown::after { border-color: #18181B; background: #FFFFFF; }
      .week-bar-fill, .week-bar-fill.is-off-fill { background: #18181B; }
      .chart-section { break-before: page; }
      footer { margin-top: 16px; }
    }

    .global-bar { position: sticky; top: -20px; z-index: 6; padding: 12px 0; margin: -12px 0 16px; background: var(--background); border-bottom: 1px solid var(--border-hairline); }
    .global-bar .range-note { margin: 8px 0 0; }
    .freshness { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; color: var(--text-secondary); }
    .control, .roster-controls button, input, select { font: inherit; color: var(--text-primary); background: var(--surface-raised); border: 1px solid var(--border-control); border-radius: 0; padding: 4px 8px; min-height: 32px; max-width: 100%; }
    .range-controls button, .range-controls input { border-color: var(--border-control); }
    .stat { text-align: left; border-top: 0; border-bottom: 0; border-left: 0; }
    button.stat:hover { background: var(--surface-raised); }
    button.stat[aria-pressed="true"], .filter-chips button[aria-pressed="true"] { box-shadow: inset 0 -2px var(--accent); }
    .stat-note { display: block; line-height: 16px; margin-top: 4px; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .roster-week { margin-bottom: 16px; }
    #weekly-section { margin: 0 0 12px; }
    .roster-controls, .filter-chips { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
    .roster-controls label { display: flex; align-items: center; gap: 8px; }
    .roster-controls { margin-bottom: 8px; }
    .sort-button { border: 0; background: transparent; padding: 4px 0; width: 100%; text-align: inherit; font-weight: 600; }
    .rep-button, .rank-name { white-space: normal; overflow: visible; overflow-wrap: anywhere; }
    .pagination { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
    .metric-disclosure { max-width: 540px; color: var(--text-secondary); font-size: 12px; }
    .metric-disclosure summary { cursor: pointer; }
    .metric-disclosure p { margin: 8px 0; }
    .rep-cards, .mobile-sort { display: none !important; }
    .skeleton-row { height: 44px; margin-bottom: 1px; background: var(--surface-raised); border: 1px solid var(--border-hairline); }
    .error-state { padding: 24px; border: 1px solid var(--danger); border-left: 4px solid var(--danger); color: var(--danger); background: var(--surface); }
    button:disabled { cursor: default; opacity: .5; }
    @media print {
      /* .global-bar now IS the page header (title + meta line) — keep it, just drop the on-screen-only controls inside it and around the roster. */
      .range-controls, .roster-controls, .pagination, .metric-disclosure { display: none !important; }
      .rep-cards { display: none !important; }
      #reps-page #table-region { display: block !important; }
      #weekly-section { break-before: auto; }
    }
    /* Below 700px the sidebar stops being a fixed column and becomes a top bar (item 1); date
       controls collapse to one preset <select>, the roster becomes cards, and charts shrink
       (item 2). Above 700px nothing in this block applies — the 200px sidebar column is untouched.
       Placed last in the file so it wins ties against the unconditional rules above it (several
       use !important, e.g. the desktop .rep-cards/.mobile-sort hide rule). */
    @media (max-width: 699.98px) {
      .app-shell { grid-template-columns: 1fr; grid-template-rows: 44px minmax(0, 1fr); height: 100dvh; }
      .sidebar { flex-direction: row; align-items: stretch; height: 44px; min-height: 44px; padding: 0 12px; gap: 12px; overflow: visible; border-right: 0; border-bottom: 1px solid var(--border-hairline); }
      /* Both wrapper divs (header, bottom) only exist to group and hairline-separate rows on the
         desktop column layout — on the phone top bar neither introduces a box of its own, so
         their children rejoin the row exactly where they always sat. */
      .sidebar-header { display: contents; }
      .sidebar-bottom { display: contents; }
      .wordmark { height: auto; margin: 0; padding: 0; border-bottom: 0; align-items: center; line-height: 44px; flex-shrink: 0; }
      .sidebar nav { flex: 0 0 auto; display: flex; align-items: stretch; gap: 4px; margin-left: auto; padding: 0; }
      .nav-link { height: 100%; padding: 0 8px; border-left: 0; border-bottom: 2px solid transparent; font-size: 12px; gap: 6px; }
      .nav-link[aria-current="page"] { border-left-color: transparent; border-bottom-color: var(--accent); background: transparent; }
      /* Collapse is a desktop-only concept (item 3) — the toggle has nothing to do on a phone top
         bar, so it does not render there at all. */
      .sidebar-toggle { display: none; }
      .nav-tooltip { display: none; }
      .sidebar .theme-toggle { flex: 0 0 auto; height: 100%; min-height: 44px; margin-top: 0; padding: 0 8px; border: 0; border-left: 1px solid var(--border-hairline); font-size: 12px; }
      /* The 44px top bar has no room for wordmark + nav + email + sign-out + theme, all at once
         (item added with auth). The signed-in email is chrome, not an action — it stays reachable
         to screen readers (same visually-hidden technique as the collapsed-sidebar nav label
         above) but doesn't compete for bar space; Sign out gets the same compact, auto-width,
         bordered treatment as the theme toggle beside it. */
      #account-email { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
      .sidebar #sign-out-button { flex: 0 0 auto; height: 100%; min-height: 44px; margin-top: 0; padding: 0 8px; border: 0; border-left: 1px solid var(--border-hairline); font-size: 12px; }
      main { padding: 16px; }
      .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
      .stat:nth-child(2) { border-right: 0; }
      .stat:nth-child(-n+2) { border-bottom: 1px solid var(--border-hairline); }
      .stat { padding: 10px; }
      .stat-value { font-size: 18px; }
      .rank-list a { grid-template-columns: 72px minmax(20px, 1fr) 48px; gap: 8px; }
      .name-col { width: 144px; }
      .global-bar { position: static; }
      .range-controls { gap: 8px; }
      .range-controls [data-preset] { display: none; }
      .range-controls > label:not(.range-preset-mobile-label) { display: none; }
      .range-controls.is-custom > label:not(.range-preset-mobile-label) { display: flex; }
      .range-controls label, .range-controls input { min-width: 0; max-width: 100%; }
      .range-controls .range-preset-mobile-label { display: flex; align-items: center; width: 100%; }
      .range-preset-mobile-label select { flex: 1; min-height: 44px; }
      .hours-chart { height: 140px; }
      #reps-page #table-region { display: none; }
      .rep-cards { display: grid !important; gap: 8px; }
      .mobile-sort { display: flex !important; }
      .rep-card { display: block; width: 100%; padding: 12px; text-align: left; background: var(--surface); border: 1px solid var(--border-hairline); cursor: pointer; }
      .card-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; margin-bottom: 8px; }
      .card-heading .card-name { display: inline; width: auto; padding: 0; flex: 1 1 auto; min-width: 0; }
      .card-name { font-weight: 600; overflow-wrap: anywhere; }
      .rep-card > .week-spark { display: flex; margin: 8px 0; }
      .card-metrics { display: flex !important; flex-wrap: wrap; gap: 4px 12px; margin: 8px 0 0; }
      .status-chip { display: inline-block !important; border: 1px solid var(--border-strong); padding: 0 4px; font-size: 11px; flex-shrink: 0; }
      .roster-controls input { width: 100%; min-width: 0; }
      .roster-controls label { flex-wrap: wrap; }
    }

    .distribution-region { border: 1px solid var(--border-hairline); }
    #chart { padding: 4px 12px; }
    .distribution-row { display: grid; grid-template-columns: 90px minmax(0, 1fr) 44px; gap: 12px; align-items: center; width: 100%; min-height: 24px; padding: 2px 0; background: transparent; border: 0; text-align: left; }
    button.distribution-row:hover { background: var(--surface); }
    .distribution-track { display: block; height: 16px; background: transparent; }
    .distribution-fill { display: block; height: 100%; background: var(--border-strong); }
    .distribution-boundary { width: 100%; height: 20px; }
    .distribution-boundary text { fill: var(--text-secondary); }
    .distribution-axis { min-height: 20px; font-size: 11px; color: var(--text-secondary); }
    .distribution-ticks { position: relative; height: 20px; }
    .distribution-ticks span { position: absolute; transform: translateX(-50%); }
    @media print { .distribution-region { break-inside: avoid; } }

    .chart-scroll-note { margin: 0; padding: 8px 12px; color: var(--text-secondary); font-size: 11px; line-height: 16px; }

    .rep-series:focus-visible .chart-hit { stroke: var(--accent); stroke-width: 2; }
    @media screen and (max-width: 699.98px) {
      .distribution-row { min-height: 44px; }
      .distribution-axis { min-height: 20px; }
      .roster-toolbar { position: sticky; top: 0; z-index: 5; padding: 8px 0; background: var(--background); border-bottom: 1px solid var(--border-hairline); }
      .roster-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 8px; }
      .roster-controls .search-control, .roster-controls .filter-chips, .roster-controls .crew-rate { grid-column: 1 / -1; }
      .roster-controls .search-control { flex-wrap: nowrap; }
      .roster-controls label, .roster-controls select { min-width: 0; }
      .roster-controls select { width: 100%; }
      .roster-controls input, .roster-controls select, .roster-controls button { min-height: 44px; }
      #rep-search, #mobile-sort, #team-filter { font-size: 16px; }
      #row-count { margin: 0; font-size: 11px; line-height: 16px; }
      #rep-cards { padding-top: 8px; }
      #rep-cards button, #rep-cards a { scroll-margin-top: 340px; scroll-margin-bottom: 12px; }
    }
    @media print {
      .roster-toolbar { position: static; }
    }

    #row-count { margin: 8px 0; }
    .distribution-row[aria-pressed="true"] { box-shadow: inset 2px 0 var(--accent); }
    .chart-region.is-empty { border: 0; }
    .chart-region.is-empty .empty-state { margin: 0; padding: 16px; }

    /* Item 1: exception tiles merged into the filter chips — each chip carries its own count,
       and crew doors/hour survives beside the search box as a small stat (a measurement, not a
       filter). No new colours or sizes: counts inherit the chip's own text colour (never muted,
       per "text-muted never carries data"), the rate value uses the existing 13px/500 tabular
       "cell numerals" role. */
    .chip-count { margin-left: 4px; font-feature-settings: "tnum" 1; }
    .crew-rate { margin: 0; color: var(--text-secondary); font-size: 12px; line-height: 16px; white-space: nowrap; }
    #crew-rate-value { color: var(--text-primary); font-size: 13px; font-weight: 500; margin-left: 4px; }

    /* Item 3: knocking calendar. Weeks as rows, Mon-Sun as columns; flexible 1fr columns so the
       grid never overflows its container (no horizontal page scroll at 390px). Status is carried
       by text/markers, never a per-status background fill, matching "status is colour and text,
       not chrome" (DESIGN.md Avoid list). */
    .calendar-region { border: 1px solid var(--border-hairline); background: var(--background); padding: 8px 12px 12px; overflow-x: auto; }
    .calendar-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
    .calendar-weekday { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-secondary); padding: 4px 6px; }
    .cal-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 44px; min-width: 44px; padding: 6px; border: 1px solid var(--border-hairline); background: var(--surface); text-align: left; position: relative; font: inherit; color: inherit; }
    .cal-cell:hover { background: var(--surface-raised); }
    .cal-cell.is-selected { background: var(--surface-raised); box-shadow: inset 0 0 0 2px var(--accent); }
    .cal-cell.is-out { border-color: transparent; background: transparent; min-height: 44px; }
    .cal-date { font-size: 11px; color: var(--text-secondary); }
    .cal-hours { font-size: 13px; font-weight: 500; }
    .cal-status { display: block; font-size: 10px; line-height: 12px; color: var(--text-secondary); }
    @media (max-width: 699.98px) {
      .calendar-grid { gap: 2px; }
      .cal-cell { padding: 4px; }
      .cal-status { display: none; }
    }
    @media print { .calendar-region { break-inside: avoid; } }

    /* Real 15-minute blocks use neutral/accent intensity; pending review uses amber diamonds. */
    .day-panel-status { color: var(--text-secondary); font-size: 12px; margin: 0 0 12px; }
    .day-panel-status.warning { color: var(--warning); }
    .day-panel-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 12px; margin-bottom: 16px; }
    .day-panel-stat { border: 1px solid var(--border-hairline); background: var(--surface); padding: 8px 12px; }
    .day-panel-stat .stat-value { font-size: 16px; line-height: 20px; }
    /* Doors-knocked list: up to ~70 rows for a single busy day, so it scrolls within its own
       fixed-height frame rather than stretching the page (same pattern as .table-region). Rows
       are a flex line, not a <table> — the global `table` rule forces a 1152px min-width for
       horizontal-scroll data tables, which is wrong for this 3-field list; wrapping text instead
       keeps it usable at 400px with no horizontal scroll. */
    .doors-section { margin-top: 24px; }
    .doors-list { max-height: 320px; overflow-y: auto; border: 1px solid var(--border-hairline); background: var(--background); }
    .doors-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 6px 12px; border-bottom: 1px solid var(--border-hairline); font-size: 13px; line-height: 20px; }
    .doors-row:last-child { border-bottom: 0; }
    .doors-row:hover { background: var(--surface); }
    .doors-time { flex: 0 0 64px; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; color: var(--text-secondary); }
    .doors-address { flex: 1 1 180px; min-width: 0; overflow-wrap: anywhere; }
    .doors-disposition { flex: 0 0 auto; margin-left: auto; text-align: right; color: var(--text-secondary); }
    /* Time axis: block width fills the container at desktop (available width ÷ block count) and
       falls back to a fixed, scrollable px-per-block only when that would be unreadably thin
       (JS). All three rows (door labels, blocks, axis) are flex children of one host sized to
       match, so the axis always scrolls together with the blocks (no separate scroll context).
       24px side padding (TIMELINE_PAD in app.js — keep in sync) insets the strip from the frame;
       edge labels are additionally flipped inward by JS so they never clip past it. */
    .day-panel-blocks { display: flex; flex-direction: column; gap: 4px; padding: 4px 24px; box-sizing: border-box; }
    .tl-markers { position: relative; height: 16px; }
    /* left/transform are set per-label by JS (positionEdgeLabel) so first/last door flip inward
       instead of clipping at either edge. */
    .tl-marker-label { position: absolute; top: 0; font-size: 11px; line-height: 14px; color: var(--text-secondary); white-space: nowrap; }
    .tl-blocks { position: relative; height: 44px; }
    /* First/last door: a rule through the strip, never amber (that's for data uncertainty only). */
    .tl-door-rule { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--text-primary); transform: translateX(-1px); pointer-events: none; z-index: 3; }
    /* The 45-min-plus gap as a region spanning its blocks, inside the strip — neutral grey, never amber. */
    .tl-gap-region { position: absolute; top: 0; bottom: 0; background: color-mix(in srgb, var(--border-strong) 22%, transparent); border-left: 1px solid var(--border-strong); border-right: 1px solid var(--border-strong); z-index: 2; pointer-events: none; display: flex; align-items: flex-start; justify-content: center; }
    .tl-gap-label { margin-top: 2px; padding: 0 4px; font-size: 11px; line-height: 14px; font-weight: 500; color: var(--text-primary); background: var(--background); white-space: nowrap; }
    .block-cell { position: absolute; top: 0; height: 44px; padding: 0; border: 0; background: transparent; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; cursor: default; z-index: 1; }
    /* Counts visible without hovering: a fixed label row above the swatch, so it's never fighting
       the fill colour for contrast. Hidden on non-hour blocks when the strip is this narrow. */
    .block-count { flex: 0 0 16px; display: flex; align-items: flex-start; justify-content: center; padding-top: 2px; font-size: 11px; line-height: 14px; color: var(--text-secondary); }
    /* Intensity ramp: --surface-raised (zero) through --accent (busiest block), set inline per block. */
    .block-swatch { display: block; width: 100%; flex: 1 1 auto; box-sizing: border-box; border: 1px solid var(--border-hairline); }
    .block-cell:hover .block-swatch, .block-cell:focus-visible .block-swatch { border-color: var(--border-control); }
    .block-cell:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
    .block-cell.is-gap .block-swatch { border-style: dashed; }
    .tl-axis { position: relative; height: 24px; border-top: 1px solid var(--border-hairline); }
    /* Mark stays centred on its tick (it's 1px, clipping a fraction of it is never visible); the
       label is a separate element so it can flip inward at either edge without dragging the mark
       off its true position. Both get their `left` (and the label's `transform`) from JS. */
    .tl-tick-mark { position: absolute; top: 0; width: 1px; height: 4px; background: var(--border-control); transform: translateX(-50%); }
    .tl-tick-label { position: absolute; top: 6px; font-size: 11px; line-height: 14px; color: var(--text-secondary); white-space: nowrap; }
    .legend-swatch.is-ramp-min { background: var(--surface-raised); border: 1px solid var(--border-hairline); }
    .footnote { margin: 12px 0 0; color: var(--text-secondary); font-size: 11px; line-height: 16px; }
    @media print {
      .gap-reopen, #day-panel-close { display: none !important; }
    }

    /* Rep surfaces: amber identifies an unfinished hours decision; failed fetches stay neutral. */
    #rep-page .uncertainty, #rep-page .warning, #reps-page .uncertainty, #reps-page .warning { color: var(--text-secondary); }
    #reps-page .week-bar.is-unknown::after { border-color: var(--text-secondary); }
    #rep-page .rep-meta { gap: 8px 16px; margin-bottom: 16px; }
    #rep-page .rep-meta div { gap: 8px; }
    #rep-page .stat { padding: 16px; }
    #rep-page .stat-value { font-size: 24px; line-height: 32px; }
    #rep-page .stat-note { white-space: normal; overflow: visible; }
    #rep-page .stat-label { font-size: 12px; }
    #rep-page .summary { margin-bottom: 24px; }
    #rep-page .chart-section { margin-top: 24px; }
    .calendar-weekday { padding: 4px; }
    .cal-cell { min-width: 0; min-height: 48px; padding: 8px; gap: 4px; }
    .cal-cell.is-empty { background: transparent; border-color: transparent; }
    .cal-cell.is-empty .cal-date { color: var(--text-muted); }
    .cal-cell.is-unknown .cal-hours { color: var(--text-secondary); }
    .cal-cell.has-reviewed::after { content: ""; position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
    .cal-cell.has-pending::after { content: ""; position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border: 1px solid var(--warning); transform: rotate(45deg); }
    #calendar-legend { font-size: 11px; line-height: 16px; }
    #calendar-legend .legend-item { align-items: center; }
    #calendar-legend .legend-marker { flex-shrink: 0; }
    .legend-reviewed-marker { display: inline-block; flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
    #day-panel-section { scroll-margin-top: 16px; }
    #rep-page .day-panel-stat .stat-value { font-size: 13px; line-height: 20px; font-weight: 500; }
    .gap-review { margin: 0 0 24px; padding: 24px; border: 1px solid var(--border-control); background: var(--surface); }
    .gap-review .section-heading { margin-bottom: 8px; }
    #gap-review-state { color: var(--text-secondary); font-size: 12px; }
    #gap-review-state.is-pending { color: var(--warning); }
    .gap-review-context { margin: 0 0 16px; color: var(--text-secondary); max-width: 100%; }
    .gap-reviewer-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding-bottom: 16px; border-bottom: 1px solid var(--border-hairline); }
    .gap-reviewer-row input { min-width: 0; min-height: 48px; }
    #gap-reviewer-note { font-size: 11px; line-height: 16px; color: var(--text-secondary); }
    .gap-card { padding: 24px 0 0; }
    .gap-card + .gap-card { margin-top: 24px; border-top: 1px solid var(--border-control); }
    .gap-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
    .gap-duration { margin: 0; font-size: 24px; line-height: 32px; font-weight: 600; }
    .gap-state { font-size: 12px; color: var(--text-secondary); }
    .gap-boundaries { margin: 4px 0; font-size: 13px; line-height: 20px; font-weight: 500; }
    .gap-evidence { margin: 0 0 16px; color: var(--text-secondary); font-size: 11px; line-height: 16px; }
    .gap-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
    .gap-choice { display: flex; flex-direction: column; align-items: stretch; gap: 8px; min-width: 0; padding: 16px; border: 1px solid var(--border-control); background: var(--background); text-align: left; }
    .gap-choice:hover { background: var(--surface-raised); }
    .gap-choice[aria-pressed="true"] { border-color: var(--accent); outline: 1px solid var(--accent); outline-offset: -2px; }
    .gap-choice:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
    .gap-choice-name { font-size: 13px; line-height: 20px; font-weight: 600; }
    .gap-choice-effect { font-size: 12px; line-height: 16px; color: var(--text-secondary); }
    .gap-choice-totals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--border-hairline); }
    .gap-choice-totals > span { display: flex; flex-direction: column; gap: 4px; }
    .gap-choice-totals strong { font-size: 24px; line-height: 32px; font-weight: 600; }
    .gap-choice-totals > span > span { font-size: 12px; line-height: 16px; color: var(--text-secondary); }
    .gap-choice-action { margin-top: 8px; color: var(--accent); font-size: 12px; line-height: 16px; }
    .gap-audit { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; margin-top: 12px; color: var(--text-secondary); font-size: 12px; line-height: 16px; overflow-wrap: anywhere; }
    .gap-audit p { margin: 0; }
    .gap-reopen { background: none; border: 0; padding: 4px 0; color: var(--text-secondary); text-decoration: underline; min-height: 32px; }
    .is-single-rep .search-control, .is-single-rep .crew-rate, .is-single-rep .filter-chips,
    .is-single-rep .roster-controls > label, .is-single-rep #clear-filters, .is-single-rep #pagination { display: none !important; }
    .is-single-rep .roster-toolbar { position: static; border-bottom: 0; padding: 0; }
    .is-single-rep .roster-controls { display: none; }
    @media (max-width: 699.98px) {
      .calendar-region { padding: 8px; }
      .calendar-grid { gap: 4px; }
      .cal-cell { padding: 4px; }
      .cal-cell.has-pending::after, .cal-cell.has-reviewed::after { top: 4px; right: 4px; width: 8px; height: 8px; }
      .gap-review { padding: 16px; }
      .gap-card.is-decided .gap-reopen { min-height: 40px; }
      .gap-choices { grid-template-columns: minmax(0, 1fr); }
      .gap-reviewer-row input { width: 100%; }
      #rep-page .stat { padding: 12px; }
      #rep-page .day-panel-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    }
    @media print {
      #rep-page .chart-section { break-before: auto; }
      .gap-reviewer-row, .gap-reopen, .gap-choice-action { display: none !important; }
      .gap-card { break-inside: avoid; }
    }

    .reps-view #day-details .warning { color: var(--text-secondary); }
    #reps-page .week-bar.is-unknown::after { content: none; }
    .fetch-failed-mark { color: var(--text-secondary); }
    .gap-history { margin-top: 12px; color: var(--text-secondary); font-size: 12px; line-height: 16px; overflow-wrap: anywhere; }
    .gap-history summary { cursor: pointer; }
    .gap-history ol { margin: 8px 0; padding-left: 24px; }
    .gap-history li + li { margin-top: 4px; }

    /* A resolved question occupies one row; long attribution wraps within the row on phones. */
    .gap-review.is-resolved { padding: 0; border: 0; background: transparent; }
    .gap-card.is-decided { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; min-height: 40px; padding: 4px 12px; border: 1px solid var(--border-hairline); background: var(--surface); }
    .gap-card.is-decided + .gap-card.is-decided { margin-top: 0; border-top: 0; }
    .gap-resolved-summary { min-width: 0; font-size: 12px; line-height: 16px; overflow-wrap: anywhere; }

    /* Reps updates retain their viewport; the footer follows the content rather than the window. */
    .reps-view .main-scroll { overflow-anchor: none; scrollbar-gutter: stable; }
    .reps-view footer { margin-top: 24px; }
    .stat-review-note { display: block; min-height: 16px; }
    #rep-stats .stat-note { min-height: 32px; }
    .refresh-error { color: var(--text-secondary); font-size: 12px; line-height: 16px; }
    .refresh-error p { margin: 0 0 12px; }
    @media (max-width: 699.98px) {
      #rep-stats .stat-note { min-height: 48px; }
    }

    /* The single-rep toolbar is static; its card needs no tall sticky-toolbar focus offset. */
    .is-single-rep #rep-cards button, .is-single-rep #rep-cards a { scroll-margin-top: 12px; }

    /* Sign-in gate. Shown whenever there is no Supabase session; the dashboard itself carries
       the `hidden` attribute in the markup, so nothing behind this can flash before JS runs. */
    .auth-gate { min-height: 100dvh; overflow-y: auto; display: flex; align-items: center; justify-content: center; padding: 24px; background: var(--background); }
    .auth-card { width: 100%; max-width: 360px; padding: 32px 24px; border: 1px solid var(--border-hairline); background: var(--surface-raised); }
    .auth-wordmark { margin: 0 0 24px; font-size: 14px; line-height: 20px; font-weight: 700; letter-spacing: 0.02em; color: var(--text-secondary); }
    .auth-title { margin: 0 0 20px; font-size: 20px; line-height: 28px; font-weight: 600; }
    #auth-form { display: flex; flex-direction: column; gap: 16px; }
    .auth-field { display: flex; flex-direction: column; gap: 6px; font-size: 12px; line-height: 16px; color: var(--text-secondary); }
    .auth-field input { min-height: 40px; font-size: 14px; }
    .auth-error, .auth-notice { margin: 0; font-size: 12px; line-height: 16px; }
    .auth-error { color: var(--warning); }
    .auth-notice { color: var(--text-secondary); }
    .auth-submit { min-height: 40px; border: 1px solid var(--accent); background: var(--accent); color: var(--background); font-weight: 600; }
    .auth-submit:hover, .auth-submit:focus-visible { background: var(--accent); opacity: .9; }
    .auth-submit:disabled { opacity: .6; }
    .auth-switch { margin: 16px 0 0; width: 100%; min-height: 36px; background: none; border: 0; padding: 0; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; font-size: 12px; }
    @media print { .auth-gate { display: none !important; } }

    /* Signed-in email, read-only — not a button, so it never takes the hover fill nav-link/
       theme-toggle get. Reuses .side-item for the shared padding/height grid and .nav-label for
       the existing collapsed-sidebar hide + ellipsis behaviour (see the >=700px block above). */
    .account-item { cursor: default; color: var(--text-secondary); font-size: 12px; }
