/* FitPulse — charcoal surfaces, one electric lime accent, big confident numbers.
   Structure still does the work: hairline rules, tracked uppercase labels,
   generous space. Colour is reserved for one thing — your own effort.
   Tokens live here; change them and the whole app follows. */
:root {
  /* Dark is this app's home mode, but light is a real design, not a flip. */
  --ink: #16181A;
  --surface: #FFFFFF;
  --paper: #FFFFFF;
  --muted: #5F676E;
  --outline: rgba(22, 24, 26, 0.15);
  --track: rgba(22, 24, 26, 0.10);

  /* Three accent tokens, not one. Raw lime is 1.24:1 on white — brilliant as a
     fill you put dark ink on, invisible as a line or a word. So: `lime` is the
     chip, `mark` is graphic marks (>=3:1), `mark-text` is type (>=4.5:1). */
  --lime: #C6F833;
  --lime-ink: #16181A;         /* what sits on top of a lime fill */
  --mark: #6F7F00;
  --mark-text: #4A5600;
  --mark-soft: rgba(111, 127, 0, 0.14);

  --accent: var(--ink);        /* chrome accents stay ink, per the house style */
  --radius: 6px;
  --radius-lg: 14px;
  --topbar-h: 60px;
  --sidebar-w: 280px;
  --line: 1px;
  --toggle-border: none;
  --shadow: none;
  --font-display: 'Space Grotesk', sans-serif;
  --font-body: ui-monospace, 'JetBrains Mono', monospace;

  --h-transform: uppercase;
  --h-spacing: 0.1em;
  --h-weight: 600;
  --l-transform: uppercase;
  --l-spacing: 0.18em;
  --l-weight: 600;

  --border: color-mix(in srgb, var(--ink) 16%, transparent);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --pop: cubic-bezier(0.34, 1.56, 0.64, 1);
}

.dark {
  --ink: #F2F4F3;
  --surface: #16181A;
  --paper: #1E2124;            /* a raised charcoal, so cards read without a line */
  --muted: #8A9099;
  --outline: rgba(255, 255, 255, 0.13);
  --track: rgba(255, 255, 255, 0.10);
  --mark: #C6F833;             /* 14.3:1 on charcoal — the accent can be itself here */
  --mark-text: #C6F833;
  /* Lower than the light-mode fill: bright lime over charcoal reads far heavier
     at the same alpha, and the slab starts competing with its own line. */
  --mark-soft: rgba(198, 248, 51, 0.09);
  --accent: var(--ink);
  --border: color-mix(in srgb, var(--ink) 20%, transparent);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--surface);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

:focus-visible { outline: 3px solid var(--mark); outline-offset: 2px; }

/* Every figure in this app is a number first. Tabular figures keep the width
   fixed while a counter animates, so nothing jitters as the digits change. */
.num {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -0.02em;
  line-height: 1;
}

.eyebrow {
  font-size: 0.68rem;
  font-weight: var(--l-weight);
  letter-spacing: var(--l-spacing);
  text-transform: var(--l-transform);
  color: var(--muted);
}

/* ---------- Splash ---------- */

.splash {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  animation: splash-lift 0.5s var(--ease) 0.9s both;
}

.splash.is-gone { display: none; }

.splash-name {
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 700;
  letter-spacing: var(--h-spacing);
  text-transform: var(--h-transform);
  animation: splash-in 0.4s var(--ease) both;
}

.splash-bar { width: 120px; height: 2px; background: var(--track); overflow: hidden; }

.splash-bar i {
  display: block;
  height: 100%;
  background: var(--mark);
  transform-origin: left;
  animation: splash-fill 0.85s var(--ease) 0.1s both;
}

@keyframes splash-lift { to { transform: translateY(-101%); } }
@keyframes splash-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes splash-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- Light / dark toggle ---------- */

.floating-controls {
  position: fixed;
  top: 14px;
  right: 14px;
  z-index: 45;
  display: flex;
  gap: 8px;
}

.mode-toggle {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  flex: none;
  cursor: pointer;
  color: inherit;
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius);
}

.mode-toggle:hover { border-color: var(--ink); }

.mode-toggle .mt-moon { display: none; }
.dark .mode-toggle .mt-sun,
.dark .mode-toggle .mt-rays { display: none; }
.dark .mode-toggle .mt-moon { display: block; }

/* ---------- Layout ---------- */

.main { max-width: 640px; margin: 0 auto; padding: 66px 18px 124px; }

/* ---------- Screens ----------
   One is mounted at a time; the switch is a short lift so the app feels like
   panels of one surface rather than three separate pages. */

.screen { display: none; }
.screen.is-active { display: block; animation: screen-in 0.38s var(--ease) both; }

@keyframes screen-in { from { opacity: 0; transform: translateY(10px); } }

.screen-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 22px;
}

.screen-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: var(--h-weight);
  letter-spacing: var(--h-spacing);
  text-transform: var(--h-transform);
}

.screen-sub { margin: 2px 0 0; font-size: 0.78rem; color: var(--muted); }

/* ---------- Streak badge ----------
   The one lime fill on the home screen. It marks a live run of goal-clearing
   days, so it only earns the accent while the streak is actually alive. */

.streak {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px 7px 10px;
  border-radius: 999px;
  background: var(--lime);
  color: var(--lime-ink);
  border: var(--line) solid transparent;
}

.streak--cold { background: transparent; color: var(--muted); border-color: var(--outline); }

.streak-n { font-size: 1rem; font-weight: 700; }

.streak-label {
  font-size: 0.6rem;
  font-weight: var(--l-weight);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.15;
  max-width: 5.5em;
}

.streak svg { flex: none; }

/* ---------- Activity ring ----------
   The signature. Steps toward today's goal, drawn as one sweep from twelve
   o'clock, with the number living inside the ring rather than beside it. */

.ring-wrap {
  display: grid;
  place-items: center;
  margin: 6px 0 26px;
}

.ring {
  position: relative;
  width: min(272px, 72vw);
  aspect-ratio: 1;
}

.ring svg { width: 100%; height: 100%; display: block; transform: rotate(-90deg); }

/* Thin enough to read as an instrument rather than a donut: the number inside
   is the loud element, the ring is the measure around it. */
.ring-track { fill: none; stroke: var(--track); stroke-width: 7; }

.ring-fill {
  fill: none;
  stroke: var(--mark);
  stroke-width: 7;
  stroke-linecap: round;
  transition: stroke-dashoffset 1.15s var(--ease);
}

/* A full goal closes the loop — the cap change is the reward. */
.ring.is-complete .ring-fill { stroke-linecap: butt; }

.ring-mid {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 2px;
  text-align: center;
}

.ring-value { font-size: clamp(2.6rem, 13vw, 3.6rem); font-weight: 700; }
.ring-of { font-size: 0.7rem; color: var(--muted); letter-spacing: 0.04em; }

.ring-cap {
  margin-top: 6px;
  font-size: 0.6rem;
  font-weight: var(--l-weight);
  letter-spacing: var(--l-spacing);
  text-transform: uppercase;
  color: var(--mark-text);
}

/* ---------- Tiles ---------- */

.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }

.tile {
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius-lg);
  padding: 14px 15px 12px;
}

.tile-value { font-size: 1.75rem; font-weight: 700; }
.tile-unit { font-size: 0.8rem; font-weight: 500; color: var(--muted); margin-left: 3px; }

.tile-label {
  margin-top: 5px;
  font-size: 0.63rem;
  font-weight: var(--l-weight);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- Sparkline ---------- */

/* <figure> carries a 40px side margin from the UA stylesheet, which insets any
   chart card unless it is reset here. */
figure.spark, figure.card { margin-left: 0; margin-right: 0; }

.spark {
  margin-top: 26px;
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius-lg);
  padding: 14px 15px 11px;
}

.spark-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.spark svg { width: 100%; height: 46px; display: block; }

/* ---------- Weekly bars ----------
   Emphasis, not category: the best day carries the accent and every other day
   recedes to the track colour, so the chart answers "which day" at a glance
   and needs no legend. */

.card {
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius-lg);
  padding: 16px 16px 12px;
  margin-bottom: 22px;
}

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

/* Both halves of a chart header stay on one line at 390px: the caption keeps
   its tracking, and the figure beside it never wraps mid-phrase. */
.card-head .eyebrow, .spark-head .eyebrow { letter-spacing: 0.1em; }
.card-head .delta, .spark-head .delta { flex: none; white-space: nowrap; }

.card-total { font-size: 1.35rem; font-weight: 700; }

/* The latest reading, so a plot says what the level IS as well as how it moved. */
.card-now { font-size: 1.9rem; font-weight: 700; line-height: 1.05; margin-top: 3px; }
.card-unit { font-size: 0.78rem; font-weight: 500; color: var(--muted); margin-left: 4px; }

.bars {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: end;
  gap: 2px;                      /* the surface gap doing the separating */
  height: 132px;
}

.bar {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

/* The plot area proper. Bar heights are a percentage of this, not of the whole
   column, so a labelled bar and an unlabelled one stay comparable. */
.bar-track {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.bar i {
  display: block;
  width: 100%;
  max-width: 26px;
  background: var(--track);
  border-radius: 4px 4px 0 0;    /* rounded data-end, square foot on the baseline */
  flex: none;
  height: 0;
  transition: height 0.75s var(--ease);
}

/* A rest day is zero, and zero draws nothing — a minimum bar height would put a
   mark where there is no training. The weekday label still holds the column. */
.bar[data-h="0.0"] i { display: none; }

.bar.is-best i { background: var(--mark); }
.bar:hover i { background: var(--mark-soft); }
.bar.is-best:hover i { background: var(--mark); filter: brightness(1.08); }

/* Reserved on every column, labelled or not, so all bars measure against the
   same track height. */
.bar-value {
  flex: none;
  height: 1rem;
  line-height: 1rem;
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: var(--mark-text);
  opacity: 0;
  transition: opacity 0.4s var(--ease) 0.5s;
}

.bar.is-best .bar-value { opacity: 1; }

.bar-day {
  flex: none;
  font-size: 0.63rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--outline);
  width: 100%;
  text-align: center;
}

.bar.is-best .bar-day { color: var(--mark-text); }

/* ---------- Line charts ----------
   Resting heart rate and weight are two different units, so they are two
   charts stacked on a shared x-axis — never one plot with two y-scales, which
   would invent a correlation the data does not contain. */

.plot { position: relative; }
.plot svg { width: 100%; height: 128px; display: block; overflow: visible; }

.plot-line {
  fill: none;
  stroke: var(--mark);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.plot-area { fill: var(--mark-soft); stroke: none; }
.plot-grid { stroke: var(--outline); stroke-width: 1; vector-effect: non-scaling-stroke; }

.plot-dot { fill: var(--mark); stroke: var(--paper); stroke-width: 2; }
.plot-hit { fill: transparent; cursor: pointer; }
.plot-hit:hover + .plot-dot, .plot-hit:focus-visible + .plot-dot { r: 6; }

.plot-scale {
  display: flex;
  justify-content: space-between;
  font-size: 0.62rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--outline);
}

.delta { font-size: 0.7rem; color: var(--mark-text); font-variant-numeric: tabular-nums; }
.delta--flat { color: var(--muted); }

/* ---------- Session list ---------- */

/* The last row clears the floating + button rather than sitting under it. */
.sessions {
  list-style: none;
  margin: 0 0 72px;
  padding: 0;
  display: grid;
  gap: 10px;
}

.session {
  display: flex;
  align-items: center;
  gap: 13px;
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius-lg);
  padding: 13px 15px;
  opacity: 0;
  transform: translateY(12px);
}

.session.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}

/* Discipline is named in type, not colour-coded — three tags would have meant
   three hues carrying meaning that the words already carry. */
.session-kind {
  flex: none;
  width: 46px;
  font-size: 0.58rem;
  font-weight: var(--l-weight);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border-right: 1px solid var(--outline);
  padding-right: 10px;
}

.session-body { flex: 1; min-width: 0; }

.session-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.session-meta {
  margin: 2px 0 0;
  font-size: 0.7rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.session-right { flex: none; display: flex; align-items: center; gap: 12px; }

.session-mins { font-size: 1.05rem; font-weight: 700; }
.session-mins span { font-size: 0.66rem; color: var(--muted); font-weight: 500; }

/* Effort, 1–5, as line-work: filled rungs against empty ones. */
.effort { display: flex; align-items: flex-end; gap: 2px; height: 16px; }
.effort i { width: 3px; border-radius: 1px; background: var(--track); }
.effort i.on { background: var(--mark); }

.session-del {
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 4px 2px;
  flex: none;
}

.session-del:hover { color: var(--ink); }

.empty {
  color: var(--muted);
  text-align: center;
  padding: 44px 16px;
  border: var(--line) dashed var(--outline);
  border-radius: var(--radius-lg);
  font-size: 0.85rem;
}

/* ---------- Composer ---------- */

.composer {
  display: grid;
  gap: 10px;
  background: var(--paper);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius-lg);
  padding: 15px;
  margin-bottom: 18px;
}

.composer[hidden] { display: none; }
.composer-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.composer-actions { display: flex; gap: 10px; justify-content: flex-end; }

.field { display: grid; gap: 5px; }

.field > span {
  font-size: 0.6rem;
  font-weight: var(--l-weight);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

input, select {
  font: inherit;
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: inherit;
  background: var(--surface);
  border: var(--line) solid var(--outline);
  border-radius: var(--radius);
  padding: 10px 12px;
  width: 100%;
}

input:focus, select:focus { outline: 2px solid var(--mark); outline-offset: -2px; }

.btn {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: var(--l-weight);
  letter-spacing: var(--l-spacing);
  text-transform: var(--l-transform);
  cursor: pointer;
  padding: 11px 20px;
  border: var(--line) solid transparent;
  border-radius: var(--radius);
  background: var(--lime);
  color: var(--lime-ink);
}

.btn:hover { filter: brightness(1.06); }
.btn--ghost { background: transparent; color: inherit; border-color: var(--outline); }
.btn--ghost:hover { filter: none; border-color: var(--ink); }

/* ---------- Floating action button ---------- */

.fab {
  position: fixed;
  right: 20px;
  bottom: 76px;
  z-index: 35;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: var(--line) solid transparent;
  background: var(--lime);
  color: var(--lime-ink);
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.25s var(--pop);
}

.fab[hidden] { display: none; }
.fab:hover { transform: scale(1.06); }
.fab.is-active { transform: rotate(45deg); }

/* ---------- Tooltip ---------- */

.tip {
  position: fixed;
  z-index: 55;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -100%);
  background: var(--ink);
  color: var(--surface);
  border-radius: var(--radius);
  padding: 6px 9px;
  font-size: 0.68rem;
  line-height: 1.35;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: opacity 0.15s ease;
}

.tip.is-on { opacity: 1; }

/* ---------- Footer navigation ---------- */

.footernav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  justify-content: space-around;
  align-items: stretch;
  background: var(--paper);
  border-top: var(--line) solid var(--outline);
  padding-bottom: env(safe-area-inset-bottom);
}

.foot-link {
  flex: 1;
  padding: 11px 8px 9px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: none;
  border: 0;
  border-top: 2px solid transparent;
  margin-top: -1px;
  color: var(--muted);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 0.58rem;
  font-weight: var(--l-weight);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.foot-link:hover { color: var(--ink); }
.foot-link.is-active { color: var(--mark-text); border-top-color: var(--mark); }

body.footer .main { padding-bottom: 124px; }

@media (max-width: 400px) {
  .main { padding-left: 14px; padding-right: 14px; }
  .session-kind { width: 40px; padding-right: 8px; }
  .composer-row { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .splash, .splash-name, .splash-bar i { animation: none; }
  .screen.is-active { animation: none; }
  .ring-fill, .bar i, .bar-value, .fab, .session { transition: none; }
  .session { opacity: 1; transform: none; }
  .bar-value { opacity: 1; }
}
