/* SPY-DER dashboard tab.
 *
 * Every rule is scoped under `.spyder-tab`. This stylesheet is loaded into
 * 0DTE's Vercel dashboard alongside that project's own CSS, so an unscoped
 * selector here would restyle a page this repository cannot see. Custom
 * properties are declared on `.spyder-tab` rather than `:root` for the same
 * reason.
 */

.spyder-tab {
  --sd-bg: #0d1117;
  --sd-panel: #161b22;
  --sd-panel-2: #1c2330;
  --sd-border: #2d333b;
  --sd-text: #e6edf3;
  --sd-muted: #8b949e;
  --sd-accent: #58a6ff;
  --sd-ok: #3fb950;
  --sd-warn: #d29922;
  --sd-bad: #f85149;
  --sd-idle: #6e7681;

  color: var(--sd-text);
  background: var(--sd-bg);
  font-family: ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  padding: 16px;
  border-radius: 8px;
}

@media (prefers-color-scheme: light) {
  .spyder-tab:not([data-force-dark]) {
    --sd-bg: #ffffff;
    --sd-panel: #f6f8fa;
    --sd-panel-2: #eef1f4;
    --sd-border: #d0d7de;
    --sd-text: #1f2328;
    --sd-muted: #656d76;
    --sd-accent: #0969da;
    --sd-ok: #1a7f37;
    --sd-warn: #9a6700;
    --sd-bad: #cf222e;
    --sd-idle: #8c959f;
  }
}

.spyder-tab * {
  box-sizing: border-box;
}

/* Header ------------------------------------------------------------------ */
.spyder-tab__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.spyder-tab__title {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin: 0;
}

.spyder-tab__title small {
  color: var(--sd-muted);
  font-weight: 400;
  margin-left: 8px;
}

.spyder-tab__spacer {
  flex: 1 1 auto;
}

.spyder-tab__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--sd-border);
  background: var(--sd-panel);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.spyder-tab__pill::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--sd-idle);
}

.spyder-tab__pill--ok::before { background: var(--sd-ok); }
.spyder-tab__pill--warn::before { background: var(--sd-warn); }
.spyder-tab__pill--bad::before { background: var(--sd-bad); }

/* Verdict lines are paragraphs carrying a whole sentence, not inline chips.
   `nowrap` is right for `NO_EDGE` and wrong here: a Dojo headline such as
   "Next sparring will focus on gap shock, range chop, crash." measures ~470px
   and pushed the entire page into horizontal scroll on a phone. */
p.spyder-tab__pill {
  white-space: normal;
  max-width: 100%;
  align-items: flex-start;
  text-transform: none;
  letter-spacing: 0;
}

p.spyder-tab__pill::before {
  flex: none;
  margin-top: 6px; /* keep the dot beside the first line, not centred on all */
}

.spyder-tab__pill--pulse::before {
  animation: spyder-tab-pulse 1.4s ease-in-out infinite;
}

@keyframes spyder-tab-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.85); }
}

.spyder-tab__refresh {
  font: inherit;
  font-size: 12px;
  color: var(--sd-muted);
  background: var(--sd-panel);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  padding: 4px 10px;
  cursor: pointer;
}

.spyder-tab__refresh:hover {
  color: var(--sd-text);
  border-color: var(--sd-accent);
}

.spyder-tab__btn {
  font: inherit;
  font-size: 12px;
  color: var(--sd-text);
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  padding: 5px 10px;
  cursor: pointer;
}

.spyder-tab__btn:hover {
  border-color: var(--sd-accent);
}

.spyder-tab__btn--ok {
  color: var(--sd-ok);
  border-color: color-mix(in srgb, var(--sd-ok) 45%, var(--sd-border));
}

.spyder-tab__btn--bad {
  color: var(--sd-bad);
  border-color: color-mix(in srgb, var(--sd-bad) 45%, var(--sd-border));
}

.spyder-tab__pending {
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  background: var(--sd-panel-2);
}

.spyder-tab__pending-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0;
}

.spyder-tab__pending-row {
  display: grid;
  grid-template-columns: minmax(120px, 0.8fr) 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  background: var(--sd-panel);
  cursor: default;
}

.spyder-tab__pending-row--selected {
  border-color: var(--sd-accent);
}

.spyder-tab__pending-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  word-break: break-all;
}

.spyder-tab__pending-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.spyder-tab__pending-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
}

.spyder-tab__operator {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.spyder-tab__operator-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.spyder-tab__operator-input {
  flex: 1 1 220px;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  color: var(--sd-text);
  background: var(--sd-panel);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  padding: 6px 10px;
}

/* Hero --------------------------------------------------------------------
 *
 * The headline figure, and there is exactly one. Everything below it is
 * supporting detail, which is the hierarchy the tab previously lacked: twenty
 * cards of identical weight, with the current action set in the same 12px pill
 * as every other label.
 *
 * Sized with clamp because the actions are words, not digits, and they vary
 * from IDLE to SELECT_CANDIDATE. 48px is the target; a phone gets the largest
 * size the longest action still fits at, and may wrap rather than overflow. */
.spyder-tab__hero {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 20px;
  padding-bottom: 16px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--sd-border);
}

.spyder-tab__hero-value {
  margin: 0;
  /* Proportional figures on purpose — tabular-nums makes a large standalone
     value look loose. Columns of numbers get tabular; this is not one. */
  font-size: clamp(32px, 10vw, 48px);
  font-weight: 650;
  line-height: 1.02;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

.spyder-tab__hero-value--ok { color: var(--sd-ok); }
.spyder-tab__hero-value--warn { color: var(--sd-warn); }
.spyder-tab__hero-value--bad { color: var(--sd-bad); }

.spyder-tab__hero-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.spyder-tab__hero-meta {
  margin: 0;
  font-size: 12px;
  color: var(--sd-muted);
}

/* Grid and panels -------------------------------------------------------- */
.spyder-tab__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
}

.spyder-tab__panel {
  background: var(--sd-panel);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  padding: 12px 14px;
  min-width: 0;
}

.spyder-tab__panel--wide {
  grid-column: 1 / -1;
}

.spyder-tab__panel h3 {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sd-muted);
}

.spyder-tab__note {
  color: var(--sd-muted);
  font-size: 12px;
  margin: 0;
}

.spyder-tab__note--bad {
  color: var(--sd-bad);
}

/* Key/value rows --------------------------------------------------------- */
.spyder-tab__kv {
  display: grid;
  grid-template-columns: minmax(90px, auto) 1fr;
  gap: 4px 12px;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.spyder-tab__kv dt {
  color: var(--sd-muted);
  font-size: 12px;
}

.spyder-tab__kv dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* Decision chain --------------------------------------------------------- */
.spyder-tab__chain {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: stretch;
}

.spyder-tab__stage {
  flex: 1 1 150px;
  min-width: 0;
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  border-left: 3px solid var(--sd-idle);
  border-radius: 6px;
  padding: 8px 10px;
}

/* Emphasis, not a rainbow.
 *
 * Every stage used to carry its own colour — green, blue, amber, red down the
 * row — so five status hues competed at equal strength and none of them read
 * as a signal. Status colour is reserved for status: a stage doing its job is
 * not news and stays neutral, and only an exception is tinted. The stage name
 * and value already say which stage it is, so nothing here is colour-alone. */
.spyder-tab__stage--warn { border-left-color: var(--sd-warn); }
.spyder-tab__stage--bad { border-left-color: var(--sd-bad); }

.spyder-tab__stage-name {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--sd-muted);
}

.spyder-tab__stage-value {
  font-weight: 600;
  font-size: 15px;
  overflow-wrap: anywhere;
}

.spyder-tab__stage-detail {
  font-size: 12px;
  color: var(--sd-muted);
  overflow-wrap: anywhere;
}

.spyder-tab__chain-caption {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--sd-muted);
}

/* Meters ----------------------------------------------------------------- */
.spyder-tab__meter {
  margin-bottom: 8px;
}

.spyder-tab__meter-head {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--sd-muted);
  margin-bottom: 3px;
}

.spyder-tab__meter-track {
  height: 6px;
  border-radius: 3px;
  background: var(--sd-panel-2);
  overflow: hidden;
}

.spyder-tab__meter-fill {
  height: 100%;
  background: var(--sd-accent);
}

.spyder-tab__meter-fill--ok { background: var(--sd-ok); }
.spyder-tab__meter-fill--warn { background: var(--sd-warn); }
.spyder-tab__meter-fill--bad { background: var(--sd-bad); }

/* Waterfall -------------------------------------------------------------- */
.spyder-tab__waterfall {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}

.spyder-tab__bar-row {
  display: grid;
  grid-template-columns: 96px 1fr 92px;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}

.spyder-tab__bar-label {
  color: var(--sd-muted);
  text-transform: capitalize;
}

/* Two half-tracks meeting at a centre line, so sign is legible as position
 * and not only as colour. */
.spyder-tab__bar-track {
  display: flex;
  height: 14px;
  background: var(--sd-panel-2);
  border-radius: 3px;
  overflow: hidden;
}

.spyder-tab__bar-half {
  flex: 1 1 50%;
  display: flex;
  min-width: 0;
}

.spyder-tab__bar-half--neg { justify-content: flex-end; }

.spyder-tab__bar-fill {
  height: 100%;
}

.spyder-tab__bar-fill--neg { background: var(--sd-bad); }
.spyder-tab__bar-fill--pos { background: var(--sd-ok); }

.spyder-tab__bar-value {
  text-align: right;
}

.spyder-tab__bar-value--neg { color: var(--sd-bad); }
.spyder-tab__bar-value--pos { color: var(--sd-ok); }

/* Books side by side ----------------------------------------------------- */
.spyder-tab__books {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}

.spyder-tab__book {
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  padding: 8px 10px;
}

.spyder-tab__book-name {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--sd-muted);
}

.spyder-tab__book-value {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.spyder-tab__book-value--neg { color: var(--sd-bad); }
.spyder-tab__book-value--pos { color: var(--sd-ok); }

.spyder-tab__book-sub {
  font-size: 12px;
  color: var(--sd-muted);
}

/* Tag lists -------------------------------------------------------------- */
.spyder-tab__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.spyder-tab__tags li {
  font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  color: var(--sd-muted);
}

.spyder-tab__tags li[data-tone="ok"] {
  border-color: var(--sd-ok);
  color: var(--sd-ok);
}

.spyder-tab__tags li[data-tone="warn"] {
  border-color: var(--sd-warn);
  color: var(--sd-warn);
}

.spyder-tab__tags li[data-tone="bad"] {
  border-color: var(--sd-bad);
  color: var(--sd-bad);
}

/* Tables ----------------------------------------------------------------- */
.spyder-tab__scroll {
  overflow-x: auto;
}

.spyder-tab table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.spyder-tab th,
.spyder-tab td {
  text-align: left;
  padding: 5px 8px;
  border-bottom: 1px solid var(--sd-border);
  white-space: nowrap;
}

.spyder-tab th {
  color: var(--sd-muted);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.spyder-tab tbody tr:last-child td {
  border-bottom: none;
}

.spyder-tab code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

.spyder-tab__rationale {
  margin: 8px 0 0;
  padding: 8px 10px;
  background: var(--sd-panel-2);
  border-radius: 6px;
  font-size: 12px;
  color: var(--sd-muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.spyder-tab__footer {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--sd-border);
  font-size: 11px;
  color: var(--sd-muted);
}

/* Dojo training room ----------------------------------------------------- */
.spyder-tab__story {
  margin: 10px 0 4px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.spyder-tab__story-row {
  padding: 8px 10px;
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
}

.spyder-tab__story-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sd-muted);
  margin-bottom: 2px;
}

.spyder-tab__story-body {
  font-size: 13px;
  line-height: 1.4;
}

.spyder-tab__subhead {
  margin: 14px 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sd-muted);
}

.spyder-tab__focus {
  margin-top: 4px;
  padding: 10px 12px;
  background: var(--sd-panel-2);
  border: 1px solid var(--sd-border);
  border-radius: 6px;
}

.spyder-tab__focus .spyder-tab__subhead {
  margin-top: 0;
}

.spyder-tab__focus-headline {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
}

.spyder-tab__focus-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.spyder-tab__focus-item {
  padding: 6px 10px;
  border-radius: 4px;
  border: 1px solid var(--sd-warn);
  background: transparent;
}

.spyder-tab__focus-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--sd-warn);
}

.spyder-tab__focus-reason {
  margin-top: 2px;
  font-size: 12px;
  color: var(--sd-muted);
}

.spyder-tab__chain--dojo {
  margin-top: 12px;
}

/* Live Dojo working square ------------------------------------------------ */
.spyder-tab__dojo-square {
  margin: 0 0 14px;
  padding: 12px;
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  background:
    linear-gradient(160deg, rgba(88, 166, 255, 0.08), transparent 42%),
    var(--sd-panel-2);
}

.spyder-tab__dojo-square-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.spyder-tab__dojo-square-phase {
  font-size: 13px;
  font-weight: 600;
  color: var(--sd-text);
}

.spyder-tab__dojo-square-detail {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--sd-muted);
}

.spyder-tab__dojo-strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
}

.spyder-tab__dojo-step {
  min-height: 54px;
  padding: 8px;
  border-radius: 4px;
  border: 1px solid var(--sd-border);
  border-left-width: 3px;
  border-left-color: var(--sd-idle);
  background: var(--sd-panel);
}

.spyder-tab__dojo-step--pending {
  border-left-color: var(--sd-idle);
  opacity: 0.72;
}

.spyder-tab__dojo-step--running {
  border-left-color: var(--sd-accent);
}

.spyder-tab__dojo-step--done {
  border-left-color: var(--sd-ok);
}

.spyder-tab__dojo-step--skipped {
  border-left-color: var(--sd-muted);
}

.spyder-tab__dojo-step--failed {
  border-left-color: var(--sd-bad);
}

.spyder-tab__dojo-step-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--sd-text);
}

.spyder-tab__dojo-step-status {
  margin-top: 4px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sd-muted);
}

.spyder-tab__dojo-step--running .spyder-tab__dojo-step-status {
  color: var(--sd-accent);
}

.spyder-tab__dojo-step--done .spyder-tab__dojo-step-status {
  color: var(--sd-ok);
}

.spyder-tab__dojo-step--failed .spyder-tab__dojo-step-status {
  color: var(--sd-bad);
}

@media (max-width: 640px) {
  .spyder-tab__dojo-strip {
    grid-template-columns: 1fr 1fr;
  }
}

.spyder-tab__robustness {
  margin-top: 4px;
}

.spyder-tab__matrix-row--weak td:first-child {
  color: var(--sd-warn);
  font-weight: 600;
}

.spyder-tab__parity {
  margin-top: 8px;
  padding-top: 4px;
  border-top: 1px solid var(--sd-border);
}

@media (max-width: 640px) {
  /* The strapline costs a whole wrapped line on a phone and says nothing the
     hero underneath it does not. The wordmark stays — on the VPS shell this
     header is the only branding there is. */
  .spyder-tab__title small {
    display: none;
  }

  .spyder-tab__chain--dojo .spyder-tab__stage {
    flex: 1 1 100%;
  }

  .spyder-tab__bar-row {
    grid-template-columns: 72px 1fr 72px;
  }

  .spyder-tab__pending-row {
    grid-template-columns: 1fr;
  }
}
