/* Yellow Duck, "Sleek" (docs/plans/2026-10-27-ui-sleek-redesign.md).
   Every colour and font on every page comes from the tokens below. Light values sit on :root.
   Dark values are written twice, because CSS cannot share one block between a media query and an
   attribute selector: once for Auto (the OS says dark and nobody forced light) and once for a
   forced Dark from the theme switch. The two dark blocks must stay identical; test:ui-theme
   fails if they drift, and also fails on any colour written outside these blocks. */
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400..700&family=Geist+Mono:wght@400..600&display=swap');

:root {
  --font-ui: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --radius: 12px;
  --radius-sm: 8px;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  /* The initials avatar keeps its per-name hue and takes only its lightness from the theme. */
  --avatar-l: 0.84;

  --bg: oklch(0.985 0.002 270);
  --bg-2: oklch(1 0 0);
  --bg-3: oklch(0.955 0.004 270);
  --fg: oklch(0.21 0.006 270);
  --fg-2: oklch(0.45 0.01 270);
  --fg-3: oklch(0.57 0.01 270);
  --line: oklch(0.91 0.004 270);
  --line-2: oklch(0.83 0.006 270);
  --accent: oklch(0.86 0.16 95);
  --accent-fg: oklch(0.24 0.04 85);
  --accent-ink: oklch(0.55 0.12 80);
  --link: oklch(0.5 0.15 258);
  --on-fill: oklch(0.99 0 0);
  --avatar-ink: oklch(0.25 0.02 270);
  --ok: oklch(0.56 0.14 155);
  --ok-ink: oklch(0.4 0.1 155);
  --ok-bg: oklch(0.965 0.03 155);
  --ok-line: oklch(0.87 0.07 155);
  --warn: oklch(0.63 0.15 65);
  --warn-ink: oklch(0.46 0.11 60);
  --warn-bg: oklch(0.97 0.04 88);
  --warn-line: oklch(0.88 0.1 85);
  --bad: oklch(0.56 0.2 25);
  --bad-ink: oklch(0.44 0.15 25);
  --bad-bg: oklch(0.965 0.02 20);
  --bad-line: oklch(0.87 0.06 20);
  --info: oklch(0.54 0.15 258);
  --info-ink: oklch(0.42 0.13 262);
  --info-bg: oklch(0.965 0.02 255);
  --info-line: oklch(0.87 0.06 255);
  --violet: oklch(0.55 0.17 293);
  --violet-ink: oklch(0.43 0.15 293);
  --violet-bg: oklch(0.965 0.025 300);
  --violet-line: oklch(0.87 0.07 300);
  /* Chart-only hues, for series that need more distinct colours than the five status families. */
  --c-indigo: oklch(0.55 0.2 275);
  --c-cyan: oklch(0.62 0.13 225);
  --c-orange: oklch(0.68 0.18 48);
  --c-teal: oklch(0.66 0.12 185);
  --c-yellow: oklch(0.78 0.15 92);
  --scrim: oklch(0.2 0.01 270 / 0.35);
  --shadow: 0 1px 2px oklch(0.2 0.01 270 / 0.05), 0 6px 20px oklch(0.2 0.01 270 / 0.04);
  --shadow-pop: 0 10px 32px oklch(0.2 0.01 270 / 0.14), 0 2px 6px oklch(0.2 0.01 270 / 0.08);
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --avatar-l: 0.74;
    --bg: oklch(0.15 0.004 270);
    --bg-2: oklch(0.185 0.005 270);
    --bg-3: oklch(0.235 0.006 270);
    --fg: oklch(0.96 0.003 270);
    --fg-2: oklch(0.74 0.008 270);
    --fg-3: oklch(0.6 0.01 270);
    --line: oklch(0.27 0.006 270);
    --line-2: oklch(0.36 0.008 270);
    --accent: oklch(0.87 0.16 95);
    --accent-fg: oklch(0.2 0.03 90);
    --accent-ink: oklch(0.87 0.16 95);
    --link: oklch(0.78 0.11 255);
    --on-fill: oklch(0.17 0.005 270);
    --avatar-ink: oklch(0.2 0.02 270);
    --ok: oklch(0.78 0.15 155);
    --ok-ink: oklch(0.86 0.11 155);
    --ok-bg: oklch(0.25 0.045 155);
    --ok-line: oklch(0.38 0.08 155);
    --warn: oklch(0.82 0.14 75);
    --warn-ink: oklch(0.88 0.11 80);
    --warn-bg: oklch(0.26 0.045 70);
    --warn-line: oklch(0.4 0.08 70);
    --bad: oklch(0.7 0.18 25);
    --bad-ink: oklch(0.84 0.09 25);
    --bad-bg: oklch(0.24 0.045 25);
    --bad-line: oklch(0.4 0.1 25);
    --info: oklch(0.74 0.12 258);
    --info-ink: oklch(0.85 0.08 258);
    --info-bg: oklch(0.25 0.05 260);
    --info-line: oklch(0.4 0.08 260);
    --violet: oklch(0.75 0.13 295);
    --violet-ink: oklch(0.85 0.09 295);
    --violet-bg: oklch(0.26 0.06 295);
    --violet-line: oklch(0.41 0.09 295);
    --c-indigo: oklch(0.7 0.15 275);
    --c-cyan: oklch(0.76 0.11 225);
    --c-orange: oklch(0.76 0.15 50);
    --c-teal: oklch(0.78 0.11 185);
    --c-yellow: oklch(0.85 0.14 95);
    --scrim: oklch(0.05 0.01 270 / 0.6);
    --shadow: inset 0 1px 0 oklch(1 0 0 / 0.04);
    --shadow-pop: 0 12px 36px oklch(0 0 0 / 0.5), inset 0 1px 0 oklch(1 0 0 / 0.06);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --avatar-l: 0.74;
  --bg: oklch(0.15 0.004 270);
  --bg-2: oklch(0.185 0.005 270);
  --bg-3: oklch(0.235 0.006 270);
  --fg: oklch(0.96 0.003 270);
  --fg-2: oklch(0.74 0.008 270);
  --fg-3: oklch(0.6 0.01 270);
  --line: oklch(0.27 0.006 270);
  --line-2: oklch(0.36 0.008 270);
  --accent: oklch(0.87 0.16 95);
  --accent-fg: oklch(0.2 0.03 90);
  --accent-ink: oklch(0.87 0.16 95);
  --link: oklch(0.78 0.11 255);
  --on-fill: oklch(0.17 0.005 270);
  --avatar-ink: oklch(0.2 0.02 270);
  --ok: oklch(0.78 0.15 155);
  --ok-ink: oklch(0.86 0.11 155);
  --ok-bg: oklch(0.25 0.045 155);
  --ok-line: oklch(0.38 0.08 155);
  --warn: oklch(0.82 0.14 75);
  --warn-ink: oklch(0.88 0.11 80);
  --warn-bg: oklch(0.26 0.045 70);
  --warn-line: oklch(0.4 0.08 70);
  --bad: oklch(0.7 0.18 25);
  --bad-ink: oklch(0.84 0.09 25);
  --bad-bg: oklch(0.24 0.045 25);
  --bad-line: oklch(0.4 0.1 25);
  --info: oklch(0.74 0.12 258);
  --info-ink: oklch(0.85 0.08 258);
  --info-bg: oklch(0.25 0.05 260);
  --info-line: oklch(0.4 0.08 260);
  --violet: oklch(0.75 0.13 295);
  --violet-ink: oklch(0.85 0.09 295);
  --violet-bg: oklch(0.26 0.06 295);
  --violet-line: oklch(0.41 0.09 295);
  --c-indigo: oklch(0.7 0.15 275);
  --c-cyan: oklch(0.76 0.11 225);
  --c-orange: oklch(0.76 0.15 50);
  --c-teal: oklch(0.78 0.11 185);
  --c-yellow: oklch(0.85 0.14 95);
  --scrim: oklch(0.05 0.01 270 / 0.6);
  --shadow: inset 0 1px 0 oklch(1 0 0 / 0.04);
  --shadow-pop: 0 12px 36px oklch(0 0 0 / 0.5), inset 0 1px 0 oklch(1 0 0 / 0.06);
  color-scheme: dark;
}

/* ── Base ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
/* clip, not hidden: hidden would turn the page into a scroll container and break sticky headers. */
html, body { overflow-x: clip; }
body {
  margin: 0;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  background: var(--bg); color: var(--fg);
  font-family: var(--font-ui); font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--link); text-underline-offset: 2px; }
h1, h2, h3, h4 { letter-spacing: -0.015em; line-height: 1.25; }
h1 { font-size: 26px; font-weight: 650; margin: 0.25rem 0 0.75rem; text-wrap: balance; }
h2 { font-size: 17px; font-weight: 600; }
h3 { font-size: 14px; font-weight: 600; }
code, kbd, pre, samp, .mono, .tabular { font-family: var(--font-mono); }
code, kbd, samp { font-size: 0.92em; }
.tabular { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
button, input, select, textarea { font: inherit; color: inherit; }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--radius-sm);
}
hr { border: 0; border-top: 1px solid var(--line); }
img { max-width: 100%; }

/* ── Shell: sidebar on wide screens, top bar on phones ───────────────── */
.yd-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.yd-ic {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.yd-sprite .yd-fill { fill: currentColor; stroke: none; }
.yd-app {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px;
  max-width: 1320px; margin-inline: auto; padding-block: 10px 56px;
}
.yd-main { min-width: 0; container-type: inline-size; }
.yd-side {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.yd-brand {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  color: var(--fg); font-weight: 600; font-size: 15px; letter-spacing: -0.01em; text-decoration: none;
}
.yd-brand img { width: 24px; height: 24px; display: block; }
nav.yd-links {
  display: flex; gap: 2px; order: 3; flex: 1 0 100%; min-width: 0;
  overflow-x: auto; scrollbar-width: none; font-size: 14px; color: var(--fg-2);
}
nav.yd-links::-webkit-scrollbar { display: none; }
.yd-link {
  display: inline-flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 10px;
  border-radius: var(--radius-sm); color: var(--fg-2); font-weight: 500; white-space: nowrap;
  text-decoration: none; transition: background-color 120ms, color 120ms;
}
.yd-link .yd-ic { color: var(--fg-3); }
.yd-link:hover { background: var(--bg-3); color: var(--fg); }
.yd-link[aria-current="page"] {
  background: var(--bg-2); color: var(--fg); box-shadow: inset 0 0 0 1px var(--line), var(--shadow);
}
.yd-link[aria-current="page"] .yd-ic { color: var(--accent-ink); }
.yd-me { margin-left: auto; display: flex; align-items: center; gap: 10px; min-width: 0; font-size: 13px; }
.yd-me-name {
  display: inline-flex; align-items: center; gap: 8px; min-width: 0; flex: 0 1 auto;
  color: var(--fg); font-weight: 500; text-decoration: none;
}
.yd-me-name .avatar { flex: none; }
.yd-me-name .avatar { margin: 0; }
.yd-me-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.yd-me-name:hover .yd-me-label { text-decoration: underline; }
.yd-me form { margin: 0; }
.yd-logout {
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--fg-3); font-size: 13px;
}
.yd-logout:hover { color: var(--fg); text-decoration: underline; }
.yd-theme {
  display: inline-flex; gap: 2px; padding: 2px; flex: none;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--bg-2);
}
.yd-theme button {
  display: grid; place-items: center; width: 28px; height: 24px; padding: 0;
  border: 0; border-radius: 6px; background: none; color: var(--fg-3); cursor: pointer;
}
.yd-theme button:hover { color: var(--fg); background: var(--bg-3); }
.yd-theme button[aria-pressed="true"] { background: var(--bg-3); color: var(--fg); }
.yd-theme .yd-ic { width: 14px; height: 14px; }
.yd-top { display: flex; align-items: center; padding-block: 14px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.yd-top + .yd-main { max-width: 1320px; margin-inline: auto; }
/* A phone's top bar keeps the avatar and drops the name, so brand, user and switch fit one row. */
@media (max-width: 520px) {
  .yd-me-label { display: none; }
}
@media (min-width: 860px) {
  .yd-app { grid-template-columns: 216px minmax(0, 1fr); gap: 36px; padding-top: 22px; }
  .yd-side {
    position: sticky; top: 22px; align-self: start; max-height: calc(100vh - 44px); overflow-y: auto;
    flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 2px;
    padding: 0; border-bottom: 0;
  }
  .yd-brand { padding: 2px 10px 16px; }
  nav.yd-links { flex-direction: column; order: 0; flex: none; overflow: visible; }
  .yd-me {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px 10px;
    margin: 18px 0 0; padding: 14px 10px 0; border-top: 1px solid var(--line);
  }
  .yd-me .yd-theme { grid-column: 1 / -1; justify-self: start; }
}

/* ── Audit page ───────────────────────────────────────────────────── */
.audit-counters { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.audit-counter { display: flex; flex-direction: column; }
.audit-counter .cnt { font-size: 1.6rem; font-weight: 700; color: var(--link);
                      font-variant-numeric: tabular-nums; line-height: 1; }
.audit-counter .cnt-label { font-size: 0.75rem; color: var(--fg-2);
                            text-transform: uppercase; letter-spacing: 0.04em;
                            margin-top: 0.15rem; }

.audit-filters-card { padding: 0.65rem 1rem; }
.audit-filters {
  display: grid; gap: 0.6rem 1rem;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  align-items: end;
}
.audit-filters label { display: flex; flex-direction: column; gap: 0.2rem;
                       font-size: 0.78rem; color: var(--fg-2); }
.audit-filters input, .audit-filters select {
  padding: 0.3rem 0.5rem; border: 1px solid var(--line-2); border-radius: 4px;
  font: inherit;
}
.audit-filters .kind-toggle { border: 1px solid var(--line-2); border-radius: 4px;
                              padding: 0.25rem 0.5rem 0.4rem; }
.audit-filters .kind-toggle legend { padding: 0 0.3rem; font-size: 0.7rem;
                                     color: var(--fg-2); text-transform: uppercase;
                                     letter-spacing: 0.04em; }
.audit-filters .kind-toggle label { flex-direction: row; gap: 0.25rem;
                                    font-size: 0.82rem; margin-right: 0.5rem; display: inline-flex; }
.audit-filter-actions { display: flex; gap: 0.5rem; align-items: center; }
.audit-filter-actions button { padding: 0.4rem 0.9rem; background: var(--info);
                               color: var(--on-fill); border: none; border-radius: 4px;
                               cursor: pointer; font-weight: 600; }
.audit-filter-actions .link-reset { font-size: 0.85rem; color: var(--fg-2);
                                    text-decoration: none; }
.audit-filter-actions .link-reset:hover { color: var(--link); text-decoration: underline; }

table.audit-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
table.audit-table th, table.audit-table td { padding: 0.35rem 0.55rem;
                                              border-bottom: 1px solid var(--line);
                                              vertical-align: top; }
table.audit-table th { background: var(--bg-3); text-align: left; font-weight: 500;
                       font-size: 0.75rem; color: var(--fg-2); text-transform: uppercase;
                       letter-spacing: 0.04em; }
table.audit-table .audit-time { font-variant-numeric: tabular-nums;
                                color: var(--fg-2); white-space: nowrap; width: 11rem; }
table.audit-table .audit-method { font-weight: 600; color: var(--ok-ink);
                                  font-size: 0.7rem; padding: 0.05rem 0.3rem;
                                  background: var(--ok-bg); border-radius: 3px;
                                  margin-right: 0.3rem; }
table.audit-table .audit-path { font-family: var(--font-mono); color: var(--fg); }
table.audit-table .audit-status { font-size: 0.7rem; padding: 0.05rem 0.3rem;
                                  border-radius: 3px; margin-left: 0.4rem;
                                  font-variant-numeric: tabular-nums; }
table.audit-table .audit-status.status-2xx { background: var(--ok-bg); color: var(--ok-ink); }
table.audit-table .audit-status.status-3xx { background: var(--info-bg); color: var(--info-ink); }
table.audit-table .audit-status.status-4xx { background: var(--warn-bg); color: var(--warn-ink); }
table.audit-table .audit-status.status-5xx { background: var(--bad-bg); color: var(--bad-ink); }
table.audit-table .audit-status.status-ok        { background: var(--ok-bg); color: var(--ok-ink); }
table.audit-table .audit-status.status-error     { background: var(--bad-bg); color: var(--bad-ink); }
table.audit-table .audit-status.status-paused    { background: var(--warn-bg); color: var(--warn-ink); }
table.audit-table .audit-status.status-maintenance { background: var(--warn-bg); color: var(--warn-ink); }
table.audit-table .audit-meta { font-size: 0.7rem; color: var(--fg-3);
                                margin-left: 0.5rem; font-family: var(--font-mono); }
table.audit-table .audit-ua   { font-size: 0.7rem; color: var(--fg-2);
                                margin-left: 0.5rem;
                                padding: 0.05rem 0.4rem;
                                background: var(--bg-3); border-radius: 3px;
                                cursor: help; }
table.audit-table .audit-subcmd { display: inline-block; padding: 0.05rem 0.4rem;
                                   background: var(--bg-3); border-radius: 3px;
                                   font-size: 0.72rem; color: var(--fg-2);
                                   margin-right: 0.4rem; }
table.audit-table .audit-cmd-text { background: var(--bg-3); padding: 0.05rem 0.3rem;
                                     border-radius: 3px; color: var(--fg); }
table.audit-table .audit-reply { display: inline-block; margin-left: 0.4rem; }
table.audit-table .audit-reply summary { font-size: 0.72rem; color: var(--fg-2); cursor: pointer; }
table.audit-table .audit-reply pre { background: var(--bg-3); padding: 0.4rem 0.6rem;
                                      border-radius: 4px; max-width: 600px;
                                      white-space: pre-wrap; word-break: break-word;
                                      font-size: 0.78rem; color: var(--fg);
                                      margin: 0.25rem 0; }
.audit-flag { display: inline-flex; align-items: center; gap: 0.25rem;
              font-size: 0.78rem; color: var(--fg-2); margin-right: 0.35rem;
              padding: 0.05rem 0.4rem; background: var(--bg-3); border-radius: 999px;
              font-variant-numeric: tabular-nums; }
.audit-exclude-me { display: inline-flex; align-items: center; gap: 0.35rem;
                    font-size: 0.85rem; color: var(--fg-2); cursor: pointer; }
.audit-exclude-me input[type="checkbox"] { margin: 0; }
nav.audit-pager { display: flex; justify-content: space-between; align-items: center;
                  gap: 1rem; padding: 0.6rem 0.2rem 0.2rem; font-size: 0.8rem;
                  color: var(--fg-2); }
nav.audit-pager .audit-pager-info { font-variant-numeric: tabular-nums; }
nav.audit-pager .audit-pager-nav { display: flex; gap: 1rem; }
nav.audit-pager a { color: var(--link); text-decoration: none; }
nav.audit-pager a:hover { text-decoration: underline; }
nav.audit-pager .muted { color: var(--fg-3); }
.kind-chip { font-size: 0.7rem; font-weight: 600; padding: 0.05rem 0.4rem;
             border-radius: 999px; text-transform: uppercase; letter-spacing: 0.03em; }
.kind-chip-visit   { background: var(--info-bg); color: var(--info-ink); }
.kind-chip-command { background: var(--violet-bg); color: var(--violet-ink); }
nav { font-size: 0.875rem; color: var(--fg-2); }
nav button.link { background: none; border: none; color: var(--link); cursor: pointer;
                  font: inherit; padding: 0; }
nav button.link:hover { text-decoration: underline; }
section.role-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
                    padding: 18px 20px; margin: 16px 0; box-shadow: var(--shadow); }
section.role-card h2 { margin: 0 0 0.75rem 0; font-size: 1.125rem; text-transform: uppercase;
                       letter-spacing: 0.05em; color: var(--fg-2); }
table.metric-table { width: 100%; border-collapse: collapse; }
table.metric-table th { text-align: left; padding: 0.25rem 0.5rem 0.25rem 0; font-weight: 500; color: var(--fg); width: 40%; }
table.metric-table td { text-align: right; padding: 0.25rem 0; font-variant-numeric: tabular-nums; }
table.metric-table tr.total { border-top: 1px solid var(--line-2); font-weight: 600; }
table.metric-table tr.total th, table.metric-table tr.total td { padding-top: 0.5rem; }

/* Multi-role matrix variant: column per role + Subtotal, total row at
   the bottom. Used when a user has more than one role in this week. */
table.metric-table.metric-table-multi th,
table.metric-table.metric-table-multi td {
  padding: 0.3rem 0.55rem;
}
table.metric-table.metric-table-multi th { width: auto; }
table.metric-table.metric-table-multi thead th {
  font-weight: 600; font-size: 0.78rem;
  color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.04em;
  border-bottom: 1px solid var(--line);
  text-align: right;
}
table.metric-table.metric-table-multi thead th:first-child { text-align: left; }
.metric-table-multi .metric-col-subtotal { color: var(--fg); }
.metric-table-multi .metric-row-label {
  text-align: left; font-weight: 500; color: var(--fg);
}
.metric-table-multi .metric-num {
  text-align: right; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.metric-table-multi .metric-num-subtotal {
  font-weight: 600; color: var(--fg);
  background: var(--bg-3);
}
.metric-table-multi tfoot th,
.metric-table-multi tfoot td {
  border-top: 1px solid var(--line-2);
  padding-top: 0.5rem; padding-bottom: 0.5rem;
  font-weight: 700;
}
.metric-table-multi .metric-num-grandtotal {
  background: var(--info-bg); color: var(--info-ink); font-size: 1.05rem;
}
.metric-table-multi .metric-role-total {
  display: block; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.metric-table-multi .delta-tiny {
  display: block; font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0;
}
.delta { color: var(--fg-2); font-weight: normal; font-size: 0.875rem; }
.conf { color: var(--fg-2); font-size: 0.875rem; margin: 0.5rem 0 0 0; }
.empty { color: var(--fg-2); font-style: italic; }
.note { color: var(--fg-2); font-size: 0.875rem; }
.error { color: var(--bad); }
table.kv th { text-align: left; padding-right: 1rem; vertical-align: top; color: var(--fg-2); font-weight: 500; }
table.kv td { padding-bottom: 0.25rem; }
blockquote { border-left: 3px solid var(--line-2); margin: 0; padding-left: 1rem; color: var(--fg); }
details summary { cursor: pointer; padding: 0.5rem 0; color: var(--link); }
form.dispute-form { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line-2); }
form.dispute-form textarea { width: 100%; min-height: 5rem; padding: 0.5rem;
                             border: 1px solid var(--line-2); border-radius: 4px;
                             font: inherit; }
form.dispute-form button { padding: 0.5rem 1rem; background: var(--info); color: var(--on-fill);
                           border: none; border-radius: 4px; cursor: pointer; }
.metric-cell { display: inline-block; min-width: 4rem; text-align: right; }
.muted { color: var(--fg-2); }
ul, li { margin: 0.25rem 0; }

/* ── Phase 1+2 — home & user pages ───────────────────────────────────── */
.card { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
        padding: 18px 20px; margin: 16px 0; box-shadow: var(--shadow); }
.card h2 { margin: 0 0 0.75rem 0; font-size: 16px; font-weight: 600; }
.card h3 { margin: 1rem 0 0.5rem 0; font-size: 0.95rem; color: var(--fg-2);
           text-transform: uppercase; letter-spacing: 0.05em; }
nav.week-nav { display: flex; gap: 1rem; align-items: center; margin: 0.5rem 0 1rem 0;
               font-size: 0.95rem; }
nav.week-nav a { color: var(--link); text-decoration: none; }
nav.week-nav a:hover { text-decoration: underline; }

/* aggregates */
dl.totals { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem 1.5rem;
            margin: 0; }
dl.totals dt { color: var(--fg-2); font-size: 0.875rem; }
dl.totals dd { margin: 0 0 0.5rem 0; font-variant-numeric: tabular-nums; font-size: 1rem; }
.delta.up   { color: var(--ok); }
.delta.down { color: var(--bad); }
.delta.flat { color: var(--fg-2); }

/* user list */
ul.user-list { list-style: none; padding: 0; display: grid;
               grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.25rem; }
ul.user-list li { display: flex; gap: 0.5rem; align-items: baseline; }
ul.user-list a { color: var(--link); text-decoration: none; }
ul.user-list a:hover { text-decoration: underline; }
.role { font-size: 0.75rem; color: var(--fg-2); text-transform: lowercase; }

/* PR lists */
ul.pr-list { list-style: none; padding: 0; }
ul.pr-list li { padding: 0.4rem 0; border-bottom: 1px solid var(--line); display: flex;
                gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
ul.pr-list .author { font-size: 0.85rem; color: var(--fg-2); }
ul.pr-list .gh-link { font-size: 0.75rem; color: var(--fg-2); }
ul.pr-list .score { margin-left: auto; font-weight: 600;
                    font-variant-numeric: tabular-nums; }

/* Per-user-page PR list as a proper table so long titles don't push the
 * score onto its own line. Columns: ref · title · state · review · GH · score. */
table.user-pr-table {
  width: 100%; border-collapse: collapse; font-size: 0.9rem;
  margin: 0.25rem 0 0.75rem 0;
}
table.user-pr-table td { padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--line);
                         vertical-align: top; }
table.user-pr-table tr:last-child td { border-bottom: none; }
table.user-pr-table .upr-ref    { width: 10.5rem; white-space: nowrap; }
table.user-pr-table .upr-title  { width: auto; line-height: 1.35; }
table.user-pr-table .upr-state  { width: 4rem; white-space: nowrap; }
table.user-pr-table .upr-review { width: 7rem; white-space: nowrap; }
table.user-pr-table .upr-gh     { width: 1.5rem; text-align: center; }
table.user-pr-table .upr-score  { width: 3.5rem; text-align: right;
                                  font-variant-numeric: tabular-nums; font-weight: 600; }
table.user-pr-table .upr-gh a   { color: var(--fg-2); text-decoration: none; }
table.user-pr-table .upr-gh a:hover { color: var(--link); }
.state { font-size: 0.75rem; padding: 0.1rem 0.4rem; border-radius: 3px;
         text-transform: lowercase; }
.state-open   { background: var(--info-bg); color: var(--link); }
.state-merged { background: var(--warn-bg); color: var(--warn-ink); }
.review-status { font-size: 0.75rem; padding: 0.1rem 0.4rem; border-radius: 3px; }
.review-approved          { background: var(--ok-bg); color: var(--ok-ink); }
.review-changes_requested { background: var(--bad-bg); color: var(--bad-ink); }
.review-reviewed          { background: var(--line); color: var(--fg-2); }
.review-requires_review   { background: var(--warn-bg); color: var(--warn-ink); }

.placeholder { color: var(--fg-2); font-style: italic; }
.admin-block ul { padding-left: 1.25rem; }
.admin-block li { margin: 0.25rem 0; }

/* PR page */
.markdown-body { line-height: 1.5; }
.markdown-body h2 { font-size: 1.1rem; margin: 1rem 0 0.5rem; }
.markdown-body h3 { font-size: 1rem; margin: 0.8rem 0 0.4rem; color: var(--fg); text-transform: none; letter-spacing: normal; }
.markdown-body h4 { font-size: 0.95rem; margin: 0.6rem 0 0.3rem; }
.markdown-body p  { margin: 0.5rem 0; }
.markdown-body ul { padding-left: 1.25rem; margin: 0.4rem 0; }
.markdown-body code { background: var(--bg-3); padding: 0.05rem 0.3rem; border-radius: 3px;
                      font-size: 0.85em; }
.markdown-body pre code { display: block; padding: 0.5rem; overflow-x: auto; }
.markdown-body blockquote { margin: 0.5rem 0; padding-left: 0.75rem; border-left: 3px solid var(--line-2);
                            color: var(--fg-2); }
.markdown-body a { color: var(--link); }

.reviewer-card h3, .author-card h2 { display: flex; gap: 0.5rem; align-items: baseline; }
.action-type { font-size: 0.75rem; padding: 0.1rem 0.4rem; border-radius: 3px;
               background: var(--bg-3); color: var(--fg-2); text-transform: lowercase; }
.evidence-level { font-size: 0.75rem; color: var(--fg-2); text-transform: lowercase; }
.reviewer-card .score, .author-card .score { margin-left: auto; font-variant-numeric: tabular-nums;
                                              font-weight: 700; }

.dispute-block { margin-top: 0.75rem; }
.dispute-block details { background: var(--bg-3); padding: 0.5rem 0.75rem; border-radius: 4px; }
.dispute-block details summary { color: var(--bad); cursor: pointer; }
.dispute-block textarea { width: 100%; min-height: 4rem; padding: 0.5rem;
                          font: inherit; border: 1px solid var(--line-2); border-radius: 4px;
                          margin: 0.5rem 0; }
.dispute-block button { padding: 0.4rem 0.9rem; background: var(--bad); color: var(--on-fill);
                        border: none; border-radius: 4px; cursor: pointer; }
.dispute-list { background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 4px;
                padding: 0.5rem 0.75rem; margin-bottom: 0.5rem; }
.dispute-list h4 { margin: 0 0 0.25rem 0; font-size: 0.85rem; color: var(--warn); }
.dispute-row blockquote { margin: 0.25rem 0; }
.dispute-resolved_no_change   { opacity: 0.7; }
.dispute-resolved_adjusted    { opacity: 0.7; }
.dispute-resolved_excluded    { opacity: 0.7; }
.score-breakdown table { margin-bottom: 1rem; }
.pr-body { padding: 0.5rem 0.75rem; background: var(--bg-3); border-radius: 4px;
           border-left: 3px solid var(--line-2); }

/* Avatars */
.avatar { display: inline-block; width: 24px; height: 24px; border-radius: 50%;
          vertical-align: middle; margin-right: 0.4rem; flex-shrink: 0; }
.avatar-init { line-height: 24px; text-align: center; font-size: 0.7rem;
               font-weight: 700; color: var(--avatar-ink);
               background: oklch(var(--avatar-l) 0.08 var(--h, 270)); }
ul.user-list li, .roster li, .loc-table td:first-child { display: flex; align-items: center; }
.roster li { gap: 0.25rem; }
.loc-table td:first-child .avatar { margin-right: 0.35rem; }

/* Rosters — card style, ranked, nicer typography */
.bot-count { font-size: 0.75rem; color: var(--warn-ink); background: var(--warn-bg);
             padding: 0.05rem 0.35rem; border-radius: 3px; margin-left: 0.4rem;
             white-space: nowrap; }
.note { color: var(--fg-2); font-size: 0.8rem; margin: 0.5rem 0 0 0; }
.small { font-size: 0.8rem; }
.rosters { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.75rem; }
.roster { background: var(--bg-3); border: 1px solid var(--line); border-radius: 8px;
          padding: 0.75rem 0.9rem; }
.roster.wide { grid-column: 1 / -1; background: var(--bg-2); }
.roster h3 { margin: 0 0 0.5rem 0; font-size: 0.9rem; color: var(--fg);
             text-transform: none; letter-spacing: normal;
             border-bottom: 1px solid var(--line); padding-bottom: 0.4rem; }
.roster h3 .muted { color: var(--fg-3); font-weight: normal; }
.roster ol { list-style: none; counter-reset: rank; padding: 0; margin: 0; }
.roster li { counter-increment: rank;
             display: grid; grid-template-columns: 1.5rem auto 1fr auto auto;
             gap: 0.4rem; align-items: center; padding: 0.2rem 0;
             border-bottom: 1px solid var(--line); font-size: 0.9rem; }
.roster li:last-child { border-bottom: none; }
.roster li::before { content: counter(rank); color: var(--fg-3);
                     font-variant-numeric: tabular-nums; font-size: 0.8rem;
                     text-align: right; }
.roster li a { color: var(--fg); text-decoration: none; }
.roster li a:hover { color: var(--link); text-decoration: underline; }
.roster li:nth-child(1) a { font-weight: 700; color: var(--ok); }
.roster li:nth-child(2) a, .roster li:nth-child(3) a { font-weight: 600; }
.roster-n { font-variant-numeric: tabular-nums; font-weight: 700;
            color: var(--fg); min-width: 2.2rem; text-align: right; }

.top-three { background: linear-gradient(135deg, var(--warn-bg) 0%, var(--warn-bg) 100%);
             border: 1px solid var(--warn-line); border-radius: 12px;
             padding: 1rem 1.25rem; margin: 0 0 1rem 0; }
.top-three h3 { margin: 0 0 0.6rem 0; font-size: 0.95rem; color: var(--warn-ink);
                text-transform: uppercase; letter-spacing: 0.04em; }
.top-three ol { list-style: none; padding: 0; margin: 0;
                display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); gap: 0.75rem; }
.top-three li { display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto;
                gap: 0.5rem; align-items: center;
                background: var(--bg-2); border-radius: var(--radius);
                padding: 0.6rem 0.8rem; border: 1px solid var(--warn-line); box-shadow: var(--shadow); }
.top-three .medal { font-size: 1.4rem; line-height: 1; }
.top-three li a { color: var(--fg); text-decoration: none; font-weight: 700; }
.top-three li a:hover { color: var(--link); text-decoration: underline; }
.top-three .total-score { font-variant-numeric: tabular-nums; font-weight: 700;
                          font-size: 1.05rem; color: var(--warn-ink);
                          min-width: 3rem; text-align: right; }
/* Last column on a top-3 row can hold (a) just .total-score, or (b)
 * .total-score + .hours-mult-badge stacked. Make it a flex column either
 * way so the existing 4-col grid is preserved. */
.top-three li { align-items: stretch; box-shadow: var(--shadow); }
.top-three .total-score,
.top-three .hours-mult-badge { grid-column: 4; }
/* .hours-mult-badge is a <button> on every surface — reset native
 * button chrome so it looks like inline muted text, but stays a real
 * click target with keyboard focus. */
.hours-mult-badge {
  background: transparent; border: 0; padding: 0; margin: 0;
  font: inherit; cursor: pointer; color: var(--fg-2);
  font-size: 0.7rem; font-weight: 500;
  font-variant-numeric: tabular-nums; line-height: 1.2;
  text-decoration: underline dotted;
  text-underline-offset: 2px; text-decoration-color: var(--fg-3);
}
.hours-mult-badge:hover { color: var(--fg); text-decoration-color: var(--fg-2); }
.hours-mult-badge:focus-visible {
  outline: 2px solid var(--info); outline-offset: 2px; border-radius: 3px;
}
.top-three .hours-mult-badge { text-align: right; display: block; }
/* Admin team table — small block under the total cell. */
.team-table .total-cell { line-height: 1.2; }
.team-table .total-cell .hours-mult-badge {
  display: block; margin-top: 0.1rem; text-align: right;
}
.top-three .rank-1 { border-color: var(--warn); box-shadow: 0 1px 3px color-mix(in oklch, var(--warn) 20%, transparent); }


/* Penalty roster — red theme, "higher = worse" */
.roster-penalty { background: var(--bad-bg); border-color: var(--bad-line); }
.roster-penalty h3 { color: var(--bad-ink); }
.penalty-n { color: var(--bad) !important; }
@media (max-width: 720px) {
  .top-three ol { grid-template-columns: 1fr; }
}
.loc-table .total { font-variant-numeric: tabular-nums; font-weight: 600; }
.loc-table tr:nth-child(even) td { background: var(--bg-3); }

/* PR section headers + tables */
.pr-section { margin: 1.25rem 0 0.5rem 0; padding: 0.4rem 0.6rem;
              border-radius: 4px; font-size: 1rem; text-transform: none;
              letter-spacing: normal; display: flex; align-items: center;
              gap: 0.4rem; }
.pr-section .dot { width: 10px; height: 10px; border-radius: 50%;
                   display: inline-block; }
.pr-section .muted { color: var(--fg-2); font-weight: normal; font-size: 0.85rem; }
.pr-section-merged    { background: var(--warn-bg); color: var(--warn-ink);
                        border-left: 4px solid var(--warn); }
.pr-section-merged .dot-merged { background: var(--c-yellow); }
.pr-section-open      { background: var(--info-bg); color: var(--link);
                        border-left: 4px solid var(--info); }
.pr-section-open .dot-open { background: var(--info); }
.pr-section-carryover { background: var(--warn-bg); color: var(--warn-ink);
                        border-left: 4px solid var(--warn); }
.pr-section-carryover .dot-carryover { background: var(--c-orange); }

.pr-table { width: 100%; border-collapse: collapse; font-size: 0.9rem;
            margin-bottom: 1rem; }
.pr-table th { padding: 0.3rem 0.5rem; text-align: left;
               border-bottom: 2px solid var(--line-2);
               color: var(--fg-2); font-size: 0.78rem;
               text-transform: uppercase; letter-spacing: 0.05em; }
.pr-table th.num, .pr-table td.num { text-align: right; }
.pr-table td { padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--line); }
.pr-table tr:hover td { background: var(--bg-3); }
.pr-table td.author { font-size: 0.85rem; color: var(--fg-2); }
.pr-table .num { font-variant-numeric: tabular-nums; font-weight: 600; }
.pr-table .gh-link { color: var(--fg-2); text-decoration: none; }
.pr-table .gh-link:hover { color: var(--link); }

/* ── To-Do card ──────────────────────────────────────────────────────── */
.card.todo { padding: 1rem 1.25rem; }
.card.todo h2 { margin: 0 0 0.75rem 0;
                font-size: 1.05rem; letter-spacing: -0.01em;
                display: flex; align-items: baseline; gap: 0.6rem; }
.card.todo h2 .todo-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.6em; padding: 0 0.45em; height: 1.4em;
  border-radius: 6px; background: var(--warn); color: var(--on-fill);
  font-family: var(--font-mono); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.02em; }
.card.todo .empty { color: var(--fg-2); font-size: 0.9rem; font-style: italic; }

.todo-list { list-style: none; margin: 0; padding: 0;
             display: flex; flex-direction: column; gap: 6px; }

/* Each item is a two-row card: title row on top (full width), meta row
   underneath with the urgency badge, reason tags and timing. */
.todo-item { display: block;
             padding: 0.55rem 0.8rem;
             background: var(--bg-2);
             border: 1px solid var(--warn-line);
             border-left-width: 4px;
             border-radius: 6px;
             transition: box-shadow 0.15s, border-color 0.15s; }
.todo-item:hover { box-shadow: var(--shadow);
                   border-color: var(--warn-line); }
/* Urgency lives on the left-border accent. We use a thicker border for
   higher urgency so the column scans top-down without reading any text. */
.todo-item.todo-urgency-overdue { border-left-color: var(--bad); background: var(--bg-3); border-left-width: 6px; }
.todo-item.todo-urgency-urgent  { border-left-color: var(--warn); background: var(--warn-bg); border-left-width: 5px; }
.todo-item.todo-urgency-soon    { border-left-color: var(--warn); border-left-width: 4px; }
.todo-item.todo-urgency-normal  { border-left-color: var(--fg-3); border-left-width: 4px; }
.todo-item.todo-urgency-info    { border-left-color: var(--line-2); border-left-width: 3px;
                                  background: var(--bg-3); }
/* Info-only Todo rows (Bugsy/Sonnet FYI heads-ups): no SLA, no penalty,
   no urgency. Muted card chrome so they read as "nice to know" rather
   than "drop what you're doing". The ℹ️ FYI urgency chip is the only
   signal that this is informational. */
.todo-item.todo-info { border-left-color: var(--info); border-left-width: 3px;
                       background: var(--info-bg); color: var(--fg-2); }
.todo-item.todo-info .todo-title-link { color: var(--fg-2); font-weight: 500; }
.todo-item.todo-info:hover { background: var(--info-bg); }
.urgency.urgency-info { background: var(--info-bg); color: var(--info-ink);
                        border: 1px solid var(--info); }

/* Title row — takes the full card width. Slug + PR title; long titles
   wrap (no ellipsis) so nothing is hidden. */
.todo-title-link { display: flex; align-items: center;
                   gap: 0.5rem; min-width: 0;
                   color: var(--fg); text-decoration: none;
                   font-weight: 600; letter-spacing: -0.005em; }
.todo-title-link:hover .todo-title { color: var(--link); text-decoration: underline; }
.todo-title-link .todo-title { flex: 1 1 auto; min-width: 0;
                               overflow-wrap: anywhere; }

/* ── Source badge ──────────────────────────────────────────────────────
   Two-letter colored pill (GH / YT / SL) at the start of the title row.
   Replaces the previous emoji-only icon. Fixed width so all rows align
   visually when scanning the column. */
.todo-source-badge {
  flex: 0 0 auto;
  display: inline-block;
  min-width: 1.65rem; height: 1.15rem;
  padding: 0 0.35rem;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center; line-height: 1.15rem;
  color: var(--on-fill);
  cursor: help;
  user-select: none;
}
.todo-source-pr    { background: var(--fg); }           /* GitHub slate */
.todo-source-yt    { background: var(--warn); color: var(--fg); }  /* YT amber */
.todo-source-slack { background: var(--violet-ink); }           /* Slack aubergine */
.todo-source-forum { background: var(--c-cyan); }           /* welley forum sky */

/* Meta row — urgency, reason tags, scoring icon, last-activity time.
   `gap` lets it wrap gracefully if a user has many reason tags. */
.todo-meta { margin-top: 0.35rem;
             display: flex; flex-wrap: wrap; align-items: center;
             gap: 0.4rem 0.6rem;
             font-size: 0.78rem; color: var(--fg-2); }
.todo-meta .urgency {
  display: inline-flex; align-items: center; gap: 0.3em;
  padding: 0.18rem 0.5rem; border-radius: 4px;
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.01em; white-space: nowrap;
  font-variant-numeric: tabular-nums;
  cursor: help; }
.urgency.urgency-overdue { background: var(--bad-bg); color: var(--bad-ink); }
.urgency.urgency-urgent  { background: var(--warn-bg); color: var(--warn-ink); }
.urgency.urgency-soon    { background: var(--warn-bg); color: var(--warn-ink); }
.urgency.urgency-normal  { background: var(--bg-3); color: var(--fg-2); }
/* urgency-info defined above near .todo-info for FYI rows */

.todo-meta .chip { cursor: help; }

/* ── Dismiss button (expired-only) ──────────────────────────────────────
   Inline form inside .todo-meta — tucked to the right of the row so it
   doesn't crowd the urgency/reason chips. Subtle by default; firms up
   on hover. Only renders for the viewer's own expired items. */
.todo-meta .todo-dismiss { display: inline-block; margin-left: auto; }
.todo-dismiss-btn {
  appearance: none;
  border: 1px solid var(--line-2);
  background: var(--bg-2);
  color: var(--fg-2);
  padding: 0.18rem 0.6rem;
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.todo-dismiss-btn:hover  { background: var(--bg-3); color: var(--fg); border-color: var(--fg-3); }
.todo-dismiss-btn:active { background: var(--line); }
.todo-dismiss-btn:focus-visible {
  outline: 2px solid var(--info); outline-offset: 1px;
}

/* ── Reason line under the Todo title ──────────────────────────────────
   Shows the deterministic `latest_reason` (or sentence-style `reason`)
   from the obligation row, rendered as a quiet subtitle. Replaces the
   on-demand "Explain" button + modal. */
.todo-reason-line {
  margin: 0.25rem 0 0 2.15rem;   /* indent past the source badge */
  font-size: 0.82rem;
  color: var(--fg-2);
  line-height: 1.35;
}

/* ── Closed-unmerged PRs ────────────────────────────────────────────────
   1) Home page section at the bottom of the PR card. Distinct icon +
      explainer line so the list reads as "didn't ship" rather than
      another flavor of merged.
   2) PR drill-down banner near the top — high-contrast yellow strip so
      the reader can't miss that the PR is closed without merge.
   3) Close-reason chips (abandoned / superseded / rejected /
      solved-elsewhere / other) — color-coded for fast scanning. */

.pr-list-closed-unmerged .pr-section .pr-icon { color: var(--warn); }
.pr-closed-explainer {
  margin: 0.25rem 0 0.5rem 0;
  color: var(--fg-2);
}
.pr-row-closed-unmerged td { color: var(--fg-2); }

.banner-closed-unmerged {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  color: var(--warn-ink);
  padding: 0.55rem 0.8rem;
  border-radius: 6px;
  margin: 0.5rem 0 0.75rem 0;
  font-size: 0.88rem;
}
.banner-closed-unmerged strong { color: var(--bad-ink); }
.banner-closed-unmerged .cu-reason {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  padding: 0.06rem 0.36rem;
  border-radius: 3px;
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  color: var(--warn-ink);
}

.closed-unmerged-note {
  margin: 0.2rem 0 0.4rem 0;
  color: var(--fg-2);
}
.closed-unmerged-note code {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn-line);
  padding: 0.06rem 0.3rem;
  border-radius: 3px;
}
.formula-tile-cu { background: var(--warn-bg) !important; border-color: var(--warn-line) !important; }
.formula-tile-cu .stat-value { color: var(--warn) !important; }

/* Close-reason chips */
.chip.cu-abandoned        { background: var(--bad-bg); color: var(--bad-ink); border-color: var(--bad-line); }
.chip.cu-superseded       { background: var(--info-bg); color: var(--violet-ink); border-color: var(--info-line); }
.chip.cu-rejected         { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.chip.cu-solved-elsewhere { background: var(--ok-bg); color: var(--ok-ink); border-color: var(--ok-line); }
.chip.cu-other            { background: var(--line); color: var(--fg-2); border-color: var(--line-2); }
.chip.cu-unknown          { background: var(--bg-3); color: var(--fg-2); border-color: var(--line); }

/* ── Fast hover tooltip ──────────────────────────────────────────────
   Browser-native title="…" tooltips take ~500ms to appear and ignore
   newlines. We use a custom CSS-only tooltip on elements with
   `data-tip="…"` so it shows on hover with zero delay, preserves
   line breaks (white-space: pre-line), and looks tighter.
   The `pointer-events: none` prevents the tooltip itself from
   triggering its own hover, which would otherwise cause flicker. */
[data-tip] { position: relative; }
[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  z-index: 100;
  background: var(--fg);
  color: var(--on-fill);
  padding: 0.55rem 0.75rem;
  border-radius: 6px;
  font: 500 0.78rem/1.4 var(--font-ui);
  white-space: pre-line;
  max-width: 32rem;
  min-width: 14rem;
  box-shadow: var(--shadow-pop);
  pointer-events: none;
}
/* Tooltip arrow */
[data-tip]:hover::before {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 0.8rem;
  border: 6px solid transparent;
  border-top-color: var(--fg);
  z-index: 101;
  pointer-events: none;
}
/* If the trigger is near the right edge of the Todo card, anchor the
   tooltip to its right edge so it doesn't overflow horizontally. */
.todo-time[data-tip]:hover::after { left: auto; right: 0; }
.todo-time[data-tip]:hover::before { left: auto; right: 0.8rem; }
.todo-time { color: var(--fg-3); font-size: 0.74rem;
             font-family: var(--font-mono);
             font-variant-numeric: tabular-nums;
             margin-left: auto; cursor: help; }
.todo-internal { color: var(--fg-3); font-size: 0.95rem;
                 line-height: 1; text-decoration: none;
                 padding: 0 0.15rem; }
.todo-internal:hover { color: var(--link); }

/* Collapsed "later" group — first 3 visible, the rest fold in here. */
.todo-later { margin-top: 0.85rem; border-top: 1px dashed var(--warn-line); padding-top: 0.75rem; }
.todo-later > summary {
  list-style: none; cursor: pointer; padding: 0.35rem 0.6rem;
  background: var(--warn-bg); border-radius: 6px;
  color: var(--warn-ink); font-size: 0.85rem; font-weight: 500;
  font-family: var(--font-mono);
  user-select: none; }
.todo-later > summary::before { content: '▸ '; transition: transform 0.15s; display: inline-block; }
.todo-later[open] > summary::before { content: '▾ '; }
.todo-later > summary::-webkit-details-marker { display: none; }
.todo-later > .todo-list { margin-top: 0.5rem; }

.chip { display: inline-block; padding: 0.1em 0.55em; border-radius: 999px;
        font-size: 0.72rem; font-weight: 600;
        border: 1px solid transparent; white-space: nowrap; }
.chip-review-req       { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.chip-commented-active { background: var(--info-bg); color: var(--info-ink); border-color: var(--info); }
.chip-approved-active  { background: var(--ok-bg); color: var(--ok-ink); border-color: var(--ok-line); }
.chip-changes-active   { background: var(--bad-bg); color: var(--bad-ink); border-color: var(--bad); }
.chip-changes-pending-author { background: var(--bad-bg); color: var(--bad-ink); border-color: var(--bad); }
.chip-jfyi             { background: var(--bg-3); color: var(--fg-2); border-color: var(--line-2); }
.chip-reason           { background: var(--info-bg); color: var(--violet-ink); border-color: var(--info-line); }
.chip-bugsy            { background: var(--violet-bg); color: var(--bad-ink); border-color: var(--bad-line); }
/* PR risk band chips (elevated bands only — low/medium aren't surfaced). */
.chip.risk-critical    { background: var(--bad); color: var(--on-fill);     border-color: var(--bad); }
.chip.risk-high        { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }

.todo-bugsy-note { margin: 0.4rem 0 0.1rem 1.5rem;
                   font-size: 0.83rem; color: var(--violet-ink);
                   line-height: 1.4; }
.todo-bugsy-note .todo-bugsy-label {
  display: inline-block; padding: 0 0.4em; margin-right: 0.4em;
  background: var(--violet-bg); color: var(--bad-ink); border-radius: 999px;
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.05em; }

.todo-context { margin: 0.5rem 0 0.1rem 1.5rem;
                border-left: 2px solid var(--warn-line); padding-left: 0.6rem; }
.todo-excerpt { font-size: 0.82rem; color: var(--fg-2);
                line-height: 1.4; margin: 0.15rem 0;
                display: grid;
                grid-template-columns: auto auto 1fr auto;
                gap: 0.4rem; align-items: baseline; }
.todo-excerpt .ex-label {
  display: inline-block; padding: 0 0.4em; min-width: 3em;
  background: var(--warn-bg); color: var(--warn-ink); border-radius: 999px;
  font-size: 0.7rem; font-weight: 600; text-align: center;
  text-transform: uppercase; letter-spacing: 0.05em; }
.todo-last .ex-label { background: var(--warn-bg); color: var(--bad-ink); }
.todo-excerpt .ex-author { color: var(--fg); font-weight: 600; }
.todo-excerpt .ex-text   { color: var(--fg-2);
                           overflow: hidden; text-overflow: ellipsis;
                           white-space: nowrap; min-width: 0; }
.todo-excerpt .ex-time   { color: var(--fg-3); font-size: 0.75rem;
                           font-variant-numeric: tabular-nums; }

/* ── Admin dashboard ─────────────────────────────────────────────────── */
.admin-monitor.monitor-fail   { border-left: 4px solid var(--bad); background: var(--bad-bg); }
.admin-monitor.monitor-ok     { border-left: 4px solid var(--ok); }
.admin-monitor.monitor-missing { border-left: 4px solid var(--fg-3); }
.monitor-table .row-fail td { background: var(--bad-bg); }
.monitor-table .row-ok td   { /* default */ }

.chip-ok                 { background: var(--ok-bg); color: var(--ok-ink); }
.chip-fail               { background: var(--bad-bg); color: var(--bad-ink); }
.chip-active             { background: var(--info-bg); color: var(--info-ink); }
.chip-completed          { background: var(--ok-bg); color: var(--ok-ink); }
.chip-running            { background: var(--info-bg); color: var(--info-ink); }
.chip-pending            { background: var(--warn-bg); color: var(--warn-ink); }
.chip-processing         { background: var(--violet-bg); color: var(--violet-ink); }
.chip-failed             { background: var(--bad-bg); color: var(--bad-ink); }
.chip-paused             { background: var(--bg-3); color: var(--fg-2); }
.chip-done               { background: var(--bg-3); color: var(--fg-2); }
.chip-queued             { background: var(--warn-bg); color: var(--warn-ink); }
.chip-open                          { background: var(--warn-bg); color: var(--warn-ink); }
.chip-resolved_no_change            { background: var(--bg-3); color: var(--fg-2); }
.chip-resolved_adjusted             { background: var(--info-bg); color: var(--info-ink); }
.chip-resolved_excluded             { background: var(--violet-bg); color: var(--violet-ink); }

.queue-table .num.bad { color: var(--bad); font-weight: 600; }
.metric-table.compact td, .metric-table.compact th { padding: 0.25rem 0.5rem; }
.metric-table .error-cell { font-size: 0.8rem; color: var(--warn-ink);
                            font-family: var(--font-mono); max-width: 32rem;
                            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.admin-tools { list-style: none; padding: 0; margin: 0; }
.admin-tools li { padding: 0.4rem 0; border-bottom: 1px solid var(--line); }
.admin-tools li:last-child { border-bottom: none; }

/* Filter strip — used on /admin/team and /admin/disputes */
.filter-form { display: flex; flex-wrap: wrap; gap: 0.6rem;
               align-items: center;
               padding: 0.5rem 0.7rem; margin: 0.5rem 0 1rem;
               background: var(--bg-3); border-radius: 8px;
               font-size: 0.9rem; }
.filter-form label { display: inline-flex; align-items: center;
                     gap: 0.2rem; cursor: pointer; }
.filter-form a { color: var(--fg-2); text-decoration: none;
                 padding: 0.15rem 0.5rem; border-radius: 4px; }
.filter-form a.active { background: var(--fg); color: var(--on-fill); }
.filter-form button { background: var(--fg); color: var(--on-fill); border: 0;
                      padding: 0.3rem 0.8rem; border-radius: 4px;
                      cursor: pointer; }

/* Team scores table */
.team-table .rank { width: 2rem; color: var(--fg-2); }
.team-table .total-cell { font-weight: 700; }
.team-table .delta.up   { color: var(--ok); }
.team-table .delta.down { color: var(--bad); }
.team-table .delta.flat { color: var(--fg-3); }
.team-table img.avatar { vertical-align: middle; }

/* Dispute cards */
.dispute-card { border: 1px solid var(--line); border-radius: var(--radius);
                padding: 0.8rem 1rem; margin-bottom: 0.8rem;
                background: var(--bg-2); box-shadow: var(--shadow); }
.dispute-card.dispute-open { border-left: 4px solid var(--warn); }
.dispute-card.dispute-resolved_adjusted { border-left: 4px solid var(--info); }
.dispute-card.dispute-resolved_excluded { border-left: 4px solid var(--violet); }
.dispute-card.dispute-resolved_no_change { border-left: 4px solid var(--fg-3); }
.dispute-head { display: flex; gap: 0.6rem; align-items: center;
                font-size: 0.9rem; margin-bottom: 0.4rem;
                flex-wrap: wrap; }
.dispute-msg { background: var(--bg-3); border-left: 3px solid var(--line-2);
               margin: 0.4rem 0; padding: 0.4rem 0.7rem;
               white-space: pre-wrap; font-size: 0.9rem; }
.dispute-resolution { font-size: 0.85rem; margin-top: 0.4rem;
                      padding-top: 0.4rem; border-top: 1px dashed var(--line); }
.dispute-form fieldset { border: 1px solid var(--line);
                          border-radius: 6px; padding: 0.5rem 0.8rem; }
.dispute-form fieldset legend { font-weight: 600; padding: 0 0.3rem;
                                 color: var(--fg-2); font-size: 0.85rem;
                                 text-transform: uppercase; letter-spacing: 0.05em; }
.dispute-form label { display: inline-flex; align-items: center;
                      gap: 0.25rem; margin-right: 1rem;
                      font-size: 0.9rem; }
.dispute-form label.full { display: block; width: 100%;
                            margin-top: 0.5rem;
                            font-size: 0.85rem; color: var(--fg-2); }
.dispute-form textarea { display: block; width: 100%;
                          padding: 0.4rem; font-size: 0.85rem;
                          border: 1px solid var(--line-2); border-radius: 4px;
                          font-family: inherit; }
.dispute-form input[type=number] { width: 6rem;
                                    padding: 0.15rem 0.3rem;
                                    border: 1px solid var(--line-2);
                                    border-radius: 4px; font-size: 0.85rem; }
.dispute-form button { background: var(--ok); color: var(--on-fill); border: 0;
                       padding: 0.35rem 0.9rem; margin-top: 0.6rem;
                       border-radius: 4px; cursor: pointer;
                       font-weight: 600; }
.dispute-form button:hover { background: var(--ok); }
button.link { background: none; border: 0; color: var(--link); cursor: pointer;
              padding: 0; font-size: inherit; font-family: inherit;
              text-decoration: underline; }
button.link:hover { color: var(--info-ink); }

/* ── Admin nav (tab strip across all admin pages) ────────────────────── */
.admin-nav { display: flex; flex-wrap: wrap; gap: 0;
             position: sticky; top: 0; z-index: 10;
             background: var(--bg-2);
             border-bottom: 1px solid var(--line);
             margin: -1rem -1rem 1.2rem;     /* extends to layout edges */
             padding: 0 1rem; }
.admin-nav a { padding: 0.75rem 1.1rem;
               color: var(--fg-2); font-weight: 500;
               text-decoration: none;
               border-bottom: 2px solid transparent;
               font-size: 0.92rem; }
.admin-nav a:hover { color: var(--fg); background: var(--bg-3); }
.admin-nav a.active { color: var(--fg); font-weight: 600;
                       border-bottom-color: var(--warn); }
.admin-nav-badge {
  display: inline-block; padding: 0 0.4em; margin-left: 0.3em;
  background: var(--bad); color: var(--on-fill); border-radius: 999px;
  font-size: 0.7rem; font-weight: 700; min-width: 1.4em;
  text-align: center; line-height: 1.4em; }

.admin-section-head { display: flex; align-items: center;
                      justify-content: space-between;
                      gap: 1rem; flex-wrap: wrap;
                      margin: 0.5rem 0 1rem; }
.admin-section-head h1 { margin: 0; }
.admin-section-head .week-nav { margin: 0; }

/* Role pill in team table */
.role-tag { display: inline-block; padding: 0.1em 0.55em;
            border-radius: 999px; font-size: 0.75rem;
            font-weight: 600;
            text-transform: uppercase; letter-spacing: 0.04em; }

/* Role filter — pretty radio chips */
.role-filter .filter-label { color: var(--fg-2); font-size: 0.85rem; margin-right: 0.4rem; }
.role-filter label { padding: 0.25rem 0.7rem; border-radius: 999px;
                     border: 1px solid var(--line-2); background: var(--bg-2);
                     color: var(--fg-2); cursor: pointer;
                     transition: background 0.1s; }
.role-filter label:hover { background: var(--bg-3); }
.role-filter label.active { background: var(--fg); color: var(--on-fill);
                             border-color: var(--fg); }
.role-filter input[type=radio] { display: none; }

/* Pill filter (Disputes status switcher) */
.pill-filter { display: flex; gap: 0.4rem; padding: 0; background: none; }
.pill-filter a { padding: 0.3rem 0.8rem; border-radius: 999px;
                 background: var(--bg-3); color: var(--fg-2);
                 font-size: 0.85rem; }
.pill-filter a.active { background: var(--fg); color: var(--on-fill); }

/* Team scores chart */
.chart-card { padding: 1rem; }

/* ── Sticky week-nav ───────────────────────────────────────────────── */
.week-nav-sticky {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 0.75rem;
  margin: 0 -1rem 1rem -1rem;
  padding: 0.45rem 1rem;
  background: color-mix(in oklch, var(--bg) 92%, transparent); backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--line);
}
.week-nav-sticky a { font-size: 0.85rem; color: var(--link); text-decoration: none; }
.week-nav-sticky a:hover { text-decoration: underline; }
.week-nav-sticky .disabled {
  font-size: 0.85rem; color: var(--fg-3); cursor: not-allowed;
  user-select: none;
}
.week-nav-chip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.25rem 0.65rem; border-radius: 999px;
  font: 600 0.85rem/1 var(--font-ui);
  font-variant-numeric: tabular-nums;
}
.week-nav.is-current .week-nav-chip { background: var(--ok-bg); color: var(--ok-ink); }
.week-nav.is-past    .week-nav-chip { background: var(--warn-bg); color: var(--warn-ink); }
.week-nav-badge {
  font-size: 0.7rem; font-weight: 600; padding: 0.05rem 0.4rem; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.week-nav-badge-current { background: var(--ok); color: var(--on-fill); }
.week-nav-badge-past    { background: var(--warn); color: var(--on-fill); }

/* ── Activity history (tabbed stacked-area charts) ─────────────────── */
.activity-history { padding: 0.4rem 0; }
.activity-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 0.5rem;
}
.activity-title { margin: 0; font-size: 1rem; }
.activity-legend { display: flex; gap: 0.9rem; font-size: 0.8rem; color: var(--fg-2); }
.activity-legend .swatch { display: inline-block; width: 14px; height: 10px;
                           border-radius: 2px; vertical-align: middle;
                           margin-right: 0.25rem; }
.activity-legend .swatch-humans { background: var(--info); opacity: 0.7; }
.activity-legend .swatch-bots   { background: var(--warn); opacity: 0.7; }
.activity-tabs {
  display: flex; gap: 0.25rem; flex-wrap: wrap;
  padding: 0.3rem 0; margin-bottom: 0.4rem;
  border-bottom: 1px solid var(--line);
}
.activity-tab {
  background: transparent; border: 1px solid transparent;
  padding: 0.3rem 0.7rem; border-radius: 6px 6px 0 0;
  font: 500 0.85rem/1 var(--font-ui); color: var(--fg-2);
  cursor: pointer;
}
.activity-tab:hover { background: var(--bg-3); color: var(--fg); }
.activity-tab.active {
  background: var(--bg-2); border-color: var(--line); border-bottom-color: var(--bg-2);
  margin-bottom: -1px; color: var(--link); font-weight: 600;
}
.activity-chart { display: none; }
.activity-chart.activity-active { display: block; }
.activity-svg { display: block; }
.activity-svg .axis-label { font: 500 10px/1 var(--font-mono); fill: var(--fg-3); }
.activity-svg .area-point circle { fill: var(--fg-2); transition: r 0.1s; }
.activity-svg .area-point:hover circle { r: 5; cursor: help; }
.activity-svg .area-point-tip {
  font: 600 10px/1 var(--font-mono);
  fill: var(--fg-2);
  paint-order: stroke;
  stroke: var(--bg-2);
  stroke-width: 3;
  stroke-linejoin: round;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.08s;
}
.activity-svg .area-point:hover .area-point-tip { opacity: 1; }
/* Current-week numeric labels parked in the right gutter, one per series. */
.activity-svg .current-label {
  font: 700 12px/1 var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.activity-svg .current-label-humans { fill: var(--info); }
.activity-svg .current-label-bots   { fill: var(--warn); }

/* ── Team members grid ─────────────────────────────────────────────── */
.team-grid {
  display: grid; gap: 0.5rem;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.team-card {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.45rem 0.6rem; background: var(--bg-3);
  border: 1px solid var(--line); border-radius: 8px;
  color: var(--fg); text-decoration: none;
  font-size: 0.85rem;
}
.team-card:hover { background: var(--bg-2); border-color: var(--line-2); }
.team-card .team-card-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.team-card .team-card-role { font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 4px; }
.team-card .team-card-role-icon { font-size: 1rem; line-height: 1; flex-shrink: 0; }

/* ── PR list visual treatment ──────────────────────────────────────── */
.pr-list { margin: 0 0 1rem 0; padding: 0.65rem 0.85rem;
           border: 1px solid var(--line); border-radius: var(--radius);
           background: var(--bg-2); box-shadow: var(--shadow); }
.pr-list .pr-section {
  display: flex; align-items: center; gap: 0.45rem;
  margin: 0 0 0.55rem 0; font-size: 0.95rem;
}
.pr-list .pr-icon { font-size: 1.1rem; }
.pr-list-merged    { background: var(--ok-bg); border-color: var(--ok-line); }
.pr-list-merged .pr-section    { color: var(--ok-ink); }
.pr-list-open      { background: var(--info-bg); border-color: var(--info-line); }
.pr-list-open .pr-section      { color: var(--info-ink); }
.pr-list-carryover { background: var(--warn-bg); border-color: var(--warn-line); }
.pr-list-carryover .pr-section { color: var(--warn-ink); }
.pr-row-bot { opacity: 0.75; }
.bot-badge {
  display: inline-block; margin-left: 0.3rem;
  font-size: 0.7rem; font-weight: 600;
  background: var(--line); color: var(--fg-2);
  padding: 0.05rem 0.4rem; border-radius: 999px;
}
.pr-table .pr-open-for { font-variant-numeric: tabular-nums; color: var(--fg-2); }

/* Sortable table headers */
table.sortable-table th.sortable {
  cursor: pointer; user-select: none;
  position: relative; padding-right: 1.3rem;
  white-space: nowrap;
}
table.sortable-table th.sortable:hover { background: var(--bg-3); }
/* Arrow pinned to the right edge of the cell so it doesn't wrap under
 * the label on narrow columns (e.g. "OPEN", "SCORE"). */
table.sortable-table th.sortable .sort-arrow {
  position: absolute; right: 0.4rem; top: 50%; transform: translateY(-50%);
  font-size: 0.78em; line-height: 1; opacity: 0.35;
  pointer-events: none;
}
table.sortable-table th.sortable .sort-arrow::after { content: '↕'; }
table.sortable-table th.sortable.sorted-asc  .sort-arrow,
table.sortable-table th.sortable.sorted-desc .sort-arrow { opacity: 1; }
table.sortable-table th.sortable.sorted-asc  .sort-arrow::after { content: '↑'; }
table.sortable-table th.sortable.sorted-desc .sort-arrow::after { content: '↓'; }
table.sortable-table th.sortable.sorted-asc,
table.sortable-table th.sortable.sorted-desc { color: var(--link); }
/* Right-align numeric column headers so they line up with the values
 * below, but leave room on the right for the absolutely-positioned arrow. */
table.sortable-table th.sortable.num { text-align: right; padding-right: 1.3rem; }

/* ── PR detail score-context banner ────────────────────────────────── */
.pr-score-context {
  margin: 0.2rem 0 0.75rem 0; padding: 0.55rem 0.8rem;
  border-radius: 8px; font-size: 0.88rem;
}
.pr-score-context-inprog {
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--bad-ink);
}
.pr-score-context-merged {
  background: var(--bg-3); border: 1px solid var(--line); color: var(--fg-2);
}

/* ── PR week nav (prev/next + pip strip) ───────────────────────────── */
.pr-week-nav {
  display: flex; align-items: center; gap: 0.6rem;
  margin: 0.5rem 0 0.85rem 0; padding: 0.45rem 0.6rem;
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 8px;
  font-size: 0.85rem;
}
.pr-week-nav a { color: var(--link); text-decoration: none; }
.pr-week-nav a:hover { text-decoration: underline; }
.pr-week-nav .disabled { color: var(--fg-3); user-select: none; cursor: not-allowed; }
.pr-week-prev { min-width: 12em; }
.pr-week-next { min-width: 12em; text-align: right; }
.pr-week-pips { display: flex; gap: 0.25rem; flex: 1; justify-content: center; }
.pr-week-pips .pip {
  display: inline-block; padding: 0.05rem 0.4rem; border-radius: 999px;
  font-size: 0.9rem; line-height: 1;
  background: var(--bg-2); border: 1px solid var(--line);
}
.pr-week-pips .pip.active { background: var(--warn-bg); border-color: var(--warn-line); }
.pr-week-pips .pip-merge_week { color: var(--ok); }
.pr-week-pips .pip-in_progress_week { color: var(--warn); }

/* ── Score derivation panel ────────────────────────────────────────── */
.score-derive h2 { margin: 0 0 0.25rem 0; font-size: 1rem; }
.score-derive h3 { margin: 0.6rem 0 0.2rem 0; font-size: 0.85rem; color: var(--fg-2); }
.score-derive p { margin: 0 0 0.6rem 0; }
.derive-table { border-collapse: collapse; width: 100%; font-size: 0.85rem;
                font-variant-numeric: tabular-nums; margin-bottom: 0.4rem; }
.derive-table th { text-align: left; color: var(--fg-2); font-weight: 500;
                   padding: 0.25rem 0.5rem; border-bottom: 1px solid var(--line);
                   width: 9rem; }
.derive-table td { padding: 0.25rem 0.5rem; border-bottom: 1px solid var(--line); }
.derive-table tfoot td, .derive-table tfoot th {
  border-top: 1px solid var(--line-2); border-bottom: none;
}
.derive-table .num { text-align: right; }
.derive-table code { background: var(--bg-3); padding: 0.05rem 0.3rem;
                     border-radius: 3px; font-size: 0.78rem; }
.derive-table .derive-final { font-size: 1.05rem; color: var(--ok-ink); }
.derive-prior tbody tr:hover { background: var(--warn-bg); }

/* PR-page repo#n reference (small breadcrumb above the title) */
.pr-ref {
  margin: 0 0 0.1rem 0; font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
.pr-ref a { color: var(--fg-2); text-decoration: none; }
.pr-ref a:hover { color: var(--link); text-decoration: underline; }
/* Reviewer-guide link — accented (not muted) so it reads as an affordance */
.pr-ref .guide-link { color: var(--link); font-weight: 500; }
.pr-ref .guide-link:hover { text-decoration: underline; }

/* PR title — emphasized, on its own line */
h1.pr-title { margin: 0 0 0.45rem 0; line-height: 1.25; }

/* PR-page header meta (by · author score · prompt v…) — readable, not muted-grey */
.pr-meta {
  margin: 0.4rem 0 0.85rem 0; font-size: 0.92rem; color: var(--fg);
}
.pr-meta strong { color: var(--fg); font-weight: 600; }

/* Compact stat-tile breakdown */
.pr-stats h2 { margin: 0 0 0.5rem 0; font-size: 1rem; }
.pr-stats .stat-group { margin: 0.55rem 0; }
.pr-stats .stat-group h4 {
  margin: 0 0 0.25rem 0; font-size: 0.72rem; color: var(--fg-2);
  text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;
}
.pr-stats .stat-row {
  display: grid; gap: 0.4rem;
  grid-template-columns: repeat(auto-fill, minmax(115px, 1fr));
}
.pr-stats .stat-tile {
  display: flex; flex-direction: column; gap: 0.05rem;
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 6px;
  padding: 0.35rem 0.55rem;
}
.pr-stats .stat-tile .stat-label {
  font-size: 0.7rem; color: var(--fg-2); line-height: 1.1;
}
.pr-stats .stat-tile .stat-value {
  font-size: 0.95rem; font-weight: 600; color: var(--fg);
  font-variant-numeric: tabular-nums;
}

/* Formula flow — Opus math as wrapping tile row */
.pr-stats .formula-flow {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.2rem; padding: 0.5rem 0.4rem; margin: 0.25rem 0 0.85rem 0;
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 8px;
}
.pr-stats .formula-flow .stat-tile.formula-tile {
  background: var(--bg-2); padding: 0.2rem 0.35rem;
  min-width: 0; gap: 0;
}
.pr-stats .formula-flow .stat-tile.formula-tile .stat-label {
  font-size: 0.6rem; line-height: 1;
}
.pr-stats .formula-flow .stat-tile.formula-tile .stat-value {
  font-size: 0.85rem; line-height: 1.1;
}
.pr-stats .formula-flow .formula-op {
  font-size: 0.85rem; font-weight: 700; color: var(--fg-2); padding: 0;
}
.pr-stats .formula-flow .formula-paren {
  font-size: 1.4rem; line-height: 0.9; color: var(--fg-3);
  font-weight: 300; padding: 0 0.05rem;
}
.pr-stats .formula-flow .stat-tile.formula-result {
  background: var(--ok-bg); border-color: var(--ok-line);
}
.pr-stats .formula-flow .stat-tile.formula-result .stat-label { color: var(--ok-ink); }
.pr-stats .formula-flow .stat-tile.formula-result .stat-value {
  font-size: 1rem; font-weight: 700; color: var(--ok-ink);
}

.pr-stats .other-details-h { margin: 0.85rem 0 0.4rem 0; font-size: 0.9rem; }

/* Final-score callout */
.score-derive .final-score-line {
  display: flex; align-items: baseline; gap: 0.6rem; margin: 0.25rem 0 0.55rem 0;
}
.score-derive .final-score {
  font-size: 2rem; font-weight: 700; color: var(--ok-ink);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.score-derive .capped-badge {
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; padding: 0.15rem 0.5rem; border-radius: 999px;
  background: var(--warn-bg); color: var(--warn-ink);
}
.score-derive .kind-badge {
  font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; padding: 0.15rem 0.5rem; border-radius: 999px;
}
.score-derive .kind-badge.kind-inprog { background: var(--warn-bg); color: var(--bad-ink); }
.score-derive .kind-badge.kind-merge  { background: var(--ok-bg); color: var(--ok-ink); }

.score-derive-prior { margin-top: 0.6rem; }
/* Truth-up math line (final = opus − prior). Same tile look as the
 * "How the score was built" card so the connection is obvious. */
.score-derive .truth-up-flow {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.35rem; padding: 0.5rem 0.4rem; margin: 0.6rem 0 0 0;
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 8px;
}
.score-derive .truth-up-flow .stat-tile {
  background: var(--bg-2); padding: 0.3rem 0.5rem;
  display: flex; flex-direction: column; gap: 0;
  border: 1px solid var(--line); border-radius: 6px;
}
.score-derive .truth-up-flow .stat-tile .stat-label {
  font-size: 0.65rem; color: var(--fg-2); line-height: 1;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.score-derive .truth-up-flow .stat-tile .stat-value {
  font-size: 0.95rem; font-weight: 600; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.score-derive .truth-up-flow .stat-tile.formula-result {
  background: var(--ok-bg); border-color: var(--ok-line);
}
.score-derive .truth-up-flow .stat-tile.formula-result .stat-label { color: var(--ok-ink); }
.score-derive .truth-up-flow .stat-tile.formula-result .stat-value { color: var(--ok-ink); }
.score-derive .truth-up-flow .formula-op {
  font-size: 1rem; font-weight: 700; color: var(--fg-2);
}

/* Hours-multiplier box inside a .role-card on /reports/user/.../week.
 * Only rendered when the user took PTO / a holiday in the period; styled
 * to match the PR-page "truth-up" tile flow above. */
.role-card .hours-derive { margin: 0.5rem 0 0.4rem 0; }
.role-card .hours-derive .truth-up-flow { margin-top: 0; }
.role-card .hours-derive-note {
  margin: 0.3rem 0 0 0; font-size: 0.8rem; color: var(--fg-2);
}
/* Same tile on /users/:id (homeRouter), shown right below the row of
 * weekly figures. Multi-role users get one tile per role with the
 * role-chip label. */
.hours-derive { margin: 0.6rem 0 0.6rem 0; }
.hours-derive-note {
  margin: 0.3rem 0 0 0; font-size: 0.8rem; color: var(--fg-2);
}
.hours-derive-role {
  display: inline-block; font-size: 0.7rem; color: var(--fg-2);
  background: var(--bg-3); border-radius: 4px; padding: 0.1rem 0.4rem;
  margin: 0 0 0.25rem 0; text-transform: uppercase; letter-spacing: 0.04em;
}

/* Score distribution histogram */
.distribution h2 { margin: 0 0 0.4rem 0; font-size: 1rem; color: var(--fg); }
.dist-stats { font-size: 0.85rem; color: var(--fg-2); margin: 0 0 0.75rem 0;
              display: flex; gap: 0.5rem; flex-wrap: wrap; }
.dist-stats strong { color: var(--fg); font-variant-numeric: tabular-nums; }
.hist-chart { display: block; }
.hist-bar:hover rect { fill: var(--info-ink); cursor: default; }
.hist-count { font-size: 10px; fill: var(--fg-2); font-variant-numeric: tabular-nums; }
.hist-count-inside { fill: var(--on-fill); font-weight: 600; }
.hist-x-label { font-size: 10px; fill: var(--fg-3); font-variant-numeric: tabular-nums; }
.hist-y-label { font-size: 10px; fill: var(--fg-3); font-variant-numeric: tabular-nums; }
.hist-ref-label { font-size: 9px; fill: var(--bad); font-variant-numeric: tabular-nums; }
.chart-wrap { display: flex; flex-direction: column; gap: 0.6rem;
              overflow-x: auto; }
/* ── Log-axis dot plots (logDotPlot.ts) ──────────────────────────────── */
.ldp { display: block; max-width: 100%; height: auto; }
.ldp-grid       { stroke: var(--line); stroke-width: 1; }
.ldp-grid-half  { stroke-dasharray: 2 4; }
.ldp-gutter-rule{ stroke: var(--line); stroke-width: 1; }
.ldp-lead       { stroke: var(--line); stroke-width: 1; }
.ldp-tick       { font-size: 10px; fill: var(--fg-3); font-variant-numeric: tabular-nums;
                  font-family: inherit; }
.ldp-name       { fill: var(--fg-2); font-size: 12px; font-family: inherit; }
.ldp-value      { fill: var(--fg-2); font-size: 11px; font-weight: 600;
                  font-variant-numeric: tabular-nums; font-family: inherit; }
.ldp-median            { stroke: var(--bad); stroke-width: 1.5; }
.ldp-median-label      { font-size: 9px; fill: var(--bad); font-family: inherit;
                         font-variant-numeric: tabular-nums; }
.ldp-median-value      { font-size: 10px; fill: var(--bad); font-family: inherit;
                         font-variant-numeric: tabular-nums; }
.ldp-row        { cursor: pointer; text-decoration: none; }
.ldp-row:hover .ldp-name  { fill: var(--info); text-decoration: underline; }
.ldp-row:hover .ldp-dot   { r: 6; }
.ldp-dot        { transition: r 0.12s; }
a.ldp-row:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

/* Strip variant on /users/:id — peers are deliberately identical grey dots. */
.ldp-peer circle { fill: var(--fg-3); }
.ldp-peer:hover circle { fill: var(--fg-3); }
.ldp-you circle { fill: var(--info); stroke: var(--bg-2); stroke-width: 2; }
.ldp-you-tag    { font-size: 9px; fill: var(--info); font-weight: 700;
                  letter-spacing: 0.08em; text-transform: uppercase;
                  font-family: inherit; }
.ldp-you-value  { font-size: 11px; fill: var(--info); font-weight: 700;
                  font-variant-numeric: tabular-nums; font-family: inherit; }
.standing-strip { overflow-x: auto; }
.chart-axis-note, .standing-axis-note {
  margin: 0.1rem 0 0; font-size: 0.75rem; color: var(--fg-2); line-height: 1.45; }
.chart-axis-note em, .standing-axis-note em { font-style: italic; color: var(--fg); }
.chart-legend { max-width: 100%; height: auto; }
.chart-legend .legend-text { fill: var(--fg-3); font-size: 11px;
                              font-family: inherit; }

/* Better tables in admin */
.table-wrap { overflow-x: auto; }
.metric-table { width: 100%; border-collapse: collapse;
                font-size: 0.9rem; }
.metric-table th { text-align: left; padding: 0.4rem 0.6rem;
                    background: var(--bg-3);
                    border-bottom: 2px solid var(--line);
                    color: var(--fg-2); font-size: 0.78rem;
                    text-transform: uppercase; letter-spacing: 0.05em;
                    font-weight: 600;
                    white-space: nowrap; }
.metric-table th.num, .metric-table td.num {
  text-align: right; font-variant-numeric: tabular-nums; }
.metric-table td { padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--line); }
.metric-table tr:hover td { background: var(--bg-3); }
.metric-table td.muted, .muted { color: var(--fg-3); }
.team-table .user-cell { display: flex; align-items: center; gap: 0.4rem; }
.team-table .total-cell { font-weight: 700; color: var(--fg); }
.team-table .rank { color: var(--fg-3); width: 2rem; font-weight: 500; }

/* Active-set badge */
.active-badge { background: var(--ok-bg); color: var(--ok-ink);
                padding: 0.1em 0.5em; border-radius: 4px;
                font-size: 0.75rem; text-transform: uppercase;
                letter-spacing: 0.05em; }

/* Run drill-down raw json */
.raw-json { background: var(--bg-3); color: var(--fg);
            padding: 0.8rem; border-radius: 6px; overflow-x: auto;
            font-size: 0.78rem; line-height: 1.5; }

.enqueue-form { background: var(--bg-3); }

/* ── To-Do urgency badges ────────────────────────────────────────────── */
.urgency { display: inline-flex; align-items: center;
           gap: 0.25rem; padding: 0.1em 0.55em;
           border-radius: 999px; font-size: 0.78rem;
           font-weight: 600; white-space: nowrap;
           font-variant-numeric: tabular-nums; }
.urgency-overdue { background: var(--bad-bg); color: var(--bad-ink); border: 1px solid var(--bad); }
.urgency-urgent  { background: var(--warn-line); color: var(--bad-ink); border: 1px solid var(--warn-line); }
.urgency-soon    { background: var(--warn-bg); color: var(--warn-ink); border: 1px solid var(--warn-line); }
.urgency-normal  { background: var(--bg-3); color: var(--fg-2); border: 1px solid var(--line); }

/* Make the whole row faintly tinted for the highest-pressure items. */
.todo-item.todo-urgency-overdue { background: var(--bad-bg); }
.todo-item.todo-urgency-overdue:hover { background: var(--bad-bg); }
.todo-item.todo-urgency-urgent  { background: var(--warn-bg); }
.todo-item.todo-urgency-urgent:hover { background: var(--warn-bg); }

/* Grid: badge | primary link | reason | scoring link | time-since */
.todo-head { grid-template-columns: auto 1fr auto auto auto; }

/* ── Block header (shared by source / rank / standing) ──────────────── */
.block-header { margin: -0.15rem 0 0.85rem 0; }
.block-header h2 { margin: 0; font-size: 1.05rem; letter-spacing: -0.005em; }
.block-header .block-sub {
  margin: 0.2rem 0 0;
  font-size: 0.78rem;
  color: var(--fg-2);
  letter-spacing: 0.01em;
}
.block-header .block-sub strong { color: var(--fg); font-weight: 700; }

/* ── Standing chart: stacked bars per peer ───────────────────────────── */
.standing-block .standing-pct-chip {
  display: inline-block; margin-left: 0.5rem;
  padding: 0.1rem 0.45rem;
  background: var(--info);
  color: var(--on-fill);
  font-family: var(--font-mono);
  font-size: 0.7rem; font-weight: 700;
  border-radius: 999px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  vertical-align: 2px;
}

/* ── By-role tabs (multi-role users) ────────────────────────────────── */
.role-tabs-card h2 { margin-bottom: 0.6rem; }
.role-tab-strip {
  display: flex; gap: 0.4rem; border-bottom: 1px solid var(--line);
  margin-bottom: 0.85rem; }
.role-tab {
  background: transparent; border: none; cursor: pointer;
  padding: 0.5rem 0.9rem;
  font: 500 0.9rem/1 var(--font-ui); color: var(--fg-2);
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  text-transform: lowercase;
  display: inline-flex; align-items: baseline; gap: 0.4rem; }
.role-tab:hover { color: var(--fg); }
.role-tab.active {
  color: var(--fg); border-bottom-color: var(--fg); font-weight: 600; }
.role-tab .role-tab-total {
  font-family: var(--font-mono); font-size: 0.78rem;
  color: var(--fg-2); font-variant-numeric: tabular-nums; }
.role-tab.active .role-tab-total { color: var(--fg); }
.role-panel { display: none; }
.role-panel.active { display: block; }
.role-panel .total { font-size: 1.4rem; font-weight: 700;
                     font-variant-numeric: tabular-nums; margin: 0 0 0.6rem 0; }

/* ── Per-user activity tabs (Pull Requests / Reviews / Issues / …) ──── */
.activity-tabs-card h2 { margin-bottom: 0.6rem; }
.activity-tab-strip {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 0.85rem;
}
.activity-tab {
  background: transparent; border: none; cursor: pointer;
  padding: 0.5rem 0.9rem;
  font: 500 0.9rem/1 var(--font-ui); color: var(--fg-2);
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
  display: inline-flex; align-items: baseline; gap: 0.4rem;
}
.activity-tab:hover { color: var(--fg); }
.activity-tab.active {
  color: var(--fg); border-bottom-color: var(--fg); font-weight: 600;
}
.activity-tab-count {
  font-family: var(--font-mono);
  font-size: 0.72rem; font-weight: 700;
  color: var(--fg-2);
  background: var(--bg-3);
  padding: 0.05rem 0.45rem; border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.activity-tab.active .activity-tab-count { color: var(--fg); background: var(--line); }
.activity-panel { display: none; }
.activity-panel.active { display: block; }
.activity-subsection { margin: 0.85rem 0 1.2rem 0; }
.activity-subsection > h3 {
  margin: 0 0 0.4rem 0; font-size: 0.95rem; color: var(--fg);
}
.activity-subsection > h3 .muted { color: var(--fg-2); font-weight: 400; }
.activity-table { width: 100%; border-collapse: collapse;
                  font-size: 0.85rem; }
.activity-table th, .activity-table td {
  text-align: left; padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--line);
}
.activity-table thead th { font-weight: 600; color: var(--fg-2);
                            background: var(--bg-3);
                            font-size: 0.75rem; text-transform: uppercase;
                            letter-spacing: 0.04em; }
.activity-table tr:hover td { background: var(--bg-3); }
.activity-table td a { color: var(--link); }
.activity-table td a:hover { text-decoration: underline; }

/* ── Techy table cells ───────────────────────────────────────────────── */

/* GitHub-style PR cell: small "GH" badge + repo/#number, monospace. */
.gh-pr-cell {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: inherit !important; text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.78rem; font-variant-numeric: tabular-nums;
}
.gh-pr-cell:hover .gh-pr-num { color: var(--link); text-decoration: underline; }
.gh-pr-repo { color: var(--fg-2); }
.gh-pr-num  { color: var(--fg); font-weight: 600; }

/* Title cell: tight cap so the column doesn't reserve a fixed wide
   slice of the table when one row has a long title. CSS table-layout
   constrains the column to fit the wrappers' max-width; the child
   <a> + display:block enables actual ellipsis. */
.activity-title-cell {
  max-width: 22rem;
  overflow: hidden;
}
/* `> a` only. A title is always an <a> or bare inline markup, never a <span>, so the old
   `> span` half matched nothing but the chips beside the title (risk, co-author) and stretched
   them into full-width bars on the personal PR page (GH #245). */
.activity-title-cell > a {
  display: block;
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.activity-table { table-layout: auto; }

/* Score cell: monospace, right-aligned, signed-color. */
.activity-score-cell { text-align: right; font-variant-numeric: tabular-nums; }
.score {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 600; font-size: 0.85rem;
  padding: 0.1rem 0.5rem; border-radius: 4px;
  min-width: 2.4rem;
}
.score-pos  { color: var(--ok-ink); background: var(--ok-bg); }
.score-neg  { color: var(--bad-ink); background: var(--bad-bg); }
.score-zero { color: var(--fg-2); background: var(--bg-3); }
.score-na   { color: var(--fg-3); background: transparent; }

/* Relative-time chip: subtle, hover reveals the absolute timestamp. */
.ago {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.76rem; color: var(--fg-2);
  padding: 0.1rem 0.4rem; border-radius: 3px;
  background: var(--bg-3);
  white-space: nowrap; cursor: help;
}

/* PR state chips — colored by lifecycle position. */
.pr-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem; font-weight: 600;
  padding: 0.1rem 0.5rem; border-radius: 999px;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  white-space: nowrap;     /* keep "✓ merged" on one line */
  line-height: 1.3;
}
.pr-chip-open               { background: var(--info-bg); color: var(--info-ink); border-color: var(--info-line); }
.pr-chip-merged             { background: var(--violet-bg); color: var(--violet-ink); border-color: var(--violet); }
.pr-chip-closed             { background: var(--bg-3); color: var(--fg-2); border-color: var(--line-2); }
.pr-chip-requested          { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.pr-chip-commented          { background: var(--info-bg); color: var(--info-ink); border-color: var(--info); }
.pr-chip-approved           { background: var(--ok-bg); color: var(--ok-ink); border-color: var(--ok-line); }
.pr-chip-changes_requested  { background: var(--bad-bg); color: var(--bad-ink); border-color: var(--bad); }
.pr-chip-draft              { background: var(--bg-3); color: var(--fg-2); border-color: var(--line-2); }

/* Generic monospace number cell. */
.num-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* TestRail event-type pill in the panel header. */
.event-type-pill {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.78rem; font-weight: 700;
  padding: 0.15rem 0.55rem; border-radius: 3px;
  background: var(--fg); color: var(--on-fill);
  letter-spacing: 0.02em;
}
.activity-explainer { margin: 0 0 0.4rem 0; }

/* Figma badge — purple "F" pill matching the source-badge family. */
.figma-badge { background: var(--violet); color: var(--on-fill); }

/* Stage transition cell: from-state → to-state with mono font. */
.stage-transition {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
}
.stage-from { color: var(--fg-2); padding: 0.1rem 0.4rem;
              background: var(--bg-3); border-radius: 3px; }
.stage-to   { color: var(--fg); padding: 0.1rem 0.4rem;
              background: var(--line); border-radius: 3px; font-weight: 600; }
.stage-arrow { color: var(--fg-3); }
/* Contributing-type chips (e.g. "state", "qa-verified") in the
   Counted-as column. */
.stage-type-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem; font-weight: 600;
  padding: 0.05rem 0.4rem; border-radius: 3px;
  background: var(--info-bg); color: var(--violet-ink);
  letter-spacing: 0.02em;
  margin-right: 0.15rem;
}
/* Penalty pill: red palette to distinguish from positive stage-action pills. */
.penalty-pill {
  display: inline-block; font-size: 0.78rem; font-weight: 600;
  padding: 0.15rem 0.55rem; border-radius: 999px;
  background: var(--bad-bg); color: var(--bad-ink); cursor: help;
  letter-spacing: -0.005em;
}

/* Multi-contributor PR label, shown inline next to the PR title on the
   user "PRs authored & merged" tab. Tooltip lists the other humans plus
   their share. Neutral palette so it doesn't read as alert/error. */
.co-contrib-badge {
  display: inline-block;
  margin-left: 0.4rem;
  font-size: 0.72rem; font-weight: 600;
  padding: 0.1rem 0.5rem; border-radius: 999px;
  background: var(--info-bg); color: var(--violet-ink); cursor: help;
  vertical-align: middle;
  letter-spacing: -0.005em;
}
.penalty-pill.penalty-responsiveness_breach          { background: var(--bad-line); color: var(--bad-ink); }
.penalty-pill.penalty-mention_unacknowledged         { background: var(--warn-line); color: var(--bad-ink); }
.penalty-pill.penalty-youtrack_qa_regression_missed  { background: var(--bad-line); color: var(--bad-ink); }
.penalty-pill.penalty-youtrack_qa_regression_penalty { background: var(--bad-bg); color: var(--bad-ink); }
.penalty-pill.penalty-sentry_issue_stagnated_penalty { background: var(--warn-bg); color: var(--bad-ink); }
.penalty-rationale-cell { color: var(--fg-2); font-size: 0.85rem; max-width: 28rem; }
.penalty-rationale-primary    { color: var(--fg-2); }
.penalty-obligation-reason    { margin-top: 0.15rem; line-height: 1.3; }
.penalty-obligation-reason::before { content: ''; }

.penalty-score-cell     { color: var(--bad); font-weight: 600; }

/* Stage-action pill: the human-readable label for a synthetic stage
   action (dev_completed_feature → "Completed (ready for QA)").
   Color-coded by category so the column reads at a glance. */
.stage-action-pill {
  display: inline-block; font-size: 0.78rem; font-weight: 600;
  padding: 0.15rem 0.55rem; border-radius: 999px;
  background: var(--info-bg); color: var(--violet-ink); cursor: help;
  letter-spacing: -0.005em;
}
/* Dev: blue */
.stage-action-pill.stage-action-dev_completed_feature  { background: var(--info-bg); color: var(--info-ink); }
.stage-action-pill.stage-action-dev_started_work       { background: var(--info-bg); color: var(--info-ink); }
/* QA positive: green */
.stage-action-pill.stage-action-qa_verified            { background: var(--ok-bg); color: var(--ok-ink); }
.stage-action-pill.stage-action-qa_closed_invalid      { background: var(--ok-bg); color: var(--ok-ink); }
/* QA negative-ish (kicked back / escalated / regression): amber/red */
.stage-action-pill.stage-action-qa_kicked_back         { background: var(--warn-bg); color: var(--warn-ink); }
.stage-action-pill.stage-action-qa_escalated_design    { background: var(--warn-bg); color: var(--warn-ink); }
.stage-action-pill.stage-action-qa_regression_missed   { background: var(--bad-bg); color: var(--bad-ink); }
/* Designer: purple */
.stage-action-pill.stage-action-design_started         { background: var(--violet-bg); color: var(--violet-ink); }
.stage-action-pill.stage-action-design_completed       { background: var(--violet-line); color: var(--violet-ink); }
.stage-action-pill.stage-action-design_prepped_for_dev { background: var(--violet-line); color: var(--violet-ink); }
.stage-action-pill.stage-action-design_verified        { background: var(--info-line); color: var(--violet-ink); }
.stage-action-pill.stage-action-design_kicked_back     { background: var(--warn-bg); color: var(--warn-ink); }
/* PM: teal */
.stage-action-pill.stage-action-pm_triaged             { background: var(--info-bg); color: var(--info-ink); }
.stage-action-pill.stage-action-pm_approved_design     { background: var(--info-line); color: var(--info-ink); }
.stage-action-pill.stage-action-pm_handed_off_to_dev   { background: var(--info-bg); color: var(--info-ink); }

/* Activity-tab strip — give each tab a faint icon-ish vibe via spacing
   and a thin underline only on hover. */
.activity-panel { padding-top: 0.3rem; }
.activity-panels { min-height: 6rem; }

/* Slight upgrade to header tabs: rounded count chips, monospace counts. */
.activity-tab-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* Activity tables inside the per-role tab. */
.role-activity-h { font-size: 0.9rem; color: var(--fg-2);
                   text-transform: uppercase; letter-spacing: 0.05em;
                   margin: 1.1rem 0 0.5rem 0; }
.role-activity-table { width: 100%; border-collapse: collapse;
                       font-size: 0.88rem; margin-bottom: 0.5rem; }
.role-activity-table th { text-align: left; padding: 0.3rem 0.55rem;
                          border-bottom: 2px solid var(--line);
                          color: var(--fg-2); font-size: 0.78rem;
                          text-transform: uppercase; letter-spacing: 0.05em; }
.role-activity-table th.num { text-align: right; }
.role-activity-table td { padding: 0.35rem 0.55rem;
                          border-bottom: 1px solid var(--line);
                          vertical-align: top; }
.role-activity-table td.num { text-align: right;
                              font-variant-numeric: tabular-nums; font-weight: 500; }
.role-activity-table td.num.up   { color: var(--ok); }
.role-activity-table td.num.down { color: var(--bad); }
.role-activity-table td.num.flat { color: var(--fg-2); }
.role-activity-table td.excerpt { color: var(--fg-2); max-width: 28rem;
                                  overflow: hidden; text-overflow: ellipsis;
                                  white-space: nowrap; }
.role-activity-table tr:hover td { background: var(--bg-3); }
.role-activity-table code { background: var(--bg-3); padding: 0.05rem 0.3rem;
                            border-radius: 3px; font: 500 0.78rem/1 var(--font-mono); }

/* ── Help icon + static popup ───────────────────────────────────────── */
.help-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-left: 0.35rem; padding: 0;
  border-radius: 50%; border: 1px solid var(--line-2); background: var(--bg-3);
  color: var(--fg-2); font: 600 0.65rem/1 var(--font-ui);
  cursor: pointer; vertical-align: middle;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.help-icon:hover { background: var(--fg); color: var(--on-fill); border-color: var(--fg); }
.help-icon:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

.help-popup {
  position: absolute; z-index: 1000;
  background: var(--bg-2); color: var(--fg);
  border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: var(--shadow-pop);
  font: 400 0.85rem/1.5 var(--font-ui);
  max-height: 70vh; overflow: auto;
}
.help-popup header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.65rem 0.9rem; border-bottom: 1px solid var(--line);
  background: var(--bg-3); border-radius: 10px 10px 0 0;
}
.help-popup h3 { margin: 0; font-size: 0.95rem; }
.help-popup .help-close {
  background: transparent; border: none; cursor: pointer;
  font-size: 1.2rem; line-height: 1; color: var(--fg-2); padding: 0 0.25rem;
}
.help-popup .help-close:hover { color: var(--fg); }
.help-popup .help-body { padding: 0.75rem 0.9rem; }
.help-popup .help-body p  { margin: 0.4rem 0; }
.help-popup .help-body ul { margin: 0.35rem 0 0.5rem 1.1rem; padding: 0; }
.help-popup .help-body li { margin: 0.15rem 0; }
.help-popup .help-body code {
  background: var(--bg-3); padding: 0.05rem 0.3rem; border-radius: 3px;
  font: 500 0.78rem/1 var(--font-mono);
}
.help-popup .help-body table.help-table {
  border-collapse: collapse; margin: 0.25rem 0 0.6rem 0;
  font-size: 0.78rem; font-variant-numeric: tabular-nums;
}
.help-popup .help-body table.help-table th,
.help-popup .help-body table.help-table td {
  border: 1px solid var(--line); padding: 0.15rem 0.5rem; text-align: left;
}
.help-popup .help-body table.help-table th { background: var(--bg-3); color: var(--fg); }
.help-popup .help-body .hint {
  margin-top: 0.7rem; padding: 0.5rem 0.7rem;
  background: var(--warn-bg); border-left: 3px solid var(--warn);
  border-radius: 0 4px 4px 0;
  font-style: italic; color: var(--warn-ink);
}

/* ── Explain dialog (Opus-generated personalised explanation) ───────── */
.explain-btn {
  display: inline-flex; align-items: center; gap: 0.35rem;
  background: var(--bg-2); border: 1px solid var(--line-2);
  color: var(--fg); font: 500 0.78rem/1 var(--font-ui);
  padding: 0.42rem 0.7rem; border-radius: 6px; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
.explain-btn .explain-btn-icon {
  font-family: var(--font-mono);
  font-size: 0.85rem; line-height: 1;
  color: var(--link); transition: transform 0.18s;
}
.explain-btn:hover { background: var(--fg); color: var(--on-fill); border-color: var(--fg); }
.explain-btn:hover .explain-btn-icon { color: var(--warn); transform: translate(2px, -2px); }
.explain-btn:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

.explain-overlay {
  position: fixed; inset: 0; z-index: 2000;
  background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
}
.explain-dialog {
  background: var(--bg-2); border-radius: 12px;
  width: 100%; max-width: 560px; max-height: 80vh;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-pop);
  font: 400 0.92rem/1.55 var(--font-ui);
}
.explain-dialog header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.85rem 1.1rem; border-bottom: 1px solid var(--line);
}
.explain-dialog h3 { margin: 0; font-size: 1.05rem; }
.explain-dialog .explain-close {
  background: transparent; border: none; cursor: pointer;
  font-size: 1.4rem; line-height: 1; color: var(--fg-2); padding: 0 0.25rem;
}
.explain-dialog .explain-close:hover { color: var(--fg); }
.explain-body { padding: 1rem 1.1rem; overflow: auto; }
.explain-pending { display: flex; flex-direction: column; align-items: center;
                   gap: 0.7rem; padding: 1.5rem 0; text-align: center; }
.spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--line); border-top-color: var(--info);
  border-radius: 50%; animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.explain-md h2 { font-size: 1rem; margin: 0.7rem 0 0.4rem; }
.explain-md p { margin: 0.45rem 0; }
.explain-md ul { padding-left: 1.25rem; margin: 0.35rem 0; }
.explain-md li { margin: 0.15rem 0; }
.explain-md code {
  background: var(--bg-3); padding: 0.05rem 0.3rem; border-radius: 3px;
  font: 500 0.85rem/1 var(--font-mono);
}
.explain-md strong { font-weight: 600; }
.explain-stamp { margin-top: 0.75rem; }
.explain-error { color: var(--bad); }
.explain-error code { background: var(--bad-bg); color: var(--bad-ink); }

/* Category colors — shared between standing legend + segments. */
.seg-delivery       { background: var(--info); }
.seg-quality        { background: var(--ok); }
.seg-collaboration  { background: var(--violet); }
.seg-responsiveness { background: var(--bad); }
.seg-hygiene        { background: var(--fg-3); }

/* Distribution sparkline — refined: light field, faint baseline rule,
 * a thicker highlight for the viewer. */
.dist-bar {
  position: relative;
  display: inline-flex; align-items: flex-end;
  gap: 1px; height: 32px; width: 100%;
  min-width: 8rem; max-width: 24rem;
  padding: 3px 3px 5px 3px;
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: 5px;
  box-sizing: border-box;
}
.dist-bar .dist-axis-base {
  position: absolute; left: 3px; right: 3px; bottom: 3px;
  height: 1px; background: var(--line);
}
.dist-tick {
  position: relative;
  flex: 1 1 0; min-width: 2px;
  display: block;
  background: var(--line);
  border-radius: 1px 1px 0 0;
  transition: background 0.15s, transform 0.15s;
}
.dist-tick.neg { background: var(--bad-line); }
.dist-tick.you {
  background: var(--fg);
  box-shadow: 0 0 0 1px var(--fg);
  z-index: 1;
}
.dist-tick.you::after {
  content: '';
  position: absolute; left: 50%; top: -7px;
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--fg);
}
.dist-tick.you.neg { background: var(--bad); box-shadow: 0 0 0 1px var(--bad); }
.dist-tick.you.neg::after { border-top-color: var(--bad); }
.dist-tick:hover { filter: brightness(1.15); transform: translateY(-1px); }

/* Weekly review cards */
.card.review { background: var(--bg-2); border-left: 4px solid var(--violet); }
.card.review-team { background: var(--info-bg); border-left-color: var(--violet-ink); }
.card.review-private { background: var(--bad-bg); border-left-color: var(--bad); }
.card.review-missing { background: var(--bg-3); border-left-color: var(--line-2); }
.card.review-error { background: var(--bad-bg); border-left-color: var(--bad); }
.card.review-pending,
.card.review-generating { background: var(--warn-bg); border-left-color: var(--warn); }
.card.review-skipped { background: var(--bg-3); border-left-color: var(--fg-3); }

.review-header { display: flex; align-items: baseline; gap: 0.75rem;
                 flex-wrap: wrap; }
.review-header h2 { flex: 1 1 auto; margin: 0; }
.review-meta { color: var(--fg-2); font-size: 0.75rem; font-family: var(--font-mono); }
.review-note { color: var(--fg-2); font-style: italic; margin: 0.5rem 0; }
.review-body { line-height: 1.55; }
.review-body h2 { margin: 1rem 0 0.4rem 0; font-size: 1rem; color: var(--violet-ink); }
.review-body h3 { margin: 0.8rem 0 0.3rem 0; font-size: 0.9rem; }
.review-body ul { margin: 0.4rem 0 0.6rem 1.2rem; }
.review-body li { margin: 0.2rem 0; }
.review-regen-btn { font-size: 0.75rem; padding: 0.2em 0.6em;
                    background: var(--line); border: 1px solid var(--line-2);
                    border-radius: 4px; cursor: pointer; }
.review-regen-btn:hover { background: var(--line); }

/* Collapsible review variant — used by the team-review banner.
   The clamped body is the <summary> (always visible). Click anywhere
   in it to expand; native <details> handles the rest. We hide the
   expanded copy when closed and the clamped copy when open. */
.review-collapsible .review-collapse { /* container */ }
.review-collapsible .review-collapse summary { list-style: none; cursor: pointer; }
.review-collapsible .review-collapse summary::-webkit-details-marker { display: none; }
.review-collapsible .review-body-clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  position: relative;
  mask-image: linear-gradient(to bottom, var(--fg) 70%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, var(--fg) 70%, transparent 100%);
}
.review-collapse-toggle {
  display: inline-block; margin-top: 0.4rem;
  color: var(--violet-ink); font-weight: 600; font-size: 0.85rem;
  cursor: pointer;
}
.review-collapse-toggle:hover { text-decoration: underline; }
.review-collapsible details[open] .review-body-clamp,
.review-collapsible details[open] .review-collapse-show     { display: none; }
.review-collapsible details:not([open]) .review-body-expanded,
.review-collapsible details:not([open]) .review-collapse-hide { display: none; }

/* ── Team obligations chart ───────────────────────────────────────────
   One horizontal bar per source (GH / YT / Slack), segments by urgency.
   Bar widths are scaled to the row with the largest total so the chart
   reads at-a-glance; segment widths inside each bar are proportional. */
.oblig-chart-card { background: var(--bg-2); }
.oblig-chart-card h2 { display: flex; align-items: baseline; gap: 0.5rem; }
.oblig-total-pill {
  display: inline-block; font-family: var(--font-mono);
  font-size: 0.75rem; font-weight: 700;
  padding: 0.1rem 0.55rem; border-radius: 999px;
  background: var(--bg-3); color: var(--fg-2);
}
.oblig-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 0.4rem 0 0.75rem 0;
                font-size: 0.8rem; color: var(--fg-2); }
.oblig-legend-item { display: inline-flex; align-items: center; gap: 0.3rem; }
.oblig-legend-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.oblig-rows { display: flex; flex-direction: column; gap: 0.5rem; }
.oblig-row { display: grid; grid-template-columns: 6rem 1fr 3rem;
             align-items: center; gap: 0.6rem; }
.oblig-label { font-weight: 600; color: var(--fg); font-size: 0.9rem; }
.oblig-total { font-family: var(--font-mono);
               text-align: right; color: var(--fg-2); font-size: 0.85rem;
               font-variant-numeric: tabular-nums; }
.oblig-bar { display: flex; height: 1.1rem; min-height: 1.1rem;
             border-radius: 3px; overflow: hidden;
             background: var(--bg-3); }
.oblig-seg { display: inline-block; height: 100%; cursor: help; }
.oblig-seg-overdue { background: var(--bad); }
.oblig-seg-urgent  { background: var(--c-orange); }
.oblig-seg-soon    { background: var(--c-yellow); }
.oblig-seg-normal  { background: var(--fg-3); }
.oblig-seg-info    { background: var(--line); }
.oblig-legend-swatch.oblig-seg-overdue { background: var(--bad); }
.oblig-legend-swatch.oblig-seg-urgent  { background: var(--c-orange); }
.oblig-legend-swatch.oblig-seg-soon    { background: var(--c-yellow); }
.oblig-legend-swatch.oblig-seg-normal  { background: var(--fg-3); }
.oblig-legend-swatch.oblig-seg-info    { background: var(--line); }

/* Admin reviews index */
.admin-table .chip-public  { background: var(--info-bg); color: var(--violet-ink); }
.admin-table .chip-private { background: var(--bad-bg); color: var(--bad-ink); }
.admin-table .chip-team    { background: var(--ok-bg); color: var(--ok-ink); }
.admin-table .status-ready      { color: var(--ok-ink); font-weight: 600; }
.admin-table .status-pending    { color: var(--warn-ink); }
.admin-table .status-generating { color: var(--warn-ink); font-style: italic; }
.admin-table .status-skipped    { color: var(--fg-2); }
.admin-table .status-error      { color: var(--bad-ink); font-weight: 600; }

/* ── Slack thread page ───────────────────────────────────────────── */
.slack-thread-header h1 { font-size: 1.05rem; margin: 0 0 0.2rem 0; }
.slack-thread-meta { color: var(--fg-2); font-size: 0.75rem; margin: 0 0 0.8rem 0; }
.slack-thread-meta .mono { font-family: var(--font-mono); }
.slack-thread-meta a { color: var(--link); text-decoration: none; }
.slack-thread-meta a:hover { text-decoration: underline; }
.slack-thread-messages { display: flex; flex-direction: column; gap: 0.6rem; }
.slack-msg { display: grid; grid-template-columns: 36px 1fr; gap: 0.6rem;
             padding: 0.4rem 0.4rem; border-radius: 6px; }
.slack-msg-root { background: var(--bg-3); }
.slack-msg-reply { padding-left: 0.4rem; border-left: 2px solid var(--line);
                   margin-left: 0.5rem; }
.slack-msg-gutter .avatar-sm { width: 30px; height: 30px; }
.slack-msg-meta { display: flex; gap: 0.5rem; align-items: baseline;
                  margin-bottom: 0.15rem; }
.slack-msg-author { font-weight: 600; color: var(--fg); text-decoration: none; }
.slack-msg-author:hover { text-decoration: underline; }
.slack-msg-time { color: var(--fg-3); font-size: 0.72rem;
                  font-family: var(--font-mono); }
.slack-edited { color: var(--fg-3); font-size: 0.7rem; font-style: italic;
                margin-left: 0.3rem; cursor: help; }
.slack-msg-text { color: var(--fg); font-size: 0.92rem; line-height: 1.45;
                  word-wrap: break-word; }
.slack-msg-text code { background: var(--line); padding: 0.05em 0.3em;
                       border-radius: 3px; font-size: 0.85em; }
.slack-msg-text pre.slack-code { background: var(--bg-3); color: var(--fg);
                                  padding: 0.6rem 0.8rem; border-radius: 6px;
                                  overflow-x: auto; font-size: 0.85rem; }
.slack-msg-text .slack-broadcast { background: var(--warn-bg); color: var(--warn-ink);
                                    padding: 0 0.3em; border-radius: 3px;
                                    font-weight: 500; }

.slack-reply-form { margin-top: 1rem; padding: 0.6rem;
                    background: var(--warn-bg); border: 1px solid var(--warn);
                    border-radius: 6px; }
.slack-reply-label { display: block; font-weight: 600; font-size: 0.85rem;
                     color: var(--warn-ink); margin-bottom: 0.3rem; }
.slack-reply-form textarea { width: 100%; box-sizing: border-box;
                             padding: 0.4rem 0.6rem;
                             border: 1px solid var(--line-2); border-radius: 4px;
                             font-family: var(--font-ui); font-size: 0.9rem; }
.slack-reply-foot { display: flex; justify-content: space-between;
                    align-items: center; margin-top: 0.4rem; gap: 0.6rem;
                    flex-wrap: wrap; }
.slack-reply-note { color: var(--warn-ink); font-size: 0.78rem; margin: 0;
                    max-width: 600px; }
.slack-reply-note code { background: var(--warn-bg); padding: 0 0.3em;
                         border-radius: 3px; font-size: 0.85em; }
.slack-reply-form button { padding: 0.4rem 1.2rem; background: var(--warn);
                            color: var(--on-fill); border: none; border-radius: 4px;
                            cursor: pointer; font-weight: 600; }
.slack-reply-form button:hover { background: var(--warn-ink); }

/* Anchored message highlight — when a link points to /slack/.../#msg-...,
 * the browser scrolls to the article. :target adds a subtle pulse so
 * users can see WHICH message the link was pointing at. */
.slack-msg:target {
  background: var(--warn-bg);
  box-shadow: 0 0 0 2px var(--warn);
  scroll-margin-top: 1rem;
  animation: slack-msg-flash 1.5s ease-out;
}
@keyframes slack-msg-flash {
  0%   { background: var(--warn-line); }
  100% { background: var(--warn-bg); }
}

/* Team-standing chart — opaque bar for peers (privacy: don't leak the
 * category breakdown of other team members; only the page subject's bar
 * shows colored segments). Neutral light-slate that is distinct from
 * hygiene (#94a3b8) so the eye doesn't read "everyone is all-hygiene".
 */
.bar-chart.stacked .seg.seg-opaque { background: var(--line); }
.bar-chart.stacked .seg.seg-opaque.seg-neg { background: var(--bad-line); }
/* New 4-bucket labels used by the standing legend (Shipping / Craft /
 * Teamwork = collaboration + hygiene / Follow-up). */
.legend-swatch.seg-shipping  { background: var(--info); }
.legend-swatch.seg-craft     { background: var(--ok); }
.legend-swatch.seg-teamwork  { background: var(--violet); }
.legend-swatch.seg-followup  { background: var(--bad); }
.seg.seg-shipping            { background: var(--info); }
.seg.seg-craft               { background: var(--ok); }
.seg.seg-teamwork            { background: var(--violet); }
.seg.seg-followup            { background: var(--bad); }

/* ── DM Insights calendar ──────────────────────────────────────────────
 * Month heat-grid. Without these rules the day number and session count
 * collapse together (e.g. day 4 with 17 sessions renders as "417"). */
.cal-head { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; }
.cal-head strong { font-size: 1rem; }
.cal-nav { text-decoration: none; font-size: 1.25rem; line-height: 1; color: var(--link);
           padding: 0 0.45rem; border-radius: 4px; }
.cal-nav:hover { background: var(--info-bg); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { text-align: center; font-size: 0.7rem; font-weight: 600; color: var(--fg-3);
           text-transform: uppercase; letter-spacing: 0.03em; padding-bottom: 2px; }
.cal-cell { position: relative; min-height: 46px; border: 1px solid var(--line);
            border-radius: 6px; display: flex; align-items: center; justify-content: center;
            text-decoration: none; color: inherit; padding: 2px; box-sizing: border-box; }
.cal-cell.cal-empty { border: none; background: transparent; min-height: 0; }
/* sessions present: small day number in the corner, big count centered */
.cal-cell .cal-day { position: absolute; top: 3px; left: 5px; font-size: 0.65rem;
                     color: var(--fg-3); line-height: 1; }
.cal-cell .cal-count { font-size: 1.05rem; font-weight: 700; color: var(--info-ink); }
.cal-cell.cal-has .cal-day { color: var(--info-ink); }
a.cal-cell.cal-has:hover { outline: 2px solid var(--info); outline-offset: -2px; }
/* no sessions: just the day number, centered and muted (overrides the corner rule) */
.cal-cell:not(.cal-has):not(.cal-empty) .cal-day { position: static; font-size: 0.85rem;
                                                   color: var(--fg-3); }

/* ── Jobs page (GH #185) ───────────────────────────────────────────────── */
.jobs-banner { border-left: 4px solid var(--warn); background: var(--warn-bg); }
/* A subscription seat that needs a person. Red, because the warn banner reads as information. */
.jobs-banner.jobs-alert { border-left-color: var(--bad); background: var(--bad-bg); color: var(--bad-ink); }
.jobs-alert ul { margin: 0.3rem 0 0; padding-left: 1.2rem; }
.jobs-elapsed { font-variant-numeric: tabular-nums; white-space: nowrap; }
.chip-blocked { background: var(--line); color: var(--fg-2); }
.jobs-stale { background: var(--bad-bg); color: var(--bad-ink); border: 1px solid var(--bad);
  border-radius: 6px; padding: 0.6rem 0.9rem; margin: 0 0 1rem; font-weight: 600; }

/* ---- /jobs: host resources, liveness signal, tokens (GH #191) ----------------
   One line, above the board. Tiles here cost the board its first screen, so this stays a strip:
   row-wrapping is allowed on a phone, but nothing in it may grow taller than a line of text. */
.jobs-stats { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
              padding: 6px 10px; font-size: 12px; }
.jobs-tokens { display: contents; }
.jobs-stat { display: inline-flex; align-items: baseline; gap: 5px; white-space: nowrap;
             border-radius: 5px; padding: 1px 4px; }
.jobs-stat-l { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-2); }
.jobs-stat-v { font-weight: 650; font-variant-numeric: tabular-nums; }
.jobs-stat.warn { background: var(--warn-bg); }
.jobs-stat.warn .jobs-stat-v { color: var(--warn); }
/* An unmounted data volume is a durability failure, not a warning. */
.jobs-stat.alarm { background: var(--bad-bg); }
.jobs-stat.alarm .jobs-stat-v { color: var(--bad); }
.jobs-stat-when { margin-left: auto; font-variant-numeric: tabular-nums; }
/* Claude subscription seats: one square per account. Colour is AVAILABILITY, not quota: there is
   no remaining-quota API for a Max subscription (see subSeats.ts). */
.jobs-seats { display: inline-flex; gap: 3px; align-items: center; }
.jobs-seat { width: 9px; height: 9px; border-radius: 2px; display: inline-block;
             border: 1px solid color-mix(in oklch, var(--fg) 18%, transparent); }
.jobs-seat-ok       { background: var(--ok); }   /* usable now */
.jobs-seat-soon     { background: var(--warn); }   /* resets within 30 min */
.jobs-seat-cooling  { background: var(--bad); }   /* out of quota, longer to wait */
.jobs-seat-disabled { background: var(--bad-ink); }   /* credential rejected, needs a re-mint */

/* Subscription quota row (GH #217): pool chip + twin bars per seat. */
.jobs-quota { padding: 6px 10px; margin-top: -4px; font-size: 12px; }
/* The head wraps so that at phone width the note drops to a new line instead of running off screen. */
.jobs-quota-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 3px; }
.jobs-quota-chip { font-weight: 700; font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
                   padding: 1px 7px; border-radius: 3px; white-space: nowrap; }
.jobs-quota-chip.healthy    { background: var(--ok-bg); color: var(--ok-ink); }
.jobs-quota-chip.tight      { background: var(--warn-bg); color: var(--warn-ink); }
.jobs-quota-chip.near-limit { background: var(--warn-bg); color: var(--warn-ink); }
.jobs-quota-chip.critical   { background: var(--bad-bg); color: var(--bad-ink); }
.jobs-quota-chip.unknown    { background: var(--bg-3); color: var(--fg-2); }
.jobs-quota-chip.degraded   { background: var(--warn-bg); color: var(--warn-ink); }
.jobs-quota-chip.off        { background: var(--bg-3); color: var(--fg-2); }
.jobs-quota-note { font-size: 11px; }
.jobs-quota-row { display: flex; align-items: baseline; gap: 12px; white-space: nowrap;
                  font-variant-numeric: tabular-nums; line-height: 1.5; }
.jobs-quota-seat { width: 46px; color: var(--fg-2); }
.jobs-quota-win { display: inline-flex; align-items: baseline; gap: 5px; }
/* GH #220: live agents holding the seat. One width for every row so the bars stay column-aligned.
 * `min-width`, never `width`, and it must clear the WIDEST content (8 dots + ellipsis + the count):
 * at 92px a busy seat printed "12 agents" straight over the 7d bar. A fixed width overlaps when the
 * content outgrows it; a floor pushes that one row's bars right instead, which is ugly but legible.
 * `space-between` parks the count against the bars, so counts line up even though dot runs differ. */
.jobs-quota-use { display: inline-flex; align-items: baseline; justify-content: space-between;
                  gap: 5px; min-width: 140px; flex: none; font-size: 11px; }
.jobs-quota-use.idle, .jobs-quota-use.unknown { color: var(--fg-3); }
/* A seat that is disabled or rejecting its login (alarm), or cooling off (warn). */
.jobs-quota-use.alarm { color: var(--bad); font-weight: 700; }
.jobs-quota-use.warn  { color: var(--warn-ink); }
.jobs-quota-dots { color: var(--ok); letter-spacing: -1px; font-size: 9px; }
.jobs-quota-agents { font-weight: 600; }
.jobs-quota-l { font-size: 10px; color: var(--fg-3); width: 16px; }

/* Model inventory (GH #261 follow-up): which model runs what, so "should we bump X" has an answer on the
 * page instead of in a grep. Its own block rather than reusing .jobs-quota-row, because that row is
 * `nowrap` for bar alignment and these descriptions have to wrap. */
.jobs-models { padding: 6px 10px; font-size: 12px; }
/* A disclosure: the head opens it. A flex summary loses the native marker, so the caret is drawn here. */
.jobs-models > summary { cursor: pointer; list-style: none; user-select: none; }
.jobs-models > summary::-webkit-details-marker { display: none; }
.jobs-models > summary::before { content: '\25B8'; color: var(--fg-2); width: 0.8em; }
.jobs-models[open] > summary::before { content: '\25BE'; }
.jobs-models:not([open]) > summary { margin-bottom: 0; }
.jobs-models-row { display: flex; gap: 10px; align-items: baseline; line-height: 1.55;
                   padding: 2px 0; border-top: 1px solid var(--line); }
.jobs-models-row:first-of-type { border-top: 0; }
.jobs-models-id { font-weight: 600; min-width: 190px; flex: none; font-variant-numeric: tabular-nums; }
.jobs-models-id .jobs-models-prov { font-weight: 400; font-size: 10px; color: var(--fg-3);
                                    text-transform: uppercase; letter-spacing: .05em; margin-left: 6px; }
.jobs-models-uses { display: flex; flex-direction: column; gap: 1px; }
.jobs-models-use { white-space: normal; }
.jobs-models-comp { color: var(--fg-2); font-weight: 600; }
.jobs-models-effort { font-size: 10px; color: var(--fg-2); border: 1px solid var(--line-2); border-radius: 3px;
                      padding: 0 4px; margin-left: 5px; text-transform: uppercase; letter-spacing: .05em; }
/* A narrow column (a phone, or a small window beside the sidebar): a seat's windows and a model's
   uses wrap under its name instead of running off the edge. */
@container (max-width: 760px) {
  .jobs-quota-row { flex-wrap: wrap; column-gap: 10px; }
  .jobs-quota-use { min-width: 0; }
  .jobs-quota-win { flex: 1 0 100%; padding-left: 56px; }
  .jobs-models-row { flex-wrap: wrap; }
  .jobs-models-id { min-width: 0; }
}
/* The bar is the one element that must not reflow: monospace keeps the columns aligned. */
/* Every usage bar is colored by its own level (GH #516): green under 80%, yellow to 95%, red above. */
.jobs-quota-bar { font-family: var(--font-mono); letter-spacing: -1px;
                  color: var(--ok); }
.jobs-quota-win.warn  .jobs-quota-bar { color: var(--warn); }
.jobs-quota-win.alarm .jobs-quota-bar,
.jobs-quota-win.full  .jobs-quota-bar { color: var(--bad); }
.jobs-quota-pct { width: 32px; text-align: right; font-weight: 600; }
.jobs-quota-win.full .jobs-quota-pct { color: var(--bad); }
.jobs-quota-reset { font-size: 11px; }
.jobs-quota-amt { font-size: 11px; }
/* A full seat cannot take work until its reset, so its name is struck out and the reset is in bold.
 * The bar and FULL keep their full red: dimming the whole row turned them pink. */
.jobs-quota-row.full .jobs-quota-seat { text-decoration: line-through; opacity: .55; }
.jobs-quota-row.full .jobs-quota-reset { color: var(--fg); font-weight: 600; }
.chip.jobs-sig-working { background: var(--ok-bg); color: var(--ok-ink); }
/* Deliberately neutral, not red: "no signal" is a statement about our observation, never an
   accusation that the agent is stuck. */
.chip.jobs-sig-quiet { background: var(--bg-3); color: var(--fg-2); }
.chip.jobs-sig-unknown { background: var(--bg-3); color: var(--fg-3); }

/* ---- /jobs: the state board (GH #193) ---------------------------------------- */
/* State is the axis: one column per state, queue demoted to a label on the card.
   Colours are semantic, not decorative — running blue, queued violet, pending amber. */
.jobs-board { display: grid; grid-template-columns: 1fr; gap: 0.75rem; margin-top: 1rem; }
@media (min-width: 60rem) { .jobs-board { grid-template-columns: repeat(3, 1fr); } }

.jobs-col { background: var(--bg-3); border-radius: var(--radius); padding: 0.6rem;
            display: flex; flex-direction: column; min-width: 0;
            /* size to content: a stretched empty column is a big grey box saying nothing */
            align-self: start; }
.jobs-col-h { display: flex; align-items: baseline; gap: 0.5rem; padding: 0 0.2rem 0.5rem; }
.jobs-col-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--fg-3); }
.jobs-col-n { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.11em; }
.jobs-col-c { margin-left: auto; font-size: 1rem; font-weight: 600; color: var(--fg-2);
              font-variant-numeric: tabular-nums; }
.jobs-col-run  .jobs-col-dot { background: var(--info); } .jobs-col-run  .jobs-col-n { color: var(--link); }
.jobs-col-queue .jobs-col-dot { background: var(--violet); } .jobs-col-queue .jobs-col-n { color: var(--violet); }
.jobs-col-pend .jobs-col-dot { background: var(--warn); } .jobs-col-pend .jobs-col-n { color: var(--warn); }
.jobs-col-empty { font-size: 0.82rem; padding: 0.3rem 0.2rem; margin: 0; }

/* ONE scroll for the whole page, never a scroller per column: the page is as tall as the tallest
   column and the window scrolls it. Nested scrollers hid cards behind an inner scrollbar nobody
   thinks to drag, and put the thing you were looking for two scroll gestures away. Do not
   reintroduce `overflow-y` or a `max-height` here — assets/jobs.js preserves WINDOW scroll across the
   10 s swap, and test-jobs-board-browser.ts asserts no column is independently scrollable. */
.jobs-stack { display: flex; flex-direction: column; gap: 0.4rem; padding: 1px; }

/* Queued column groups. One block per queue, each in that claimer's real order.
   NO overflow/max-height here: test-jobs-board-browser.ts asserts no column is independently
   scrollable, and a scroll container on the group would break that just as surely as on the column. */
.jobs-group { display: flex; flex-direction: column; gap: 0.4rem; }
.jobs-group + .jobs-group { margin-top: 0.85rem; padding-top: 0.6rem; border-top: 1px solid var(--line); }
.jobs-group-h { display: flex; align-items: baseline; gap: 0.4rem; padding: 0 0.2rem; }
.jobs-group-n { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; color: var(--fg-2); }
.jobs-group-c { margin-left: auto; font-size: 0.78rem; font-weight: 600; color: var(--fg-2); }
.jobs-group-paused { margin: 0 0.2rem; font-size: 0.7rem; line-height: 1.35; color: var(--warn); }
.jobs-group-caveat { display: block; color: var(--fg-3); }
.jobs-col-paused { font-weight: 500; color: var(--warn); }

.jobs-card { display: block; width: 100%; text-align: left; font: inherit; color: inherit;
             cursor: pointer; background: var(--bg-2); border: 1px solid var(--line);
             border-left: 3px solid var(--fg-3); border-radius: 8px; padding: 0.45rem 0.6rem;
             min-width: 0; transition: border-color 0.12s, box-shadow 0.12s; }
.jobs-card:hover { box-shadow: var(--shadow); border-color: var(--line-2); }
.jobs-card:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
.jobs-card-run { border-left-color: var(--info); }
.jobs-card-queue { border-left-color: var(--violet); }
.jobs-card-pend { border-left-color: var(--warn); }
.jobs-card-done { border-left-color: var(--line-2); }
.jobs-card-top { display: flex; align-items: baseline; gap: 0.4rem; }
.jobs-card-q { font-size: 0.6rem; font-weight: 700; text-transform: uppercase;
               letter-spacing: 0.09em; color: var(--fg-2); overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; }
.jobs-card-el { margin-left: auto; font-size: 0.76rem; font-weight: 600; }
/* Every long value ellipsises here: the dialog is where the full text lives. */
.jobs-card-h, .jobs-card-d { display: block; overflow: hidden; text-overflow: ellipsis;
                             white-space: nowrap; }
.jobs-card-h { font-size: 0.82rem; font-weight: 600; color: var(--link); margin: 0.12rem 0 0.05rem; }
.jobs-card-d { font-size: 0.72rem; color: var(--fg-2); }
.jobs-card-f { display: flex; gap: 0.35rem; margin-top: 0.3rem; flex-wrap: wrap; }
.jobs-card-f .chip { font-size: 0.62rem; }
.chip.jobs-chip-why { background: var(--warn-bg); color: var(--warn-ink); }
.chip.jobs-chip-pos, .chip.jobs-chip-took { background: var(--bg-3); color: var(--fg-2); }
.chip.jobs-chip-cpu, .chip.jobs-chip-tok { background: var(--bg-3); color: var(--fg-2);
                                           font-variant-numeric: tabular-nums; }
.chip.jobs-chip-unknown { background: var(--bg-3); color: var(--fg-2); }
.chip.jobs-chip-run { background: var(--info-bg); color: var(--info-ink); }
.chip.jobs-chip-queue { background: var(--violet-bg); color: var(--violet-ink); }
.chip.jobs-chip-pend { background: var(--warn-bg); color: var(--warn-ink); }
.chip.jobs-chip-done { background: var(--bg-3); color: var(--fg-2); }

.jobs-truncated { font-size: 0.8rem; margin: 0.5rem 0 0; }
.jobs-workers-off { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem;
                    padding: 0.55rem 0.9rem; }
.jobs-wo-l { font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
             letter-spacing: 0.1em; color: var(--warn-ink); }
.jobs-wo-q { font-size: 0.82rem; color: var(--fg-2); }
.jobs-wo-q code { font-size: 0.75rem; color: var(--fg-2); }

.jobs-finished { margin-top: 0.9rem; padding: 0; }
.jobs-finished summary { cursor: pointer; padding: 0.6rem 0.9rem; display: flex;
                         align-items: baseline; gap: 0.6rem; list-style: none; }
.jobs-finished summary::-webkit-details-marker { display: none; }
.jobs-fin-n { font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
              letter-spacing: 0.11em; color: var(--fg-2); }
.jobs-fin-c { font-size: 0.8rem; color: var(--fg-2); font-variant-numeric: tabular-nums; }
.jobs-fin-list { border-top: 1px solid var(--line); padding: 0.5rem 0.6rem; display: flex;
                 flex-direction: column; gap: 0.3rem; max-height: 22rem; overflow-y: auto; }

/* ---- /jobs: the detail dialog ------------------------------------------------ */
#jobs-dialog { border: none; border-radius: 12px; padding: 0; max-width: 34rem;
               width: calc(100% - 1.6rem); background: var(--bg-2); color: var(--fg);
               box-shadow: var(--shadow-pop); }
#jobs-dialog::backdrop { background: var(--scrim); }
.jobs-dlg-h { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.85rem 1rem 0.6rem;
              border-bottom: 1px solid var(--line); }
.jobs-dlg-id { min-width: 0; }
.jobs-dlg-q { font-size: 0.62rem; font-weight: 700; text-transform: uppercase;
              letter-spacing: 0.1em; color: var(--fg-2); }
.jobs-dlg-t { font-size: 1rem; font-weight: 600; margin-top: 0.1rem; overflow-wrap: anywhere; }
.jobs-dlg-x { margin-left: auto; background: none; border: none; font-size: 1.4rem; line-height: 1;
              color: var(--fg-2); cursor: pointer; padding: 0 0.15rem; border-radius: 4px; }
.jobs-dlg-x:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
.jobs-dlg-b { padding: 0.75rem 1rem 1rem; display: flex; flex-direction: column; gap: 0.7rem; }
.jobs-dlg-links { display: flex; gap: 0.6rem; flex-wrap: wrap; font-size: 0.85rem; }
.jobs-dlg-why { background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 8px;
                padding: 0.5rem 0.7rem; font-size: 0.85rem; }
.jobs-dlg-why-l { display: block; font-weight: 650; margin-bottom: 0.1rem; }
.jobs-kv { display: grid; grid-template-columns: 8rem 1fr; gap: 0.3rem 0.7rem;
           font-size: 0.85rem; margin: 0; }
.jobs-kv dt { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.09em;
              color: var(--fg-2); padding-top: 0.15rem; }
.jobs-kv dd { margin: 0; overflow-wrap: anywhere; }
.jobs-dlg-lab { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.09em;
                color: var(--fg-2); margin-bottom: 0.25rem; }
/* The full last_error, not the 60-character slice the table showed. */
.jobs-dlg-err { background: var(--bad-bg); border: 1px solid var(--bad-line); border-radius: 8px;
                padding: 0.5rem 0.7rem; font-family: var(--font-mono); font-size: 0.75rem;
                color: var(--bad-ink); white-space: pre-wrap; overflow-wrap: anywhere;
                max-height: 12rem; overflow-y: auto; }
/* A disconnected page must say so INSIDE the dialog: #jobs-stale sits in <main>, which the
   modal's top layer covers completely. */
.jobs-dlg-stale { background: var(--bad-bg); color: var(--bad-ink); border: 1px solid var(--bad);
                  border-radius: 6px; padding: 0.5rem 0.7rem; font-size: 0.82rem; font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .jobs-card { transition: none; } }

/* ── /jobs actions (GH #195) ─────────────────────────────────────────────────────────────────── */

.jobs-dlg-act { display: flex; flex-direction: column; gap: 0.55rem;
                border-top: 1px solid var(--line); padding-top: 0.75rem; }
.jobs-act-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.jobs-act { font: inherit; font-size: 0.82rem; font-weight: 600; cursor: pointer;
            border: 1px solid var(--line-2); background: var(--bg-2); color: var(--fg);
            border-radius: 6px; padding: 0.35rem 0.7rem; }
.jobs-act:hover:not(:disabled) { background: var(--bg-3); }
.jobs-act:disabled { opacity: 0.55; cursor: default; }
/* Cancel is the one irreversible action here, so it is the one that looks it. */
.jobs-act-cancel { border-color: var(--bad); color: var(--bad); }
.jobs-act-cancel:hover:not(:disabled) { background: var(--bad-bg); }

.jobs-act-note { font-size: 0.78rem; line-height: 1.35; }

.jobs-act-copy { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.jobs-copy { font: inherit; font-size: 0.75rem; cursor: pointer; border: 1px solid var(--line);
             background: var(--bg-3); border-radius: 5px; padding: 0.2rem 0.5rem; color: var(--fg-2); }
.jobs-copy:hover { background: var(--bg-3); }
.jobs-sql { font-family: var(--font-mono); font-size: 0.74rem;
            color: var(--fg-2); overflow-x: auto; white-space: nowrap; flex: 1 1 12rem; }

.jobs-act-result:empty { display: none; }
.jobs-act-result { font-size: 0.8rem; font-weight: 600; border-radius: 6px; padding: 0.4rem 0.6rem; }
.jobs-act-ok { background: var(--ok-bg); color: var(--ok-ink); border: 1px solid var(--ok-line); }
.jobs-act-bad { background: var(--bad-bg); color: var(--bad-ink); border: 1px solid var(--bad); }

/* Transcript. `overflow-x: auto` on the row body, never on the page: a long command must scroll
   inside its own box rather than making the whole dialog scroll sideways. */
.jobs-tr-load { font: inherit; font-size: 0.8rem; font-weight: 600; cursor: pointer;
                border: 1px solid var(--line-2); background: var(--bg-2); border-radius: 6px;
                padding: 0.3rem 0.65rem; }
.jobs-tr { display: flex; flex-direction: column; gap: 0.2rem; margin-top: 0.5rem;
           max-height: 22rem; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px;
           padding: 0.5rem; background: var(--bg-3); }
.jobs-tr-row { display: grid; grid-template-columns: 4.5rem 7rem 1fr; gap: 0.5rem;
               font-size: 0.76rem; line-height: 1.35; align-items: baseline; }
.jobs-tr-t { color: var(--fg-3); font-family: var(--font-mono); }
.jobs-tr-k { font-weight: 600; color: var(--fg-2); overflow-wrap: anywhere; }
.jobs-tr-b { color: var(--fg-2); overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
.jobs-tr-res { display: block; color: var(--fg-2); border-left: 2px solid var(--line);
               padding-left: 0.5rem; margin-top: 0.2rem; }
.jobs-tr-err .jobs-tr-k { color: var(--bad); }
.jobs-tr-thinking .jobs-tr-b { font-style: italic; color: var(--fg-2); }
.jobs-tr-foot { font-size: 0.74rem; margin-top: 0.35rem; }

@media (max-width: 40rem) {
  .jobs-tr-row { grid-template-columns: 4.5rem 1fr; }
  .jobs-tr-t { grid-row: 1; }
  .jobs-tr-b { grid-column: 1 / -1; }
}

/* ── QA testing (/qa, epic #308) ─────────────────────────────────── */
/* Every QA page sits in .qa-page, so its links and buttons take the Sleek look without changing
   other pages. */
.qa-page a { text-decoration: none; }
.qa-page a:hover { text-decoration: underline; text-underline-offset: 3px; }
.qa-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 20px; margin-bottom: 14px; }
.qa-head h1 { margin: 0; }
.qa-page h1 { margin: 2px 0 6px; }
.qa-meta { margin: 0 0 6px; font-size: 12.5px; color: var(--fg-3); }
.qa-meta a { color: var(--fg-2); }
.qa-page h1 + .qa-meta { margin-bottom: 16px; }

.qa-filters { display: flex; flex-direction: column; gap: 6px; margin: 0 0 16px; }
.qa-filters div { display: flex; flex-wrap: wrap; gap: 6px; }
.qa-page a.qa-chip { display: inline-flex; align-items: center; min-height: 28px; padding: 0 10px; border-radius: var(--radius-sm);
                     border: 1px solid var(--line); background: var(--bg-2); color: var(--fg-2); font-size: 13px; font-weight: 500; }
.qa-page a.qa-chip:hover { background: var(--bg-3); text-decoration: none; }
.qa-page a.qa-chip[aria-current="true"] { background: var(--fg); border-color: var(--fg); color: var(--bg-2); }

table.qa-board { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--bg-2); font-size: 13.5px;
                 border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); }
table.qa-board th, table.qa-board td { padding: 9px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
table.qa-board tbody tr:last-child td { border-bottom: 0; }
table.qa-board thead th { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
table.qa-board tbody tr:not(.qa-group-row):hover { background: var(--bg-3); }
table.qa-board tr.qa-group-row th { padding: 7px 12px; background: var(--bg-3); color: var(--fg-2); font-size: 12.5px; font-weight: 600; }
/* The phone rule keeps links in table cells on one line. A section name is the one cell that must
   wrap, or a phone shows a table four screens wide. */
table.qa-board .qa-name > a { color: var(--fg); font-weight: 500; white-space: normal; }
/* The spec and file links under a section name are grey and underlined, so they read as links and
   not as part of the name above them. */
table.qa-board .qa-sub a { color: var(--fg-3); text-decoration: underline; text-underline-offset: 3px; }
table.qa-board .qa-sub a:hover { color: var(--fg-2); }
/* The number columns never wrap, so the section name gets the width they gave up. */
table.qa-board td.qa-num { white-space: nowrap; }
table.qa-board .qa-held { width: 24%; }
.qa-sub { font-size: 0.8rem; color: var(--fg-2); margin-top: 0.15rem; }
.qa-problem-count, .qa-fail { color: var(--bad-ink); font-weight: 600; }
.qa-banner { background: var(--warn-bg); border-left: 4px solid var(--warn); }
.qa-problems { background: var(--bad-bg); border-color: var(--bad-line); border-left: 4px solid var(--bad); }
.qa-problems h2 { color: var(--bad-ink); }
.qa-page a.qa-id { color: var(--link); }
.qa-page a.qa-test { color: var(--fg-2); }
.qa-page button:not(.qa-btn) { padding: 5px 12px; border-radius: var(--radius-sm); border: 1px solid var(--fg); background: var(--fg);
                               color: var(--bg-2); font-size: 13px; font-weight: 500; cursor: pointer; }
.qa-page button:not(.qa-btn):hover { opacity: 0.88; }
.qa-page button.qa-danger { background: var(--bad-bg); border-color: var(--bad-line); color: var(--bad-ink); }
.qa-page progress { accent-color: var(--ok); vertical-align: middle; }
form.qa-audit-filters { margin: 0 0 16px; color: var(--fg-2); }
form.qa-audit-filters input, form.qa-audit-filters select { padding: 5px 8px; }
.qa-problems ul, .qa-unknown ul { margin: 0.25rem 0 0 1.1rem; padding: 0; font-size: 0.85rem; }
.qa-group h2 { font-size: 15px; margin: 20px 0 8px; }
ul.qa-scenarios { list-style: none; margin: 0; padding: 0; }
li.qa-scenario { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
                 padding: 0.5rem 0.7rem; margin-bottom: 0.35rem; box-shadow: var(--shadow); }
li.qa-scenario.qa-open-failure { border-left: 4px solid var(--bad); }
.qa-latest { margin-top: 0.1rem; }
.qa-history summary, .qa-automated-block summary, .qa-unknown summary { cursor: pointer; font-size: 0.85rem; color: var(--link); }
.qa-automated-block { margin: 0.3rem 0 0.6rem; }
table.qa-history-table { border-collapse: collapse; font-size: 0.8rem; margin-top: 0.3rem; }
table.qa-history-table td { padding: 0.2rem 0.5rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.chip.qa-passed    { background: var(--ok-bg); color: var(--ok-ink); border-color: var(--ok-line); }
.chip.qa-failed    { background: var(--bad-bg); color: var(--bad-ink); border-color: var(--bad); }
.chip.qa-blocked   { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.chip.qa-skipped   { background: var(--bg-3); color: var(--fg-2); border-color: var(--line); }
.chip.qa-broken    { background: var(--info-bg); color: var(--violet-ink); border-color: var(--info-line); }
.chip.qa-automated { background: var(--info-bg); color: var(--info-ink); border-color: var(--info); }
.chip.qa-fix-testing { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.qa-report-form { display: inline-block; margin: 0.2rem 0; }
.chip.qa-waiting   { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
/* A phone drops Last full pass; the holder column says more on a small screen. */
@media (max-width: 600px) { table.qa-board .qa-wide { display: none; } }
.qa-hold p { margin: 0.2rem 0; }
.qa-hold.qa-mine { border-left: 4px solid var(--info); }
.qa-notice { background: var(--info-bg); border-left: 4px solid var(--info); }
.qa-idle { color: var(--warn-ink); font-weight: 600; }
.qa-recent { color: var(--ok-ink); }
form.qa-checkout-form { display: flex; flex-wrap: wrap; gap: 0.5rem 0.9rem; align-items: end; margin-top: 0.5rem; font-size: 0.85rem; }
form.qa-checkout-form label { display: flex; flex-direction: column; gap: 0.15rem; }
form.qa-result-form { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; margin-top: 0.35rem; }
form.qa-result-form input[type=text] { flex: 1 1 12rem; min-width: 8rem; font-size: 0.8rem; padding: 0.2rem 0.4rem; }
.qa-btn { font-size: 0.75rem; padding: 0.15rem 0.55rem; border-radius: 999px; border: 1px solid var(--line-2); background: var(--bg-2); cursor: pointer; }
.qa-btn.qa-chosen { font-weight: 700; box-shadow: inset 0 0 0 1px currentColor; }
button.qa-passed  { color: var(--ok-ink); } button.qa-failed { color: var(--bad-ink); }
button.qa-blocked { color: var(--warn-ink); } button.qa-skipped { color: var(--fg-2); }
.qa-edit summary { cursor: pointer; font-size: 0.8rem; color: var(--link); }
form.qa-edit-form, form.qa-add-form { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; margin-top: 0.35rem; }
form.qa-edit-form input[type=text], form.qa-add-form input[type=text] { flex: 1 1 16rem; font-size: 0.85rem; padding: 0.2rem 0.4rem; }
.qa-danger { color: var(--bad-ink); }
.qa-section-delete { margin-top: 1.2rem; }

/* Bugsy's regression proposals on a section page (#319). */
.qa-proposals ul { list-style: none; padding: 0; margin: 0; }
.qa-proposals li { padding: 6px 0; border-top: 1px solid var(--line); }
.qa-proposals li:first-child { border-top: none; }
.qa-inline-form { display: inline; margin-left: 8px; }

/* ── /admin/memory (memoryView.ts) ───────────────────────────────────── */
.mem-cards { display: flex; gap: 12px; flex-wrap: wrap; margin: 12px 0; }
.mem-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 16px; min-width: 90px; text-align: center; }
.mem-card-n { font-size: 22px; font-weight: 650; font-variant-numeric: tabular-nums; }
.mem-card-l { font-size: 12px; color: var(--fg-3); }
.mem-meta { font-size: 13px; color: var(--fg-2); margin: 8px 0; }
.mem-chip { display: inline-block; background: var(--info-bg); color: var(--info-ink); border-radius: 10px; padding: 1px 8px; margin: 2px; font-size: 12px; }
.mem-filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 12px 0; }
.mem-filters select, .mem-filters input[type=text] { padding: 5px 8px; }
.mem-filters input[type=text] { min-width: min(240px, 100%); }
.mem-inc { font-size: 13px; color: var(--fg-2); }
.mem-reset, .mem-count { font-size: 13px; color: var(--fg-3); }
.mem-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.mem-table th, .mem-table td { border-bottom: 1px solid var(--line); padding: 6px 8px; text-align: left; vertical-align: top; }
.mem-table th { position: sticky; top: 0; background: var(--bg-2); color: var(--fg-2); font-size: 12px; font-weight: 500; }
.mem-num { text-align: right; white-space: nowrap; }
.mem-date { white-space: nowrap; color: var(--fg-3); font-size: 12px; }
.mem-scope { white-space: nowrap; font-family: var(--font-mono); font-size: 12px; }
.mem-bodycol { max-width: 620px; }
.mem-trigger { color: var(--violet); font-size: 12px; font-weight: 600; }
.mem-text { color: var(--fg); }
.mem-badge { display: inline-block; border-radius: 4px; padding: 0 6px; font-size: 11px; font-weight: 600; }
.mem-semantic { background: var(--info-bg); color: var(--info-ink); }
.mem-procedural { background: var(--ok-bg); color: var(--ok-ink); }
.mem-sup { background: var(--bad-bg); color: var(--bad-ink); }
.mem-superseded { opacity: .5; }
.mem-ok { color: var(--ok); }
.mem-x { color: var(--bad); }

/* ── Login, set-password and forgot-password (src/auth/routes.ts) ───────── */
.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px 0; }
.auth-card {
  width: 100%; max-width: 400px; padding: 28px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-pop);
}
.auth-card h1 { margin: 0 0 20px; font-size: 22px; }
.auth-card label { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500; color: var(--fg-2); }
.auth-card label small { color: var(--fg-3); font-weight: 400; }
.auth-card input { width: 100%; padding: 9px 12px; margin-bottom: 16px; background: var(--bg); }
.auth-card input:focus { outline: 2px solid var(--accent-ink); outline-offset: 0; border-color: transparent; }
.auth-card button[type="submit"] {
  width: 100%; padding: 10px; border: 0; border-radius: var(--radius-sm);
  background: var(--fg); color: var(--bg); font-weight: 600; cursor: pointer;
}
.auth-card button[type="submit"]:hover { opacity: 0.88; }
.auth-error {
  background: var(--bad-bg); color: var(--bad-ink); border: 1px solid var(--bad-line);
  border-radius: var(--radius-sm); padding: 9px 12px; margin-bottom: 16px; font-size: 13px;
}
.auth-hint { margin-top: 16px; font-size: 13px; color: var(--fg-3); }
.bugsy-avatar { width: 20px; height: 20px; border-radius: 50%; vertical-align: middle; margin: 0 0.15rem 0 0.1rem; }
.auth-410 { text-align: center; color: var(--fg-2); }
.auth-410 p { margin: 0.5rem 0; }
.auth-410 code { background: var(--bg-3); border: 1px solid var(--line); border-radius: 4px; padding: 0.15rem 0.4rem; }
.auth-back { margin-top: 1.2rem; }

/* ── User page, /users/:id (docs/plans/2026-10-28-user-page-dashboard.md) ─────────────────────── */
.ud-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 14px 20px; margin: 4px 0 20px;
}
.ud-who { display: flex; align-items: center; gap: 14px; min-width: 0; }
.ud-avatar .avatar { width: 48px; height: 48px; margin: 0; }
.ud-avatar .avatar-init { line-height: 48px; font-size: 1.05rem; }
.ud-name {
  margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 1.6rem; font-weight: 650; letter-spacing: -0.02em; line-height: 1.15;
}
.ud-role {
  font: 600 0.64rem/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.06em;
  padding: 5px 8px; border-radius: 999px;
  background: var(--bg-3); color: var(--fg-2); border: 1px solid var(--line);
}
.ud-role-primary { background: var(--fg); color: var(--on-fill); border-color: var(--fg); }
.ud-sub { margin: 4px 0 0; font-size: 0.82rem; color: var(--fg-2); }
.ud-week {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 999px; box-shadow: var(--shadow);
}
.ud-week-prev, .ud-week-next {
  width: 32px; height: 32px; display: grid; place-items: center; border-radius: 999px;
  font-size: 1.15rem; color: var(--fg-2); text-decoration: none;
}
a.ud-week-prev:hover, a.ud-week-next:hover { background: var(--bg-3); color: var(--fg); }
.ud-week .is-off { opacity: 0.35; }
.ud-week-label { padding: 0 4px 0 6px; font-size: 0.82rem; color: var(--fg-2); white-space: nowrap; }
.ud-week-label strong { color: var(--fg); font-weight: 600; margin-right: 2px; }
.ud-week-badge {
  font: 600 0.62rem/1 var(--font-mono); text-transform: uppercase; letter-spacing: 0.06em;
  padding: 5px 8px; border-radius: 999px; white-space: nowrap;
}
.ud-week-badge.is-current { background: var(--ok-bg); color: var(--ok-ink); }
.ud-week-badge.is-past { background: var(--warn-bg); color: var(--warn-ink); }

/* The four figures under the header. The week's own tile is wider because it leads. */
.ud-kpis { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 16px; }
.ud-kpi {
  flex: 1 1 150px; min-width: 0; padding: 14px 16px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
}
.ud-kpi-week { flex: 1.5 1 220px; }
.ud-kpi-k {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px;
  font-size: 0.8rem; color: var(--fg-2);
}
.ud-kpi-v { margin-top: 8px; font-size: 1.75rem; font-weight: 650; letter-spacing: -0.03em; line-height: 1; }
.ud-kpi-week .ud-kpi-v { font-size: 2.6rem; }
.ud-kpi-v small { margin-left: 5px; font-size: 0.8rem; font-weight: 500; letter-spacing: 0; color: var(--fg-2); }
.ud-kpi-d {
  margin-top: 9px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: 0.76rem; color: var(--fg-2);
}
.ud-delta, .ud-live {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font: 600 0.7rem/1 var(--font-mono); padding: 4px 7px; border-radius: 999px;
}
.ud-delta.up { background: var(--ok-bg); color: var(--ok-ink); }
.ud-delta.down { background: var(--bad-bg); color: var(--bad-ink); }
.ud-delta.flat { background: var(--bg-3); color: var(--fg-2); }
.ud-live { background: var(--info-bg); color: var(--info-ink); }
.ud-live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--info); }

/* The weekly column chart. Every position is a percentage, set inline by renderWeeklyChart. */
.ud-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: -4px 0 6px; font-size: 0.76rem; color: var(--fg-2); }
.ud-key { display: inline-flex; align-items: center; gap: 6px; }
.ud-sw { width: 10px; height: 10px; border-radius: 2px; }
.ud-sw-full { background: var(--info); }
.ud-sw-now { background: repeating-linear-gradient(135deg, var(--info) 0 2px, transparent 2px 4px); box-shadow: inset 0 0 0 1px var(--info); }
.ud-sw-lost { background: var(--bad-line); }
.ud-sw-avg { width: 14px; height: 0; border-radius: 0; border-top: 1px dashed var(--fg-2); }
.ud-figure { margin: 0; }
.ud-plot { position: relative; height: 220px; margin: 26px 4px 0 34px; }
.ud-grid { position: absolute; left: 0; right: 0; height: 0; border-top: 1px solid var(--line); }
.ud-grid span {
  position: absolute; right: calc(100% + 8px); top: -0.4rem;
  font: 500 0.68rem/1 var(--font-mono); color: var(--fg-2);
}
.ud-zero { position: absolute; left: 0; right: 0; height: 0; border-top: 1px solid var(--line-2); }
.ud-cols { position: absolute; inset: 0; display: flex; }
.ud-col { position: relative; flex: 1 1 0; min-width: 0; height: 100%; border-radius: 4px 4px 0 0; }
.ud-col:hover { background: color-mix(in oklch, var(--bg-3) 70%, transparent); }
.ud-bar, .ud-lost {
  position: absolute; left: 50%; transform: translateX(-50%); width: 64%; max-width: 18px;
  border-radius: 4px 4px 0 0;
}
/* Mixed in oklab: oklch would swing the hue from blue through purple on its way to the neutral surface. */
.ud-bar { min-height: 2px; background: color-mix(in oklab, var(--info) 45%, var(--bg-2)); }
.ud-bar-focus, .ud-col:hover .ud-bar:not(.ud-bar-now):not(.ud-bar-neg) { background: var(--info); }
.ud-bar-now { background: repeating-linear-gradient(135deg, var(--info) 0 3px, transparent 3px 6px); box-shadow: inset 0 0 0 1.5px var(--info); }
.ud-bar-neg { border-radius: 0 0 4px 4px; background: var(--bad); }
/* The 2px shadow in the surface colour is the gap between a column and its penalty cap. */
.ud-lost { background: var(--bad-line); box-shadow: 0 2px 0 var(--bg-2); }
.ud-col-end[data-tip]:hover::after { left: auto; right: 0; }
.ud-col-end[data-tip]:hover::before { left: auto; right: 0.4rem; }
.ud-avg { position: absolute; left: 0; right: 0; height: 0; border-top: 1px dashed var(--fg-2); z-index: 2; pointer-events: none; }
.ud-avg span {
  position: absolute; left: 0; bottom: 3px; padding: 2px 6px 2px 0;
  font: 500 0.68rem/1 var(--font-mono); color: var(--fg-2); background: var(--bg-2);
}
.ud-cap {
  position: absolute; z-index: 3; pointer-events: none; transform: translate(-50%, -5px); white-space: nowrap;
  font: 600 0.7rem/1 var(--font-mono); color: var(--fg);
}
.ud-cap-end { transform: translate(-88%, -5px); }
.ud-xaxis { position: relative; height: 22px; margin: 0 4px 0 34px; border-top: 1px solid var(--line-2); }
.ud-xl {
  position: absolute; top: 7px; transform: translateX(-50%); white-space: nowrap;
  font: 500 0.68rem/1 var(--font-mono); color: var(--fg-2);
}
.ud-xl-now { color: var(--info-ink); font-weight: 700; }

/* Sources beside components; one column when the main column is narrow. */
.ud-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin: 16px 0; }
.ud-pair > .card { margin: 0; }
@container (max-width: 780px) { .ud-pair { grid-template-columns: minmax(0, 1fr); } }
.ud-src-list, .ud-cmp-list { list-style: none; margin: 0; padding: 0; }
.ud-src-list li, .ud-cmp-list li { margin: 0; }
.ud-src-row {
  display: grid; grid-template-columns: minmax(7rem, 9.5rem) minmax(0, 1fr) 3.6rem; gap: 12px; align-items: center;
  padding: 8px 0; border-top: 1px solid var(--line);
}
.ud-src-row:first-child, .ud-cmp-row:first-child { border-top: 0; padding-top: 2px; }
.ud-src-name, .ud-cmp-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; font-size: 0.86rem; white-space: nowrap; }
.ud-dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.ud-track { position: relative; height: 8px; border-radius: 999px; background: var(--bg-3); overflow: hidden; }
.ud-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 999px; }
.ud-val { text-align: right; font: 600 0.84rem/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.ud-val.is-neg { color: var(--bad-ink); }
.ud-src-none { margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--line); font-size: 0.78rem; color: var(--fg-2); }
.ud-c-info { background: var(--info); }
.ud-c-ok { background: var(--ok); }
.ud-c-indigo { background: var(--c-indigo); }
.ud-c-warn { background: var(--warn); }
.ud-c-violet { background: var(--violet); }
.ud-c-cyan { background: var(--c-cyan); }
.ud-c-orange { background: var(--c-orange); }
.ud-c-teal { background: var(--c-teal); }
.ud-c-bad { background: var(--bad); }
.ud-cmp-row { padding: 10px 0; border-top: 1px solid var(--line); }
.ud-cmp-top { display: flex; align-items: center; gap: 10px; }
.ud-cmp-top .ud-val { margin-left: auto; font-size: 0.92rem; }
.ud-cmp-bot { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.ud-rank { flex: none; min-width: 6.5rem; font-size: 0.78rem; color: var(--fg-2); white-space: nowrap; cursor: help; }
.ud-rank strong { color: var(--fg); font-size: 0.86rem; font-weight: 650; }
.ud-rank-clean { color: var(--ok-ink); }
.ud-rank-bad { color: var(--bad-ink); }
.ud-cmp-bot .dist-bar { flex: 1 1 auto; min-width: 0; max-width: none; height: 26px; }

/* ── Phones ───────────────────────────────────────────────────────────────
   Last in the file on purpose: these override the per-page rules above at the same specificity. */
/* v2.js wraps every table in .yd-scroll and marks it is-wide while the table is wider than the
   column, so a wide table scrolls inside its panel instead of being cut off. */
.yd-scroll { max-width: 100%; }
.yd-scroll.is-wide { overflow-x: auto; }
@media (max-width: 720px) {
  .yd-main td a { white-space: nowrap; }
  /* Tab strips scroll sideways on a phone instead of stacking into rows. */
  .admin-nav, .activity-tabs, .role-tab-strip { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .admin-nav a, .activity-tab, .role-tab { flex: none; white-space: nowrap; }
}
/* A week nav may wrap as a row, but never in the middle of a link or of the week chip. */
nav.week-nav, .week-nav-sticky { flex-wrap: wrap; }
nav.week-nav a, .week-nav-sticky a, .week-nav-sticky .disabled, .week-nav-chip { white-space: nowrap; }
