/* AtomicGain - "the instrument".
   The app weighs decisions, so it is dressed as something calibrated: milled
   surfaces, hairline rules, and every number set in mono.

   One rule holds the palette together: GREEN AND RED MEAN DATA. They are only
   ever used to say "this measurement is good / bad". Neutral chrome - focus
   rings, the active date, the selected day - uses the periwinkle accent, so a
   coloured surface always carries meaning instead of decoration. */

/* ------------------------------------------------------------------- fonts */
/* Vendored into public/fonts/. Nothing is fetched from the network, and the
   stacks below degrade to system faces if those files ever go missing. */

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/InstrumentSans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/InstrumentSans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/JetBrainsMono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/JetBrainsMono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------ tokens */

:root {
  /* surfaces, lit from above */
  --bg: #0a0d13;
  --surface: #11151d;
  --surface-2: #171d27;
  --surface-3: #1e2532;
  --line: #232b38;
  --line-soft: #1a212c;
  --line-strong: #364052;

  /* text */
  --text: #e9edf5;
  --muted: #808b9e;
  --faint: #5a6474;

  /* data semantics - never used on neutral chrome */
  --good: #34d99a;
  --bad: #ff5f70;
  --trend: #ffb020;
  --amber: #ffb020;

  /* chrome accent - never used to mean good or bad */
  --accent: #7b8cff;
  --accent-2: #a06bff;

  --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, 'Courier New', monospace;

  --radius: 16px;
  --radius-sm: 11px;
  --thumb: 22px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --shadow-card: 0 14px 34px -24px rgba(0, 0, 0, 0.95);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background:
    radial-gradient(1100px 520px at 50% -180px, rgba(123, 140, 255, 0.07), transparent 70%),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font: 15px/1.55 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main {
  max-width: 1180px;
  margin: 0 auto;
  padding: 22px 20px 72px;
}

/* Every control gets a keyboard affordance. There were none before. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* All numerals are mono and tabular, so nothing jitters as values change. */
.mono, .stat-value, .badge, .chip-sign, .rk-num, .slope, .delta,
.gauge-value, .log-btn-points, .today-pill-value, .net-value, .lag, .char-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.note { color: var(--muted); font-size: 12.5px; margin: 12px 0 0; }
.hint { color: var(--faint); font-size: 13px; }

/* ----------------------------------------------------------------- topbar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px max(20px, calc((100% - 1180px) / 2));
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border-bottom: 1px solid var(--line-soft);
  transition: padding 220ms var(--ease), background 220ms, border-color 220ms;
}
/* Shrinks once you leave the top, so the today figure follows you down the
   page without taking a band of it the whole way. */
.topbar.condensed {
  padding-top: 9px;
  padding-bottom: 9px;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  border-bottom-color: var(--line);
}
.brand { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.topbar h1 {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.015em;
  transition: font-size 220ms var(--ease);
}
.topbar.condensed h1 { font-size: 16px; }
.topbar.condensed .tagline { display: none; }
.tagline {
  margin: 0;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
}

.topbar-right { display: flex; align-items: center; gap: 14px; }

/* Hosted mode only, and quiet on purpose: it is the least interesting control
   on the page and should never compete with the today figure beside it.
   Neutral chrome, so --muted and --accent -- never --good or --bad. */
.signout {
  border: 0;
  background: none;
  padding: 4px 2px;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.signout:hover { color: var(--muted); }
/* Own `display` would otherwise beat the hidden attribute's UA rule. */
.signout[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .signout { transition: color 160ms; }
}

.today-pill {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  transition: border-color 200ms, box-shadow 200ms;
}
.today-pill-label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}
.today-pill-value { font-size: 14px; font-weight: 700; }
.today-pill.good { border-color: color-mix(in srgb, var(--good) 40%, transparent); }
.today-pill.bad { border-color: color-mix(in srgb, var(--bad) 40%, transparent); }
.today-pill.good .today-pill-value { color: var(--good); }
.today-pill.bad .today-pill-value { color: var(--bad); }

/* ------------------------------------------------------------------ cards */

.card {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 150px),
    var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045), var(--shadow-card);
}
.card h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

/* ------------------------------------------------------------------- hero */
/* The page's thesis: which way the last 30 days went, before anything else. */

.hero {
  display: grid;
  grid-template-columns: minmax(180px, 240px) 1fr;
  gap: 30px;
  align-items: center;
  overflow: hidden;
}
/* A hairline along the top edge, coloured by the answer itself. */
.hero::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--hero-tone, var(--line-strong)), transparent);
}
.hero.good { --hero-tone: var(--good); }
.hero.bad { --hero-tone: var(--bad); }

.hero-net {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 46px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  margin: 10px 0 9px;
}
.hero-net.good { color: var(--good); }
.hero-net.bad { color: var(--bad); }

.hero-verdict { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13.5px; }
.hero-arrow { font-size: 9px; }
.hero-arrow.good, .hero-word.good { color: var(--good); }
.hero-arrow.bad, .hero-word.bad { color: var(--bad); }
.hero-word { font-weight: 600; color: var(--muted); }
.hero-rate {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  color: var(--faint);
}

.hero-spark { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* aspect-ratio comes from the inline style, built at the measured width. */
.ag-spark { width: 100%; display: block; }
.hero-meta {
  display: flex;
  gap: 20px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--faint);
}
.hero-meta b { color: var(--muted); font-weight: 700; }

/* ----------------------------------------------------------------- logger */

.logger { position: relative; overflow: hidden; }

.backfill-bar {
  display: none;
  align-items: center;
  gap: 10px;
  margin: -20px -20px 16px;
  padding: 10px 18px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--amber) 18%, transparent),
    color-mix(in srgb, var(--amber) 9%, transparent));
  border-bottom: 1px solid color-mix(in srgb, var(--amber) 32%, transparent);
  color: var(--amber);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.logger.backfill { border-color: color-mix(in srgb, var(--amber) 34%, var(--line)); }
.logger.backfill .backfill-bar { display: flex; }
#backfill-clear {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--amber);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  border-radius: 6px;
  opacity: 0.75;
  transition: opacity 150ms;
}
#backfill-clear:hover { opacity: 1; }

/* date row */

.date-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.date-btn {
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: 10px;
  padding: 8px 14px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: color 150ms, border-color 150ms, background 150ms, transform 150ms;
}
.date-btn:hover { color: var(--text); border-color: var(--line-strong); transform: translateY(-1px); }
.date-btn.active {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 13%, var(--surface-2));
}
.date-input { color: var(--text); font-family: var(--font-mono); font-size: 12px; }
.date-input::-webkit-calendar-picker-indicator { filter: invert(0.62); cursor: pointer; }
.date-echo {
  margin-left: auto;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 11.5px;
}

/* repeat chips */

.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; min-height: 22px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 320px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 999px;
  padding: 6px 14px 6px 7px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: border-color 150ms, background 150ms, transform 150ms;
}
.chip:hover {
  border-color: var(--line-strong);
  background: var(--surface-3);
  transform: translateY(-1px);
}
.chip:active { transform: translateY(0); }
.chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip-sign {
  flex: none;
  font-weight: 700;
  font-size: 11px;
  padding: 3px 7px;
  border-radius: 999px;
}
.chip.good .chip-sign { background: color-mix(in srgb, var(--good) 16%, transparent); color: var(--good); }
.chip.bad .chip-sign { background: color-mix(in srgb, var(--bad) 16%, transparent); color: var(--bad); }

/* composer */

.composer-wrap { position: relative; }
.composer {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  font: inherit;
  font-size: 16px;
  padding: 16px 68px 16px 17px;
  transition: border-color 160ms, box-shadow 160ms;
}
/* The border + ring IS the focus indicator here, so dropping the outline is safe. */
.composer:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.composer::placeholder { color: var(--faint); font-size: 14.5px; }
.char-count {
  position: absolute;
  right: 15px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 11px;
  color: var(--faint);
  pointer-events: none;
}
.char-count.near-limit { color: var(--amber); }

/* good / bad -- a choice, not a commit */

.type-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.type-btn {
  position: relative;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  border-radius: 12px;
  padding: 15px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 180ms, border-color 180ms, background 180ms,
              box-shadow 180ms, transform 180ms;
}
.type-btn:hover { color: var(--text); border-color: var(--line-strong); transform: translateY(-1px); }
.type-btn:active { transform: translateY(0); }

/* A dot appears on the selected side -- colour is never the only signal. */
.type-btn::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%) scale(0);
  transition: transform 220ms var(--ease);
}
.type-btn.selected::before { transform: translateY(-50%) scale(1); }

.type-btn.good.selected {
  color: var(--good);
  border-color: color-mix(in srgb, var(--good) 48%, transparent);
  background: color-mix(in srgb, var(--good) 12%, var(--surface-2));
  box-shadow: inset 0 0 28px -10px var(--good);
}
.type-btn.bad.selected {
  color: var(--bad);
  border-color: color-mix(in srgb, var(--bad) 48%, transparent);
  background: color-mix(in srgb, var(--bad) 12%, var(--surface-2));
  box-shadow: inset 0 0 28px -10px var(--bad);
}

/* ------------------------------------------------------------- the gauge */
/* The signature element. --fill (0..1) is written by app.js on every input;
   --tone is the colour of whichever side is currently selected. */

.gauge {
  --fill: 0.222;
  --tone: var(--accent);
  margin-top: 18px;
}
.logger.picked-good .gauge { --tone: var(--good); }
.logger.picked-bad .gauge { --tone: var(--bad); }

.gauge-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.gauge-read { display: flex; align-items: baseline; gap: 9px; }
.gauge-value {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--tone);
  transition: color 220ms;
}
.gauge-word {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  min-width: 46px;
}

.gauge-track { position: relative; height: var(--thumb); margin-top: 10px; }

/* rail + the calibration ticks, one per whole point */
.gauge-track::before {
  content: '';
  position: absolute;
  left: calc(var(--thumb) / 2);
  right: calc(var(--thumb) / 2);
  top: 50%;
  transform: translateY(-50%);
  height: 6px;
  border-radius: 999px;
  background:
    repeating-linear-gradient(90deg,
      var(--line-strong) 0 1px, transparent 1px calc(100% / 9)),
    var(--surface-2);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.55);
}

/* the filled portion, in the active tone */
.gauge-track::after {
  content: '';
  position: absolute;
  left: calc(var(--thumb) / 2);
  top: 50%;
  transform: translateY(-50%);
  width: calc(var(--fill) * (100% - var(--thumb)));
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--tone) 45%, transparent), var(--tone));
  box-shadow: 0 0 14px -3px var(--tone);
}

/* the streak left behind when the fill retracts after a log */
.gauge-trail {
  position: absolute;
  top: 50%;
  left: calc(var(--thumb) / 2 + var(--trail-a, 0) * (100% - var(--thumb)));
  width: calc((var(--trail-b, 0) - var(--trail-a, 0)) * (100% - var(--thumb)));
  height: 6px;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-50%);
}
.gauge[data-trail-tone='good'] .gauge-trail { background: var(--good); }
.gauge[data-trail-tone='bad'] .gauge-trail { background: var(--bad); }

#weight {
  position: relative;
  z-index: 2;
  width: 100%;
  height: var(--thumb);
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: grab;
}
#weight:active { cursor: grabbing; }
#weight::-webkit-slider-runnable-track { height: var(--thumb); background: transparent; }
#weight::-moz-range-track { height: var(--thumb); background: transparent; }
#weight::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--thumb);
  height: var(--thumb);
  border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 32%, #ffffff, #dfe4f2 58%, #b4bccf);
  box-shadow:
    0 0 0 3px var(--surface),
    0 0 0 4px color-mix(in srgb, var(--tone) 55%, transparent),
    0 0 18px -3px var(--tone),
    0 3px 8px rgba(0, 0, 0, 0.65);
  transition: box-shadow 200ms, transform 140ms var(--ease);
}
#weight::-moz-range-thumb {
  width: var(--thumb);
  height: var(--thumb);
  border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 32%, #ffffff, #dfe4f2 58%, #b4bccf);
  box-shadow:
    0 0 0 3px var(--surface),
    0 0 0 4px color-mix(in srgb, var(--tone) 55%, transparent),
    0 0 18px -3px var(--tone),
    0 3px 8px rgba(0, 0, 0, 0.65);
}
#weight:hover::-webkit-slider-thumb { transform: scale(1.06); }
#weight:active::-webkit-slider-thumb { transform: scale(1.12); }

.gauge-anchors {
  display: flex;
  justify-content: space-between;
  margin-top: 7px;
}
.anchor {
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------- log button */

.log-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  background: var(--surface-2);
  color: var(--faint);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 200ms, color 200ms, box-shadow 200ms,
              transform 160ms, border-color 200ms;
}
.log-btn:disabled { cursor: not-allowed; }
.log-btn:not(:disabled) {
  border-color: transparent;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28),
              0 10px 26px -14px var(--tone-btn, transparent);
}
.log-btn.good:not(:disabled) {
  --tone-btn: var(--good);
  background: linear-gradient(135deg, color-mix(in srgb, var(--good) 72%, #06120d), var(--good));
  color: #04241a;
}
.log-btn.bad:not(:disabled) {
  --tone-btn: var(--bad);
  background: linear-gradient(135deg, color-mix(in srgb, var(--bad) 72%, #180509), var(--bad));
  color: #2d0409;
}
.log-btn:not(:disabled):hover {
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3),
              0 16px 34px -14px var(--tone-btn, transparent);
}
.log-btn:not(:disabled):active { transform: translateY(0); }
.log-btn-points {
  font-weight: 700;
  font-size: 13px;
  padding: 3px 9px;
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.18);
}
.log-btn-points:empty { display: none; }

/* -------------------------------------------------------------- dot strip */

.dots-wrap { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.dots-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.dots-summary { color: var(--faint); font-family: var(--font-mono); font-size: 11px; }
.dots-summary .good { color: var(--good); }
.dots-summary .bad { color: var(--bad); }
.dots { display: flex; gap: 7px; margin-top: 11px; flex-wrap: wrap; }
.dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid transparent;
  cursor: pointer;
  padding: 0;
  opacity: var(--mag, 1);
  transition: transform 170ms var(--ease), box-shadow 170ms;
}
.dot.pos { background: var(--good); }
.dot.neg { background: var(--bad); }
.dot.zero { background: var(--line-strong); }
.dot.empty { background: transparent; border: 1.5px dashed var(--line-strong); opacity: 1; }
.dot.selected { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--amber); }
.dot.today { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--accent); }
.dot:hover { transform: scale(1.2); }

/* --------------------------------------------------------------- day list */

.day-list-net { display: flex; align-items: baseline; gap: 7px; }
.net-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}
.net-value { font-size: 15px; font-weight: 700; }
.net-value.good { color: var(--good); }
.net-value.bad { color: var(--bad); }

.day-list { list-style: none; margin: 0; padding: 0; }
.entry {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  margin: 0 -8px;
  border-radius: 9px;
  border-bottom: 1px solid var(--line-soft);
  transition: background 160ms;
}
.entry:last-child { border-bottom: 0; }
.entry:hover { background: var(--surface-2); }
.badge {
  flex: none;
  min-width: 44px;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 5px 0;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 150ms, transform 150ms;
}
.badge.good {
  background: color-mix(in srgb, var(--good) 15%, transparent);
  color: var(--good);
}
.badge.bad {
  background: color-mix(in srgb, var(--bad) 15%, transparent);
  color: var(--bad);
}
.badge:hover { transform: scale(1.05); border-color: currentColor; }
.entry-text { flex: 1; cursor: text; min-width: 0; word-break: break-word; }
.inline-edit {
  width: 100%;
  background: var(--bg);
  border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  padding: 6px 9px;
}
.inline-edit:focus { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.lag {
  flex: none;
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 13%, transparent);
  border-radius: 6px;
  padding: 2px 7px;
  font-size: 10.5px;
}
.del {
  flex: none;
  background: none;
  border: 0;
  color: var(--faint);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 7px;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 150ms, color 150ms;
}
.entry:hover .del, .del:focus-visible { opacity: 1; }
.del:hover { color: var(--bad); }

/* --------------------------------------------------------------- insights */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.stat {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), transparent 60%), var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  padding: 14px 15px;
  transition: border-color 180ms, transform 180ms;
}
.stat:hover { border-color: var(--line); transform: translateY(-2px); }
.stat-label {
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.stat-value {
  font-size: 27px;
  font-weight: 700;
  margin: 6px 0 3px;
  letter-spacing: -0.035em;
  line-height: 1.1;
}
.stat-value.good { color: var(--good); }
.stat-value.bad { color: var(--bad); }
.stat-value .unit { font-size: 14px; font-weight: 500; color: var(--faint); margin-left: 2px; }
.stat-sub { color: var(--muted); font-size: 11.5px; }
.delta { font-weight: 700; font-size: 11px; }
.delta.up { color: var(--good); }
.delta.down { color: var(--bad); }
.delta.flat { color: var(--faint); font-weight: 500; }

.ranking {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.rk-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.rk-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.rk-title.good { color: var(--good); }
.rk-title.bad { color: var(--bad); }
.rk-list { list-style: none; margin: 0; padding: 0; }
.rk-list li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 6px 0;
  font-size: 13.5px;
  border-bottom: 1px solid var(--line-soft);
}
.rk-list li:last-child { border-bottom: 0; }
.rk-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-num { color: var(--faint); font-size: 11.5px; white-space: nowrap; }
.rk-num b { color: var(--text); }
.rk-pts.good { color: var(--good); }
.rk-pts.bad { color: var(--bad); }

/* --------------------------------------------------------------- controls */

.controls { display: flex; align-items: center; gap: 12px; margin: 6px 0 16px; flex-wrap: wrap; }
.segmented {
  display: flex;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 3px;
}
.segmented button {
  background: none;
  border: 0;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  padding: 7px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: color 150ms, background 150ms;
}
.segmented button:hover { color: var(--text); }
.segmented button.active {
  background: color-mix(in srgb, var(--accent) 16%, var(--surface-2));
  color: var(--text);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}
.tag-filter {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 11px;
  padding: 9px 12px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: border-color 150ms;
}
.tag-filter:hover { border-color: var(--line-strong); }

/* ----------------------------------------------------------------- charts */

/* One primary chart, three supporting ones. The hierarchy is the point: Overall
   answers the question, the row underneath explains it. */
.chart-grid { display: flex; flex-direction: column; gap: 16px; }
.chart-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.chart { margin-bottom: 0; }
.chart-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.chart-primary .chart-head h2 { font-size: 16px; }

/* aspect-ratio is set inline by charts.js, derived from the measured width, so
   the viewBox and the rendered box always agree and nothing is letterboxed. */
.ag-svg { width: 100%; height: auto; display: block; }
.ag-svg .ag-tick {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
}
.ag-chart-empty {
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--faint);
  font-size: 13px;
  border: 1px dashed var(--line);
  border-radius: 12px;
}

.slope { font-size: 11.5px; font-weight: 700; }
.slope.good { color: var(--good); }
.slope.bad { color: var(--bad); }
.slope.flat { color: var(--faint); font-weight: 500; }

.legend {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  color: var(--faint);
  font-size: 11px;
  margin: 12px 0 0;
}
.key { width: 15px; height: 3px; border-radius: 2px; display: inline-block; }
.key + .key { margin-left: 8px; }
.key.good { background: var(--good); }
.key.bad { background: var(--bad); }
.key.trend { background: var(--trend); }
.key.trend-overall { background: var(--accent-2); }
.key.line { background: var(--text); }
.key.dash { background: repeating-linear-gradient(90deg, var(--muted) 0 4px, transparent 4px 7px); }
.sep { margin-left: 4px; }

/* ----------------------------------------------------- chart hover readout */

/* Chrome, not data: the hairline says "you are here", so it must be findable
   without competing with the line it is measuring. Hence the axis grey and a
   dotted stroke, matching the zero baselines already drawn in charts.js.
   No transition on these -- a crosshair that eases into place lags the pointer. */
.ag-focus, .ag-band-hi { opacity: 0; }
.ag-focus.on { opacity: 1; }
.ag-focus .ag-focus-halo { opacity: 0.18; }
.ag-band-hi.on { opacity: 0.6; }
.ag-band { cursor: crosshair; }

/* Fixed, like the toast, because a card would clip it: the bottom row of charts
   has no room underneath, and `overflow: hidden` on .chart would cut it off. */
.chart-tip {
  position: fixed;
  left: 0;
  top: 0;
  min-width: 148px;
  background: color-mix(in srgb, var(--surface-3) 92%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  padding: 9px 12px 10px;
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9);
  opacity: 0;
  pointer-events: none;
  z-index: 60;
}
.chart-tip.show { opacity: 1; }

.tip-when {
  margin: 0 0 7px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
/* The value is the strong element and the label the quiet one -- the legend's
   hierarchy inverted, because here the reader has the series and wants the
   number. Grid so the numbers line up in a column of their own. */
.tip-row {
  display: grid;
  grid-template-columns: 15px 1fr auto;
  align-items: center;
  gap: 8px;
  margin: 0;
}
.tip-row + .tip-row { margin-top: 3px; }
.tip-label { font-size: 11.5px; color: var(--muted); }
.tip-val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--text);
}
.key.blank { background: none; }
.tip-none { margin: 0; font-size: 11.5px; color: var(--faint); }

.footnote {
  color: var(--faint);
  font-size: 12.5px;
  margin: 28px auto 0;
  max-width: 720px;
  text-align: center;
  line-height: 1.7;
}
.footnote em { color: var(--muted); font-style: normal; font-weight: 600; }

/* ------------------------------------------------------------------ toast */

.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  display: flex;
  align-items: center;
  gap: 4px;
  overflow: hidden;
  transform: translate(-50%, 20px);
  background: color-mix(in srgb, var(--surface-3) 92%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  padding: 12px 18px;
  font-size: 13.5px;
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms var(--ease), transform 220ms var(--ease);
  z-index: 60;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.undo {
  background: none;
  border: 0;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  margin-left: 10px;
  padding: 2px 4px;
  border-radius: 6px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.undo:hover { color: var(--accent-2); }
/* Drains over the 5s undo window, so the deadline is visible rather than felt. */
.toast-bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
}

/* ----------------------------------------------------------------- motion */

@keyframes ag-rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}
@keyframes ag-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ag-trail {
  from { opacity: 0.8; transform: translateY(-50%) scaleX(1); }
  to { opacity: 0; transform: translateY(-50%) scaleX(0); }
}
@keyframes ag-sweep {
  from { background: color-mix(in srgb, var(--row-tone) 22%, transparent); transform: translateX(-6px); }
  to { background: transparent; transform: none; }
}
@keyframes ag-drain { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes ag-draw {
  from { stroke-dasharray: 1; stroke-dashoffset: 1; }
  to { stroke-dasharray: 1; stroke-dashoffset: 0; }
}
@keyframes ag-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes ag-pop {
  from { opacity: 0; transform: scale(0.4); }
  to { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: no-preference) {
  /* One orchestrated entrance, top to bottom. */
  .topbar { animation: ag-fade 500ms both; }
  main > * { animation: ag-rise 620ms var(--ease) both; }
  main > *:nth-child(1) { animation-delay: 60ms; }
  main > *:nth-child(2) { animation-delay: 120ms; }
  main > *:nth-child(3) { animation-delay: 180ms; }
  main > *:nth-child(4) { animation-delay: 240ms; }
  main > *:nth-child(5) { animation-delay: 300ms; }
  main > *:nth-child(6) { animation-delay: 360ms; }
  main > *:nth-child(7) { animation-delay: 420ms; }

  /* The sparkline draws itself once, on the first paint only. One thing moves
     at a time: the card finishes rising (60ms + 620ms, and its ease-out has
     visually settled well before the end) before the line starts, and the line
     lands before the dot pops. Overlapping any of these reads as two competing
     motions rather than one gesture. If you retime this, update the class
     removal in renderHero() -- it has to outlast the last animation. */
  .hero.draw-in .ag-line { animation: ag-draw 760ms 380ms cubic-bezier(0.4, 0, 0.2, 1) both; }
  .hero.draw-in .ag-last { animation: ag-pop 300ms 1140ms var(--ease) both; transform-box: fill-box; transform-origin: center; }

  .gauge.retracting .gauge-trail {
    animation: ag-trail 460ms var(--ease) forwards;
    transform-origin: var(--trail-origin, left) center;
  }

  .entry.just-added { animation: ag-sweep 1500ms ease-out; }
  .entry.good.just-added { --row-tone: var(--good); }
  .entry.bad.just-added { --row-tone: var(--bad); }

  .toast.show .toast-bar { animation: ag-drain 5s linear forwards; }

  .chart-grid.draw-in .ag-line { animation: ag-draw 950ms cubic-bezier(0.4, 0, 0.2, 1) both; }
  .chart-grid.draw-in .ag-trend { animation: ag-draw 950ms 220ms cubic-bezier(0.4, 0, 0.2, 1) both; }
  .chart-grid.draw-in .ag-last { animation: ag-pop 420ms 780ms var(--ease) both; transform-box: fill-box; transform-origin: center; }
  .chart-grid.draw-in .ag-bar {
    animation: ag-grow 520ms var(--ease) both;
    animation-delay: calc(var(--i, 0) * 11ms);
    transform-box: fill-box;
    transform-origin: center bottom;
  }

  /* Only the readout box fades; the crosshair and the bar wash stay instant,
     since they have to keep up with the pointer. */
  .chart-tip { transition: opacity 120ms var(--ease); }
  .ag-band-hi { transition: opacity 120ms var(--ease); }
}

/* ------------------------------------------------------------- responsive */

@media (max-width: 1000px) {
  .chart-row { grid-template-columns: 1fr; }
}

@media (max-width: 780px) {
  .hero { grid-template-columns: 1fr; gap: 18px; }
  .hero-net { font-size: 40px; }
}

@media (max-width: 700px) {
  main { padding: 18px 14px 56px; }
  .card { padding: 16px; border-radius: 14px; }
  .backfill-bar { margin: -16px -16px 14px; }
  .date-row { gap: 6px; }
  .date-echo { width: 100%; margin-left: 0; order: 3; }
  .composer { font-size: 16px; padding: 14px 62px 14px 14px; }
  .stats { grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
  .stat-value { font-size: 23px; }
  .topbar { padding: 12px 14px; }
  .tagline { display: none; }
  .del { opacity: 1; }
  .dots { gap: 6px; }
  .dot { width: 20px; height: 20px; }
}

/* ------------------------------------------------------------- sign in page */
/* login.html only, and hosted mode only. Kept here rather than in a <style>
   block so the Content-Security-Policy can refuse inline styles outright.

   Note the colour: --accent, never --good. A sign-in button is chrome, and
   green and red stay reserved for saying a measurement was good or bad. */

.auth-page { display: flex; min-height: 100vh; min-height: 100dvh; }
.auth-main {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 420px;
  padding: 24px 20px 64px;
}
.auth-card { width: 100%; margin-bottom: 0; padding: 26px 24px; }

.auth-brand { flex-direction: column; gap: 3px; margin-bottom: 26px; }
.auth-brand .tagline { display: block; }

.auth-form { display: flex; flex-direction: column; gap: 15px; }
.auth-field { display: flex; flex-direction: column; gap: 7px; }
/* .composer carries the field styling; only the composer's room for the
   character counter has to be given back. */
.auth-input { padding: 14px 15px; }

.auth-btn {
  width: 100%;
  margin-top: 4px;
  border: 1px solid transparent;
  border-radius: 12px;
  padding: 15px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 76%, #0b0f1c), var(--accent));
  color: #0b0f1f;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28),
              0 10px 26px -14px var(--accent);
}
.auth-btn:disabled {
  cursor: progress;
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--faint);
  box-shadow: none;
}

/* Amber, not red: this is a warning about the form, not a measurement that
   went badly. Same reasoning as .char-count.near-limit. */
.auth-error {
  margin: 0;
  min-height: 1.2em;
  color: var(--amber);
  font-size: 13px;
  opacity: 0;
}
.auth-error.show { opacity: 1; }

.auth-note { margin: 20px 0 0; padding-top: 16px; border-top: 1px solid var(--line-soft); }

@media (prefers-reduced-motion: no-preference) {
  .auth-btn { transition: background 200ms, box-shadow 200ms, transform 160ms, color 200ms; }
  .auth-btn:not(:disabled):hover {
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3),
                0 16px 34px -14px var(--accent);
  }
  .auth-btn:not(:disabled):active { transform: translateY(0); }
  .auth-error { transition: opacity 180ms; }
}
