@charset "utf-8";

/* ═══════════════════════════════════════════════════════════════════════
   FORGE — Obsidian & Ember
   Mobile-first. Dark is primary; light is a full peer, not an afterthought.
   SPEC §6.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────── fonts ── */
/* Variable WOFF2, latin subset, self-hosted. `make fonts` fetches these;
   until then the fallback stacks below carry the design without breaking it. */

@font-face {
  font-family: 'Fraunces';
  src: url('/static/fonts/fraunces.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('/static/fonts/switzer.woff2') format('woff2-variations');
  font-weight: 300 800;
  font-display: swap;
}
@font-face {
  font-family: 'GeistMono';
  src: url('/static/fonts/geist-mono.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-display: swap;
}

/* ────────────────────────────────────────────────────────────── tokens ── */

:root {
  /* Surfaces — warm near-black, never the blue-black of every dev tool */
  --bg:            #0B0A09;
  --bg-1:          #131110;
  --bg-2:          #1A1715;
  --bg-3:          #221E1A;
  --border:        #2A241D;
  --border-strong: #3A322A;
  --hairline:      rgba(245, 240, 232, .06);

  /* Text — warm bone, not pure white */
  --text:   #F5F0E8;
  --text-2: #B8AFA2;
  --text-3: #8A8073;
  --text-4: #5C544A;

  /* Accent */
  --ember:      #FF6B35;
  --ember-hi:   #FF8557;
  --ember-lo:   #C24A1E;
  --ember-soft: rgba(255, 107, 53, .12);
  --ember-glow: rgba(255, 107, 53, .35);
  --brass:      #E8B84B;

  /* Semantic */
  --ok:     #4ADE80;
  --warn:   #F0A93F;
  --danger: #F0533F;
  --info:   #6BA8D6;

  /* Heat ramp — ash through to white-hot */
  --heat-0: #16130F;
  --heat-1: #4A2416;
  --heat-2: #8A3D1E;
  --heat-3: #D4551F;
  --heat-4: #FF6B35;
  --heat-r: #E8B84B;

  /* Reflection strip — deliberately NOT the ember scale, and 'fell short'
     is muted slate rather than red: red is the vocabulary of judgment. */
  --refl-none:  #16130F;
  --refl-short: #3A4450;
  --refl-ord:   #5C544A;
  --refl-lived: #E8B84B;

  /* Type */
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-ui:      'Switzer', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'GeistMono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --text-2xs: .6875rem;
  --text-xs:  .75rem;
  --text-sm:  .875rem;
  --text-md:  1rem;
  --text-lg:  1.125rem;
  --text-xl:  1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.5rem;
  --text-hero: 3.5rem;

  /* Geometry */
  --r-chip: 6px;
  --r-ctl: 10px;
  --r-card: 14px;
  --r-sheet: 20px;
  --r-pill: 999px;

  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;  --sp-10: 40px; --sp-12: 48px;

  /* Depth in dark = lighter surface + an inner top highlight. Not shadows. */
  --lift-1: inset 0 1px 0 rgba(245, 240, 232, .04);
  --lift-2: inset 0 1px 0 rgba(245, 240, 232, .06), 0 1px 2px rgba(0, 0, 0, .4);
  --lift-3: inset 0 1px 0 rgba(245, 240, 232, .08), 0 8px 32px rgba(0, 0, 0, .5);

  /* Motion */
  --t-micro: 120ms;
  --t-std:   200ms;
  --t-sheet: 320ms;
  --ease:        cubic-bezier(.32, .72, 0, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);

  --hdr-h: 56px;
  --nav-h: 60px;

  color-scheme: dark;
}

/* Light — a full peer. Ember is darkened to #D9480F to hold 4.9:1 on paper.
   Two blocks: the media query handles theme='auto', the attribute selector
   handles an explicit choice and must win in both directions. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) {
    --bg:            #FDFBF7;
    --bg-1:          #FFFFFF;
    --bg-2:          #F7F3EC;
    --bg-3:          #F0EAE0;
    --border:        #E5DDD0;
    --border-strong: #D4C9B8;
    --hairline:      rgba(26, 22, 20, .07);

    --text:   #1A1614;
    --text-2: #4A423A;
    --text-3: #75695C;
    --text-4: #A0947F;

    --ember:      #D9480F;
    --ember-hi:   #F25C21;
    --ember-lo:   #9A320A;
    --ember-soft: rgba(217, 72, 15, .10);
    --ember-glow: rgba(217, 72, 15, .25);
    --brass:      #A16207;

    --ok:     #15803D;
    --warn:   #B45309;
    --danger: #C2350F;
    --info:   #1D4ED8;

    --heat-0: #F0EAE0;
    --heat-1: #FBD5B8;
    --heat-2: #F5A87A;
    --heat-3: #E8763C;
    --heat-4: #D9480F;
    --heat-r: #A16207;

    --refl-none:  #F0EAE0;
    --refl-short: #B8C2CE;
    --refl-ord:   #C9BFB0;
    --refl-lived: #A16207;

    --lift-1: 0 1px 2px rgba(74, 66, 58, .06);
    --lift-2: 0 2px 8px rgba(74, 66, 58, .08);
    --lift-3: 0 12px 32px rgba(74, 66, 58, .14);

    color-scheme: light;
  }
}

/* Explicit override wins over the media query in both directions. */
:root[data-theme='light'] {
  --bg:            #FDFBF7;
  --bg-1:          #FFFFFF;
  --bg-2:          #F7F3EC;
  --bg-3:          #F0EAE0;
  --border:        #E5DDD0;
  --border-strong: #D4C9B8;
  --hairline:      rgba(26, 22, 20, .07);

  --text:   #1A1614;
  --text-2: #4A423A;
  --text-3: #75695C;
  --text-4: #A0947F;

  --ember:      #D9480F;
  --ember-hi:   #F25C21;
  --ember-lo:   #9A320A;
  --ember-soft: rgba(217, 72, 15, .10);
  --ember-glow: rgba(217, 72, 15, .25);
  --brass:      #A16207;

  --ok:     #15803D;
  --warn:   #B45309;
  --danger: #C2350F;
  --info:   #1D4ED8;

  --heat-0: #F0EAE0;
  --heat-1: #FBD5B8;
  --heat-2: #F5A87A;
  --heat-3: #E8763C;
  --heat-4: #D9480F;
  --heat-r: #A16207;

  --refl-none:  #F0EAE0;
  --refl-short: #B8C2CE;
  --refl-ord:   #C9BFB0;
  --refl-lived: #A16207;

  --lift-1: 0 1px 2px rgba(74, 66, 58, .06);
  --lift-2: 0 2px 8px rgba(74, 66, 58, .08);
  --lift-3: 0 12px 32px rgba(74, 66, 58, .14);

  color-scheme: light;
}

/* ─────────────────────────────────────────────────────────────── reset ── */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--text-md);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior-y: contain;
}

/* Film grain. Stops large black areas reading as flat and dead — the
   difference between "dark mode" and "designed". Dark theme only. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) body::before { opacity: 0; }
}
:root[data-theme='light'] body::before { opacity: 0; }

h1, h2, h3, p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.display {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 48, 'SOFT' 30, 'WONK' 1;
  font-weight: 600;
  letter-spacing: -.025em;
  line-height: 1.1;
}

.stat {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-xs);
  letter-spacing: -.01em;
}

/* ────────────────────────────────────────────────────────────── layout ── */

.main {
  position: relative;
  z-index: 1;
  padding: var(--sp-5) var(--sp-4);
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + var(--sp-12));
  max-width: 720px;
  margin-inline: auto;
}

.main--bare {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding-bottom: var(--sp-5);
}

.page__title { font-size: var(--text-3xl); margin-bottom: var(--sp-1); }
.page__date  { color: var(--text-3); margin-bottom: var(--sp-8); }

/* ────────────────────────────────────────────────────────────── header ── */

.hdr {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--hdr-h);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: 0 var(--sp-4);
  padding-top: env(safe-area-inset-top);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border-bottom: 1px solid var(--hairline);
}

.hdr__streak { display: flex; align-items: center; gap: var(--sp-2); color: var(--text-3); }
.hdr__streak .flame { width: 16px; height: 20px; fill: var(--ember); stroke: none; }
.hdr__out { margin-left: auto; display: flex; }

.hdr__ring { position: relative; width: 32px; height: 32px; }
.hdr__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring__track { stroke: var(--border); stroke-width: 3; }
.ring__fill  { stroke: var(--ember); stroke-width: 3; stroke-linecap: round;
               transition: stroke-dasharray var(--t-sheet) var(--ease); }
.ring__label { position: absolute; inset: 0; display: grid; place-items: center;
               font-size: var(--text-2xs); color: var(--text-3); }

.icon-btn {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;      /* 44px minimum touch target */
  margin: -6px;
  background: none;
  border: 0;
  border-radius: var(--r-ctl);
  color: var(--text-3);
  cursor: pointer;
  transition: color var(--t-micro) var(--ease), background var(--t-micro) var(--ease);
}
.icon-btn svg { width: 20px; height: 20px; }
.icon-btn:hover { color: var(--text); background: var(--bg-2); }

/* ───────────────────────────────────────────────────────── bottom nav ── */
/* Bottom, never top: the top of a modern phone is unreachable one-handed. */

.nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  height: var(--nav-h);
  padding-bottom: env(safe-area-inset-bottom);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  border-top: 1px solid var(--hairline);
}

.nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--text-4);
  font-size: var(--text-2xs);
  letter-spacing: .01em;
  transition: color var(--t-micro) var(--ease);
}
.nav__item svg { width: 21px; height: 21px; }
.nav__item.is-active { color: var(--ember); }

/* ───────────────────────────────────────────────────────────────── fab ── */

.fab {
  position: fixed;
  right: var(--sp-5);
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + var(--sp-4));
  z-index: 21;
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--ember);
  color: #14100D;
  box-shadow: 0 6px 20px var(--ember-glow);
  cursor: pointer;
  transition: transform var(--t-micro) var(--ease-spring),
              box-shadow var(--t-std) var(--ease);
}
.fab svg { width: 24px; height: 24px; stroke-width: 2; }
.fab:active { transform: scale(.93); }

/* ───────────────────────────────────────────────────────────── controls ── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 48px;
  padding: 0 var(--sp-5);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--bg-2);
  color: var(--text);
  font-size: var(--text-md);
  font-weight: 500;
  cursor: pointer;
  transition: transform var(--t-micro) var(--ease),
              background var(--t-micro) var(--ease);
}
.btn:active { transform: scale(.985); }
.btn--block { width: 100%; }

.btn--primary {
  background: var(--ember);
  border-color: transparent;
  color: #14100D;
  font-weight: 600;
}
.btn--primary:hover { background: var(--ember-hi); }

.field { display: block; margin-bottom: var(--sp-4); }
.field__label {
  display: block;
  margin-bottom: var(--sp-2);
  color: var(--text-3);
  font-size: var(--text-sm);
  font-weight: 500;
}
.field input {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text);
  font-family: inherit;
  font-size: 16px;              /* never below 16px, or iOS zooms on focus */
  box-shadow: var(--lift-1);
  transition: border-color var(--t-micro) var(--ease),
              box-shadow var(--t-micro) var(--ease);
}
.field input:focus {
  outline: none;
  border-color: var(--ember);
  box-shadow: 0 0 0 3px var(--ember-soft);
}

:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
}

/* ──────────────────────────────────────────────────────────────── auth ── */

.auth { width: 100%; max-width: 360px; padding: var(--sp-6) var(--sp-5); text-align: center; }

.auth__mark {
  display: grid;
  place-items: center;
  width: 60px; height: 60px;
  margin: 0 auto var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
  box-shadow: var(--lift-2);
}
.auth__mark svg { width: 22px; height: 27px; fill: var(--ember); stroke: none; }

.auth__title { font-size: var(--text-2xl); margin-bottom: var(--sp-2); }
.auth__sub   { color: var(--text-3); font-size: var(--text-sm); margin-bottom: var(--sp-8); }
.auth__form  { text-align: left; }
.auth__form .btn { margin-top: var(--sp-5); }

/* ─────────────────────────────────────────────────────────────── empty ── */

.empty { text-align: center; padding: var(--sp-12) var(--sp-4); }
.empty__mark {
  display: grid; place-items: center;
  width: 72px; height: 72px;
  margin: 0 auto var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--bg-1);
  border: 1px solid var(--border);
  color: var(--text-4);
}
.empty__mark svg { width: 34px; height: 34px; }
.empty__lead { font-size: var(--text-xl); margin-bottom: var(--sp-2); }
.empty__body { color: var(--text-3); font-size: var(--text-sm); max-width: 34ch; margin-inline: auto; }

/* ──────────────────────────────────────────────────────── flash & toast ── */

.flash {
  position: relative;
  z-index: 30;
  margin: var(--sp-4) var(--sp-4) 0;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  font-size: var(--text-sm);
  box-shadow: var(--lift-2);
}
.flash--error { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); color: var(--danger); }
.flash--ok    { border-color: color-mix(in srgb, var(--ok) 40%, var(--border)); color: var(--ok); }

.toasts {
  position: fixed;
  left: var(--sp-4); right: var(--sp-4);
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + var(--sp-4));
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  pointer-events: none;
}
.toast {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-ctl);
  background: var(--bg-3);
  box-shadow: var(--lift-3);
  font-size: var(--text-sm);
  pointer-events: auto;
  animation: toast-in var(--t-std) var(--ease-spring);
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

/* ───────────────────────────────────────────────────────── larger screens ── */

@media (min-width: 720px) {
  .main { padding-inline: var(--sp-8); padding-bottom: var(--sp-12); }
  .nav {
    left: 50%;
    right: auto;
    bottom: var(--sp-5);
    transform: translateX(-50%);
    width: min(440px, calc(100% - var(--sp-8)));
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    box-shadow: var(--lift-3);
    background: color-mix(in srgb, var(--bg-1) 92%, transparent);
    backdrop-filter: blur(12px);
  }
  .fab { bottom: calc(var(--nav-h) + var(--sp-10)); }
}

/* ──────────────────────────────────────────────────── reduced motion ── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   PHASE 1 — tasks, routines, quick capture, sheet
   ═══════════════════════════════════════════════════════════════════════ */

.page { margin-bottom: var(--sp-5); }

/* ─────────────────────────────────────────────────────── quick capture ── */

.qa {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  box-shadow: var(--lift-1);
  transition: border-color var(--t-micro) var(--ease),
              box-shadow var(--t-micro) var(--ease);
}
.qa:focus-within {
  border-color: var(--ember);
  box-shadow: 0 0 0 3px var(--ember-soft);
}
.qa__input {
  flex: 1;
  min-height: 46px;
  border: 0;
  background: none;
  color: var(--text);
  font-family: inherit;
  font-size: 16px;          /* below this, iOS zooms the whole page on focus */
}
.qa__input:focus { outline: none; }
.qa__input::placeholder { color: var(--text-4); }
.qa__go {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border: 0; border-radius: var(--r-chip);
  background: var(--ember-soft);
  color: var(--ember);
  cursor: pointer;
}
.qa__go svg { width: 18px; height: 18px; stroke-width: 2; }

/* Live parse preview — showing the interpretation is what makes a
   natural-language field trustworthy rather than a guessing game. */
.qa__preview {
  display: flex; flex-wrap: wrap; gap: var(--sp-2);
  min-height: 22px;
  margin: var(--sp-2) var(--sp-1) var(--sp-6);
  font-size: var(--text-xs);
}
.qa__preview:empty { margin-bottom: var(--sp-5); }
.qp__title { color: var(--text-2); font-weight: 500; }
.qp__bit {
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--ember-soft);
  color: var(--ember);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
}

/* ──────────────────────────────────────────────────────────── sections ── */

.sec-block { margin-bottom: var(--sp-8); }

.sec {
  display: flex; align-items: baseline; gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-family: var(--font-ui);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-3);
}
.sec__n { color: var(--text-4); letter-spacing: 0; }
.sec__hint {
  margin: calc(var(--sp-2) * -1) 0 var(--sp-3);
  color: var(--text-4);
  font-size: var(--text-xs);
}
.sec__hint--top { margin: 0 0 var(--sp-4); }

.sec-block--overdue .sec { color: var(--danger); }
.sec-block--done { opacity: .55; }

/* ─────────────────────────────────────────────────────────── routines ── */
/* Compact and tap-only. Deliberately a different rhythm from tasks: a
   five-second morning sweep, not considered work. */

.rt-strip {
  display: flex; flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
  overflow: hidden;
}
.rt-row { display: flex; align-items: center; }
.rt-row + .rt-row { border-top: 1px solid var(--hairline); }
.rt { flex: 1; min-width: 0; }
.rt__btn {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; min-height: 48px;
  padding: 0 var(--sp-2) 0 var(--sp-4);
  border: 0; background: none;
  text-align: left;
  cursor: pointer;
}
.rt__tick { display: grid; place-items: center; width: 20px; height: 20px; color: var(--text-4); }
.rt__tick svg { width: 20px; height: 20px; }
.rt__title { flex: 1; font-size: var(--text-sm); }
.rt__prog, .rt__time { color: var(--text-4); }

.rt-row .task__check { stroke-dasharray: 20; stroke-dashoffset: 20; }
.rt-row.is-done .rt__tick { color: var(--ok); }
.rt-row.is-done .task__check { stroke-dashoffset: 0; transition: stroke-dashoffset var(--t-std) var(--ease); }
.rt-row.is-done .rt__title { color: var(--text-3); text-decoration: line-through; }

/* ────────────────────────────────────────────────────────────── tasks ── */

.tasks { list-style: none; margin: 0; padding: 0; }

.task {
  position: relative;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--bg-1);
  border: 1px solid var(--border);
  margin-bottom: var(--sp-2);
}

/* Revealed beneath the row as it is dragged. */
.task__under {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--sp-5);
  font-size: var(--text-sm); font-weight: 600;
}
.task__under-do    { color: var(--ok); }
.task__under-later { color: var(--warn); margin-left: auto; }

.task__row {
  position: relative;
  display: flex; align-items: flex-start; gap: var(--sp-1);
  min-height: 56px;
  padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-1);
  background: var(--bg-1);
  transition: transform var(--t-std) var(--ease);
  touch-action: pan-y;
}
.task.is-dragging .task__row { transition: none; }

.task__tick {
  flex: none;
  display: grid; place-items: center;
  width: 44px; height: 44px;       /* full-size target even though it looks small */
  margin-top: 3px;
  border: 0; background: none;
  color: var(--text-4);
  cursor: pointer;
}
.task__tick svg { width: 21px; height: 21px; }
.task__check { stroke-dasharray: 20; stroke-dashoffset: 20; }

.task.is-done .task__tick { color: var(--ok); }
.task.is-done .task__check { stroke-dashoffset: 0; transition: stroke-dashoffset var(--t-std) var(--ease); }
.task.is-done .task__title { color: var(--text-3); text-decoration: line-through; }

.task__main {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 3px;
  padding: var(--sp-2) 0;
}
.task__title { font-size: var(--text-md); line-height: 1.35; }
.task__meta { display: flex; flex-wrap: wrap; gap: var(--sp-1); }

.task__prio {
  flex: none;
  align-self: center;
  color: var(--danger);
  font-weight: 700;
  font-size: var(--text-lg);
  padding-right: var(--sp-1);
}

.chip {
  padding: 1px 7px;
  border-radius: var(--r-chip);
  background: var(--bg-2);
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chip--today    { background: var(--ember-soft); color: var(--ember); }
.chip--overdue  { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.chip--slip     { background: transparent; color: var(--text-4); font-style: italic; }
.chip--resched  { background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); }

/* Row actions, revealed by a left swipe or the sheet. */
.task__actions {
  display: none;
  gap: var(--sp-2);
  flex-wrap: wrap;
  padding: 0 var(--sp-3) var(--sp-3) var(--sp-3);
  border-top: 1px solid var(--hairline);
  padding-top: var(--sp-3);
}
.task.is-open .task__actions { display: flex; }

.act {
  min-height: 36px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-chip);
  background: var(--bg-2);
  color: var(--text-2);
  font-size: var(--text-xs);
  cursor: pointer;
}
.act--plan { border-color: var(--ember); color: var(--ember); }
.act--drop { color: var(--text-3); }
.act--snooze { color: var(--warn); }

/* ─────────────────────────────────────────────────────────────── sheet ── */

.sheet-wrap { position: fixed; inset: 0; z-index: 50; }
.sheet__scrim {
  position: absolute; inset: 0;
  background: rgba(0,0,0,.5);
  animation: fade-in var(--t-std) var(--ease);
}
@keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }

.sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 90dvh;
  overflow-y: auto;
  padding: var(--sp-3) var(--sp-5) calc(var(--sp-6) + env(safe-area-inset-bottom));
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  background: var(--bg-2);
  box-shadow: var(--lift-3);
  animation: sheet-up var(--t-sheet) var(--ease);
}
@keyframes sheet-up { from { transform: translateY(100%) } to { transform: none } }

.sheet__grip {
  width: 36px; height: 4px;
  margin: 0 auto var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--border-strong);
}
.sheet textarea {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text);
  font-family: inherit;
  font-size: 16px;
  resize: vertical;
}
.sheet select {
  width: 100%; min-height: 48px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text);
  font-family: inherit;
  font-size: 16px;
}
.sheet input[type=date], .sheet input[type=time] {
  min-height: 48px;
}
.field-row { display: flex; gap: var(--sp-3); }
.field-row .field { flex: 1; }
.field-row .field--time { flex: 0 0 106px; }

.sheet__note {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3);
  border-radius: var(--r-ctl);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  color: var(--warn);
  font-size: var(--text-xs);
}
.sheet__foot { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
.sheet__foot .btn { flex: 1; }

.sheet__drop {
  width: 100%;
  margin-top: var(--sp-4);
  padding: var(--sp-3);
  border: 0; background: none;
  color: var(--text-4);
  font-size: var(--text-sm);
  cursor: pointer;
}
.sheet__drop:hover { color: var(--danger); }

.toast { display: flex; align-items: center; gap: var(--sp-4); }
.toast__act {
  margin-left: auto;
  border: 0; background: none;
  color: var(--ember);
  font-weight: 600;
  font-size: var(--text-sm);
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════ PHASE 2 ══════ */

.banner {
  margin-bottom: var(--sp-5);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.banner--fail { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.banner code { font-family: var(--font-mono); font-size: var(--text-xs); }

.card {
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
  box-shadow: var(--lift-1);
}
.card__lead { color: var(--text-2); font-size: var(--text-sm); margin-bottom: var(--sp-4); }
.card__note { color: var(--text-4); font-size: var(--text-xs); margin-top: var(--sp-2); }
.card__note code, .card code { font-family: var(--font-mono); }
.card__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-4); }
.card__actions .btn { flex: 1; min-width: 140px; }

.inline-form { display: flex; gap: var(--sp-3); align-items: flex-end; }
.inline-form .field { flex: 1; margin-bottom: 0; }
.inline-form .field--time { flex: 0 0 130px; }
.inline-form .btn { flex: none; }

.keybox {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3);
  border: 1px solid var(--ember);
  border-radius: var(--r-ctl);
  background: var(--ember-soft);
}
.keybox__label { color: var(--ember); font-size: var(--text-xs); margin-bottom: var(--sp-2); }
.keybox__value {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  word-break: break-all;
  color: var(--text);
}

.keys { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.keys__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--hairline);
}
.keys__name { display: block; font-size: var(--text-sm); }
.keys__meta { display: block; color: var(--text-4); }
.keys__revoke {
  border: 0; background: none; color: var(--text-4);
  font-size: var(--text-xs); cursor: pointer;
}
.keys__revoke:hover { color: var(--danger); }

.recipe { margin-top: var(--sp-5); }
.recipe summary {
  cursor: pointer;
  color: var(--ember);
  font-size: var(--text-sm);
  padding: var(--sp-2) 0;
}
.recipe__steps { margin: var(--sp-3) 0; padding-left: var(--sp-5); color: var(--text-2); font-size: var(--text-sm); }
.recipe__steps li { margin-bottom: var(--sp-2); }
.recipe__steps ul { margin: var(--sp-2) 0; padding-left: var(--sp-4); }
.recipe__steps code, .recipe__note code { font-family: var(--font-mono); font-size: var(--text-xs); }
.recipe__note { color: var(--text-3); font-size: var(--text-xs); margin: var(--sp-3) 0; }
.recipe__code {
  overflow-x: auto;
  padding: var(--sp-3);
  border-radius: var(--r-ctl);
  background: var(--bg-3);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  line-height: 1.6;
}

.maillog { list-style: none; margin: 0; padding: 0; }
.maillog__row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--hairline);
  font-size: var(--text-xs);
}
.maillog__row:first-child { border-top: 0; }
.maillog__when { flex: none; color: var(--text-4); }
.maillog__subj { flex: 1; min-width: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.maillog__status { flex: none; font-family: var(--font-mono); font-size: var(--text-2xs); }
.maillog__status--sent { color: var(--ok); }
.maillog__status--failed { color: var(--danger); }

/* Email action confirmation — the page you land on from the lock screen.
   Big, calm, and obvious; you are half-awake when you see it. */
.act-page {
  display: grid; place-items: center;
  min-height: 80dvh;
  text-align: center;
  padding: var(--sp-8) var(--sp-5);
}
.act-page__mark {
  display: grid; place-items: center;
  width: 84px; height: 84px;
  margin-bottom: var(--sp-5);
  border-radius: var(--r-pill);
  background: var(--ember-soft);
  color: var(--ember);
}
.act-page__mark.is-fail { background: var(--bg-2); color: var(--text-4); }
.act-page__mark svg { width: 40px; height: 40px; }
.act-page__head { font-size: var(--text-2xl); margin-bottom: var(--sp-2); }
.act-page__detail { color: var(--text-3); font-size: var(--text-sm); max-width: 30ch; }
.act-page__undo { margin-top: var(--sp-6); }
.act-page__link { margin-top: var(--sp-6); color: var(--ember); font-size: var(--text-sm); }

/* ═══════════════════════════════════════════════════════ PHASE 3 ══════ */

.hdr__streak, .hdr__ring { text-decoration: none; }
.hdr__streak.is-hot .flame   { fill: var(--brass); }
.hdr__streak.is-white .flame { fill: var(--text); filter: drop-shadow(0 0 4px var(--brass)); }
.hdr__ring.is-met .ring__fill { stroke: var(--ok); }
.hdr__welcome {
  margin-left: auto;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: var(--ember-soft);
  color: var(--ember);
  font-size: var(--text-xs);
  font-weight: 600;
}
.hdr__welcome ~ .hdr__out { margin-left: var(--sp-2); }

/* ── tiles ─────────────────────────────────────────────────────────── */

.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); }
.tile {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
  box-shadow: var(--lift-1);
  text-align: center;
}
.tile__ring { position: relative; width: 52px; height: 52px; }
.tile__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.tile__ringnum { position: absolute; inset: 0; display: grid; place-items: center; }
.tile__big { font-size: var(--text-2xl); line-height: 1; }
.tile__label { color: var(--text-3); font-size: var(--text-2xs); line-height: 1.3; }
.tile__sub { color: var(--brass); }

/* ── heat map ──────────────────────────────────────────────────────── */
/* Heat ramp: cold ash → ember → white-hot. Left over from the heat map,
   which returns in phase 8. */

.heat-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: var(--sp-2);
  -webkit-overflow-scrolling: touch;
}
.heat { display: flex; gap: 3px; min-width: min-content; }
.heat__col { display: flex; flex-direction: column; gap: 3px; scroll-snap-align: start; }

.heat__cell {
  width: 12px; height: 12px;
  border-radius: 3px;
  background: var(--heat-0);
  flex: none;
}
.heat__cell--l0 { background: var(--heat-0); }
.heat__cell--l1 { background: var(--heat-1); }
.heat__cell--l2 { background: var(--heat-2); }
.heat__cell--l3 { background: var(--heat-3); }
.heat__cell--l4 { background: var(--heat-4); }
.heat__cell--future { background: transparent; }

/* A record day gets a brass rim. */
.heat__cell.is-record { box-shadow: inset 0 0 0 1.5px var(--brass); }

/* Days you were away read as a gap, not a failure. Hatched, not empty —
   the difference between "I stopped for a while" and "I failed". */
.heat__cell.is-paused {
  background: repeating-linear-gradient(45deg,
    var(--heat-0) 0 2px, var(--border) 2px 4px);
}

/* Today breathes. */
.heat__cell.is-today {
  box-shadow: inset 0 0 0 1.5px var(--ember);
  animation: ember-pulse 2.4s ease-in-out infinite;
}
@keyframes ember-pulse {
  0%, 100% { box-shadow: inset 0 0 0 1.5px var(--ember); }
  50%      { box-shadow: inset 0 0 0 1.5px var(--ember), 0 0 7px var(--ember-glow); }
}

.heat__legend {
  display: flex; align-items: center; gap: var(--sp-1);
  margin-top: var(--sp-3);
  color: var(--text-4);
}
.heat__legend .heat__cell { width: 10px; height: 10px; }
.heat__toggle { margin-left: auto; color: var(--ember); font-size: var(--text-xs); }

/* ── deferral gauge ────────────────────────────────────────────────── */

.gauge-card { display: block; }
.gauge__bar {
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
  overflow: hidden;
}
.gauge__fill {
  height: 100%;
  border-radius: var(--r-pill);
  transition: width var(--t-sheet) var(--ease);
}
.gauge__fill--clear    { background: var(--ok); }
.gauge__fill--building { background: var(--brass); }
.gauge__fill--heavy    { background: var(--warn); }
.gauge__fill--critical { background: var(--danger); }

.gauge__row {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-top: var(--sp-2);
}
.gauge__band { font-size: var(--text-sm); font-weight: 600; }
.gauge__band--clear    { color: var(--ok); }
.gauge__band--building { color: var(--brass); }
.gauge__band--heavy    { color: var(--warn); }
.gauge__band--critical { color: var(--danger); }
.gauge__row .stat { color: var(--text-4); }

/* Reckoning: "Let it go" carries the same weight as doing it. A large share
   of what sits here is stuff you are never going to do. */
.task__actions.is-shown { display: flex; }
.act--letgo { color: var(--text-3); }

/* ── welcome back ──────────────────────────────────────────────────── */

.welcome {
  display: grid; place-content: center; align-content: center;
  min-height: 70dvh;
  text-align: center;
  padding: var(--sp-8) var(--sp-5);
  max-width: 30rem; margin-inline: auto;
}
.welcome__head { font-size: var(--text-2xl); margin-bottom: var(--sp-2); }
.welcome__sub { color: var(--text-3); margin-bottom: var(--sp-6); }
.welcome__facts { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: var(--sp-8); }
.welcome__fact { color: var(--text-2); font-size: var(--text-sm); }
.welcome__fact--good { color: var(--ok); }
.welcome__go { margin-bottom: var(--sp-4); }
.welcome__skip { color: var(--text-4); font-size: var(--text-sm); }

/* ═══════════════════════════════════════════════════════ PHASE 4 ══════ */

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.refl__title { font-size: var(--text-xl); margin-bottom: var(--sp-3); }
.refl__body { color: var(--text-2); font-size: var(--text-md); line-height: 1.6; }
.refl__points { margin: var(--sp-4) 0 0; padding-left: var(--sp-5); color: var(--text-2); font-size: var(--text-sm); }
.refl__points li { margin-bottom: var(--sp-2); line-height: 1.55; }
.refl__meta { color: var(--text-4); margin-top: var(--sp-4); }
.refl .act { margin-top: var(--sp-4); }

/* The reflection strip. Its own palette, its own page — never beside the
   ember heat map, or the two read as one metric. */
.refl-strip { display: flex; flex-wrap: wrap; gap: 4px; }
.refl-cell { width: 14px; height: 14px; border-radius: 4px; background: var(--refl-none); }
.refl-cell--lived { background: var(--refl-lived); }
.refl-cell--ord   { background: var(--refl-ord); }
/* Muted slate, never red: red is the vocabulary of danger and failure. */
.refl-cell--short { background: var(--refl-short); }

.diff { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); font-size: var(--text-sm); }
.diff__err { margin-top: var(--sp-2); color: var(--danger); font-size: var(--text-xs); }

.import { margin-top: var(--sp-4); }
.import input[type=file] { width: 100%; font-size: var(--text-sm); color: var(--text-3); }
.import__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); }
.import__opt { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--text-xs); color: var(--text-3); }

.themes { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.theme-chip {
  padding: 4px 10px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--bg-1);
  color: var(--text-3); font-size: var(--text-xs);
}
.theme-chip.is-active { border-color: var(--ember); color: var(--ember); background: var(--ember-soft); }

.lib { list-style: none; margin: 0; padding: 0; }
.lib__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) 0; border-top: 1px solid var(--hairline);
}
.lib__row.is-off { opacity: .45; }
.lib__title { display: block; font-size: var(--text-sm); }
.lib__meta { display: block; color: var(--text-4); }
.lib__toggle { border: 0; background: none; color: var(--text-4); font-size: var(--text-xs); cursor: pointer; }
.lib__toggle:hover { color: var(--ember); }

/* ── signature moments ─────────────────────────────────────────────── */

/* Completion burst: the checkbox fills, sparks scatter, the points chip
   flies to the ring. Under half a second, and gone. */
@keyframes spark {
  from { opacity: 1; transform: translate(0,0) scale(1); }
  to   { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.2); }
}
.spark {
  position: fixed; z-index: 60;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--ember);
  pointer-events: none;
  animation: spark 420ms var(--ease) forwards;
}
@keyframes fly {
  from { opacity: 1; transform: translate(0,0) scale(1); }
  70%  { opacity: 1; }
  to   { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.6); }
}
.pointfly {
  position: fixed; z-index: 61;
  padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--ember); color: #14100D;
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  pointer-events: none;
  animation: fly 520ms var(--ease) forwards;
}

/* Pull to refresh — an ember that brightens as you pull. */
.ptr {
  position: fixed; left: 50%; top: 0; z-index: 25;
  width: 30px; height: 30px; margin-left: -15px;
  display: grid; place-items: center;
  pointer-events: none;
  opacity: 0;
}
.ptr svg { width: 16px; height: 20px; fill: var(--ember); stroke: none; }
.ptr.is-armed svg { filter: drop-shadow(0 0 6px var(--ember-glow)); }
.ptr.is-spinning { animation: ptr-spin 700ms linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* Install prompt — offered once, dismissible, never nagging. */
.install {
  position: fixed; left: var(--sp-4); right: var(--sp-4);
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + var(--sp-4));
  z-index: 45;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border-strong); border-radius: var(--r-card);
  background: var(--bg-3); box-shadow: var(--lift-3);
  font-size: var(--text-sm);
  animation: toast-in var(--t-std) var(--ease-spring);
}
.install__x { margin-left: auto; border: 0; background: none; color: var(--text-4); cursor: pointer; }

@media (prefers-reduced-motion: reduce) {
  .spark, .pointfly, .ptr { display: none !important; }
}

/* ── calendar ──────────────────────────────────────────────────────── */

.cal-head { display: flex; align-items: flex-start; justify-content: space-between; }
.cal-nav { display: flex; gap: var(--sp-1); }

.cal__dow {
  display: grid; grid-template-columns: repeat(7, 1fr);
  margin-bottom: var(--sp-2);
  color: var(--text-4);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  text-align: center;
}
.cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }

.cal__day {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  aspect-ratio: 1;
  min-height: 44px;                 /* touch target */
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text-2);
  font-size: var(--text-sm);
  cursor: pointer;
}
.cal__day.is-out { opacity: .32; }
.cal__day.is-empty { background: transparent; }
.cal__day.is-today {
  border-color: var(--ember);
  color: var(--ember);
  font-weight: 600;
}
.cal__n { font-variant-numeric: tabular-nums; }

.cal__dots { display: flex; gap: 3px; height: 5px; }
.dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; }
.dot--plan  { background: var(--ember); }
.dot--due   { background: var(--danger); }
.dot--event { background: var(--info); }

.cal__key {
  display: flex; gap: var(--sp-4);
  margin: var(--sp-3) 0 var(--sp-8);
  color: var(--text-4);
  font-size: var(--text-2xs);
}
.cal__key span { display: flex; align-items: center; gap: var(--sp-1); }

.sheet__title { font-size: var(--text-xl); margin-bottom: var(--sp-4); }
.sheet__empty { color: var(--text-3); font-size: var(--text-sm); padding: var(--sp-4) 0; }

.agenda { list-style: none; margin: 0 0 var(--sp-5); padding: 0; }
.agenda__row {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--hairline);
}
.agenda__time { flex: none; width: 64px; color: var(--text-4); }
.agenda__title { flex: 1; font-size: var(--text-sm); }
.agenda__row--event .agenda__time { color: var(--info); }
.agenda__row--due .agenda__time { color: var(--danger); }

/* ── weekly review ─────────────────────────────────────────────────── */

.steps { display: flex; gap: var(--sp-2); list-style: none; margin: 0 0 var(--sp-6); padding: 0; }
.steps__i {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px;
  color: var(--text-4); font-size: var(--text-2xs);
}
.steps__n {
  display: grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--border-strong);
  font-family: var(--font-mono); font-size: var(--text-2xs);
}
.steps__i.is-now  { color: var(--ember); }
.steps__i.is-now .steps__n { border-color: var(--ember); background: var(--ember-soft); }
.steps__i.is-done { color: var(--ok); }
.steps__i.is-done .steps__n { border-color: var(--ok); }
.steps__l { text-align: center; }

.review__head { font-size: var(--text-xl); margin-bottom: var(--sp-2); }
.review__lead { color: var(--text-3); font-size: var(--text-sm); margin-bottom: var(--sp-5); line-height: 1.55; }
.review__clear { color: var(--ok); font-size: var(--text-sm); padding: var(--sp-6) 0; text-align: center; }
.review__nav { display: flex; gap: var(--sp-3); margin-top: var(--sp-8); }
.review__nav .btn { flex: 1; }
.review__skip { text-align: center; margin-top: var(--sp-4); }
.review__skip button {
  border: 0; background: none; color: var(--text-4);
  font-size: var(--text-xs); cursor: pointer;
}
.week-day { margin-bottom: var(--sp-5); }

/* ── accessibility ─────────────────────────────────────────────────── */

.skip {
  position: absolute; left: var(--sp-4); top: -100px; z-index: 100;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-ctl);
  background: var(--ember); color: #14100D;
  font-weight: 600;
  transition: top var(--t-std) var(--ease);
}
.skip:focus { top: var(--sp-4); }

/* The bottom nav is fixed, so a focused control can end up underneath it. */
.main :focus-visible { scroll-margin-bottom: calc(var(--nav-h) + var(--sp-6)); }

/* Honour a forced-colours mode rather than fighting it. */
@media (forced-colors: active) {
  .heat__cell, .refl-cell, .dot { forced-color-adjust: none; }
  .task, .card, .cal__day { border: 1px solid CanvasText; }
}

/* ── updates ───────────────────────────────────────────────────────── */

.banner__detail { margin-top: var(--sp-2); color: var(--text-3); font-size: var(--text-xs); line-height: 1.55; }
.upload { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; margin-bottom: var(--sp-4); }
.upload input[type=file] { flex: 1; min-width: 180px; font-size: var(--text-sm); color: var(--text-3); }

.steps-list {
  margin: 0; padding-left: var(--sp-5);
  color: var(--text-3); font-size: var(--text-xs); line-height: 1.7;
}

.rel { list-style: none; margin: 0; padding: 0; }
.rel__row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border); border-radius: var(--r-ctl);
  background: var(--bg-1);
  margin-bottom: var(--sp-2);
}
.rel__row.is-current { border-color: var(--ember); }
.rel__v { display: block; font-size: var(--text-sm); font-family: var(--font-mono); }
.rel__meta { display: block; color: var(--text-4); margin-top: 2px; }
.rel__tag {
  margin-left: var(--sp-2); padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--ember-soft); color: var(--ember);
  font-family: var(--font-ui); font-size: var(--text-2xs);
}
.rel__tag--prev { background: var(--bg-3); color: var(--text-4); }

.backups { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.backups__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-2) 0; border-top: 1px solid var(--hairline);
  font-size: var(--text-xs);
}
.backups__row a { color: var(--ember); font-family: var(--font-mono); }
.backups__meta { color: var(--text-4); }

.field__hint {
  margin: calc(var(--sp-3) * -1) 0 var(--sp-4);
  color: var(--text-4);
  font-size: var(--text-xs);
  line-height: 1.5;
}
.field__opt { color: var(--text-4); font-weight: 400; }

/* ═══════════════════════════════════════════════════════ MOBILE SHEETS ══
   Sheets are full-screen on a phone with an explicit X.
   A part-height sheet sounds nicer and isn't: the form is taller than the
   space, the scrim eats taps meant for fields, and the only way out reads as
   "Cancel", which looks like it cancels the task rather than the dialog. */

.sheet {
  display: flex;
  flex-direction: column;
  max-height: 100dvh;
  height: 100dvh;
  border-radius: 0;
  padding: 0;
  animation: sheet-up var(--t-sheet) var(--ease);
}

.sheet__bar {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: none;
  min-height: 56px;
  padding: env(safe-area-inset-top) var(--sp-3) 0 var(--sp-5);
  background: var(--bg-2);
  border-bottom: 1px solid var(--hairline);
}
.sheet__bar .sheet__title { flex: 1; font-size: var(--text-lg); margin: 0; }

.sheet__x {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  flex: none;
  border: 0; background: none;
  border-radius: var(--r-ctl);
  color: var(--text-2);
  cursor: pointer;
}
.sheet__x svg { width: 22px; height: 22px; stroke-width: 2; }
.sheet__x:active { background: var(--bg-3); }

.sheet__body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-5) var(--sp-5) var(--sp-8);
}

.sheet__foot {
  position: sticky;
  bottom: 0;
  flex: none;
  display: flex;
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-3) var(--sp-5) calc(var(--sp-3) + env(safe-area-inset-bottom));
  background: var(--bg-2);
  border-top: 1px solid var(--hairline);
}
.sheet__foot .btn { flex: 1; }

/* The grip belongs to a draggable part-height sheet; full-screen doesn't
   need it, and it invites a drag that does nothing. */
.sheet__grip { display: none; }
.sheet__scrim { display: none; }

/* Roomier on a desktop, where a full-screen dialog is overkill. */
@media (min-width: 720px) {
  .sheet-wrap { display: grid; place-items: center; }
  .sheet__scrim { display: block; }
  .sheet {
    position: relative;
    height: auto;
    max-height: 86dvh;
    width: min(560px, calc(100% - var(--sp-8)));
    border-radius: var(--r-sheet);
    box-shadow: var(--lift-3);
    animation: fade-in var(--t-std) var(--ease);
  }
  .sheet__bar { border-radius: var(--r-sheet) var(--r-sheet) 0 0; padding-top: 0; }
  .sheet__foot { border-radius: 0 0 var(--r-sheet) var(--r-sheet); }
}

/* ── row actions reachable without any gesture ──────────────────────── */

.task__more {
  flex: none;
  align-self: center;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 0; background: none;
  color: var(--text-4);
  border-radius: var(--r-ctl);
  cursor: pointer;
}
.task__more svg {
  width: 18px; height: 18px;
  /* The global reset makes every svg stroked-and-unfilled, which turns a
     dot into a ring. These want the opposite. */
  fill: currentColor;
  stroke: none;
}
.task__more:active { background: var(--bg-2); color: var(--text-2); }

/* Routines get the same affordance — until now the row was a tick and
   nothing else, so a habit could never be removed. */
.rt__more {
  flex: none;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  margin-right: var(--sp-1);
  border: 0; background: none;
  color: var(--text-4);
  border-radius: var(--r-ctl);
  cursor: pointer;
}
.rt__more svg { width: 16px; height: 16px; fill: currentColor; stroke: none; }
.rt__more:active { background: var(--bg-2); color: var(--text-2); }

.sheet__section {
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--hairline);
}
.sheet__acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.sheet__acts .act { flex: 1; min-width: 118px; min-height: 44px; }


/* An <svg> with no intrinsic size fills its container. Every icon in the app
   is a button glyph, so cap them — a missing rule should look slightly wrong,
   not like the page has broken. */
button > svg, a > svg { max-width: 28px; max-height: 28px; }
.empty__mark svg, .act-page__mark svg, .auth__mark svg { max-width: none; max-height: none; }

/* ── labels: projects and tags ──────────────────────────────────────── */

.task__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.task__labels {
  display: flex; flex-wrap: wrap; gap: var(--sp-1);
  padding: 0 0 var(--sp-2);
}

.chip--project {
  background: color-mix(in srgb, var(--ember) 14%, transparent);
  color: var(--ember);
  font-family: var(--font-ui);
}
.chip--tag {
  background: color-mix(in srgb, var(--info) 14%, transparent);
  color: var(--info);
  font-family: var(--font-ui);
}
.chip--project:active, .chip--tag:active { filter: brightness(1.3); }

.labels { list-style: none; margin: 0; padding: 0; }
.label-row {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 56px;
  padding: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
}
.label-row__dot {
  flex: none;
  display: grid; place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--r-chip);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}
.label-row__dot--project { background: var(--ember-soft); color: var(--ember); }
.label-row__dot--tag     { background: color-mix(in srgb, var(--info) 14%, transparent); color: var(--info); }
.label-row__main { flex: 1; min-width: 0; }
.label-row__name { display: block; font-size: var(--text-md); }
.label-row__meta { display: block; color: var(--text-4); }
.label-row__next { flex: none; color: var(--text-4); }
.label-row__go { flex: none; width: 18px; height: 18px; color: var(--text-4); }


/* ── label filter bar ───────────────────────────────────────────────── */

.fbar { margin: 0 0 var(--sp-4); }
.fbar__scroll {
  display: flex; gap: var(--sp-2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--sp-1);
  /* Bleed to the screen edges so it reads as scrollable rather than clipped. */
  margin-inline: calc(var(--sp-4) * -1);
  padding-inline: var(--sp-4);
  scrollbar-width: none;
}
.fbar__scroll::-webkit-scrollbar { display: none; }

.fchip {
  display: inline-flex; align-items: center; gap: 5px;
  flex: none;
  min-height: 34px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--bg-1);
  color: var(--text-3);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.fchip__n {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--text-4);
}
.fchip.is-on { border-color: var(--ember); background: var(--ember-soft); color: var(--ember); }
.fchip.is-on .fchip__n { color: var(--ember); }
.fchip--tag.is-on { border-color: var(--info); background: color-mix(in srgb, var(--info) 14%, transparent); color: var(--info); }
.fchip--tag.is-on .fchip__n { color: var(--info); }

.fbar__note {
  margin: calc(var(--sp-2) * -1) 0 var(--sp-5);
  color: var(--text-4);
  font-size: var(--text-xs);
}
.fbar__note a { color: var(--ember); }

/* ════════════════════════════════════════════ The morning, redesigned ══ */
/*
   Read one-handed, half-awake, between 06:30 and 09:00 — but also reviewed at
   a desk in daylight, which the first pass forgot. Two surfaces two per cent
   apart in luminance look considered on a design monitor and look like nothing
   at all on a phone in a bright kitchen.

   So: every surface here is separated by a real step and an outline, and no
   text that carries meaning is dimmer than --text-3. The only genuinely quiet
   things left are the ones you never need to read.

   The two people are the palette. All seven category colours were cut — at
   06:30 nobody scans by "cleaning is blue".
*/

/* Lois's colour, declared the same way every other token is so there is one
   rule per theme rather than a scoped override fighting a media query. Teal
   has to darken a long way to hold its own against paper. */
:root { --them: #3EC5AE; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) { --them: #0F7A6A; }
}
:root[data-theme='light'] { --them: #0F7A6A; }
:root[data-theme='dark']  { --them: #3EC5AE; }

.day {
  --me: var(--ember);
  --surface: var(--bg-2);
  --surface-hi: var(--bg-3);
}

.dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 7px;
}
.dot--a { background: var(--me); }
.dot--b, .dot--them { background: var(--them); }

/* ── Header ─────────────────────────────────────────────────────────── */
.dayhead { margin-bottom: var(--sp-4); }
.dayhead__row { display: flex; align-items: center; gap: var(--sp-3); }
.dayhead__name {
  flex: 1;
  font-family: var(--font-display);
  font-size: clamp(2rem, 9vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--text);
}
.dayhead__date { margin-top: var(--sp-1); color: var(--text-2); font-size: var(--text-sm); }

.step {
  flex: none;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
}
.step:hover, .step:focus-visible { background: var(--surface-hi); border-color: var(--border-strong); }
.step svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 2.25;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ── Week ───────────────────────────────────────────────────────────── */
.week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
  margin-bottom: var(--sp-6);
}
.week__d {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 2px;
  min-height: 46px;            /* seven of these across a phone is tight enough */
  padding: 5px 0;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  color: var(--text-3);
  text-decoration: none;
}
.week__l { font-size: var(--text-2xs); }
.week__n {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  color: var(--text-2);
}
.week__d.is-today .week__n { color: var(--me); font-weight: 600; }
.week__d.is-shown {
  background: var(--surface);
  border-color: var(--border-strong);
}
.week__d.is-shown .week__l { color: var(--text-2); }
.week__d.is-shown .week__n { color: var(--text); }
.week__d:hover:not(.is-shown) { background: var(--bg-1); }

/* ── Now ─────────────────────────────────────────────────────────────
   The hero. On most mornings this is the only part anyone reads. */
.now {
  padding: var(--sp-5);
  margin-bottom: var(--sp-8);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  box-shadow: var(--lift-2);
}
.now.has-block { border-left: 3px solid var(--me); }
.now__lead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}
.now__label { color: var(--me); font-size: var(--text-sm); font-weight: 600; }
.now__left {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-size: var(--text-md);
}
.now__title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 6.5vw, 2rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.015em;
  color: var(--text);
  text-wrap: balance;
}
.now__then { margin-top: var(--sp-3); color: var(--text-2); font-size: var(--text-sm); }
.now__other {
  display: flex; align-items: center;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  color: var(--text-2);
  font-size: var(--text-sm);
}

/* The one piece of motion: how far through you are. It answers a question
   rather than decorating an entrance. */
.now__bar {
  margin-top: var(--sp-4);
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--bg);
  border: 1px solid var(--border);
  overflow: hidden;
}
.now__bar i {
  display: block; height: 100%;
  background: var(--me);
  transition: width 600ms var(--ease);
}
.p0{width:0}    .p1{width:5%}   .p2{width:10%}  .p3{width:15%}  .p4{width:20%}
.p5{width:25%}  .p6{width:30%}  .p7{width:35%}  .p8{width:40%}  .p9{width:45%}
.p10{width:50%} .p11{width:55%} .p12{width:60%} .p13{width:65%} .p14{width:70%}
.p15{width:75%} .p16{width:80%} .p17{width:85%} .p18{width:90%} .p19{width:95%}
.p20{width:100%}

/* ── The running order ───────────────────────────────────────────────
   Rows are events, not minutes: a row begins whenever anything starts or
   finishes. Every row is legible, and reading across shows what the two of
   you are on at the same moment. */
/* One five-minute unit. Everything on the grid is a multiple of this, which
   is what makes thirty minutes twice the height of fifteen. */
/* One five-minute unit.
   26px is set by the smallest block, not the largest: at one unit a five-
   minute block has 24px of usable box once the border and the gap below it
   are taken out, and a tick mark plus a line of text needs 23 of them. Any
   less and the descenders get sliced off, which is what 22px was doing.
   Everything else follows from it, so the morning is about a fifth longer
   than it would be if the short end were allowed to squash. */
.run { --gutter: 3.75rem; --unit-h: 30px; --b-pad: 10px; }

.run__who {
  display: grid;
  grid-template-columns: var(--gutter) 1fr 1fr;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.run__name {
  display: flex; align-items: center;
  color: var(--text-2);
  font-size: var(--text-sm);
}
.run__name.is-me { color: var(--text); font-weight: 600; }

.run__grid {
  display: grid;
  grid-template-columns: var(--gutter) 1fr 1fr;
  grid-auto-rows: var(--unit-h);
  column-gap: var(--sp-2);
}

/* The spine — the only structural device on the page, and what says
   "timeline" without an outline around every block. */
.run__t {
  grid-column: 1;
  grid-row: var(--u);
  padding-right: var(--sp-3);
  border-right: 1px solid var(--border);
  text-align: right;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  font-weight: 500;
  color: var(--text-2);
  letter-spacing: -.01em;
}
.run__t.is-major { color: var(--text); font-weight: 600; }

.run__line {
  grid-column: 2 / span 2;
  grid-row: var(--u);
  height: 1px;
  align-self: start;
  margin-top: .62em;
  background: var(--hairline);
}
.run__line.is-major { background: var(--border); }

.run__now {
  grid-column: 1 / span 3;
  grid-row: var(--u);
  align-self: start;
  margin-top: .58em;
  height: 2px;
  background: var(--me);
  border-radius: var(--r-pill);
  box-shadow: 0 0 12px var(--ember-glow);
  z-index: 3;
}

.run__end {
  display: flex; gap: var(--sp-3);
  padding-left: calc(var(--gutter) + var(--sp-2));
  margin-top: var(--sp-3);
  color: var(--text-3);
  font-size: var(--text-xs);
}
.run__end time { font-family: var(--font-display); font-variant-numeric: tabular-nums; }

/* ── Blocks ──────────────────────────────────────────────────────────
   Most blocks tick when you tap them: a 44px card is a far better target at
   06:30 than a checkbox. A workout block is the exception — tapping it opens
   the session, because that is the substantive thing to do, and the mark gets
   its own small target beside it. */
.b {
  position: relative;
  grid-row: var(--u) / span var(--us);
  margin-bottom: 2px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--r-ctl);
  background: var(--surface);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.b--0 { grid-column: 2 / span 2; border-left-color: var(--text-3); }
.b--1 { grid-column: 2; border-left-color: var(--me); }
.b--2 { grid-column: 3; border-left-color: var(--them); }

.b__row { flex: 1 1 auto; display: flex; align-items: stretch; min-width: 0; }

/* The tick. Its own target, sized for a thumb. */
/* Top-aligned, not centred. Centring put the mark halfway down whatever
   height the block happened to be, so a five-minute row and a ten-minute row
   sitting next to each other had their marks at visibly different heights and
   the column read as crooked. Aligned to the title's first line, every mark
   sits on the same axis whatever the duration. */
.b__tick {
  display: flex;
  align-items: flex-start;
  min-width: 44px;
  padding: var(--b-pad) 0 0 var(--sp-3);
  border: 0;
  background: none;
  cursor: pointer;
}
.b__tick:disabled { cursor: default; opacity: .6; }
.b__mark {
  display: grid; place-items: center;
  flex: none;
  width: 18px; height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 6px;
  background: var(--bg);
}
.b__mark svg {
  width: 14px; height: 14px;
  fill: none; stroke: var(--bg); stroke-width: 2.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* The rest of the row: a link on a workout, a second tick target otherwise. */
.b__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 3px;
  min-width: 0;
  padding: var(--b-pad) var(--sp-3);
  text-decoration: none;
}
.b__wide {
  display: flex; flex-direction: column; gap: 3px;
  width: 100%; height: 100%;
  padding: 0;
  border: 0; background: none; color: inherit; font: inherit;
  text-align: left;
  cursor: pointer;
}
.b__wide:disabled { cursor: default; }
.b__body--link:hover { background: var(--bg-3); }

.b__t {
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.3;
  color: var(--text);
  text-wrap: pretty;
}
.b__m {
  color: var(--text-3);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.b__w  { color: var(--me); font-weight: 600; }
.b__by { color: var(--them); }
.b__o  { padding: 0 var(--sp-3) var(--sp-2); color: var(--brass); font-size: var(--text-xs); }

/* The chevron is the whole affordance for "this goes somewhere". */
.b__chev {
  flex: none;
  display: grid; place-items: center;
  width: 30px;
  color: var(--me);
}
.b__chev svg {
  width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 2.25;
  stroke-linecap: round; stroke-linejoin: round;
}

.b.is-done { background: transparent; }
.b.is-done .b__t { color: var(--text-3); text-decoration: line-through; }
.b--1.is-done .b__mark { background: var(--me); border-color: var(--me); }
.b--2.is-done .b__mark { background: var(--them); border-color: var(--them); }
.b--0.is-done .b__mark { background: var(--text-3); border-color: var(--text-3); }

/* Grid placement, generated because the CSP sets style-src 'self' with no
   unsafe-inline and weakening a good header to position a div is a bad trade.
   The unit is five minutes; 300 of them is twenty-five hours. */
.u0{--u:1}.u1{--u:2}.u2{--u:3}.u3{--u:4}.u4{--u:5}.u5{--u:6}.u6{--u:7}.u7{--u:8}.u8{--u:9}.u9{--u:10}.u10{--u:11}.u11{--u:12}.u12{--u:13}.u13{--u:14}.u14{--u:15}.u15{--u:16}.u16{--u:17}.u17{--u:18}.u18{--u:19}.u19{--u:20}.u20{--u:21}.u21{--u:22}.u22{--u:23}.u23{--u:24}.u24{--u:25}.u25{--u:26}.u26{--u:27}.u27{--u:28}.u28{--u:29}.u29{--u:30}.u30{--u:31}.u31{--u:32}.u32{--u:33}.u33{--u:34}.u34{--u:35}.u35{--u:36}.u36{--u:37}.u37{--u:38}.u38{--u:39}.u39{--u:40}.u40{--u:41}.u41{--u:42}.u42{--u:43}.u43{--u:44}.u44{--u:45}.u45{--u:46}.u46{--u:47}.u47{--u:48}.u48{--u:49}.u49{--u:50}.u50{--u:51}.u51{--u:52}.u52{--u:53}.u53{--u:54}.u54{--u:55}.u55{--u:56}.u56{--u:57}.u57{--u:58}.u58{--u:59}.u59{--u:60}.u60{--u:61}.u61{--u:62}.u62{--u:63}.u63{--u:64}.u64{--u:65}.u65{--u:66}.u66{--u:67}.u67{--u:68}.u68{--u:69}.u69{--u:70}.u70{--u:71}.u71{--u:72}.u72{--u:73}.u73{--u:74}.u74{--u:75}.u75{--u:76}.u76{--u:77}.u77{--u:78}.u78{--u:79}.u79{--u:80}.u80{--u:81}.u81{--u:82}.u82{--u:83}.u83{--u:84}.u84{--u:85}.u85{--u:86}.u86{--u:87}.u87{--u:88}.u88{--u:89}.u89{--u:90}.u90{--u:91}.u91{--u:92}.u92{--u:93}.u93{--u:94}.u94{--u:95}.u95{--u:96}.u96{--u:97}.u97{--u:98}.u98{--u:99}.u99{--u:100}.u100{--u:101}.u101{--u:102}.u102{--u:103}.u103{--u:104}.u104{--u:105}.u105{--u:106}.u106{--u:107}.u107{--u:108}.u108{--u:109}.u109{--u:110}.u110{--u:111}.u111{--u:112}.u112{--u:113}.u113{--u:114}.u114{--u:115}.u115{--u:116}.u116{--u:117}.u117{--u:118}.u118{--u:119}.u119{--u:120}.u120{--u:121}.u121{--u:122}.u122{--u:123}.u123{--u:124}.u124{--u:125}.u125{--u:126}.u126{--u:127}.u127{--u:128}.u128{--u:129}.u129{--u:130}.u130{--u:131}.u131{--u:132}.u132{--u:133}.u133{--u:134}.u134{--u:135}.u135{--u:136}.u136{--u:137}.u137{--u:138}.u138{--u:139}.u139{--u:140}.u140{--u:141}.u141{--u:142}.u142{--u:143}.u143{--u:144}.u144{--u:145}.u145{--u:146}.u146{--u:147}.u147{--u:148}.u148{--u:149}.u149{--u:150}.u150{--u:151}.u151{--u:152}.u152{--u:153}.u153{--u:154}.u154{--u:155}.u155{--u:156}.u156{--u:157}.u157{--u:158}.u158{--u:159}.u159{--u:160}.u160{--u:161}.u161{--u:162}.u162{--u:163}.u163{--u:164}.u164{--u:165}.u165{--u:166}.u166{--u:167}.u167{--u:168}.u168{--u:169}.u169{--u:170}.u170{--u:171}.u171{--u:172}.u172{--u:173}.u173{--u:174}.u174{--u:175}.u175{--u:176}.u176{--u:177}.u177{--u:178}.u178{--u:179}.u179{--u:180}.u180{--u:181}.u181{--u:182}.u182{--u:183}.u183{--u:184}.u184{--u:185}.u185{--u:186}.u186{--u:187}.u187{--u:188}.u188{--u:189}.u189{--u:190}.u190{--u:191}.u191{--u:192}.u192{--u:193}.u193{--u:194}.u194{--u:195}.u195{--u:196}.u196{--u:197}.u197{--u:198}.u198{--u:199}.u199{--u:200}.u200{--u:201}.u201{--u:202}.u202{--u:203}.u203{--u:204}.u204{--u:205}.u205{--u:206}.u206{--u:207}.u207{--u:208}.u208{--u:209}.u209{--u:210}.u210{--u:211}.u211{--u:212}.u212{--u:213}.u213{--u:214}.u214{--u:215}.u215{--u:216}.u216{--u:217}.u217{--u:218}.u218{--u:219}.u219{--u:220}.u220{--u:221}.u221{--u:222}.u222{--u:223}.u223{--u:224}.u224{--u:225}.u225{--u:226}.u226{--u:227}.u227{--u:228}.u228{--u:229}.u229{--u:230}.u230{--u:231}.u231{--u:232}.u232{--u:233}.u233{--u:234}.u234{--u:235}.u235{--u:236}.u236{--u:237}.u237{--u:238}.u238{--u:239}.u239{--u:240}.u240{--u:241}.u241{--u:242}.u242{--u:243}.u243{--u:244}.u244{--u:245}.u245{--u:246}.u246{--u:247}.u247{--u:248}.u248{--u:249}.u249{--u:250}.u250{--u:251}.u251{--u:252}.u252{--u:253}.u253{--u:254}.u254{--u:255}.u255{--u:256}.u256{--u:257}.u257{--u:258}.u258{--u:259}.u259{--u:260}.u260{--u:261}.u261{--u:262}.u262{--u:263}.u263{--u:264}.u264{--u:265}.u265{--u:266}.u266{--u:267}.u267{--u:268}.u268{--u:269}.u269{--u:270}.u270{--u:271}.u271{--u:272}.u272{--u:273}.u273{--u:274}.u274{--u:275}.u275{--u:276}.u276{--u:277}.u277{--u:278}.u278{--u:279}.u279{--u:280}.u280{--u:281}.u281{--u:282}.u282{--u:283}.u283{--u:284}.u284{--u:285}.u285{--u:286}.u286{--u:287}.u287{--u:288}.u288{--u:289}.u289{--u:290}.u290{--u:291}.u291{--u:292}.u292{--u:293}.u293{--u:294}.u294{--u:295}.u295{--u:296}.u296{--u:297}.u297{--u:298}.u298{--u:299}.u299{--u:300}
.us1{--us:1}.us2{--us:2}.us3{--us:3}.us4{--us:4}.us5{--us:5}.us6{--us:6}.us7{--us:7}.us8{--us:8}.us9{--us:9}.us10{--us:10}.us11{--us:11}.us12{--us:12}.us13{--us:13}.us14{--us:14}.us15{--us:15}.us16{--us:16}.us17{--us:17}.us18{--us:18}.us19{--us:19}.us20{--us:20}.us21{--us:21}.us22{--us:22}.us23{--us:23}.us24{--us:24}.us25{--us:25}.us26{--us:26}.us27{--us:27}.us28{--us:28}.us29{--us:29}.us30{--us:30}.us31{--us:31}.us32{--us:32}.us33{--us:33}.us34{--us:34}.us35{--us:35}.us36{--us:36}.us37{--us:37}.us38{--us:38}.us39{--us:39}.us40{--us:40}.us41{--us:41}.us42{--us:42}.us43{--us:43}.us44{--us:44}.us45{--us:45}.us46{--us:46}.us47{--us:47}.us48{--us:48}.us49{--us:49}.us50{--us:50}.us51{--us:51}.us52{--us:52}.us53{--us:53}.us54{--us:54}.us55{--us:55}.us56{--us:56}.us57{--us:57}.us58{--us:58}.us59{--us:59}.us60{--us:60}.us61{--us:61}.us62{--us:62}.us63{--us:63}.us64{--us:64}.us65{--us:65}.us66{--us:66}.us67{--us:67}.us68{--us:68}.us69{--us:69}.us70{--us:70}.us71{--us:71}.us72{--us:72}.us73{--us:73}.us74{--us:74}.us75{--us:75}.us76{--us:76}.us77{--us:77}.us78{--us:78}.us79{--us:79}.us80{--us:80}.us81{--us:81}.us82{--us:82}.us83{--us:83}.us84{--us:84}.us85{--us:85}.us86{--us:86}.us87{--us:87}.us88{--us:88}.us89{--us:89}.us90{--us:90}.us91{--us:91}.us92{--us:92}.us93{--us:93}.us94{--us:94}.us95{--us:95}.us96{--us:96}.us97{--us:97}.us98{--us:98}.us99{--us:99}.us100{--us:100}.us101{--us:101}.us102{--us:102}.us103{--us:103}.us104{--us:104}.us105{--us:105}.us106{--us:106}.us107{--us:107}.us108{--us:108}.us109{--us:109}.us110{--us:110}.us111{--us:111}.us112{--us:112}.us113{--us:113}.us114{--us:114}.us115{--us:115}.us116{--us:116}.us117{--us:117}.us118{--us:118}.us119{--us:119}.us120{--us:120}.us121{--us:121}.us122{--us:122}.us123{--us:123}.us124{--us:124}.us125{--us:125}.us126{--us:126}.us127{--us:127}.us128{--us:128}.us129{--us:129}.us130{--us:130}.us131{--us:131}.us132{--us:132}.us133{--us:133}.us134{--us:134}.us135{--us:135}.us136{--us:136}.us137{--us:137}.us138{--us:138}.us139{--us:139}.us140{--us:140}.us141{--us:141}.us142{--us:142}.us143{--us:143}.us144{--us:144}.us145{--us:145}.us146{--us:146}.us147{--us:147}.us148{--us:148}.us149{--us:149}.us150{--us:150}.us151{--us:151}.us152{--us:152}.us153{--us:153}.us154{--us:154}.us155{--us:155}.us156{--us:156}.us157{--us:157}.us158{--us:158}.us159{--us:159}.us160{--us:160}.us161{--us:161}.us162{--us:162}.us163{--us:163}.us164{--us:164}.us165{--us:165}.us166{--us:166}.us167{--us:167}.us168{--us:168}.us169{--us:169}.us170{--us:170}.us171{--us:171}.us172{--us:172}.us173{--us:173}.us174{--us:174}.us175{--us:175}.us176{--us:176}.us177{--us:177}.us178{--us:178}.us179{--us:179}.us180{--us:180}.us181{--us:181}.us182{--us:182}.us183{--us:183}.us184{--us:184}.us185{--us:185}.us186{--us:186}.us187{--us:187}.us188{--us:188}.us189{--us:189}.us190{--us:190}.us191{--us:191}.us192{--us:192}.us193{--us:193}.us194{--us:194}.us195{--us:195}.us196{--us:196}.us197{--us:197}.us198{--us:198}.us199{--us:199}.us200{--us:200}.us201{--us:201}.us202{--us:202}.us203{--us:203}.us204{--us:204}.us205{--us:205}.us206{--us:206}.us207{--us:207}.us208{--us:208}.us209{--us:209}.us210{--us:210}.us211{--us:211}.us212{--us:212}.us213{--us:213}.us214{--us:214}.us215{--us:215}.us216{--us:216}.us217{--us:217}.us218{--us:218}.us219{--us:219}.us220{--us:220}.us221{--us:221}.us222{--us:222}.us223{--us:223}.us224{--us:224}.us225{--us:225}.us226{--us:226}.us227{--us:227}.us228{--us:228}.us229{--us:229}.us230{--us:230}.us231{--us:231}.us232{--us:232}.us233{--us:233}.us234{--us:234}.us235{--us:235}.us236{--us:236}.us237{--us:237}.us238{--us:238}.us239{--us:239}.us240{--us:240}.us241{--us:241}.us242{--us:242}.us243{--us:243}.us244{--us:244}.us245{--us:245}.us246{--us:246}.us247{--us:247}.us248{--us:248}.us249{--us:249}.us250{--us:250}.us251{--us:251}.us252{--us:252}.us253{--us:253}.us254{--us:254}.us255{--us:255}.us256{--us:256}.us257{--us:257}.us258{--us:258}.us259{--us:259}.us260{--us:260}.us261{--us:261}.us262{--us:262}.us263{--us:263}.us264{--us:264}.us265{--us:265}.us266{--us:266}.us267{--us:267}.us268{--us:268}.us269{--us:269}.us270{--us:270}.us271{--us:271}.us272{--us:272}.us273{--us:273}.us274{--us:274}.us275{--us:275}.us276{--us:276}.us277{--us:277}.us278{--us:278}.us279{--us:279}.us280{--us:280}.us281{--us:281}.us282{--us:282}.us283{--us:283}.us284{--us:284}.us285{--us:285}.us286{--us:286}.us287{--us:287}.us288{--us:288}.us289{--us:289}.us290{--us:290}.us291{--us:291}.us292{--us:292}.us293{--us:293}.us294{--us:294}.us295{--us:295}.us296{--us:296}.us297{--us:297}.us298{--us:298}.us299{--us:299}.us300{--us:300}

/* ── Empty & misc ───────────────────────────────────────────────────── */
.blank {
  padding: var(--sp-10) var(--sp-4);
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-card);
}
.blank__head { font-family: var(--font-display); font-size: var(--text-lg); color: var(--text); }
.blank__body {
  margin: var(--sp-2) auto 0;
  max-width: 28ch;
  color: var(--text-2);
  font-size: var(--text-sm);
}
.backlink { margin-top: var(--sp-8); text-align: center; font-size: var(--text-sm); }
.backlink a { color: var(--text-2); }
.backlink a:hover { color: var(--text); }

/* Two lanes want a little more room than a single reading column. */
@media (min-width: 760px) { .day { width: min(100%, 44rem); margin-inline: auto; } }

@media (prefers-reduced-motion: reduce) { .now__bar i { transition: none; } }

/* Theme picker — a segmented control, because three mutually exclusive
   options are a choice, not a toggle you have to guess the state of. */
.themepick { display: flex; gap: var(--sp-2); padding: var(--sp-3); }
.themepick button {
  flex: 1;
  padding: var(--sp-3) var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-2);
  color: var(--text-2);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.themepick button:hover { border-color: var(--border-strong); color: var(--text); }
.themepick button.is-on {
  background: var(--ember-soft);
  border-color: var(--ember);
  color: var(--text);
  font-weight: 600;
}
.card__note { margin-top: var(--sp-2); color: var(--text-3); font-size: var(--text-xs); }

/* ════════════════════════════════════════════════ Editing the rota ══ */

.form-page { padding-bottom: var(--sp-10); }
.field--tight { margin-top: var(--sp-3); margin-bottom: 0; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.field textarea {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text);
  font-family: inherit;
  font-size: 16px;
  resize: vertical;
}
.field textarea:focus {
  outline: none;
  border-color: var(--ember);
  box-shadow: 0 0 0 3px var(--ember-soft);
}
fieldset.field { border: 0; padding: 0; margin-inline: 0; }
.fields legend.field__label { padding: 0; }

.formerr {
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
  border: 1px solid var(--danger);
  border-radius: var(--r-ctl);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--text);
  font-size: var(--text-sm);
}

/* Radio groups as cards. The native control stays in the DOM for keyboard and
   screen readers; it just isn't what you aim at with a thumb. */
.pickrow { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pick {
  flex: 1 1 0;
  display: flex; align-items: center; justify-content: center;
  min-height: 48px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text-2);
  font-size: var(--text-sm);
  text-align: center;
  cursor: pointer;
}
.pick--wide { flex: 1 1 100%; justify-content: flex-start; text-align: left; padding: var(--sp-3); }
.pick input { position: absolute; opacity: 0; pointer-events: none; }
.pick:has(input:checked) {
  border-color: var(--ember);
  background: var(--ember-soft);
  color: var(--text);
  font-weight: 500;
}
.pick:has(input:focus-visible) { outline: 2px solid var(--ember); outline-offset: 2px; }

.days { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-2); margin-top: var(--sp-3); }
.day-box {
  display: grid; place-items: center;
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-1);
  color: var(--text-3);
  font-size: var(--text-sm);
  cursor: pointer;
}
.day-box input { position: absolute; opacity: 0; pointer-events: none; }
.day-box:has(input:checked) {
  border-color: var(--ember);
  background: var(--ember-soft);
  color: var(--text);
  font-weight: 600;
}
.day-box:has(input:focus-visible) { outline: 2px solid var(--ember); outline-offset: 2px; }

.check { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.check input { width: 22px; height: 22px; accent-color: var(--ember); }

.scope { padding: var(--sp-4); border: 1px solid var(--brass); border-radius: var(--r-ctl); }
.scope legend.field__label { color: var(--brass); padding: 0 var(--sp-2); }

.actions { display: flex; gap: var(--sp-3); margin-top: var(--sp-6); }
.actions .btn { flex: 1; }

.danger { margin-top: var(--sp-10); padding-top: var(--sp-5); border-top: 1px solid var(--border); }
.btn--danger { width: 100%; border-color: var(--danger); color: var(--danger); background: transparent; }
.btn--danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.danger__note { margin-top: var(--sp-2); color: var(--text-3); font-size: var(--text-xs); text-align: center; }

.addrow { margin-top: var(--sp-5); }
.addrow .btn { width: 100%; }

/* The edit handle sits in the block's corner, small and quiet — the block
   itself is the tick target, and that is the action you want at 06:30. */
.b__edit {
  position: absolute;
  top: 0; right: 0;
  display: grid; place-items: center;
  width: 44px; height: 44px;   /* the icon is small; the target must not be */
  border-radius: 8px;
  color: var(--text-4);
  opacity: 0;
}
.b { position: relative; }
.b:hover .b__edit, .b__edit:focus-visible { opacity: 1; }
.b__edit:hover { background: var(--bg-3); color: var(--text); }
.b__edit svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
/* No hover on a touchscreen, so it is always there — quietly. */
@media (hover: none) { .b__edit { opacity: .5; } }

/* ═══════════════════════════════════════════════════ The workout ══ */

.b__open {
  flex: none;
  display: block;
  padding: 7px var(--sp-3);
  border-top: 1px solid var(--border);
  background: var(--ember-soft);
  color: var(--me);
  font-size: var(--text-xs);
  font-weight: 600;
  text-align: center;
}
.b__open:hover { background: var(--ember); color: #14100D; }

/* The circuit. Numbered because it genuinely is a sequence — you go through
   it in order, and knowing you're on four of seven is the thing you want
   between breaths. */
.circuit { list-style: none; margin-top: var(--sp-5); }
.ex {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--hairline);
}
.ex:last-child { border-bottom: 0; }
.ex__n {
  flex: none;
  width: 1.75rem;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  color: var(--text-4);
}
.ex__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ex__name { font-size: var(--text-md); color: var(--text); line-height: 1.25; }
.ex__load { color: var(--text-3); font-size: var(--text-xs); }
.ex__note { color: var(--text-3); font-size: var(--text-xs); font-style: italic; }

/* Run legs. Weight follows effort — the running is the point, the walking is
   the recovery, and at a glance you want to see the shape of the session. */
.legs { list-style: none; margin-top: var(--sp-5); }
.leg {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3);
  margin-bottom: var(--sp-2);
  border-radius: var(--r-ctl);
  border-left: 3px solid var(--border-strong);
  background: var(--surface, var(--bg-2));
}
.leg--run { border-left-color: var(--ember); }
.leg--brisk_walk { border-left-color: var(--info); }
.leg__what { font-size: var(--text-md); color: var(--text); }
.leg--run .leg__what { font-weight: 600; }
.leg__len {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  color: var(--text-2);
}
.leg__x { color: var(--me); font-weight: 600; }

.soon {
  margin-top: var(--sp-8);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
  color: var(--text-4);
  font-size: var(--text-xs);
  text-align: center;
}

/* ─────────────────────────────────────────── Rescheduling a workout ── */

.reschedule {
  margin-top: var(--sp-8);
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-1);
}
.reschedule__q { color: var(--text-2); font-size: var(--text-sm); margin-bottom: var(--sp-3); }
.reschedule__opts { display: grid; gap: var(--sp-2); }
.reschedule__opts button {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3);
  min-height: 48px;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--bg-2);
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
}
.reschedule__opts button:hover { border-color: var(--ember); background: var(--ember-soft); }
.reschedule__opts button span {
  color: var(--text-3);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.reschedule__note { margin-top: var(--sp-3); color: var(--text-4); font-size: var(--text-xs); }

.now__moved {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  color: var(--brass);
  font-size: var(--text-sm);
}
.now__moved button {
  border: 0; background: none; padding: 0;
  color: var(--text-2); font: inherit; font-size: var(--text-xs);
  text-decoration: underline; cursor: pointer;
}
.now__moved button:hover { color: var(--text); }

/* A collapsed stretch of nothing. It says how long it was, so the timeline
   stays honest about a gap it is not drawing to scale. */
.run__gap {
  grid-column: 2 / span 2;
  grid-row: var(--u) / span 6;
  align-self: center;
  justify-self: center;
  padding: 3px var(--sp-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-pill);
  color: var(--text-4);
  font-size: var(--text-2xs);
}

/* Ten minutes or less. One line, a smaller mark, and the duration dropped —
   the spine already gives the start time and the next mark gives the end, so
   on a block this short the minutes are the one thing you can infer. */
/* One unit. The mark stays the same size as everywhere else — a smaller one
   next to a normal one is exactly the inconsistency this was meant to fix —
   so only the padding tightens, and the row centres because there is a single
   line to centre on. */
.b.is-short .b__row { align-items: center; }
.b.is-short .b__tick { min-width: 40px; padding: 0 0 0 var(--sp-3); align-items: center; }
.b.is-short .b__body { padding: 0 var(--sp-2); justify-content: center; }
.b.is-short .b__wide { flex-direction: row; align-items: baseline; gap: var(--sp-2); }
.b.is-short .b__t { font-size: var(--text-xs); line-height: 1.2; white-space: nowrap;
                    overflow: hidden; text-overflow: ellipsis; }
.b.is-short .b__m { display: none; }

/* ═════════════════════════════════════════════════════ The timer ══ */
/*
   Held in one hand, at arm's length, between sets. Everything is sized for
   being glanced at rather than read: one number, one name, and a ring that
   tells you how long is left without your having to parse a digit.
*/

.go__head { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-5); }
.go__title { font-family: var(--font-display); font-size: var(--text-xl); line-height: 1.1; }
.go__sub { color: var(--text-3); font-size: var(--text-xs); margin-top: 2px; }

.go__start { margin: var(--sp-6) 0; }
.go__hint {
  margin-top: var(--sp-3);
  color: var(--text-3);
  font-size: var(--text-xs);
  text-align: center;
  max-width: 34ch;
  margin-inline: auto;
}

/* The stage. Colour carries the one thing you need peripherally: whether you
   are working or recovering. */
.stage {
  padding: var(--sp-6) var(--sp-4);
  margin-bottom: var(--sp-6);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-card);
  background: var(--bg-1);
  text-align: center;
}
.stage[data-kind="work"], .stage[data-kind="move"] { border-color: var(--ember); }
.stage__where { color: var(--text-3); font-size: var(--text-xs); min-height: 1.2em; }
.stage__what {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 7vw, 2.25rem);
  line-height: 1.1;
  margin-top: var(--sp-1);
  text-wrap: balance;
}
.stage[data-kind="rest"] .stage__what,
.stage[data-kind="round_rest"] .stage__what { color: var(--text-2); }
.stage__load { color: var(--text-3); font-size: var(--text-sm); margin-top: var(--sp-1); }

.stage__clock { position: relative; width: 190px; margin: var(--sp-5) auto var(--sp-3); }
.stage__clock svg { width: 100%; transform: rotate(-90deg); }
.ring__bg { fill: none; stroke: var(--bg-3); stroke-width: 7; }
.ring__fg {
  fill: none;
  stroke: var(--ember);
  stroke-width: 7;
  stroke-linecap: round;
  transition: stroke-dashoffset 120ms linear;
}
.stage[data-kind="rest"] .ring__fg,
.stage[data-kind="round_rest"] .ring__fg { stroke: var(--text-3); }
.stage__count {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 3.25rem;
  color: var(--text);
}
.stage__next { color: var(--text-3); font-size: var(--text-sm); min-height: 1.4em; }
.stage__controls { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
.stage__controls .btn { flex: 1; }

/* Reps. Offered during the recovery after a work period, prefilled with
   nothing — the timer already knows you got through the round, so an
   untouched stepper records no claim about how many. */
.reps {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}
.reps__q { color: var(--text-2); font-size: var(--text-sm); }
.reps__row {
  display: flex; align-items: center; justify-content: center;
  gap: var(--sp-5);
  margin-top: var(--sp-2);
}
.reps__btn {
  width: 56px; height: 56px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--bg-2);
  color: var(--text);
  font-size: var(--text-2xl);
  line-height: 1;
  cursor: pointer;
}
.reps__btn:active { background: var(--ember-soft); border-color: var(--ember); }
.reps__n {
  min-width: 3ch;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-3xl);
  color: var(--text);
}
.reps__last { margin-top: var(--sp-2); color: var(--text-4); font-size: var(--text-xs); }

/* The run of segments, doubling as the plan before you start and the progress
   list once you have. */
.plan { list-style: none; margin-bottom: var(--sp-5); }
.plan__seg {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-left: 2px solid transparent;
  font-size: var(--text-sm);
}
.plan__seg[data-kind="rest"], .plan__seg[data-kind="round_rest"] { color: var(--text-4); }
.plan__what { color: var(--text-2); }
.plan__meta {
  color: var(--text-4);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.plan__seg.is-now {
  border-left-color: var(--ember);
  background: var(--ember-soft);
}
.plan__seg.is-now .plan__what { color: var(--text); font-weight: 600; }
.plan__seg.is-done { opacity: .45; }
.plan__seg.is-done .plan__what { text-decoration: line-through; }

.go__finish { margin-top: var(--sp-4); }
.go__finish .btn { width: 100%; }

.lastwk { margin-top: var(--sp-8); padding-top: var(--sp-4); border-top: 1px solid var(--border); }
.lastwk__h { font-size: var(--text-xs); color: var(--text-4); margin-bottom: var(--sp-2); }
.lastwk ul { list-style: none; }
.lastwk li {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  padding: 3px 0;
  color: var(--text-3);
  font-size: var(--text-xs);
}
.lastwk__r { font-variant-numeric: tabular-nums; color: var(--text-2); }

@media (prefers-reduced-motion: reduce) { .ring__fg { transition: none; } }

.gorow { margin-top: var(--sp-6); }
