:root {
  --bg: #121212;
  --surface: #1e1e1e;
  --text: #e8e8e8;
  --text-muted: #a0a0a0;
  --border: #333;
  --accent-cgm: #4fd1c5;
  --accent-bolus: #f6ad55;
  --accent-basal: #b794f4;
  --accent-insulin-bolus: #38b2ac;
  --accent-insulin-basal: #7f9cf5;
  --accent-weekend-bolus: #2c7a7b;
  --accent-weekend-basal: #5a67d8;
  --accent-a1c: #fc8181;
  --accent-weight: #68d391;
  --accent-bmi: #63b3ed;
  --accent-bodyfat: #ed8936;
  --accent-muscle: #ecc94b;
  /* /composition-only accents: validated as a set via dataviz's
     validate_palette.js against this app's dark --surface (#1e1e1e).
     Fat/muscle are the two series the page exists to make legible (the
     "emphasis" color job -- these are the point, bone/other are
     context), so they get the two vivid, CVD-checked hues; bone/other
     are deliberately muted/desaturated to recede. Kept separate from
     --accent-bodyfat/--accent-muscle above (the /renpho page's own
     body-fat%/muscle% line charts) so this fix doesn't recolor a page
     nobody flagged. */
  --accent-comp-fat: #d95926;
  --accent-comp-muscle: #3987e5;
  --accent-bone: #8b93a1;
  --accent-other: #6b7480;
  --accent-surplus: #f56565;
  --accent-no-surplus: #4a5568;
  /* Was #4299e1, identical to --accent-blood-oxygen -- both can be
     checked simultaneously on the summary page's overlay chart, so a
     shared hex made two different series render as the same color. */
  --accent-steps: #48bb78;
  --accent-distance: #38b2ac;
  /* Was #f56565, identical to --accent-heart-rate -- same overlay-chart
     collision as --accent-steps above. */
  --accent-energy: #ecc94b;
  --accent-exercise: #9f7aea;
  --accent-sleep-deep: #4c51bf;
  --accent-sleep-core: #667eea;
  --accent-sleep-rem: #9f7aea;
  --accent-sleep-awake: #cbd5e0;
  --accent-workout: #48bb78;
  --accent-heart-rate: #f56565;
  --accent-blood-oxygen: #4299e1;
  /* Was #9f7aea, near-indistinguishable from --accent-blood-oxygen
     under CVD simulation (both checked together on the overlay chart's
     "Heart" toggle group). */
  --accent-respiratory: #ed64a6;
  --accent-hrv: #48bb78;
  --accent-resting-hr: #ed8936;
  --accent-basal-energy: #d53f8c;
  --accent-flights: #dd6b20;
  --accent-stand-time: #319795;
  --accent-exercise-time: #805ad5;
  --accent-physical-effort: #e53e3e;
  --accent-daylight: #d69e2e;
  --accent-headphone-audio: #718096;
  --accent-gait-step-length: #3182ce;
  --accent-gait-speed: #00b5d8;
  --accent-gait-double-support: #38a169;
  --accent-gait-asymmetry: #b83280;
  --accent-stair-speed-up: #c05621;
  --accent-stair-speed-down: #9c4221;
  --trend-good: #48bb78;
  --trend-bad: #f56565;
}

body {
  font-family: system-ui, sans-serif;
  margin: 2rem;
  background: var(--bg);
  color: var(--text);
}

a { color: var(--accent-cgm); }
a:visited { color: var(--accent-basal); }

header h1 { margin-bottom: 0.25rem; }
header nav a { color: var(--text-muted); }
.nav-logout-form { display: inline; margin: 0; }
.nav-logout-button {
  background: none; border: none; padding: 0; margin-left: 0.5em;
  font: inherit; color: inherit; text-decoration: underline;
  cursor: pointer;
}

.controls { margin-bottom: 1.5rem; }

/* Standalone login screen (web/app/templates/login.html) -- not part of
   the app shell, so it overrides body's own margin/layout rather than
   inheriting it, and centers a single card instead of the app's usual
   left-aligned page content. */
body.login-page { margin: 0; }
.login-page-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  box-sizing: border-box;
}
.login-card {
  width: 100%;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2rem;
  box-sizing: border-box;
}
.login-card h1 {
  margin: 0 0 1.5rem;
  font-size: 1.4rem;
  text-align: center;
  letter-spacing: 0.01em;
}
.login-card form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.login-card label {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.login-card input {
  width: 100%;
  box-sizing: border-box;
  font-size: 1rem;
  padding: 0.6rem 0.7rem;
}
.login-card button {
  width: 100%;
  padding: 0.65rem;
  font-size: 1rem;
  margin-top: 0.25rem;
}
.login-card .hint { margin: 0 0 1rem; font-size: 0.9rem; }
.login-card .hint-error { text-align: center; }

.date-presets { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.75rem; }

.preset-button {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.4rem 0.8rem;
  font-size: 0.9rem;
  text-decoration: none;
  font-family: inherit;
  font-weight: 400;
  cursor: pointer;
}
.preset-button:hover { border-color: var(--accent-cgm); }
.preset-button:visited { color: var(--text); }
.preset-button.active {
  background: var(--accent-cgm);
  color: #0a0a0a;
  border-color: var(--accent-cgm);
  font-weight: 600;
}

/* The dashboard's custom date range is one line of controls, visually
   separated from the preset-button row above it by this divider; the
   setup form below is a stack of fields, so this must not apply to every
   form on the site. */
form.range-form {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

input, select, button {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.4rem 0.6rem;
  font-size: 1rem;
}
button {
  background: var(--accent-cgm);
  color: #0a0a0a;
  border: none;
  cursor: pointer;
  font-weight: 600;
}
button:hover { opacity: 0.9; }
input:focus, select:focus, button:focus {
  outline: 2px solid var(--accent-cgm);
  outline-offset: 1px;
}

#stats, .stat-group {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.5rem;
  margin-bottom: 1.5rem;
}
.stat { display: flex; flex-direction: column; gap: 0.2rem; }
.stat-label { color: var(--text-muted); font-size: 0.85rem; }
.stat-value-row { display: flex; align-items: baseline; gap: 0.3rem; }
.stat-value { font-size: 1.25rem; font-weight: 600; }
.stat-trend { font-size: 1.5rem; font-weight: 600; }
.stat-trend-good { color: var(--trend-good); }
.stat-trend-bad { color: var(--trend-bad); }
.hint-error { color: var(--trend-bad); }
.stat-trend-neutral { color: var(--text-muted); }
.stat-target { display: block; color: var(--text-muted); font-size: 0.75rem; margin-top: 0.1rem; }
.stat-group-heading { font-size: 0.95rem; color: var(--text-muted); margin: 1rem 0 0.5rem; text-transform: uppercase; letter-spacing: 0.05em; }
.stat-group-heading:first-of-type { margin-top: 0; }

.notice { color: var(--accent-cgm); }
.error { color: var(--accent-a1c); }

/* Chart.js needs a parent with a real, non-zero height to size into --
   a bare <canvas> in normal document flow can render at 0 height (nothing
   visible, no error) since it has nothing else establishing one. */
.chart-container {
  position: relative;
  height: 300px;
  margin-bottom: 2rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
}
.chart-container canvas { max-width: 100%; }

/* Small-multiple trend charts (e.g. /composition's fat/muscle detail
   charts below the main stacked chart) -- each on its own auto-scaled
   axis so a small real change isn't visually flattened by sharing a
   much larger-magnitude chart's scale. */
.chart-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }
.chart-row .chart-container { height: 180px; margin-bottom: 0; }
.chart-row-heading { color: var(--text-muted); font-size: 0.85rem; margin: 0 0 0.4rem; }

#setup-form label { display: block; margin-bottom: 0.75rem; }
#setup-form input { display: block; width: 100%; max-width: 20rem; margin-top: 0.25rem; }
#setup-form .hint { max-width: 30rem; margin: -0.25rem 0 0.75rem; color: var(--text-muted); font-size: 0.875rem; }

.workouts-table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.workouts-table th, .workouts-table td { text-align: left; padding: 0.4rem 0.8rem; border-bottom: 1px solid var(--border); }
.workouts-table th { color: var(--text-muted); font-weight: 600; }
.workouts-more-note { color: var(--text-muted); font-size: 0.9rem; margin-top: 0.5rem; }

.source-links { display: flex; gap: 1.5rem; margin-bottom: 1rem; }
.source-links a { font-weight: 600; }
#overlay-toggles { display: flex; flex-wrap: wrap; gap: 0.75rem 2.5rem; margin-bottom: 0.75rem; }
.overlay-toggles { display: flex; flex-direction: column; gap: 0.3rem; }
.overlay-toggles label { display: flex; align-items: center; gap: 0.35rem; color: var(--text-muted); font-size: 0.9rem; }
.overlay-toggle-group { margin-bottom: 0; }
.overlay-toggle-group-label { display: block; color: var(--text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.3rem; }
.overlay-band-key { display: flex; gap: 1.25rem; align-items: center; margin-bottom: 0.75rem; color: var(--text-muted); font-size: 0.9rem; }
.band-swatch { display: inline-block; width: 14px; height: 14px; border-radius: 3px; vertical-align: middle; margin-right: 0.3rem; }
.band-swatch-exercise { background: rgba(72, 187, 120, 0.55); }
.band-swatch-sleep { background: rgba(120, 170, 255, 0.45); }
.band-swatch-cgm { background: var(--accent-cgm); }
.band-swatch-heart-rate { background: var(--accent-heart-rate); }
.band-swatch-blood-oxygen { background: var(--accent-blood-oxygen); }
.band-swatch-respiratory { background: var(--accent-respiratory); }
.band-swatch-steps { background: var(--accent-steps); }
.band-swatch-energy { background: var(--accent-energy); }
.band-swatch-basal-energy { background: var(--accent-basal-energy); }
.band-swatch-distance { background: var(--accent-distance); }
.band-swatch-flights { background: var(--accent-flights); }
.band-swatch-exercise-time { background: var(--accent-exercise-time); }
.band-swatch-physical-effort { background: var(--accent-physical-effort); }
/* The overlay chart carries two dense continuous series (CGM every ~5min,
   heart rate every ~5min, both over a 7-day window -- thousands of points
   combined) plus shaded exercise/sleep bands and up to 9 more toggleable
   series -- the standard 300px .chart-container height (fine for every
   other, single-series chart on the site) is too cramped for this much
   information to stay readable. */
#overlay .chart-container { height: 480px; }

/* /reports comparison page -- metric rows and status pills. Reuses this
   app's existing tokens throughout: --trend-good/--trend-bad/
   --accent-muscle for the three pill states (matching the existing
   Improved/Watch/Flat vocabulary the dashboard's own trend arrows
   already use for --trend-good/--trend-bad; --accent-muscle -- already
   an established amber elsewhere in this file -- covers "Watch," a
   deliberately less alarming color than --trend-bad's red). */
.metric-group { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-bottom: 1.5rem; }
.metric-row { display: grid; grid-template-columns: 200px 1fr 90px; align-items: center; gap: 1rem; padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); }
.metric-label { font-size: 0.9rem; color: var(--text); }
.metric-values { font-size: 0.85rem; color: var(--text-muted); text-align: right; white-space: nowrap; }
.metric-values .now-val { color: var(--text); font-weight: 600; }
.metric-values .arrow { margin: 0 0.2rem; }

.report-pill { display: inline-block; border: 1px solid currentColor; border-radius: 20px; padding: 0.15rem 0.55rem; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; justify-self: end; }
.report-pill.improved { color: var(--trend-good); }
.report-pill.watch { color: var(--accent-muscle); }
.report-pill.flat { color: var(--text-muted); }

/* level-band colors -- where the CURRENT value sits against its
   guideline, a distinct axis from the trend pill above (which
   compares before vs. now). Four tiers reusing only existing tokens:
   needs_attention/fair/good match the trend-bad/accent-muscle/
   trend-good vocabulary already established above; excellent gets
   this page's own primary accent (--accent-cgm) so the top tier reads
   as a distinct step up from merely "good," not just a repeated
   green. Shared by both .level-word (inline, in the brief sentence)
   and .level-badge (next to the value). */
.level-word { font-weight: 600; }
.level-word.needs_attention { color: var(--trend-bad); }
.level-word.fair { color: var(--accent-muscle); }
.level-word.good { color: var(--trend-good); }
.level-word.excellent { color: var(--accent-cgm); }

.level-badge { display: inline-block; margin-left: 0.35rem; padding: 0.05rem 0.4rem; border: 1px solid currentColor; border-radius: 10px; font-size: 0.65rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.level-badge.needs_attention { color: var(--trend-bad); }
.level-badge.fair { color: var(--accent-muscle); }
.level-badge.good { color: var(--trend-good); }
.level-badge.excellent { color: var(--accent-cgm); }

/* Always-visible plain-language "what is this + how am I doing"
   sentence, and the "More info" disclosure (plain <details>/<summary>,
   no JS) beneath it for the deeper technical explanation. Both sit
   directly under their .metric-row as siblings, not nested inside it,
   so they can span the row's full width without fighting its own
   column grid. */
.metric-brief { margin: 0; padding: 0 1rem 0.5rem; font-size: 0.82rem; color: var(--text-muted); line-height: 1.45; }
.metric-description { border-bottom: 1px solid var(--border); }
.metric-description summary { cursor: pointer; padding: 0.4rem 1rem; font-size: 0.78rem; color: var(--text-muted); }
.metric-description summary:hover { color: var(--text); }
.metric-description p { margin: 0; padding: 0 1rem 0.75rem; font-size: 0.82rem; color: var(--text-muted); line-height: 1.45; }
.metric-group > *:last-child { border-bottom: none; }

.metric-checklist-group { margin-bottom: 1rem; }
.metric-checkbox { display: block; color: var(--text-muted); font-size: 0.85rem; margin-bottom: 0.2rem; }

.report-toolbar { display: flex; justify-content: flex-end; margin-bottom: 1rem; }
.share-button { display: inline-block; padding: 0.35rem 0.9rem; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); color: var(--text); font-size: 0.85rem; text-decoration: none; }
.share-button:hover { border-color: var(--accent-cgm); color: var(--accent-cgm); }

@media (max-width: 620px) {
  .metric-row { grid-template-columns: 130px 1fr 70px; gap: 0.5rem; }
}

/* This app's whole palette is dark-only (--bg/--text near-white-on-near-
   black), and browsers drop background colors by default when printing --
   without this override, the /reports print/share view (and any other
   page's print output) renders near-invisible light-grey text on white
   paper. Scoped narrowly: only the print-time colors change, nothing in
   the on-screen dark theme is touched. */
@media print {
  body { background: #fff; color: #000; }
  .metric-group { background: #fff; border-color: #ccc; }
  .metric-label, .metric-values, .metric-values .now-val, .stat-target, .metric-brief { color: #000; }
}

.print-main { max-width: 760px; margin: 0 auto; padding: 2rem 1.5rem; }
