/* Legacy variable names — kept so every existing consumer keeps reading
   `var(--bg)` / `var(--card)` / `var(--accent)` etc. without a parallel
   refactor. The VALUES are now token references (see styles/tokens.css)
   so the brand-primitive layer becomes the single source of truth. The
   `:root.light-mode` overrides below + the matching block in the index.html
   critical CSS keep the variable VALUES in sync across modes.

   These names are scheduled to be renamed to the semantic aliases in
   themes/mad.css (--bg → --bg-page, --card → --bg-surface, etc.) in a
   later pass — for now they coexist so foundation lands cleanly. */
:root {
  --bg:          var(--color-neutral-900);
  --card:        var(--color-neutral-800);
  --card-border: var(--color-card-border-dark);
  --text:        var(--color-text-dark);
  --text-dim:    var(--color-text-dim-dark);
  --accent:      var(--color-teal-500);
  --orange:      var(--color-orange-500);
  --green:       var(--color-green-500);
  --red:         var(--color-red-500);
  --yellow:      var(--color-yellow-500);
  --blue:        var(--color-blue-500);
  --purple:      var(--color-purple-500);
  --avl:         var(--color-neutral-500);
  --gvl:         var(--color-purple-500);
  --jup:         var(--color-blue-500);
}

/* Light mode — flips the same legacy names. Status colors (green/orange/
   red/etc.) stay identical between modes so semantic readings ("green
   = on target") don't change. The accent drops a step (teal-light) since
   the dark-mode teal washes out on white but still passes WCAG AA. */
:root.light-mode {
  --bg:          var(--color-neutral-50);
  --card:        var(--color-neutral-0);
  --card-border: var(--color-neutral-200);
  --text:        var(--color-text-light);
  --text-dim:    var(--color-text-dim-light);
  --accent:      var(--color-teal-light);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  font-feature-settings: 'cv11', 'ss01';
  background: var(--bg);
  color: var(--text);
  height: 100vh;
  overflow: hidden;
}

/* Tabular-numerals utility — applied to every metric number class site-wide
   so columns like 501 / 751 / 1,082 line up digit-for-digit instead of the
   proportional widths that ship with most fonts. JetBrains Mono is the
   chosen mono typeface; fall back through a safe stack if it fails to
   load from Google Fonts. */
.num,
.scorecard-value,
.ratio-card-value,
.stat-num,
.indicator-value,
.data-table .num-cell,
.metric-num {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' on, 'lnum' on;
  letter-spacing: -0.01em;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

input, select, textarea, button {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

input, select, textarea {
  background: var(--bg);
  border: 1px solid var(--card-border);
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--text);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
}

button {
  cursor: pointer;
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  font-weight: 500;
  transition: opacity 0.15s;
}
button:hover { opacity: 0.85; }

.btn-primary {
  background: var(--accent);
  color: var(--bg);
}

.btn-secondary {
  background: var(--card);
  border: 1px solid var(--card-border);
  color: var(--text);
}

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
}
/* Status palette — only red/orange/green carry meaning. Informational
   chips (ontrack/frozen) drop to neutral; unbilled folds into the
   orange/warning lane. 2026-04-20 palette simplification pass.
   Post-ChatGPT review: .badge-frozen and .badge-ontrack use full --text
   (not --text-dim) at 11px uppercase to clear WCAG AA on the card
   background. Frozen also gets a subtle card-border fill so it reads
   as a bounded chip, not floating text. */
.badge-promoter { background: rgba(34,197,94,0.15); color: var(--green); }
.badge-ontrack  { background: rgba(228,228,231,0.08); color: var(--text);  border: 1px solid var(--card-border); }
.badge-nurture  { background: rgba(249,115,22,0.15); color: var(--orange); }
.badge-atrisk   { background: rgba(239,68,68,0.15);  color: var(--red); }
.badge-frozen   { background: rgba(228,228,231,0.05); color: var(--text);  border: 1px solid var(--card-border); }
.badge-unbilled { background: rgba(249,115,22,0.15); color: var(--orange); }

.spinner {
  width: 24px; height: 24px;
  border: 3px solid var(--card-border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── madOS brand loader ──────────────────────────────────────────────
   Whoop-style trace: a teal circle draws around an "M", both strokes
   tracing in then erasing in a continuous loop. Used by loadingHtml()
   in place of the generic CSS-border spinner. Stroke length math:
   ring circumference 2π × 24 ≈ 151; M path length ≈ 76 (measured). */
.mad-trace {
  width: 56px;
  height: 56px;
  color: var(--accent);
  display: block;
}
.mad-trace-ring {
  stroke-dasharray: 151;
  stroke-dashoffset: 151;
  animation: mad-trace-ring 2.4s ease-in-out infinite;
}
.mad-trace-letter {
  stroke-dasharray: 76;
  stroke-dashoffset: 76;
  animation: mad-trace-letter 2.4s ease-in-out infinite;
}
@keyframes mad-trace-ring {
  0%   { stroke-dashoffset: 151; }
  50%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: -151; }
}
@keyframes mad-trace-letter {
  0%, 18%  { stroke-dashoffset: 76; }
  58%      { stroke-dashoffset: 0; }
  100%     { stroke-dashoffset: -76; }
}

.skipper-working-pulse {
  animation: skipper-working-pulse 1.4s ease-in-out infinite;
}
@keyframes skipper-working-pulse {
  0%, 100% { opacity: 0.45; }
  50% { opacity: 0.85; }
}

.loading-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: 200px;
  color: var(--text-dim);
  font-size: 13px;
}

/* Cycling exercise phrases inside loadingHtml() */
.loading-phrases {
  position: relative;
  height: 1.4em;
  min-width: 110px;
  text-align: center;
}
.lp-word {
  position: absolute;
  left: 0; right: 0;
  opacity: 0;
  animation: lp-fade 9.8s infinite;
}
@keyframes lp-fade {
  0%, 1%    { opacity: 0; }
  3%, 12%   { opacity: 1; }
  15%, 100% { opacity: 0; }
}
