:root {
  /* dark theme (default) */
  --bg:           #0d1117;
  --bg-deep:      #11161d;
  --panel:        #161b22;
  --surface:      #1b2129;
  --line:         #272e37;
  --line-soft:    rgba(39,46,55,.5);
  --line-hover:   #3a434e;
  --fg:           #e6edf3;
  --muted:        #8b949e;
  --muted2:       #6e7681;
  --accent:       #4ba3ff;
  --accent-dim:   #1f6feb;
  --accent-alpha: rgba(31,111,235,.12);
  --ok:           #3fb950;
  color-scheme:   dark;
}

/* Light theme — applied by JS adding data-theme="light" to <html> */
[data-theme="light"] {
  --bg:           #f6f8fa;
  --bg-deep:      #eaeef2;
  --panel:        #ffffff;
  --surface:      #f0f3f6;
  --line:         #d0d7de;
  --line-soft:    rgba(208,215,222,.5);
  --line-hover:   #8c959f;
  --fg:           #1f2328;
  --muted:        #57606a;
  --muted2:       #6e7781;
  --accent:       #0969da;
  --accent-dim:   #218bff;
  --accent-alpha: rgba(9,105,218,.1);
  --ok:           #1a7f37;
  color-scheme:   light;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC",
        Roboto, Helvetica, Arial, sans-serif;
}

.shell { max-width: 880px; margin: 0 auto; padding: 48px 24px 64px; }

.hero { border-bottom: 1px solid var(--line); padding-bottom: 28px; margin-bottom: 32px; }

.badge {
  display: inline-block;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  border-radius: 999px;
  padding: 3px 10px;
}

h1 { font-size: 34px; margin: 14px 0 4px; font-weight: 650; letter-spacing: -.01em; }
h1 span { color: var(--accent); }
h2 { font-size: 15px; margin: 0 0 14px; text-transform: uppercase;
     letter-spacing: .07em; color: var(--muted); font-weight: 600; }

.domain { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
          color: var(--muted); font-size: 14px; }
.lede { color: var(--muted); max-width: 60ch; margin: 16px 0 0; }

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 22px 24px;
  margin-bottom: 20px;
}

.kv { display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; margin: 0; }
.kv dt { color: var(--muted); font-size: 13px; }
.kv dd { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; }
.card { background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: 16px; }
.card .label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .05em; }
.card .value { font-size: 26px; font-weight: 600; margin-top: 6px; font-variant-numeric: tabular-nums; }
.card .unit { font-size: 13px; color: var(--muted); margin-left: 4px; font-weight: 400; }

.hint { color: var(--muted); font-size: 13px; margin: 0 0 14px; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .92em;
       background: var(--bg); border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px; }

.ok { color: var(--ok); }

/* ---- 5xx chart panel ---- */

.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 4px;
}
.panel-head h2 { margin: 0; }

.rangebar { display: flex; gap: 4px; }
.range-btn {
  background: var(--bg); color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 11px; font: inherit; font-size: 12px;
  cursor: pointer; font-variant-numeric: tabular-nums;
}
.range-btn:hover { color: var(--fg); border-color: var(--line-hover); }
.range-btn.active {
  color: var(--accent); border-color: var(--accent-dim);
  background: var(--accent-alpha);
}
.range-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- Filter panel ---- */

.filter-panel { margin-bottom: 14px; }

.filter-row {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end;
  margin-bottom: 10px;
}
.filter-row:last-child { margin-bottom: 0; }

.time-input-group, .combo-group {
  display: flex; flex-direction: column; gap: 4px;
}

.time-input-group label, .combo-group label {
  font-size: 12px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .05em;
}

.datetime-input, .combo-input {
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 8px; font: inherit; font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.datetime-input:focus, .combo-input:focus {
  outline: 2px solid var(--accent); outline-offset: 1px;
  border-color: var(--accent-dim);
}

.quick-buttons { display: flex; gap: 4px; }
.quick-btn {
  background: var(--bg); color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 10px; font: inherit; font-size: 12px;
  cursor: pointer; font-variant-numeric: tabular-nums;
}
.quick-btn:hover { color: var(--fg); border-color: var(--line-hover); }
.quick-btn.active {
  color: var(--accent); border-color: var(--accent-dim);
  background: var(--accent-alpha);
}
.quick-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ComboBox */

.combo-wrapper {
  position: relative; width: 100%;
}

.combo-input {
  width: 100%;
}

.combo-dropdown {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 1000;
  background: #0d1117; border: 1px solid var(--line); border-radius: 6px;
  max-height: 200px; overflow-y: auto; margin-top: 2px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .3);
}

.combo-option {
  padding: 8px 10px; cursor: pointer; color: var(--fg);
  border-bottom: 1px solid var(--line-soft);
  font-size: 13px;
}
.combo-option:last-child { border-bottom: none; }
.combo-option:hover, .combo-option.highlighted {
  background: var(--surface); color: var(--accent);
}

/* A real name with no 5xx in the current window. Still selectable — this is
   a "quiet right now" cue, not a disabled state. The row already SAYS
   "0 errors in this window", so this styling is redundant by design and the
   meaning survives with CSS off. The left rule is a non-colour channel so
   the distinction does not rest on hue alone (WCAG 1.4.1). */
.combo-option.is-quiet {
  color: var(--muted);
  border-left: 3px solid #484f58;
  padding-left: 7px;
  font-style: italic;
}
.combo-option.is-quiet:hover, .combo-option.is-quiet.highlighted {
  background: var(--surface); color: var(--accent);
}

/* Truncation footer: "Showing first 20 of 2,485". Deliberately NOT a
   .combo-option — it carries no role=option, is not in the keyboard list, and
   must not look clickable, so no hover and no pointer cursor. The sticky
   bottom keeps it visible while the operator scrolls the 20 rows above it,
   which is the moment the count matters. */
.combo-note {
  padding: 7px 10px;
  color: var(--muted);
  font-size: 12px;
  cursor: default;
  background: var(--bg-deep);
  border-top: 1px solid var(--line);
  position: sticky;
  bottom: 0;
}

.filter-reset {
  background: transparent; color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 11px; font: inherit; font-size: 12px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
}
.filter-reset:hover:not(:disabled) { color: var(--fg); border-color: var(--line-hover); }
.filter-reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.filter-summary {
  font-size: 12px; color: var(--muted); margin-top: 8px;
}
.filter-summary.error { color: #f85149; }

/* ---- Totals ---- */

.totals {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 10px; margin: 14px 0 18px;
}
.total-card {
  background: var(--bg); border: 1px solid var(--line);
  border-left: 3px solid var(--line); border-radius: 7px; padding: 10px 12px;
}
.total-card .label {
  color: var(--muted); font-size: 11px; text-transform: uppercase;
  letter-spacing: .05em;
}
.total-card .value {
  font-size: 21px; font-weight: 600; margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.total-grand { border-left-color: var(--accent); }

/* Muted code: dimmed, but the number stays legible — hiding a line from the
   chart must not look like the measurement went away. Opacity on its own is
   a weak signal, so the accent rule also switches from solid to dashed and
   the label is struck through: both are non-colour cues (WCAG 1.4.1). */
.total-card.is-muted { opacity: .55; border-left-style: dashed; }
.total-card.is-muted .value { font-weight: 500; }
.total-card.is-muted .label { text-decoration: line-through; }

.chartwrap { position: relative; min-height: 190px; }
.chart { display: block; width: 100%; height: 300px; }

.chart-state {
  display: flex; align-items: center; justify-content: center;
  min-height: 190px; color: var(--muted); font-size: 13px; text-align: center;
  border: 1px dashed var(--line); border-radius: 8px; padding: 16px;
}
.chart-state.err { color: #f85149; border-color: #5c2b28; }

/* The HTML `hidden` attribute is only display:none in the UA stylesheet, so any
   author `display` declaration above beats it. These elements are all toggled
   via el.hidden in app.js and all carry an author display value, so each one
   needs an explicit [hidden] rule or it stays laid out while marked hidden. */
.chart-state[hidden],
.totals[hidden],
.legend[hidden] { display: none !important; }

/* #chart is an inline <svg>, so it must NOT be in the rule above. The UA
   `[hidden]{display:none}` rule is @namespace-scoped to XHTML and SVGElement
   has no `hidden` IDL property, so `svg.hidden = false` is an inert expando
   that never clears the attribute. A `.chart[hidden]` rule would therefore
   hide the chart forever. Toggle this class instead. */
.chart.is-hidden { display: none; }

.c-grid { stroke: #222a33; stroke-width: 1; }
.c-base { stroke: #333d48; stroke-width: 1; }
.c-axis { fill: var(--muted); font-size: 10px;
          font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.c-empty { fill: var(--muted); font-size: 12px; }
/* Zone caption on the X axis. One step smaller and dimmer than a tick label so
   it reads as a unit annotation rather than as another tick. */
.c-tz { font-size: 9px; opacity: 0.8; letter-spacing: 0.02em; }

/* Legend items are <button>s, not styled divs: each one toggles its series
   and carries aria-pressed. Reset the UA button chrome, keep the dark look. */
.legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 14px;
}
.legend-item {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 11px 4px 9px; margin: 0;
  font: inherit; font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  cursor: pointer; -webkit-appearance: none; appearance: none;
}
.legend-item:hover { border-color: var(--line-hover); }
.legend-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The swatch is an inline <svg> miniature of the series line — it carries the
   same dash pattern and the same marker shape as the chart, so the legend is
   readable without relying on hue (WCAG 1.4.1). Sized in the markup via
   viewBox; `overflow: visible` keeps a marker that slightly exceeds the 26x12
   box from being clipped. */
.legend-item .swatch {
  width: 26px; height: 12px; display: inline-block; flex: none;
  overflow: visible;
}
.legend-item .legend-code { font-weight: 600; }
.legend-item .legend-count { color: var(--muted); }

/* Muted series. Three cues stack here, only one of which is colour:
   the marker in the swatch goes hollow (shape), the code is struck through
   (text decoration), and the pill border goes dashed (border style). An
   operator who cannot see the hue change still has two unambiguous signals.
   The label stays readable enough to click back on. */
.legend-item[aria-pressed="false"] {
  background: transparent; border-color: var(--line); border-style: dashed;
  color: var(--muted);
}
.legend-item[aria-pressed="false"] .swatch { opacity: .6; }
.legend-item[aria-pressed="false"] .legend-code { text-decoration: line-through; }

.legend-reset {
  background: transparent; color: var(--muted);
  border: 1px dashed var(--line); border-radius: 999px;
  padding: 4px 11px; margin: 0; font: inherit; font-size: 12px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
}
.legend-reset:hover:not(:disabled) { color: var(--fg); border-color: var(--line-hover); }
.legend-reset:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.legend-reset:disabled { opacity: .35; cursor: default; }

.legend-hint { margin: 10px 0 0; font-size: 12px; }
/* The hint is only true when there is a legend to act on. It sits immediately
   after the legend, so it follows the legend's hidden state. */
.legend[hidden] + .legend-hint { display: none; }

/* Visually hidden but still announced — used for the toggle live region. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0);
  clip-path: inset(50%); white-space: nowrap;
}

/* ---- 2xx vs 5xx class chart panel ---- */

.class-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 4px;
}
.class-panel-head h2 { margin: 0; }

/* Error rate badge shown beside the heading. Inline text, no background,
   so it reads as a annotation not a button. A screen reader still hears it
   because it is in the DOM order immediately after the heading. */
.class-rate {
  font-size: 13px; color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-variant-numeric: tabular-nums;
}
.class-rate .class-rate-value { color: var(--fg); font-weight: 600; }

/* Totals row for the class chart: two tiles, 2xx and 5xx. */
.class-totals {
  display: flex; gap: 10px; margin: 14px 0 18px; flex-wrap: wrap;
}
.class-totals .total-card {
  flex: 1 1 140px;
}

/* The 5xx line in the class chart is intentionally not rescaled —
   operators use the crush-to-bottom signal to spot incidents. The CSS
   keeps a 1-2px floor so the line is not hidden by the X-axis rule.
   stroke-width and color are set in JS via SERIES_CLASS_STYLES. */
.c-class-floor { /* marker class; no rule needed — floor is a data-y offset */ }

.chart-state[hidden],
.totals[hidden],
.class-totals[hidden],
.legend[hidden] { display: none !important; }

#class-legend-hint { margin-top: 10px; }
#class-legend[hidden] + #class-legend-hint { display: none; }

.foot { color: var(--muted); font-size: 13px; text-align: center; margin-top: 36px; }
.foot a { color: var(--accent); text-decoration: none; }
.foot a:hover { text-decoration: underline; }

@media (prefers-reduced-motion: no-preference) {
  .card { transition: border-color .15s ease; }
  .card:hover { border-color: var(--accent-dim); }
}

/* ---- top navigation, shared by index.html and perf.html ---------------- */
/* Lives here, not in perf.css: both pages load app.css and both
   render this nav, so a page-private file would leave the other
   page with unstyled default links. */

.site-nav {
  display: flex;
  gap: 4px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 0;
}

.nav-tab {
  display: inline-block;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  /* Not colour alone: the inactive tab is also visually de-emphasised by a
     transparent border and a lighter weight position. */
  margin-bottom: -1px;
}

.nav-tab:hover,
.nav-tab:focus-visible {
  color: var(--fg);
  background: var(--surface);
  border-color: var(--line);
  outline: none;
}

.nav-tab--active {
  color: var(--fg);
  background: var(--panel);
  border-color: var(--line);
  /* A second, non-colour cue for "you are here". */
  box-shadow: inset 0 2px 0 0 var(--accent);
}

/* A four-tab nav wraps on narrow screens rather than overflowing. */
@media (max-width: 640px) {
  .site-nav { flex-wrap: wrap; }
}

/* ---- user pill (injected by auth.js into .site-nav) ------------------- */

.mca-user-pill {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  font-size: 12px;
}

.mca-user-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent, #4b73e8);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}

.mca-user-name {
  color: var(--fg);
  font-weight: 500;
}

.mca-admin-link {
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid rgba(75,163,255,.35);
  color: #79c0ff;
  font-size: 11px;
  font-weight: 500;
  text-decoration: none;
  transition: border-color 120ms, background 120ms;
}

.mca-admin-link:hover {
  background: rgba(75,163,255,.1);
  border-color: #79c0ff;
}

.mca-logout-btn {
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
  transition: border-color 120ms, color 120ms;
}

.mca-logout-btn:hover {
  border-color: #f85149;
  color: #f85149;
}

/* ---- theme toggle button ------------------------------------------------ */

.mca-theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  line-height: 1;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
  flex-shrink: 0;
}

.mca-theme-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-alpha);
}

.mca-theme-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

