/*
 * Shared dashboard styling.
 *
 * ONE SOURCE, TWO CONSUMERS: the live app (web/index.html) links it, and the
 * static snapshot renderer inlines it into a self-contained file. Keeping a
 * second copy in the template would have drifted within a week - the two
 * dashboards have different lifecycles but must not have different appearances.
 */

:root {
  --ground: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --ink: #0f141a;
  --muted: #5b6772;
  --faint: #8a94a0;
  --line: #e0e5eb;
  --line-strong: #cdd4dd;
  --accent: #a25a06;
  --accent-soft: #fdf3e4;
  --up: #00685e;
  --down: #9b2c24;
  --unknown: #6b7a8a;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --ground: #0e1217;
    --surface: #171c23;
    --surface-2: #1e242c;
    --ink: #e7ecf2;
    --muted: #8a97a4;
    --faint: #6a7683;
    --line: #242c36;
    --line-strong: #323c48;
    --accent: #e5a33f;
    --accent-soft: #2a2015;
    --up: #41b9a2;
    --down: #df6f67;
    --unknown: #7e8c9b;
  }
}

:root[data-theme='dark'] {
  --ground: #0e1217;
  --surface: #171c23;
  --surface-2: #1e242c;
  --ink: #e7ecf2;
  --muted: #8a97a4;
  --faint: #6a7683;
  --line: #242c36;
  --line-strong: #323c48;
  --accent: #e5a33f;
  --accent-soft: #2a2015;
  --up: #41b9a2;
  --down: #df6f67;
  --unknown: #7e8c9b;
}

/*
 * `hidden` must actually hide.
 *
 * `[hidden]` is only a default UA rule of `display: none`, so ANY later
 * declaration that sets `display` on the same element wins — and the whole
 * page toggles visibility through `el.hidden`. `.gate { display: flex }` did
 * exactly that: the sign-in panel stayed on screen above the signed-in
 * dashboard, and setting `gate.hidden = true` changed nothing visible
 * (Codex, PR #13).
 *
 * `!important` here rather than per-component `[hidden]` overrides, because
 * the next component with a `display` rule would reintroduce it.
 */
[hidden] {
  display: none !important;
}

body {
  background: var(--ground);
  color: var(--ink);
  font-family: Archivo, 'Helvetica Neue', Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding-inline: 16px;
  padding-block: 28px 64px;
}

.num,
.tick {
  font-family: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-variant-numeric: tabular-nums;
}

header.masthead { margin-bottom: 20px; }
.eyebrow {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 6px;
}
h1 {
  font-size: clamp(22px, 4vw, 30px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 4px;
  text-wrap: balance;
}
.sub { color: var(--muted); margin: 0; max-width: 62ch; }

.warning {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-left-width: 4px;
  border-radius: 3px;
  padding: 14px 16px;
  margin: 22px 0;
}
.warning-mark {
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 600;
  color: var(--accent);
  font-size: 18px;
  line-height: 1.2;
  flex-shrink: 0;
}
.warning h2 {
  font-size: 14px;
  font-weight: 700;
  margin: 0 0 4px;
  color: var(--accent);
  letter-spacing: -0.01em;
}
.warning p { margin: 0 0 8px; color: var(--ink); max-width: 72ch; }
.warning p:last-child { margin-bottom: 0; }
.blocklist {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  color: var(--muted);
  word-spacing: 0.3em;
}

.summary { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 18px; }
.stat {
  flex: 1 1 130px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 12px 14px;
}
.stat-label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  display: block;
  margin-bottom: 5px;
}
.stat-value { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; }
.stat-value.is-setup { color: var(--accent); }
.stat-note { font-size: 12px; color: var(--muted); margin-top: 2px; }

.controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; }
.filter {
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  background: var(--surface);
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 13px;
  cursor: pointer;
}
.filter:hover { border-color: var(--line-strong); color: var(--ink); }
.filter[aria-pressed='true'] { background: var(--ink); color: var(--ground); border-color: var(--ink); }
.filter:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hint { font-size: 12px; color: var(--faint); margin-left: auto; }

.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 3px; background: var(--surface); }
table { border-collapse: collapse; width: 100%; min-width: 760px; }
thead th {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 500;
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--surface-2);
}
thead th.stage { text-align: center; }
tbody tr { border-bottom: 1px solid var(--line); }
tbody tr:last-child { border-bottom: 0; }
tbody tr.row { cursor: pointer; }
tbody tr.row:hover { background: var(--surface-2); }
tbody tr.row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
td { padding: 11px 12px; vertical-align: middle; }

.sym { font-weight: 600; font-size: 14px; letter-spacing: 0.02em; }
.sym-name { font-size: 11px; color: var(--faint); font-family: Archivo, sans-serif; letter-spacing: 0; }
.price { font-size: 14px; font-weight: 500; }
.chg { font-size: 12px; font-weight: 500; }
.chg.up { color: var(--up); }
.chg.down { color: var(--down); }

.stage-cell { text-align: center; white-space: nowrap; }
.pill {
  display: inline-block;
  min-width: 34px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  font-weight: 500;
  padding: 3px 7px;
  border-radius: 2px;
  border: 1px solid;
}
.pill.pass { background: var(--ink); color: var(--ground); border-color: var(--ink); }
.pill.fail { background: transparent; color: var(--muted); border-color: var(--line-strong); }
.pill.unk { background: transparent; color: var(--unknown); border-color: var(--unknown); border-style: dashed; }

.verdict {
  display: inline-block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 2px;
  white-space: nowrap;
}
.verdict.setup { background: var(--accent); color: var(--surface); }
.verdict.no-setup { background: transparent; color: var(--muted); border: 1px solid var(--line-strong); }
.verdict.unavailable { background: transparent; color: var(--unknown); border: 1px dashed var(--unknown); }

/*
  Forming is a watch state, so it reads as present but not actionable: the
  accent colour without the filled background a real setup gets.

  Missed is deliberately NOT alarming. It is information, not a warning — the
  move has gone, and the correct response is to do nothing. Styling it in red
  would make it feel like a loss to recover, which is the psychology this
  distinction exists to defuse.
*/
.verdict.forming { background: transparent; color: var(--accent); border: 1px solid var(--accent); }
.verdict.missed { background: transparent; color: var(--muted); border: 1px dashed var(--line-strong); }

.trigger-age { white-space: nowrap; }
.age {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 12px;
  color: var(--muted);
}
.age.today { color: var(--accent); font-weight: 600; }
.age.none { color: var(--line-strong); }

.stat-value.is-forming { color: var(--accent); }
.stat-value.is-missed { color: var(--muted); }

.spark { display: block; }

tr.detail td { padding: 0; background: var(--surface-2); }
.detail-inner { padding: 16px 14px 18px; border-top: 1px solid var(--line); }
.cond-group { margin-bottom: 14px; }
.cond-group:last-child { margin-bottom: 0; }
.cond-group h4 {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 500;
  margin: 0 0 7px;
}
.cond { display: flex; gap: 10px; align-items: baseline; padding: 5px 0; border-bottom: 1px dotted var(--line); }
.cond:last-child { border-bottom: 0; }
.cond-mark { font-family: 'IBM Plex Mono', monospace; font-weight: 600; width: 14px; flex-shrink: 0; text-align: center; }
.cond.met .cond-mark { color: var(--up); }
.cond.unmet .cond-mark { color: var(--down); }
.cond.unavailable .cond-mark { color: var(--unknown); }
.cond-label { flex: 1 1 auto; min-width: 0; }
.cond-detail { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--muted); text-align: right; flex-shrink: 0; }
.manual-tag {
  display: inline-block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 2px;
  padding: 0 4px;
  margin-left: 7px;
  vertical-align: 1px;
}

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 8px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.metric-label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  display: block;
}
.metric-value { font-family: 'IBM Plex Mono', monospace; font-size: 13px; font-weight: 500; }

footer { margin-top: 28px; padding-top: 16px; border-top: 1px solid var(--line); font-size: 12px; color: var(--faint); }
footer p { margin: 0 0 6px; max-width: 76ch; }
footer code {
  font-family: 'IBM Plex Mono', monospace;
  background: var(--surface-2);
  padding: 1px 5px;
  border-radius: 2px;
  color: var(--muted);
}

/* ---------- sign-in gate (live app only) ---------- */
.gate {
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 14px;
}
.gate h2 { font-size: 18px; margin: 0; letter-spacing: -0.01em; }
.gate p { color: var(--muted); margin: 0; max-width: 46ch; }
.signin {
  font: inherit;
  font-weight: 600;
  background: var(--ink);
  color: var(--ground);
  border: 1px solid var(--ink);
  border-radius: 3px;
  padding: 10px 20px;
  min-height: 44px;
  cursor: pointer;
}
.signin:hover { opacity: 0.9; }
.signin:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gate-error {
  color: var(--down);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  max-width: 60ch;
}
/*
 * The session bar sits OUTSIDE the dashboard, so signing out stays reachable
 * when the dashboard is not shown. It used to live inside the app container,
 * which meant the denied, empty and failed-read states hid the only sign-out
 * control — leaving no way to switch accounts from the screen that most needs
 * it. The accidentally-visible sign-in panel was masking that (Codex, PR #13).
 */
.session {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--faint);
  justify-content: flex-end;
  margin-bottom: 14px;
}
.signout {
  font: inherit;
  font-size: 12px;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 14px;
  /* 44px, the shared touch minimum — this is a primary control on a phone. */
  min-height: 44px;
  cursor: pointer;
}
.signout:hover { border-color: var(--line-strong); color: var(--ink); }
.signout:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 560px) {
  .stat { flex-basis: calc(50% - 5px); }
  .hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
