/* SportHQ3 — mobile-first styles.
   "Mobile-first" = the base rules are for a phone; the @media rule at the
   bottom adds tweaks for bigger screens. */

/* ---------- Design tokens: change a colour once here, it changes everywhere ----------
   Look chosen on 2026-10-14 ("A + C"): soft white cards with a light shadow,
   a charcoal top bar, small uppercase card labels, a thin accent line on
   dashboard cards and planner sessions; done = green.
   HQ family: every HQ shares this style and only changes its ACCENT
   (hub = ink, Sport = deep purple, Work = blue, Personal = raspberry). Green,
   amber and red keep their meaning (done / warning / error) in every HQ. */
/* Number font (step 17b): Barlow Condensed, stored in the app (fonts/, SIL Open
   Font License) instead of loaded from Google: works offline, nothing sent to
   Google. Only for numbers (.num); the rest stays in the phone's own font. */
@font-face {
  font-family: "Barlow Condensed";
  src: url("../fonts/barlow-condensed-latin-600-normal.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Barlow Condensed";
  src: url("../fonts/barlow-condensed-latin-700-normal.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --bg: #e9edf2;
  --surface: #ffffff;
  --text: #161922;
  --muted: #5b6472;
  --border: #d6dce4;
  --card-border: transparent;   /* light mode: cards are lifted by a shadow, no border */
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 4px 14px rgba(0, 0, 0, 0.05);
  --shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.09); /* a card under the mouse (23b) */
  --hover-bg: rgba(0, 0, 0, 0.035);   /* a row under the mouse */
  --card-border-hover: transparent;
  --accent: #3d0079;            /* Sport HQ deep purple, dark enough for white text and small text */
  --accent-strong: #3d0079;     /* lines and bars: the deep purple already reads well thin */
  --accent-text: #ffffff;
  --topbar-bg: #3d0079;         /* deep purple top bar with the white logo (33) */
  --strip-bg: #13111a;          /* charcoal for the workout strip and bar (dark, not branded) */
  --topbar-text: #ffffff;
  --ok: #15803d;
  --done-line: #16a34a;
  --error: #b91c1c;
  /* One colour per sport (planner cards, month, Home strip). Never green /
     amber / red (done / warning / error) and not the purple accent. */
  --sport-running: #2563eb;   /* blue */
  --sport-football: #0891b2;  /* cyan */
  --sport-muscle: #db2777;    /* pink */
  --sport-biking: #ea580c;    /* orange */
  --sport-swimming: #4f46e5;  /* indigo */
  --sport-stairs: #8b5e3c;    /* brown */
  --radius: 14px;
  /* Page widths (28a): two sizes only, so content doesn't jump between screens.
     narrow = forms, profiles, detail pages; wide = dashboards, lists, tables.
     The planner's week (7 day columns) is the one exception: 1400px. */
  --page-narrow: 760px;
  --page-wide: 1200px;
  --tabbar-height: 64px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-num: "Barlow Condensed", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* RPE bands, cool to warm (never green / amber / red): background + text */
  --rpe-low-bg: #dbeafe;  --rpe-low-text: #1d4ed8;
  --rpe-mid-bg: #ece4f7;  --rpe-mid-text: #3d0079;
  --rpe-high-bg: #fce7f3; --rpe-high-text: #9d174d;
  --rpe-max-bg: #831843;  --rpe-max-text: #ffffff;
  /* RPE 9-10 buttons in the log form: light until chosen, like 1-8 (23d) */
  --rpe-max-soft-bg: #fbcfe8; --rpe-max-soft-text: #831843;
  /* Home (17c): the Today hero, the amber warning line, empty bar segments */
  --hero-bg: #3d0079;
  --hero-text: #ffffff;
  --hero-muted: rgba(255, 255, 255, 0.82);
  --hero-soft: rgba(255, 255, 255, 0.16);
  --hero-line: rgba(255, 255, 255, 0.26);
  --hero-button-bg: #ffffff;
  --hero-button-text: #3d0079;
  --warn-bg: #fef3c7;
  --warn-text: #92400e;
  --segment-empty: #dde2e9;
  --load-past: #d9cdee;         /* past weeks in the load chart */
  /* Race mode (17d): the dark race block on top of Home */
  --race-mode-bg: #3d0079;      /* purple, so the block continues the top bar (34) */
  --race-mode-text: #ffffff;
  --race-mode-muted: #d3d6de;
  --race-mode-accent: #c4a5ff;
  --race-mode-soft: rgba(255, 255, 255, 0.14);
  --race-mode-empty: rgba(255, 255, 255, 0.2);
  --race-mode-button: #5b2a9e;   /* lifted purple: #3d0079 vanishes on the dark block */
  /* Workout mode (18): the dark strip on top and the bar pinned at the bottom */
  --strip-accent: #c4a5ff;
  --strip-muted: #a3a9b5;
  --strip-track: #3a3646;
  --tick-halo: rgba(61, 0, 121, 0.25);
  --done-bg: #dcfce7;
}

/* Dark mode follows the phone's setting automatically. Shadows don't show
   on dark backgrounds, so cards get a thin border instead. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0e14;
    --surface: #1a1822;
    --text: #f2f0f6;
    --muted: #a39fb0;
    --border: #2f2c3b;
    --card-border: #262331;
    --shadow: none;
    --shadow-hover: none;              /* dark mode: the card's border lights up instead */
    --hover-bg: rgba(255, 255, 255, 0.05);
    --card-border-hover: #433f52;
    --accent: #c4a5ff;
    --accent-strong: #c4a5ff;
    --accent-text: #1a0d33;
    --topbar-bg: #3d0079;
    --strip-bg: #08070b;
    --ok: #4ade80;
    --done-line: #4ade80;
    --error: #f87171;
    --sport-running: #60a5fa;
    --sport-football: #22d3ee;
    --sport-muscle: #f472b6;
    --sport-biking: #fb923c;
    --sport-swimming: #818cf8;
    --sport-stairs: #c08a5e;
    --rpe-low-bg: #1e3a5f;  --rpe-low-text: #bfdbfe;
    --rpe-mid-bg: #2f1f4d;  --rpe-mid-text: #e4d9ff;
    --rpe-high-bg: #5c1d3f; --rpe-high-text: #fbcfe8;
    --rpe-max-bg: #f9a8d4;  --rpe-max-text: #500724;
    --rpe-max-soft-bg: #7a1f4f; --rpe-max-soft-text: #fce7f3;
    --hero-bg: #3d0079;
    --hero-button-text: #3d0079;
    --warn-bg: #3b2b0b;
    --warn-text: #fcd34d;
    --segment-empty: #2f2c3b;
    --load-past: #4a3a6e;
    --race-mode-bg: #3d0079;
    --race-mode-button: #5b2a9e;
    --tick-halo: rgba(196, 165, 255, 0.3);
    --done-bg: #14301f;
  }
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;            /* 16px+ stops iPhone zooming into inputs */
  line-height: 1.5;
  background: var(--bg);
  color: var(--text);
}

h1, h2 { line-height: 1.2; margin: 0 0 8px; }
/* Links are purple everywhere (20d): no browser-default blue. */
a { color: var(--accent); }

/* Line icons (utils/icons.js, step 17a): inline SVG drawn in the text colour,
   sized with the text around them. */
.icon { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.2em; flex-shrink: 0; }
.icon.is-ok { color: var(--ok); }
.icon.is-error { color: var(--error); }
.icon.is-muted { color: var(--muted); }

/* Numbers (step 17b): value in the condensed stat font, digits all the same
   width (so 1:11 and 8:88 line up), unit small and light next to it. */
.num { font-family: var(--font-num); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: 0.01em; }
.unit { font-family: var(--font); font-size: 0.8rem; font-weight: 500; color: var(--muted); letter-spacing: 0; }
h2 { font-size: 1.15rem; }
p { margin: 0 0 12px; }
.muted { color: var(--muted); }

/* ---------- Top bar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  /* 3 columns: logo | title | empty mirror of the logo column,
     so the title sits in the centre of the page, not of the leftover space. */
  display: grid;
  /* (30d) the sides never shrink below their content ("‹ Blocks", "Edit"); the
     title gets what is left and ends in "…" when it doesn't fit */
  grid-template-columns: minmax(max-content, 1fr) minmax(0, max-content) minmax(max-content, 1fr);
  align-items: center;
  gap: 12px;
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  background: var(--topbar-bg);
  color: var(--topbar-text);
}
.topbar-left { justify-self: start; display: flex; align-items: center; min-width: 0; }
.topbar-right { justify-self: end; display: flex; align-items: center; }
.brand { display: flex; text-decoration: none; }
.brand[hidden] { display: none; }
.brand img { display: block; height: 30px; width: auto; }  /* logo is 188 x 104 */
.page-title { font-size: 1rem; font-weight: 600; margin: 0; color: var(--topbar-text); text-align: center;
  /* a long race / block name ends in "…" instead of pushing "‹ Races" / "Edit" away (30d) */
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Step 20: "‹ Me" instead of the logo on a screen inside another one, and
   one action on the right (planner "⋯", block "Edit"). The negative margins
   keep the bar as thin as before while the tap area stays 44px. */
.topbar-back {
  display: inline-flex; align-items: center; gap: 2px; min-height: 44px; margin: -7px 0 -7px -8px; padding: 0 8px;
  color: var(--strip-accent); font-weight: 600; font-size: 0.95rem; text-decoration: none; white-space: nowrap;
}
.topbar-back .icon { width: 20px; height: 20px; stroke-width: 2.25; }
.topbar-button {
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px;
  margin: -7px -10px -7px 0; padding: 0 10px; border: 0; border-radius: 10px; background: transparent;
  color: var(--strip-accent); font: inherit; font-weight: 600; cursor: pointer;
}
.topbar-button.is-icon { color: var(--topbar-text); }
.topbar-button .icon { width: 22px; height: 22px; }
.topbar-button:hover { background: rgba(255, 255, 255, 0.1); }

/* ---------- Main area ---------- */
.view {
  max-width: var(--page-narrow);
  margin: 0 auto;
  /* bottom padding keeps content above the fixed tab bar */
  padding: 16px 16px calc(var(--tabbar-height) + 24px + env(safe-area-inset-bottom));
}

.card {
  background: var(--surface);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
}
.card > :last-child { margin-bottom: 0; }
.placeholder { border: 1px dashed var(--border); box-shadow: none; }

/* ---------- Forms ---------- */
label { display: block; font-weight: 600; margin-bottom: 4px; }

input {
  width: 100%;
  font: inherit;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  margin-bottom: 12px;
}
input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* iPhone Safari draws date boxes at their own width and ignores width: 100%,
   so they stuck out of the card. Drop the built-in look so they obey the width. */
input[type="date"] {
  -webkit-appearance: none; appearance: none;
  display: block; min-width: 0; max-width: 100%; min-height: 48px; text-align: left;
}
input[type="date"]::-webkit-date-and-time-value { text-align: left; }

.button {
  display: inline-block;
  font: inherit;
  font-weight: 600;
  min-height: 44px;            /* big enough for a thumb */
  padding: 10px 16px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.button.primary {
  width: 100%;
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}
.button:disabled { opacity: 0.6; cursor: default; }
/* A link that looks like a button never gets the link underline (22d) */
a.button, a.hero-button, a.hero-small-button { text-decoration: none; text-align: center; }

/* Step 22: a saved workout whose planned session is gone, done or skipped */
.orphan-workout h2 { margin-bottom: 4px; }
.button-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.button-row .button.primary { flex: 1 1 180px; width: auto; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.unfinished-workout { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: 12px; }
.unfinished-workout p { display: flex; align-items: flex-start; gap: 8px; margin: 0; }
.unfinished-workout p > span { flex: 1; min-width: 0; }
.unfinished-workout .small { display: block; opacity: 0.85; }
.unfinished-actions { display: flex; gap: 8px; }
.unfinished-actions .button { flex: 1; text-align: center; }
.unfinished-actions .button.is-quiet { flex: none; background: transparent; border-color: transparent; }
/* On Home it sits in the purple hero */
.unfinished-workout.in-hero { background: var(--hero-soft); color: var(--hero-text); }
.unfinished-workout.in-hero .button { background: var(--hero-button-bg); color: var(--hero-button-text); border-color: transparent; }
.unfinished-workout.in-hero .button.is-quiet { background: transparent; color: var(--hero-text); }
/* In the planner it looks like the other banners */
.unfinished-workout.in-plan { background: var(--surface); border: 1px solid var(--border); margin-bottom: 12px; }

.status { margin: 12px 0 0; }
.status:empty { display: none; }
.status.ok { color: var(--ok); }
.status.error { color: var(--error); }
.status.warning { color: #b45309; }
@media (prefers-color-scheme: dark) { .status.warning { color: #fbbf24; } }

.login { margin-top: 24px; }

/* ---------- Bottom tab bar ---------- */
.tabbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  height: calc(var(--tabbar-height) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.04);
}


.tabbar a {
  flex: 1;                     /* 5 equal-width tabs */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 0.75rem;
  color: var(--muted);
  text-decoration: none;
}
.tabbar a .icon { width: 24px; height: 24px; stroke-width: 1.75; }
.tabbar a.active { color: var(--accent); font-weight: 700; }
.tabbar a.active .icon { stroke-width: 2.25; }

/* ---------- Bigger screens ---------- */
@media (min-width: 720px) {
  .tabbar { justify-content: center; }
  .tabbar a { flex: 0 0 120px; }
}
/* Laptop (17e): no floating bar at the bottom of a wide screen; the tabs
   sit on the right of the top bar instead (same links, same order). */
@media (min-width: 1000px) {
  .tabbar {
    top: 0; bottom: auto; left: auto; right: 16px; height: auto;
    padding: 0; gap: 4px; align-items: center;
    /* same height as the top bar: its padding + the 30px logo */
    min-height: calc(54px + env(safe-area-inset-top)); padding-top: env(safe-area-inset-top);
    background: transparent; border: 0; box-shadow: none; z-index: 11;
  }
  .tabbar a {
    flex: none; flex-direction: row; gap: 6px; padding: 8px 12px; border-radius: 999px;
    font-size: 0.9rem; color: rgba(255, 255, 255, 0.78);
  }
  .tabbar a .icon { width: 20px; height: 20px; }
  .tabbar a:hover { background: rgba(255, 255, 255, 0.1); }
  /* the tabs take the right side of the bar: the screen's action sits next
     to the logo / back link instead, and the title stays in the middle */
  .topbar { display: flex; }
  .page-title { position: absolute; left: 50%; transform: translateX(-50%); max-width: 28vw; }
  .topbar-right { margin-left: 12px; }
  .topbar-button { margin: -7px 0; }
  .tabbar a.active { color: var(--topbar-text); background: rgba(255, 255, 255, 0.14); }
  .view { padding-bottom: calc(32px + env(safe-area-inset-bottom)); }
}
/* Small laptops: icons only (the label is still read out), so the tabs
   never bump into the page title in the middle of the bar. */
@media (min-width: 1000px) and (max-width: 1199px) {
  .tabbar a { font-size: 0; gap: 0; padding: 10px; }
}

/* ---------- Activity log: list ---------- */
.add-button { display: block; text-align: center; text-decoration: none; margin-bottom: 16px; line-height: 24px; }
/* Phone (31e, Rom chose it from a mock-up): the "+ Add …" button becomes a round
   "+" floating at the bottom right, just above the tab bar (thumb zone), on Log,
   Races, Shoes, Blocks and Catalogue. The text stays for screen readers (aria-label). */
@media (max-width: 999px) {
  .view .add-button {
    position: fixed; z-index: 20; margin: 0; padding: 0;
    right: calc(16px + env(safe-area-inset-right));
    bottom: calc(var(--tabbar-height) + 16px + env(safe-area-inset-bottom));
    width: 58px; height: 58px; min-height: 0; border-radius: 50%;
    display: grid; place-items: center;
    box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 35%, transparent), 0 2px 6px rgba(0, 0, 0, 0.15);
  }
  .view .add-button .add-text { display: none; }
  .view .add-button .add-plus { font-size: 2.1rem; font-weight: 300; line-height: 1; margin-top: -3px; }
  /* room under the list so the last row is never hidden behind the "+" */
  .view:has(.add-button) { padding-bottom: calc(var(--tabbar-height) + 100px + env(safe-area-inset-bottom)); }
  /* a toast (e.g. "Deleted: …") sits above the "+" instead of under it */
  body:has(.view .add-button) .toast { bottom: calc(var(--tabbar-height) + 90px + env(safe-area-inset-bottom)); }
}
.load-more { width: 100%; }

.week { margin-bottom: 20px; }
.week-title {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  margin: 0 4px 8px;
}
.week-title .muted { font-size: 0.85rem; font-weight: 400; }

.activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  overflow: hidden;            /* keeps the rounded corners on the first/last row */
}
.activity-list li + li { border-top: 1px solid var(--border); }
.activity-list .log-head + li { border-top: none; } /* the titles row draws its own line (laptop), or is hidden (phone) */

.activity-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  color: inherit;
  text-decoration: none;
  min-height: 56px;
}
.activity-item:active { background: var(--bg); }
.activity-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.activity-main .muted { font-size: 0.85rem; }
.activity-title { font-weight: 600; }
.activity-subtitle { font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.match-line { font-size: 0.85rem; color: var(--accent); font-weight: 600; }

.rpe-chip {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 0.85rem;
  background: var(--bg);
  border: 1px solid var(--border);
}
/* RPE colour bands (step 17b): cool (easy) to warm (very hard). */
.rpe-chip.rpe-low, .rpe-chip.rpe-mid, .rpe-chip.rpe-high, .rpe-chip.rpe-max { border-color: transparent; }
.rpe-low { background: var(--rpe-low-bg); color: var(--rpe-low-text); }
.rpe-mid { background: var(--rpe-mid-bg); color: var(--rpe-mid-text); }
.rpe-high { background: var(--rpe-high-bg); color: var(--rpe-high-text); }
.rpe-max { background: var(--rpe-max-bg); color: var(--rpe-max-text); }
.rpe-chip { font-family: var(--font-num); font-size: 1.05rem; font-variant-numeric: tabular-nums; }

/* The numbers of a log row (phone): distance, time, pace, D+ side by side. */
.activity-date { font-size: 0.8rem; }
.stat-row { display: flex; flex-wrap: wrap; column-gap: 12px; row-gap: 0; margin-top: 4px; }
.stat-row .num { font-size: 1.2rem; }
.stat-row .unit { font-size: 0.75rem; }

/* ---------- Activity log: form ---------- */
select, textarea {
  width: 100%;
  font: inherit;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  margin-bottom: 12px;
}
select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
textarea { resize: vertical; }

[hidden] { display: none !important; }
/* Shown only on a laptop / only on a phone (29b): one action, one place per screen size */
@media (max-width: 999px) { .laptop-only { display: none !important; } }
@media (min-width: 1000px) { .phone-only { display: none !important; } }

.hint { font-size: 0.85rem; color: var(--muted); margin: -8px 0 12px; }
.speed { font-weight: 700; color: var(--accent); margin: -4px 0 12px; }
.speed:empty { display: none; }

fieldset { border: 0; padding: 0; margin: 0 0 12px; min-width: 0; }
legend { font-weight: 600; padding: 0; margin-bottom: 8px; }

.match-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  background: var(--bg);
}
.match-card legend { padding: 0 4px; }
.match-card input { background: var(--surface); }
.row-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.row-3 input { margin-bottom: 0; }

/* ---------- Log form (20c): tiles and chips, numbers in one card,
   extras folded, Save pinned at the bottom ---------- */
.log-form { display: flex; flex-direction: column; gap: 18px; }
.log-form > * { margin: 0; }
.log-form .card { margin: 0; }
.form-section { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.form-section > legend.section-label { margin: 0 2px 8px; padding: 0; }
.form-section input[type="date"] { margin: 0; }
.chip-button[aria-pressed="true"] .icon { color: inherit; }
.chip-button .icon { width: 1em; height: 1em; vertical-align: -0.15em; }
/* Sport tiles: 3 per row, the line icon in the sport colour */
.sport-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.sport-tile { position: relative; margin: 0; font-weight: 600; }
.sport-tile input, .type-chip input, .rpe-option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.sport-tile > span {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 66px; padding: 6px;
  border-radius: 14px; border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-size: 0.82rem; text-align: center; line-height: 1.15; cursor: pointer;
}
.sport-tile .icon { width: 22px; height: 22px; color: var(--sport); }
.sport-tile .sport-short { display: none; }
/* Phone (31c): the 6 sports on ONE row of small tiles with a short name
   ("Run", "Gym"…), so Duration is in sight without scrolling */
@media (max-width: 999px) {
  .sport-tiles { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; }
  .sport-tile > span { min-height: 56px; padding: 6px 2px; gap: 3px; border-radius: 12px; font-size: 0.72rem; }
  .sport-tile .icon { width: 20px; height: 20px; }
  /* the full name stays for screen readers (the short one is aria-hidden) */
  .sport-tile .sport-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .sport-tile .sport-short { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
.sport-tile input:checked + span { border: 2px solid var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--surface)); }
.sport-tile input:focus-visible + span, .type-chip input:focus-visible + span, .rpe-option input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Type chips (radio buttons that look like chips) */
.type-chip { margin: 0; font-weight: 500; }
.type-chip[hidden] { display: none; }
.type-chip span {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); font-size: 0.9rem; cursor: pointer;
}
.type-chip input:checked + span { background: var(--accent); border-color: var(--accent); color: var(--accent-text); font-weight: 600; }
.more-chip { border: 0; background: none; color: var(--accent); font-weight: 600; }
/* The numbers card: duration big, distance + D+ side by side */
.numbers-card { display: flex; flex-direction: column; gap: 12px; }
.numbers-card label { font-size: 0.85rem; }
.numbers-card .hint { margin: 4px 0 0; }
.numbers-card input { margin: 0; }
.big-input { font-family: var(--font-num); font-size: 1.9rem; font-weight: 700; padding: 8px 14px; min-height: 58px;
  border: 2px solid var(--accent); background: var(--surface); font-variant-numeric: tabular-nums; }
/* The example ("45:00") must not look like a value already typed: light, thin, normal font */
.big-input::placeholder, .mid-input::placeholder { font-family: var(--font); font-size: 1.1rem; font-weight: 400; color: var(--muted); opacity: 0.7; }
.mid-input { font-family: var(--font-num); font-size: 1.45rem; font-weight: 700; padding: 8px 12px; min-height: 52px; font-variant-numeric: tabular-nums; }
.number-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.number-pair:not(:has(> :not([hidden]))) { display: none; }
.numbers-card .speed { margin: 0; }
.log-form .match-card { margin: 0; padding: 16px; background: var(--surface); border: 1px solid var(--card-border); }
.log-form .match-card input { background: var(--bg); }
.match-card > legend.section-label { float: left; width: 100%; margin: 0 0 10px; }
.match-card .row-3 { clear: both; align-items: end; }
/* RPE: ten colour buttons, cool to warm (never green / amber / red) */
/* the legend on the left, "5 · Moderate" on the right of the same line */
.form-section.rpe { display: block; }
.form-section.rpe > legend.section-label { float: left; margin: 0 2px 0; }
.rpe-what { text-transform: none; letter-spacing: 0; font-weight: 400; }
.rpe-label { margin: 0 2px 0 0; text-align: right; font-size: 0.85rem; font-weight: 600; line-height: 1.5; color: var(--accent); }
.rpe-label.is-empty { color: var(--muted); font-weight: 400; }
.rpe-grid { clear: both; display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 4px; padding-top: 8px; }
@media (max-width: 359px) { .rpe-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.rpe-option { margin: 0; position: relative; }
.rpe-option span {
  display: grid; place-items: center; height: 48px; border-radius: 10px; font-size: 1.15rem; cursor: pointer;
  background: var(--rpe-bg); color: var(--rpe-text);
}
.rpe-option.level-low  { --rpe-bg: var(--rpe-low-bg);  --rpe-text: var(--rpe-low-text); }
.rpe-option.level-mid  { --rpe-bg: var(--rpe-mid-bg);  --rpe-text: var(--rpe-mid-text); }
.rpe-option.level-high { --rpe-bg: var(--rpe-high-bg); --rpe-text: var(--rpe-high-text); }
.rpe-option.level-max  { --rpe-bg: var(--rpe-max-soft-bg); --rpe-text: var(--rpe-max-soft-text); }
.rpe-option input:checked + span { background: var(--rpe-text); color: var(--rpe-bg); box-shadow: 0 0 0 3px color-mix(in srgb, var(--rpe-text) 30%, transparent); font-size: 1.3rem; }
/* Shoes / Title / Notes folded into rows */
.fold-card { padding: 0; overflow: hidden; }
.fold-row + .fold-row { border-top: 1px solid var(--border); }
.fold-row > summary { list-style: none; display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 16px; cursor: pointer; }
.fold-row > summary::-webkit-details-marker { display: none; }
.fold-row > summary > .icon:first-child { color: var(--muted); }
.fold-label { font-weight: 500; }
.fold-value { flex: 1; min-width: 0; text-align: right; color: var(--muted); font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fold-chevron { color: var(--muted); transition: transform 0.2s ease; }
.fold-row[open] .fold-chevron { transform: rotate(180deg); }
.fold-body { padding: 0 16px 14px; }
.fold-body select, .fold-body input, .fold-body textarea { margin: 0; }
.delete-activity { align-self: center; margin: 0; display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; }
/* Save pinned at the bottom of the screen (safe-area aware) */
.save-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 9;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 94%, transparent); border-top: 1px solid var(--border);
}
.save-bar .button { display: block; max-width: calc(var(--page-narrow) - 32px); margin: 0 auto; min-height: 54px; border-radius: 16px; font-size: 1.05rem; font-weight: 700; }
.is-form .view { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
.is-form .toast { bottom: calc(96px + env(safe-area-inset-bottom)); }
@media (max-width: 999px) { .is-form .tabbar { display: none; } }
/* Log form columns (29a): phone = one list (the wrappers melt away); laptop = two columns */
.log-col { display: contents; }
@media (min-width: 1000px) {
  .view:has(.log-form) { max-width: var(--page-wide); }
  .log-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 32px; row-gap: 18px; align-items: start; }
  .log-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
  .log-col > * { margin: 0; }
  .log-form > :not(.log-col) { grid-column: 1 / -1; }
  .save-bar .button { max-width: calc(var(--page-wide) - 32px); }
}

.form-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.form-actions .button.primary { flex: 1 1 100%; }
.form-actions a.button { text-decoration: none; text-align: center; line-height: 24px; }
.button.danger { color: var(--error); margin-left: auto; }

/* ---------- Login: password + link ---------- */
.login-alt { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
.login-alt .button { width: 100%; }
.login-alt p { margin-bottom: 8px; font-size: 0.9rem; }

/* Present for the password manager, invisible on screen. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  margin: 0;
  padding: 0;
  border: 0;
}

/* ---------- Me menu ---------- */
.menu { padding: 0; overflow: hidden; }
.menu a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  min-height: 52px;
  color: inherit;
  text-decoration: none;
  font-weight: 600;
}
.menu a + a { border-top: 1px solid var(--border); }
.menu a > .icon { color: var(--accent); width: 1.3em; height: 1.3em; }
.menu a > span:last-child { margin-left: auto; }  /* the › on the right */
.menu a span { color: var(--muted); font-size: 1.3rem; }

.back-link {
  display: inline-block;
  margin: 0 0 12px;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}

/* ---------- Shoes ---------- */
.shoe-card { display: flex; flex-direction: column; gap: 6px; color: inherit; text-decoration: none; }
.shoe-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.chip {
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
}
.small { font-size: 0.85rem; }

/* Progress bar: grey track, coloured fill whose width = % of the replace distance. */
.bar { display: block; height: 8px; border-radius: 4px; background: var(--bg); border: 1px solid var(--border); overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--ok); border-radius: 4px; }
.status-warn .bar-fill { background: #d97706; }
.status-replace .bar-fill { background: var(--error); }
.status-retired { opacity: 0.7; }
.status-retired .bar-fill { background: var(--muted); }
.shoe-message { font-size: 0.85rem; font-weight: 700; }
.status-warn .shoe-message { color: #b45309; }
.status-replace .shoe-message { color: var(--error); }

.retired { margin-bottom: 16px; }
.retired summary { cursor: pointer; font-weight: 600; padding: 8px 4px; color: var(--muted);
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.07em; }

.checkbox { display: flex; align-items: center; gap: 8px; font-weight: 400; margin-bottom: 12px; }
.checkbox input { width: 20px; height: 20px; margin: 0; }

@media (prefers-color-scheme: dark) {
  .status-warn .shoe-message { color: #fbbf24; }
}

/* ---------- Catalogue editor ---------- */
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.row-2 > [hidden] { display: none !important; }
.exercises { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 4px; }
.exercise-row {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 12px;
  background: var(--bg);
}
.exercise-row input { background: var(--surface); }
.exercise-row .row-3 label { font-size: 0.8rem; font-weight: 600; margin: 0; }
.exercise-row .row-3 input { margin: 4px 0 12px; }
.row-actions { display: flex; gap: 8px; justify-content: flex-end; }
.small-button { min-height: 36px; min-width: 44px; padding: 4px 10px; }

/* ---------- Planner: week ---------- */
/* One row (20a): ‹ title + dates › and the Week | Month switch; the
   switch drops to its own line only on a very narrow phone. */
.week-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
.week-nav-title { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; text-align: center; line-height: 1.25; }
.nav-button {
  flex: none; display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text); text-decoration: none;
}
.nav-button .icon { width: 20px; height: 20px; }
.nav-spacer { flex: none; width: 44px; height: 44px; }   /* week review: no › after this week (30a) */
.week-head .view-switch { margin: 0; }
.week-head .view-switch a { padding: 6px 12px; }
.week-nav-title strong { white-space: nowrap; }
/* Phone: a long title ("Week of 2 Nov 2026") wraps instead of running under the arrows (29c) */
@media (max-width: 999px) { .week-nav-title strong { white-space: normal; text-wrap: balance; } }
.week-nav-title span { white-space: nowrap; }
@media (max-width: 359px) {
  .week-nav-title { flex-basis: 150px; }
  .week-head .view-switch { order: 4; margin: 0 auto; }
}
/* The stat strip (same look as Home's race-mode strip) + block / review links.
   It sits inside the head row (28c): on a phone it takes its own line below. */
.week-head .plan-strip { order: 5; flex-basis: 100%; margin: 4px 0 0; }
/* "2h42 / 4h06" stays on one line; on the narrowest phones the numbers shrink a little to fit */
.plan-strip #strip-load { white-space: nowrap; }
@media (max-width: 359px) {
  .plan-strip .num { font-size: 1.35rem; }
  /* each column as wide as its numbers, so "2h38 / 4h55" never runs into the warnings count (28c) */
  .week-head .plan-strip { grid-template-columns: repeat(3, auto); justify-content: space-between; }
}
.strip-cell { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; padding: 0; border: 0;
  background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.strip-cell:disabled { cursor: default; }
.week-links { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.week-links a { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; margin: 0;
  font-size: 0.9rem; font-weight: 600; color: var(--accent); text-decoration: none; }
.week-links .week-review-link { margin-left: auto; }
/* The planner's tools on a laptop (29b): Copy last week · Templates · Catalogue */
.plan-tools { display: inline-flex; align-items: center; gap: 20px; margin-left: 24px; }
.week-links:has(.plan-tools) { justify-content: flex-start; }
.plan-tools .link-button { min-height: 36px; gap: 6px; }
.plan-tools .icon, .month-tools .icon { width: 16px; height: 16px; }
.month-tools { justify-content: center; gap: 24px; }
.today-link { display: block; text-align: center; color: var(--accent); font-weight: 600; text-decoration: none; margin-bottom: 4px; }
.week-summary { text-align: center; font-size: 0.9rem; margin-bottom: 12px; }

.days { display: flex; flex-direction: column; gap: 12px; }
.day {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow);
  border-radius: var(--radius);
  padding: 10px 12px 12px;
}
.day.is-today { border-color: var(--accent-strong); box-shadow: 0 0 0 1px var(--accent-strong), var(--shadow); }
.day-title { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 0.95rem; margin: 0; }
.day-name { margin-right: 2px; }
.day-tags { display: contents; }   /* phone: the tags sit in the row like before */
.day-add {
  display: inline-grid; place-items: center; flex: none; margin-left: auto;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface); color: var(--accent); cursor: pointer;
}
.day-add .icon { width: 18px; height: 18px; stroke-width: 2.25; }
/* The day's load tag (20a, rules.js dayLoadTag): the heaviest kind of
   session that day. Cool colours / grey, never green / amber / red. */
.day-tag { padding: 2px 8px; border-radius: 999px; font-size: 0.7rem; font-weight: 700; line-height: 1.5; white-space: nowrap;
  background: var(--bg); color: var(--muted); }
.day-tag.tag-heavy_legs { background: var(--rpe-high-bg); color: var(--rpe-high-text); }
.day-tag.tag-easy_run { background: var(--rpe-low-bg); color: var(--rpe-low-text); }
.day-tag.tag-upper_body { background: var(--bg); color: var(--text); }
.day-tag.is-today { background: var(--accent); color: var(--accent-text); }

/* Planner meta lines: digits the same width, so durations line up (17b). */
.plan-card .muted { font-variant-numeric: tabular-nums; }
.plan-card {
  display: flex; align-items: center; gap: 10px; width: 100%;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  padding: 10px; margin: 0;
  border: 0; border-left: 4px solid var(--accent-strong); border-radius: 10px; background: var(--bg);
}
.plan-card.status-done { border-left-color: var(--done-line); }
/* Skipped (cancelled): greyed and dashed, a quiet "Skipped" (20a) */
.plan-card.status-cancelled { background: transparent; border: 1px dashed var(--border); border-left: 4px dashed var(--border); color: var(--muted); }
.plan-card.status-cancelled .sport-badge { opacity: 0.5; }
.skipped-tag { font-size: 0.78rem; font-weight: 600; color: var(--muted); }
/* Today's planned session: "Log it" + (with a recipe) a round play button on the card (20a) */
.plan-row { position: relative; }
.plan-row.has-quick .plan-card { padding-right: 110px; }
.plan-row.has-play .plan-card { padding-right: 160px; }
.plan-quick {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 8px;
}
.plan-log {
  display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 14px; border-radius: 22px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text); text-decoration: none;
  font-size: 0.9rem; font-weight: 600;
}
.plan-log .icon { width: 18px; height: 18px; }
.plan-play {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  background: var(--accent); color: var(--accent-text); text-decoration: none;
}
.plan-play .icon { width: 18px; height: 18px; fill: currentColor; margin-left: 2px; }
.plan-card.extra { border: 1px dashed var(--border); border-left: 4px dashed var(--muted); opacity: 0.8; }
.plan-status { font-size: 1.1rem; }

/* Sport badge: the sport icon on a soft circle in the sport's colour
   (utils/plan.js sportBadge). The card's left line keeps showing the status. */
.sport-badge {
  --sport: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 2.2rem; height: 2.2rem; border-radius: 50%; line-height: 1;
  color: var(--sport);   /* the line icon is drawn in the sport colour */
  background: color-mix(in srgb, var(--sport) 20%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--sport) 45%, transparent);
}
.sport-badge .icon { width: 56%; height: 56%; }
.sport-badge.small { width: 1.6rem; height: 1.6rem; }
.sport-running  { --sport: var(--sport-running); }
.sport-football { --sport: var(--sport-football); }
.sport-muscle   { --sport: var(--sport-muscle); }
.sport-biking   { --sport: var(--sport-biking); }
.sport-swimming { --sport: var(--sport-swimming); }
.sport-stairs   { --sport: var(--sport-stairs); }

/* Laptop: the 7 days side by side, like a calendar. */
@media (min-width: 1000px) {
  .view:has(.days) { max-width: 1400px; }
  .view:has(.month) { max-width: var(--page-wide); }
  /* every day the same width AND height (the tallest day sets the height) */
  .days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; align-items: stretch; }
  .day { min-height: 160px; padding: 8px; }
  /* Day header (28c), the same on every day: date + "+" on line 1,
     Today + load tag on line 2 (kept even when empty, so the first cards line up) */
  .day-title { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px; font-size: 0.85rem; }
  .day-name { grid-column: 1; grid-row: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .day-add { grid-column: 2; grid-row: 1; width: 28px; height: 28px; }
  .day-tags { grid-column: 1 / -1; grid-row: 2; display: flex; gap: 4px; min-height: 22px; min-width: 0; }
  /* one line: in a narrow column the load tag is cut ("Heavy l…") rather than pushing the cards down */
  .day-tags .day-tag { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .day-tags .day-tag.is-today { flex: none; }
  /* Head row (28c): ‹ This week ›, the numbers inline, Week | Month */
  .week-nav-title { flex: none; min-width: 150px; }
  .week-head .plan-strip {
    order: 0; flex: 1; flex-basis: auto; margin: 0; padding: 0 16px;
    display: flex; justify-content: center; gap: 40px; background: none; border: 0; box-shadow: none;
  }
  .week-head .view-switch { margin-left: auto; }
  .plan-card { flex-direction: column; align-items: flex-start; gap: 4px; padding: 8px; }
  .plan-row.has-quick .plan-card, .plan-row.has-play .plan-card { padding-right: 8px; padding-bottom: 52px; }
  /* narrow day column: the buttons span the card's width, "Log it" without its pen icon */
  .plan-quick { top: auto; bottom: 8px; left: 8px; right: 8px; transform: none; gap: 6px; }
  .plan-play { flex: none; width: 36px; height: 36px; }
  .plan-log { flex: 1; justify-content: center; height: 36px; padding: 0 8px; font-size: 0.85rem; white-space: nowrap; }
  .plan-log .icon { display: none; }
  /* 7 columns: a warning chip can't sit between two days, so it shows in the later day */
  .warning-between { display: none !important; }
  .day .warning-chip.warning-dup { display: flex; }
  .warning-chip { align-self: stretch; border-radius: 12px; font-size: 0.75rem; }
  /* one line in the narrow day column (28d); the full message shows on mouse-over (title) and on tap */
  .day .warning-chip .chip-short { display: none; }
  .day .warning-chip .chip-tiny { display: inline; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .plan-card .sport-badge { width: 1.8rem; height: 1.8rem; }
}

/* ---------- Bottom sheet (pop-up panel) ---------- */
.sheet {
  border: 0; padding: 0; margin: auto auto 0;
  width: 100%; max-width: 560px; max-height: 85vh;
  border-radius: 16px 16px 0 0;
  background: var(--surface); color: var(--text);
}
.sheet::backdrop { background: rgba(0, 0, 0, 0.45); }
.sheet-header {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 16px 16px 8px; position: sticky; top: 0; background: var(--surface);
}
.sheet-header h2 { margin: 0; font-size: 1.1rem; }
.sheet-heading { flex: 1; min-width: 0; }
.sheet-heading p { margin: 2px 0 0; }
.sheet-header.has-badge { justify-content: flex-start; gap: 12px; }
.sheet-header.has-badge h2 { font-size: 1.25rem; line-height: 1.2; }
.sheet-header .sport-badge { width: 2.75rem; height: 2.75rem; border-radius: 14px; }
/* Session menu (20b): numbers row, one big main action, Done + Log it side by side */
.sheet-facts { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 4px 0 12px; padding: 10px 12px; border-radius: 12px; background: var(--bg); }
.sheet-facts .num { font-size: 1.35rem; }
.sheet-exercises { margin: 0 0 4px; }
.sheet-exercises summary { cursor: pointer; color: var(--accent); font-weight: 600; font-size: 0.9rem; min-height: 36px; display: flex; align-items: center; }
.sheet-exercises .exercise-list { margin-top: 4px; }
.sheet-actions .sheet-main { min-height: 54px; border-radius: 14px; font-size: 1.05rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.sheet-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.sheet-pair .button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 48px; border-radius: 12px; }
.sheet-actions + .sheet-rows { margin-top: 12px; }
/* Quiet list rows inside a sheet (20a/b): icon, label, › */
.sheet-rows { display: flex; flex-direction: column; border-top: 1px solid var(--border); margin-top: 8px; }
.sheet-row {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 50px; padding: 0 4px;
  border: 0; border-bottom: 1px solid var(--border); background: transparent;
  font: inherit; font-weight: 500; color: var(--text); text-align: left; cursor: pointer;
}
.sheet-row:last-child { border-bottom: 0; }
.sheet-row > .icon:first-child { color: var(--muted); }
.sheet-row-label { flex: 1; min-width: 0; }
.sheet-row-chevron { color: var(--muted); opacity: 0.7; }
.sheet-row.is-danger { color: var(--error); font-weight: 600; }
/* A hint on the right ("just running", 30e): the label stays on one line, the hint is what gets cut */
.sheet-row:has(> .muted.small) .sheet-row-label { flex: 1 0 auto; white-space: nowrap; }
.sheet-row > .muted.small { flex: 0 1 auto; min-width: 0; margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-row.is-danger > .icon:first-child { color: var(--error); }
.sheet-close { border: 0; background: none; font-size: 1.3rem; color: var(--muted); cursor: pointer; min-width: 44px; min-height: 44px; }
.sheet-body { padding: 0 16px calc(20px + env(safe-area-inset-bottom)); }
.sheet-subtitle { font-size: 0.85rem; color: var(--muted); margin: 12px 0 6px; font-weight: 600; display: block; }
.sheet-list { display: flex; flex-direction: column; gap: 6px; }
.sheet-item {
  display: flex; justify-content: flex-start; align-items: center; gap: 8px;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  padding: 12px; min-height: 44px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--bg);
}
.sheet-item > .muted { margin-left: auto; }  /* a hint (e.g. "· 7 in catalogue") sits on the right */
.sheet-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.sheet-actions .button { width: 100%; }
.sheet-body input[type="date"] { margin-top: 4px; }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-button {
  font: inherit; font-size: 0.9rem; cursor: pointer; color: inherit;
  padding: 8px 12px; min-height: 40px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--bg);
}
.chip-button:disabled { opacity: 0.4; cursor: default; }
.exercise-list { margin: 0 0 8px; padding-left: 20px; }
.exercise-list li { margin-bottom: 4px; }
.pre-line { white-space: pre-line; }
@media (min-width: 700px) {
  .sheet { margin: auto; border-radius: 16px; }
}

/* ---------- Toast (small message at the bottom) ---------- */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--tabbar-height) + 16px + env(safe-area-inset-bottom));
  z-index: 50; display: flex; align-items: center; gap: 12px;
  max-width: calc(100% - 32px); padding: 12px 16px; border-radius: 12px;
  background: var(--text); color: var(--bg); box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}
.toast button { font: inherit; font-weight: 700; color: var(--accent); background: none; border: 0; cursor: pointer; padding: 4px; }
@media (prefers-color-scheme: dark) { .toast button { color: #3d0079; } }
@media (min-width: 1000px) { .toast { bottom: calc(24px + env(safe-area-inset-bottom)); } }  /* no bottom bar on a laptop */

.plan-banner { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; font-size: 0.9rem; }
/* "Big jump" / race-week load note: amber text on a card, the same look as on Home (28d) */
.plan-banner.load-banner { background: var(--surface); border-color: var(--card-border); box-shadow: var(--shadow); color: var(--warn-text); font-weight: 500; }
/* 31b: a button now (tap = whole note on a phone) */
.load-banner { display: flex; align-items: center; gap: 6px; width: 100%; text-align: left; font: inherit; cursor: pointer; }
.load-banner .icon { flex: none; }
.load-banner .load-short { display: none; }
@media (max-width: 999px) {
  /* Phone: one amber line; tapped (aria-expanded) = the whole note */
  .load-banner[aria-expanded="false"] .load-short { display: block; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .load-banner[aria-expanded="false"] .load-full { display: none; }
  .load-banner { padding: 8px 12px; }
  /* Block link + Week review always on one line; a long block name ends in "…" */
  .week-links { flex-wrap: nowrap; }
  .week-links .week-block { min-width: 0; }
  .week-links .week-block > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .week-links .week-review-link { flex: none; }
}

/* Week templates screen */
.week-template h2 { margin-top: 0; }
.template-days { list-style: none; margin: 0 0 12px; padding: 0; }
.template-days li { display: flex; gap: 12px; padding: 6px 0; border-top: 1px solid var(--border); }
.template-day { width: 2.5em; flex-shrink: 0; font-weight: 600; }

/* Workout mode (step 18): dark strip on top, the current exercise as a big
   card, short rows for the others, a bar pinned at the bottom while resting.
   Full screen: no tab bar (main.js hides it, body gets .is-workout). */
.is-workout .view { max-width: 560px; padding-bottom: calc(32px + env(safe-area-inset-bottom)); }
.is-workout .view.has-workout-bar { padding-bottom: calc(200px + env(safe-area-inset-bottom)); }
.chip-button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }

.workout-strip {
  margin: -16px -16px 16px; padding: 10px 16px 14px;
  background: var(--strip-bg); color: var(--topbar-text);
  display: flex; flex-direction: column; gap: 12px;
}
.strip-top { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; }
.strip-back {
  justify-self: start; display: inline-flex; align-items: center; gap: 2px; min-height: 44px; padding-right: 8px;
  color: var(--strip-accent); font-weight: 600; font-size: 0.9rem; text-decoration: none;
}
.strip-time { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.strip-time .num { font-size: 2rem; }
.strip-name { font-size: 0.72rem; color: var(--strip-muted); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.strip-sets { justify-self: end; display: flex; flex-direction: column; align-items: flex-end; }
.strip-count { display: flex; align-items: baseline; gap: 3px; }
.strip-count .num { font-size: 1.45rem; }
.strip-of { font-family: var(--font-num); font-weight: 600; font-size: 1.05rem; color: var(--strip-muted); }
.strip-unit { font-size: 0.72rem; color: var(--strip-muted); }
.strip-bar { height: 4px; border-radius: 2px; background: var(--strip-track); overflow: hidden; }
.strip-bar span { display: block; height: 100%; width: 0; background: var(--strip-accent); border-radius: 2px; transition: width 0.3s ease; }
.strip-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.strip-chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 12px;
  font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  color: var(--topbar-text); background: transparent; border: 1px solid var(--strip-track); border-radius: 999px;
}
.strip-chip[aria-pressed="false"] { color: var(--strip-muted); }
.strip-about { margin: 0; font-size: 0.82rem; color: var(--strip-muted); white-space: pre-line; }

/* The current exercise */
.workout-now { border: 2px solid var(--accent); display: flex; flex-direction: column; gap: 14px; padding: 18px; }
.now-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.now-label { margin: 0; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--accent); }
.now-edit {
  width: 44px; height: 44px; margin: -12px -10px -12px 0; flex-shrink: 0;
  border: 0; background: none; color: var(--muted); cursor: pointer;
}
.now-edit .icon { width: 20px; height: 20px; }
.now-name { margin: -6px 0 0; font-size: 1.75rem; line-height: 1.1; }
.now-facts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 24px; }
.now-fact .num { font-size: 3.2rem; line-height: 0.9; }
.now-fact.is-weight .num { font-size: 2.2rem; }
.now-fact .unit { font-size: 0.9rem; }
.now-fact-text { font-size: 1.2rem; font-weight: 600; }
.now-note { margin: -6px 0 0; color: var(--muted); font-size: 0.9rem; }
.workout-now .tick-row { margin-top: 0; }
.now-button {
  width: 100%; min-height: 64px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--accent); border: 2px solid var(--accent); color: var(--accent-text);
  font-size: 1.15rem; font-weight: 700;
}
.now-button .icon { width: 22px; height: 22px; stroke-width: 2.75; }
.now-button.is-outline { background: var(--surface); color: var(--accent); }
.now-hint { margin: -6px 0 0; text-align: center; font-size: 0.85rem; color: var(--muted); }
.workout-now.is-all-done { border-color: var(--ok); }
.workout-now.is-all-done .now-label { color: var(--ok); display: flex; align-items: center; gap: 6px; }
.workout-rounds { margin: 0 4px 12px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.9rem; }

/* Set circles: done = filled + check, next = ring in the accent */
.tick-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.tick {
  width: 48px; height: 48px; border-radius: 50%; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--border); background: var(--surface); color: var(--muted);
  font-size: 1.1rem; cursor: pointer;
}
.tick .num { font-size: 1.3rem; }
.tick.is-next { border: 3px solid var(--accent); color: var(--accent); }
.tick.is-ticked { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.tick.is-ticked .icon { width: 22px; height: 22px; stroke-width: 3; }
.tick.just-ticked { animation: tick-pop 0.35s ease-out; }
@keyframes tick-pop {
  0% { transform: scale(0.7); box-shadow: 0 0 0 0 var(--tick-halo); }
  60% { transform: scale(1.12); box-shadow: 0 0 0 8px var(--tick-halo); }
  100% { transform: scale(1); box-shadow: 0 0 0 6px transparent; }
}
@media (prefers-reduced-motion: reduce) { .tick.just-ticked { animation: none; } .strip-bar span, .bar-track span { transition: none; } }

/* Up next / Done rows */
.ex-list { padding: 0; overflow: hidden; }
.ex-row {
  width: 100%; min-height: 60px; padding: 10px 16px;
  display: flex; align-items: center; gap: 12px;
  border: 0; border-top: 1px solid var(--border); background: none;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.ex-row:first-child { border-top: 0; }
.ex-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ex-row-name { font-weight: 600; }
.ex-row-meta { font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.ex-dots { display: flex; gap: 4px; flex-shrink: 0; }
.ex-dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--border); box-sizing: border-box; }
.ex-dot.is-ticked { background: var(--accent); border-color: var(--accent); }
.is-done-list .ex-row { color: var(--muted); }
.is-done-list .ex-row-name { color: var(--text); font-weight: 500; }
.ex-done-badge {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--done-bg); color: var(--ok);
}
.ex-done-badge .icon { width: 16px; height: 16px; stroke-width: 3; }

.add-exercise { width: 100%; margin: 4px 0 8px; border-style: dashed; background: transparent; display: flex; align-items: center; justify-content: center; gap: 6px; }
.sheet .row-2 label, .sheet .row-3 label { font-size: 0.8rem; font-weight: 600; margin: 0; }
.sheet .row-2 input, .sheet .row-3 input { margin: 4px 0 8px; }
.sheet-item.is-current { border-color: var(--accent); font-weight: 600; }
.sheet-item.is-current .icon { margin-left: auto; color: var(--accent); }
.workout-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.workout-actions .button { width: 100%; }
.finish-button {
  min-height: 56px; display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--strip-bg); border-color: var(--strip-bg); color: var(--topbar-text); font-size: 1.05rem;
}
.workout-actions .button.danger { margin-left: 0; border-color: transparent; background: transparent; }

/* The bar pinned at the bottom: rest countdown, or a timed set running */
.workout-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  max-width: 560px; margin: 0 auto;
  padding: 14px 16px calc(16px + env(safe-area-inset-bottom));
  border-radius: 22px 22px 0 0;
  background: var(--strip-bg); color: var(--topbar-text);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.18);
  display: flex; flex-direction: column; gap: 10px;
}
.bar-row { display: flex; align-items: center; gap: 10px; }
.bar-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bar-label { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--strip-accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-left { font-size: 3.2rem; line-height: 0.95; }
.workout-bar .button { min-height: 52px; border-radius: 14px; font-weight: 700; flex-shrink: 0; }
.bar-more { background: transparent; color: var(--topbar-text); border-color: var(--strip-track); }
.bar-skip { background: var(--strip-accent); border-color: var(--strip-accent); color: var(--strip-bg); }
.bar-track { height: 6px; border-radius: 3px; background: var(--strip-track); overflow: hidden; }
.bar-track span { display: block; height: 100%; width: 0; background: var(--strip-accent); border-radius: 3px; transition: width 1s linear; }
.bar-next { margin: 0; font-size: 0.85rem; color: var(--strip-muted); }
.bar-next strong { color: var(--topbar-text); }
.workout-banner { display: block; text-decoration: none; color: inherit; }

@media (min-width: 720px) {
  .workout-strip { margin: 0 0 16px; border-radius: 16px; }
}
/* Phone (30c): the dark workout strip IS the top of the screen. The app's top
   bar would be a second dark bar above it; the strip has its own "‹ Plan".
   Only when the strip is there: the error / "session removed" pages keep the
   top bar (the tab bar is hidden in workout mode, it's their only way out). */
@media (max-width: 719px) {
  .is-workout:has(.workout-strip) .topbar { display: none; }
  .is-workout .workout-strip { padding-top: calc(10px + env(safe-area-inset-top)); }
}

/* Training-rule warnings on the planner (20a): a small amber chip with a few
   words; tap = the full message (+ mute). Between two day cards on a phone,
   inside the later day on a laptop. Muted ones are grey (16e). */
.warning-chip {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; max-width: 100%;
  min-height: 32px; padding: 4px 12px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--warn-text) 30%, transparent);
  background: var(--warn-bg); color: var(--warn-text); font: inherit; font-size: 0.8rem; font-weight: 600; text-align: left; cursor: pointer;
}
.warning-chip .icon { width: 15px; height: 15px; }
.warning-chip.is-muted { background: var(--bg); color: var(--muted); border-color: var(--border); }
.warning-chip.warning-dup { display: none; }
.warning-chip .chip-tiny { display: none; }   /* the laptop's narrow columns show the tiny text (28d) */
/* between two days: centred on the gap, a little over both cards */
.days > .warning-between { align-self: center; margin: -8px 0; position: relative; z-index: 1; }

/* Step 16: race marker on a planner day, missed sessions, load notes, week review */
.race-marker {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  margin: 0; padding: 8px 10px; border-radius: 10px;
  border: 1px dashed var(--accent-strong); color: inherit; text-decoration: none;
}
.month-race { display: inline-flex; align-items: center; height: 1.6rem; color: var(--accent); }
/* A session left "planned" on a past day: dashed amber line + a small tag. */
.plan-card.is-missed { border-left: 4px dashed #d97706; }
.missed-tag { display: block; color: #b45309; }
@media (prefers-color-scheme: dark) { .missed-tag { color: #fbbf24; } }
.load-banner { margin: 0 0 12px; }
.week-review-link { color: var(--accent); text-decoration: none; }
.review-list { margin: 0; padding-left: 1.2rem; }
.review-notes { width: 100%; min-height: 8rem; }
.block-review { margin: 0 0 12px; }
.block-review p { margin: 4px 0 0; white-space: pre-line; }

/* Races */
.race-card { display: flex; flex-direction: column; gap: 4px; text-decoration: none; color: inherit; }
.race-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.race-card.status-cancelled { opacity: 0.6; }
.countdown { color: var(--accent); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* Race page cards (step 19c): routine rows and the checklist */
.card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.card-head h2 { margin: 0; }
.card-head .num { font-size: 1.4rem; }
#routine .button, #checklist .button { margin-top: 8px; }
.routine-rows { display: flex; flex-direction: column; margin-bottom: 4px; }
.routine-row { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 6px 0; color: inherit; text-decoration: none; }
.routine-row + .routine-row { border-top: 1px solid var(--border); }
.routine-day { flex: none; width: 44px; display: flex; flex-direction: column; align-items: center; line-height: 1.1; }
.routine-day > span:first-child { font-size: 0.7rem; font-weight: 600; text-transform: uppercase; color: var(--muted); }
.routine-day .num { font-size: 1.4rem; }
.routine-day.is-race, .routine-day.is-race > span:first-child { color: var(--accent); }
.routine-rest { background: var(--bg); color: var(--muted); }
.routine-race { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--accent); }
.routine-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.routine-warn { display: inline-flex; align-items: center; gap: 4px; color: var(--warn-text); }
.link-button {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 0.9rem; font-weight: 600; color: var(--accent); cursor: pointer;
}
.link-button.is-quiet { color: var(--muted); }
.checklist-bar { margin: 0 0 6px; height: 6px; border: 0; background: var(--segment-empty); }
.checklist { list-style: none; margin: 0 0 8px; padding: 0; }
.checklist li { display: flex; justify-content: space-between; align-items: center; gap: 8px; border-bottom: 1px solid var(--border); }
.check-row { flex: 1; display: flex; align-items: center; gap: 12px; min-height: 48px; margin: 0; font-weight: 500; cursor: pointer; }
.check-row input { flex: none; width: 24px; height: 24px; margin: 0; accent-color: var(--done-line); }
.checklist li.is-done .check-row { color: var(--muted); font-weight: 400; text-decoration: line-through; }
.add-item { display: flex; gap: 8px; margin-top: 10px; }
.add-item input { flex: 1; margin: 0; }
.add-item .button { margin-top: 0 !important; }
.button.icon-only { flex: none; width: 48px; padding: 0; display: inline-grid; place-items: center; }
.checklist-links { display: flex; justify-content: space-between; gap: 8px; margin-top: 4px; }
.race-title { margin: 8px 0 0; }   /* also the block page title */
.race-subtitle { margin: 2px 0 12px; }

/* Training blocks */
.block-card { display: flex; flex-direction: column; gap: 4px; text-decoration: none; color: inherit; }
.block-goal { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }
.stat-grid div { display: flex; flex-direction: column; min-width: 0; }
/* Big values in the stat font (17b); a unit inside (.unit) stays small. */
.stat-grid strong { font-family: var(--font-num); font-size: 1.75rem; font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
@media (min-width: 700px) { .stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.week-block { color: var(--accent); text-decoration: none; }
.week-block[hidden] { display: none; }
.block-reminder { color: var(--accent); font-weight: 600; }

/* Body & goals */
.weigh-when { margin-bottom: 8px; }
.weigh-form input[type="date"] { margin-bottom: 8px; }
.weigh-form input[name="weight_kg"] { flex: 1; min-width: 70px; }
.goal-line { margin: 12px 0 6px; }
.goal-edit, .weigh-list { margin-top: 16px; }
.goal-edit summary, .weigh-list summary { cursor: pointer; color: var(--accent); font-weight: 600; }
#goal-form { margin-top: 8px; align-items: end; }
#goal-form .button { grid-column: 1 / -1; }
.pb-list { list-style: none; margin: 0 0 8px; padding: 0; }
.pb-row { display: flex; gap: 12px; align-items: baseline; border-top: 1px solid var(--border); padding: 8px 0; }
.pb-row strong { font-family: var(--font-num); font-size: 1.4rem; font-variant-numeric: tabular-nums; }
.weight-latest .num { font-size: 1.6rem; }
.pb-label { width: 7.5em; flex-shrink: 0; font-weight: 600; }

/* Weight chart (colours come from the theme tokens, so dark mode works) */
.chart-legend { display: flex; gap: 16px; font-size: 0.85rem; color: var(--muted); margin: 12px 0 4px; }
.chart-legend .key { display: inline-block; vertical-align: middle; margin-right: 6px; }
.key-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.key-line { width: 16px; height: 2px; background: var(--accent); }
.key-dash { width: 16px; height: 0; border-top: 2px dashed var(--muted); }
.chart-box { position: relative; }
.weight-chart { display: block; touch-action: pan-y; }
.weight-chart .grid { stroke: var(--border); stroke-width: 1; }
.weight-chart .axis { fill: var(--muted); font-size: 11px; }
.weight-chart .dot { fill: var(--muted); opacity: 0.55; stroke: var(--surface); stroke-width: 2; }
.weight-chart .trend { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.weight-chart .target { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 6 4; }
.weight-chart .cursor { stroke: var(--muted); stroke-width: 1; }
.weight-chart .cursor-dot { fill: var(--accent); stroke: var(--surface); stroke-width: 2; }
.weight-chart .hit { fill: transparent; }
.chart-tip {
  position: absolute; top: 0; pointer-events: none; padding: 6px 10px; border-radius: 8px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  font-size: 0.85rem; white-space: nowrap;
}
.pb-row a { color: var(--accent); }

/* Dashboard: shared bits (also used by the week review and settings) */
.dash-card { min-width: 0; }
.dash-card h2 { margin: 0 0 8px; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }
.dash-card h2 a { color: inherit; text-decoration: none; }
/* the whole card opens its screen (see dashboard.js) */
.dash-card:has(h2 a), .dash-hero { cursor: pointer; }
.dash-card h2 a::after { content: " →"; color: var(--accent); }
.dash-big { font-family: var(--font-num); font-size: 2.2rem; font-weight: 700; margin: 4px 0; line-height: 1.1; font-variant-numeric: tabular-nums; }
.dash-big .muted { font-family: var(--font); font-size: 0.95rem; font-weight: 400; }
.dash-card .stat-grid strong { font-size: 1.5rem; }
.dash-card .stat-grid { gap: 8px; }
.dash-list { list-style: none; margin: 0; padding: 0; }
.dash-list li { display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 6px 0; border-top: 1px solid var(--border); flex-wrap: wrap; }
.dash-list li:first-child { border-top: 0; }
.week-strip { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin: 8px 0; text-align: center; }
.strip-day { display: flex; flex-direction: column; gap: 2px; padding: 4px 0; border-radius: 8px; }
.strip-day.is-today { outline: 2px solid var(--accent); }

/* ---------- Home (step 17c, "Today first") ----------
   Phone: the two columns melt into one list (display: contents) and `order`
   sets the sequence: hero, notes, race, week, load, tiles.
   Only the hero (and the race countdown) stand out; the rest is quiet. */
.dashboard { display: flex; flex-direction: column; }
.dash-main, .dash-side { display: contents; }
.dash-hero { order: 1; }
.dash-notes { order: 2; }
.dash-race { order: 3; }
#dash-week { order: 4; }
#dash-load { order: 5; }
.dash-tiles { order: 6; }
.dash-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.dash-head h2 { margin: 0; }
.dash-head p { margin: 0; }
.dash-count .num { font-size: 1.7rem; }
.dash-count .num.of { font-size: 1.25rem; color: var(--muted); }

/* The Today hero: purple block, white text, one big button */
.dash-hero {
  background: var(--hero-bg); color: var(--hero-text);
  border-radius: 20px; padding: 18px; margin-bottom: 16px;
  display: flex; flex-direction: column; gap: 14px;
}
.dash-hero a { color: inherit; }
.dash-hero .unit { color: var(--hero-muted); }
.hero-label, .hero-missed-title { margin: 0; font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; color: var(--hero-muted); }
.hero-label a, .hero-missed-title a { text-decoration: none; }
#dash-today { display: flex; flex-direction: column; gap: 14px; }
#dash-today > p:only-child { margin: 0; }
.hero-session + .hero-session { border-top: 1px solid var(--hero-line); padding-top: 14px; }
.hero-session-top { display: flex; align-items: center; gap: 12px; }
.hero-badge { flex: none; width: 48px; height: 48px; border-radius: 14px; background: var(--hero-soft); display: grid; place-items: center; }
.hero-badge .icon { width: 26px; height: 26px; }
.hero-session-text { flex: 1; min-width: 0; }
.hero-name { margin: 0; font-size: 1.4rem; font-weight: 700; line-height: 1.15; overflow-wrap: anywhere; }
.hero-facts { margin: 4px 0 0; display: flex; flex-wrap: wrap; column-gap: 14px; }
.hero-facts .num { font-size: 1.35rem; }
.hero-state { flex: none; display: flex; align-items: center; gap: 4px; font-size: 0.9rem; font-weight: 600; color: var(--hero-muted); }
.hero-session.status-cancelled .hero-name { text-decoration: line-through; opacity: 0.8; }
.hero-actions { display: flex; gap: 10px; margin-top: 14px; }
.hero-button {
  flex: 1; min-height: 52px; padding: 0 16px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--hero-button-bg); color: var(--hero-button-text) !important;
  font-weight: 700; font-size: 1.05rem; text-decoration: none;
}
.hero-button.is-quiet { flex: none; align-self: flex-start; min-height: 44px; background: var(--hero-soft); color: var(--hero-text) !important; font-size: 0.95rem; }
/* "Log it" next to Start / Resume workout: labelled, outlined, narrower than the main button */
.hero-button.is-secondary { flex: 0 1 auto; background: transparent; color: var(--hero-text) !important; border: 1px solid var(--hero-line); font-size: 0.95rem; }
.hero-icon-button { flex: none; width: 52px; min-height: 52px; border-radius: 14px; border: 1px solid var(--hero-line); display: grid; place-items: center; }
.hero-button .icon, .hero-icon-button .icon { width: 20px; height: 20px; }
/* "Choose session" under a "just a sport" session (21): small, quiet, still 44px tall */
.hero-choose {
  margin-top: 8px; min-height: 44px; padding: 0 12px; border: 0; border-radius: 12px;
  display: inline-flex; align-items: center; gap: 6px; background: var(--hero-soft); color: var(--hero-text);
  font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
}
.hero-choose .icon { width: 18px; height: 18px; }
.hero-rest { margin: 0; display: flex; align-items: center; gap: 8px; font-size: 1.2rem; font-weight: 600; }
.hero-resume { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 12px; background: var(--hero-soft); text-decoration: none; }
.hero-resume span { flex: 1; min-width: 0; }
/* "Did you do it?" inside the hero */
.hero-missed { border-top: 1px solid var(--hero-line); padding-top: 12px; }
.hero-missed-title { margin-bottom: 6px; }
.hero-missed-list { list-style: none; margin: 0; padding: 0; }
.hero-missed-list li { display: flex; align-items: center; gap: 6px; padding: 4px 0; }
.hero-missed-name { flex: 1; min-width: 0; font-weight: 600; line-height: 1.25; }
.hero-missed-name .small { display: block; font-weight: 400; color: var(--hero-muted); }
.hero-small-button {
  flex: none; min-width: 44px; height: 44px; padding: 0 12px; border: 0; border-radius: 12px;
  display: grid; place-items: center; background: var(--hero-soft); color: var(--hero-text);
  font: inherit; font-size: 0.9rem; font-weight: 600; text-decoration: none; cursor: pointer;
}
.hero-small-button.is-quiet { background: transparent; }
.hero-small-button .icon { width: 20px; height: 20px; }
.hero-missed p.small { margin: 4px 0 0; color: var(--hero-muted); }

/* Small notes under the hero (week review, load jump) */
.dash-notes { display: flex; flex-direction: column; }
.dash-note { padding: 12px 16px; }
p.dash-note { margin-bottom: 16px; }

/* Next race */
.chip.is-ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, var(--surface)); border-color: transparent; }
.race-hero-top { display: flex; align-items: flex-end; gap: 14px; margin: 4px 0 12px; }
.race-hero-days { margin: 0; color: var(--accent); white-space: nowrap; }
.race-hero-days .num { font-size: 4.4rem; line-height: 0.82; }
.race-hero-days-label { font-size: 0.95rem; font-weight: 700; }
.race-hero-name { flex: 1; min-width: 0; }
.race-hero-title { margin: 0; font-size: 1.15rem; font-weight: 700; line-height: 1.2; }
.race-hero-name .muted { margin: 0; }
.race-hero-facts { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 4px; padding: 10px 12px; border-radius: 12px; background: var(--bg); }
.race-hero-facts .num { font-size: 1.35rem; }
.race-hero-bar { margin-top: 10px; }
.race-hero-bar p { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 4px; }
.race-hero-bar .bar { height: 6px; border: 0; background: var(--segment-empty); }
.week-segments { display: flex; gap: 3px; }
.week-segments span { flex: 1; height: 6px; border-radius: 3px; background: var(--segment-empty); }
.week-segments .is-done { background: var(--accent-strong); }
.week-segments .is-now { background: color-mix(in srgb, var(--accent-strong) 50%, var(--segment-empty)); }

/* This week: all warnings as one amber line (each one is on its day in the planner) */
.warning-line {
  display: flex; align-items: center; gap: 8px; margin-top: 10px; padding: 10px 12px; border-radius: 10px;
  background: var(--warn-bg); color: var(--warn-text); font-size: 0.88rem; text-decoration: none;
}
.warning-line span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Training load: hours per week as columns (not ".bar": that's the shoe bar) */
.dash-load-total { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0 0 12px; }
.dash-load-total > .num { font-size: 2.6rem; }
.dash-load-planned .num { font-size: 1.35rem; color: var(--muted); }
.dash-card .dash-load-stats strong { font-size: 1.3rem; }
.load-chart { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 4px;
  align-items: end; height: 100px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.load-week { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; min-width: 0; }
.load-value { font-size: 0.62rem; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.load-track { position: relative; flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.load-column { position: relative; width: 100%; max-width: 28px; min-height: 2px; border-radius: 4px 4px 0 0; background: var(--load-past); }
.load-week.is-current .load-column { background: var(--accent-strong); }
.load-week.is-current .load-value { color: var(--text); font-weight: 600; }
/* This week's planned hours: a dashed outline behind the done column */
.load-ghost { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 28px;
  border: 1.5px dashed var(--accent-strong); border-bottom: 0; border-radius: 4px 4px 0 0; }
.load-caption { display: flex; justify-content: space-between; margin: 4px 0 0; }
.load-caption-now { color: var(--accent); font-weight: 600; }
#dash-load .hint { margin: 8px 0 0; }

/* Small tiles: two per row */
.dash-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 16px; }
.dash-tiles:not(:has(.dash-tile:not([hidden]))) { display: none; }
.dash-tile {
  min-width: 0; display: flex; flex-direction: column; gap: 2px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--card-border); box-shadow: var(--shadow); border-radius: var(--radius);
  color: inherit; text-decoration: none;
}
.tile-label { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; font-weight: 600; color: var(--muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tile-value .num { font-size: 1.8rem; }
.tile-note { font-size: 0.8rem; line-height: 1.3; color: var(--muted); overflow-wrap: anywhere; }
.tile-note.is-warning { color: var(--warn-text); font-weight: 600; }

/* ---------- Race mode (step 17d): the last 3 weeks before a registered race ----------
   Race first (a dark block glued to the top bar), Today as a white card,
   then a one-line status strip; the rest follows like normal. */
.race-mode .dash-race { order: 0; }
.race-mode .dash-hero { order: 1; }
.race-mode .dash-strip { order: 2; }
.race-mode .dash-notes { order: 3; }
.race-mode .dash-tiles { order: 4; }
.race-mode #dash-week { order: 5; }
.race-mode #dash-load { order: 6; }
.race-mode .dash-race {
  margin: -16px -16px 16px; padding: 18px 16px 22px; border: 0; border-radius: 0 0 28px 28px;
  background: var(--race-mode-bg); color: var(--race-mode-text); box-shadow: none;
}
.race-mode .dash-race h2 { color: var(--race-mode-accent); }
.race-mode .dash-race h2 a::after { color: var(--race-mode-accent); }
.race-mode-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700; background: var(--race-mode-soft); color: var(--race-mode-text); white-space: nowrap; }
.race-mode-top { display: flex; align-items: flex-end; gap: 14px; margin: 8px 0 0; }
.race-mode-days { margin: 0; color: var(--race-mode-accent); }
.race-mode-days .num { font-size: 6.5rem; line-height: 0.8; }
.race-mode-name { margin: 0; padding-bottom: 4px; font-size: 1.35rem; font-weight: 700; line-height: 1.15; min-width: 0; overflow-wrap: anywhere; }
.race-mode-to { display: block; font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--race-mode-accent); }
.race-mode-facts { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 16px 0 0; }
.race-mode-facts .num { font-size: 1.6rem; }
.race-mode-facts .unit, .race-mode-bar p { color: var(--race-mode-muted); }
.race-mode-bar { margin-top: 16px; }
.race-mode-bar p { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 6px; }
.race-mode-bar .week-segments span { height: 8px; border-radius: 4px; background: var(--race-mode-empty); }
.race-mode-bar .week-segments .is-done { background: var(--race-mode-accent); }
.race-mode-bar .week-segments .is-now { background: var(--race-mode-text); }
/* Today becomes a white card with a purple button: the hero colours swap */
.race-mode .dash-hero {
  --hero-bg: var(--surface); --hero-text: var(--text); --hero-muted: var(--muted);
  --hero-soft: var(--bg); --hero-line: var(--border);
  --hero-button-bg: var(--race-mode-button); --hero-button-text: #ffffff;
  border: 1px solid var(--card-border); box-shadow: var(--shadow);
}
.race-mode .hero-badge { color: var(--accent); }
/* The status strip: week, load, warnings in one line */
.dash-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 12px 14px; color: inherit; text-decoration: none; }
.dash-strip > span { display: flex; flex-direction: column; min-width: 0; }
.strip-label { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.dash-strip .num { font-size: 1.6rem; }
.dash-strip .num.of { font-size: 1.2rem; color: var(--muted); }
.dash-strip .is-warning, .dash-strip .is-warning .num { color: var(--warn-text); }

/* Laptop: two real columns (left "now", right overview) */
@media (min-width: 900px) {
  .view:has(.dashboard) { max-width: var(--page-wide); }   /* the page may be wider than the phone layout */
  .dashboard { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); column-gap: 20px; align-items: start; }
  .dash-main, .dash-side { display: block; }
  .race-mode .dash-race { margin: 0 0 16px; border-radius: 20px; }
  /* Race mode's status strip repeats the This week card, which sits right
     below on a laptop: only the phone keeps it (28b). */
  .race-mode .dash-strip { display: none; }
}
/* Laptop: each Today session on ONE row, name left, buttons right (28b) */
@media (min-width: 1000px) {
  .hero-session { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 16px; }
  .hero-session-top { grid-column: 1; }
  .hero-actions { grid-column: 2; margin-top: 0; }
  .hero-actions .hero-button { flex: none; min-width: 200px; }
  .hero-actions .hero-button.is-secondary { min-width: 0; }
  .hero-choose { grid-column: 1 / -1; justify-self: start; }
}

/* Drag and drop in the planner */
.plan-card[data-session] { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.plan-card.is-dragging { opacity: 0.35; }
.drag-ghost {
  position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none; margin: 0;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25); transform-origin: top left; opacity: 0.95;
}
.day.is-drop-target { outline: 2px dashed var(--accent); outline-offset: 2px; background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }

/* Weigh-in form: the Save button keeps its own size */
.weigh-form { margin-bottom: 12px; }
.weigh-form .button { width: auto; flex: 0 0 auto; }
@media (min-width: 700px) { .weigh-form { max-width: 460px; } }
.strip-day.is-done { background: color-mix(in srgb, var(--done-line) 16%, transparent); }
.strip-icons { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px;
  font-size: 1rem; line-height: 1.2; min-height: 1.6rem; }

/* Planner: Week | Month switch */
.planner { display: flex; flex-direction: column; }
.view-switch { display: flex; align-self: center; gap: 4px; padding: 4px; margin-bottom: 12px;
  background: var(--surface); border-radius: 999px; box-shadow: var(--shadow); border: 1px solid var(--card-border); }
.view-switch a { padding: 6px 18px; border-radius: 999px; text-decoration: none; color: var(--muted); font-weight: 600; font-size: 0.9rem; }
.view-switch a[aria-selected="true"] { background: var(--accent); color: var(--accent-text); }

/* Planner: month calendar */
.month { padding: 8px; }
.month-head, .month-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.month-head span { text-align: center; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); padding: 4px 0; }
.month-day { display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 56px; padding: 4px 2px;
  border-radius: 8px; text-decoration: none; color: inherit; background: var(--bg); }
.month-day.is-other { opacity: 0.4; }
.month-day.is-today { outline: 2px solid var(--accent-strong); }
.month-day.is-done { background: color-mix(in srgb, var(--done-line) 16%, var(--surface)); }
.month-date { font-size: 0.8rem; font-weight: 600; }
.month-icons { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px; }

/* Laptop: the catalogue / templates links go below the calendar */
@media (min-width: 1000px) {
  .planner-menu { order: 99; margin-top: 16px; }
  .month-grid { grid-auto-rows: 1fr; } /* all weeks of the month the same height */
  .month-day { min-height: 92px; align-items: flex-start; padding: 6px 8px; }
  .month-icons { justify-content: flex-start; }
  .month-icons .sport-badge.small { width: 1.9rem; height: 1.9rem; }
  /* 29c: each day lists its sessions by name (icon + name, one line each) */
  .month-day { min-height: 104px; }
  .month-names { display: flex; flex-direction: column; gap: 3px; width: 100%; min-width: 0; margin-top: 2px; }
  .month-name { display: flex; align-items: center; gap: 5px; min-width: 0; font-size: 0.78rem; font-weight: 500; line-height: 1.3; }
  .month-name > span:last-child { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .month-name .sport-badge.small { flex: none; width: 1.25rem; height: 1.25rem; }
  .month-name > .icon { flex: none; width: 1rem; height: 1rem; color: var(--accent); }
  .month-more { font-size: 0.72rem; color: var(--muted); padding-left: 2px; }
  .today-button { flex: none; min-height: 44px; display: inline-flex; align-items: center; text-decoration: none; }
}

/* ---------- Laptop: wider list screens ---------- */
.log-head, .activity-item .col { display: none; }
@media (min-width: 1000px) {
  .view:has(.log-page), .view:has(.wide-page) { max-width: var(--page-wide); }

  /* Log: one table row per activity */
  .log-head, .log-page .activity-item {
    display: grid;
    grid-template-columns: 32px 130px minmax(0, 1fr) 80px 150px 100px 44px;
    gap: 12px; align-items: center;
  }
  /* Column titles = first row inside each week card */
  .log-head { padding: 8px 16px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--muted); border-bottom: 1px solid var(--border); }
  .log-page .activity-item { min-height: 0; padding: 10px 16px; }
  .log-page .activity-item:hover { background: var(--bg); }
  .log-page .activity-item .col { display: block; font-variant-numeric: tabular-nums; font-size: 0.92rem; }
  .log-page .activity-item .col .num { font-size: 1.15rem; }
  .log-page .col-date { color: var(--muted); }
  .log-page .activity-meta { display: none; }
  .log-page .sport-badge { width: 2rem; height: 2rem; }
  .log-toolbar { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
  .log-toolbar .log-filters { order: -1; flex: 1; min-width: 0; margin-bottom: 0; padding-bottom: 0; }
  .log-toolbar .add-button { flex: none; width: auto; margin: 0; padding-left: 24px; padding-right: 24px; }

  /* Races, blocks, shoes: cards side by side */
  .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; align-items: start; }
  .card-grid > .card { margin-bottom: 0; }
  /* Races, Shoes, Blocks (28e): "+ Add" sits at the right end of the first
     section's title row, and each count follows its label ("UPCOMING  2") */
  .wide-page { position: relative; }
  .wide-page > .add-button { position: absolute; top: 0; right: 0; width: auto; max-width: none; margin: 0; padding: 10px 24px; }
  .wide-page > div > .week:first-child > .week-title { min-height: 44px; align-items: center; padding-right: 240px; }
  .wide-page > div > .placeholder:first-child { margin-top: 60px; }
  .wide-page .week-title { justify-content: flex-start; }
  .wide-page .week, .wide-page .retired { margin-bottom: 24px; }
}
@media (min-width: 1000px) {
  .view:has(.body-page) { max-width: var(--page-wide); }
  .body-page { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); grid-template-areas: "weight chart" "pb chart";
    column-gap: 16px; align-items: start; }
  #weight-card { grid-area: weight; }
  #chart-card { grid-area: chart; }
  #pb-card { grid-area: pb; }
}
.menu-hint { margin: 0 auto 0 8px; font-weight: 400; }
.card-grid + .hint, .card-grid + .retired { margin-top: 12px; }
.menu a .menu-hint { font-size: 0.85rem; color: var(--muted); }

/* Race cards: one look per group */
.race-upcoming { border-left: 4px solid var(--accent-strong); }
.race-countdown { font-family: var(--font-num); font-size: 2.8rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; color: var(--accent); margin: 4px 0; }
.race-countdown span { font-family: var(--font); font-size: 1rem; font-weight: 600; }
.race-idea { background: transparent; box-shadow: none; border: 1px dashed var(--border); }
.race-idea strong { font-weight: 600; }
/* Ideas can be deleted from the list (24a): the bin sits in the card's corner */
.race-idea-item { position: relative; min-width: 0; }
.race-idea-item > .race-card { height: 100%; margin-bottom: 0; padding-right: 56px; }
.race-idea-delete {
  position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; display: grid; place-items: center;
  border: 0; border-radius: 10px; background: none; color: var(--muted); cursor: pointer;
}
.race-idea-delete .icon { width: 18px; height: 18px; }
@media (hover: hover) { .race-idea-delete:hover { color: var(--error); background: var(--hover-bg); } }
/* "Delete this idea" on the idea's page (24b): quiet, red */
.race-delete-idea { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--error); }
.race-delete-idea .icon { width: 16px; height: 16px; }
.show-all-past { display: flex; margin: 8px auto 0; }  /* centred under the past races (26) */
.race-result { font-family: var(--font-num); font-size: 2rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.race-result .muted { font-family: var(--font); font-size: 0.85rem; font-weight: 400; margin-left: 4px; }
.race-past.is-not-run { opacity: 0.6; }
.race-past.is-not-run strong { text-decoration: line-through; }
/* Race and training-block cards: the same size WITHIN a group (every row
   of a grid gets the height of its tallest card); different groups (e.g.
   the current block vs past blocks) can differ. */
.card-grid:has(.race-card), .card-grid:has(.block-card) { display: grid; grid-auto-rows: 1fr; gap: 16px; align-items: stretch; }
.card-grid:has(.race-card) > .card, .card-grid:has(.block-card) > .card { margin-bottom: 0; }

/* Race page (step 19): a summary first, the details form behind "Edit".
   Phone = one column (summary, then routine + checklist); laptop = summary
   or form left, routine + checklist as a sidebar right. */
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: 16px; }
.race-topline { display: flex; justify-content: flex-end; align-items: center; gap: 8px; margin-bottom: 8px; }
.race-topline .back-link { margin: 0; min-height: 44px; display: inline-flex; align-items: center; }
.pill-button {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px;
  border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
}
.section-label { margin: 4px 2px 8px; font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }

.race-sum { display: flex; flex-direction: column; gap: 10px; padding: 20px; }
/* "Edit" in the summary card's corner on a laptop (29b) */
.race-sum:has(.sum-edit) { position: relative; }
.sum-edit { position: absolute; top: 14px; right: 14px; margin: 0; }
.race-sum:has(.sum-edit) .race-sum-meta { padding-right: 80px; }
.race-sum > * { margin: 0; }
.race-sum-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 0.85rem; color: var(--muted); }
.race-pill {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 999px;
  font-size: 0.75rem; font-weight: 700; background: var(--bg); color: var(--text);
}
.race-pill.is-ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface)); }
.race-pill .icon { width: 0.95em; height: 0.95em; }
.race-sum-name { font-size: 1.55rem; font-weight: 700; line-height: 1.15; overflow-wrap: anywhere; }
.race-sum-days { display: flex; align-items: baseline; gap: 8px; color: var(--accent); }
.race-sum-days .num { font-size: 5.5rem; line-height: 0.85; }
.race-sum-days-label { font-size: 0.9rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.race-sum-facts { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.race-sum-facts .num { display: block; font-size: 1.6rem; }
.race-sum-label { display: block; font-size: 0.75rem; color: var(--muted); }
.race-sum-box { background: var(--bg); border-radius: 12px; padding: 10px 12px; }
.race-sum-box .num { font-size: 1.4rem; }
.race-sum-label-top { font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }
.race-sum-result { color: var(--accent); margin-top: -6px !important; }
.race-sum-result .num { font-size: 4.6rem; line-height: 0.95; }
.race-delta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.race-delta .race-pill { font-size: 0.82rem; padding: 4px 10px; }
.race-sum-block { display: flex; align-items: center; gap: 6px; }
.race-sum-bar p { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 6px; }
.race-sum .button { align-self: flex-start; margin-top: 4px; }
.race-sum.is-not-run { opacity: 0.6; }
.race-sum.is-not-run .race-sum-name { text-decoration: line-through; }
/* Upcoming: the dark block, same colours as Home's race mode */
.race-sum.is-dark { background: var(--race-mode-bg); color: var(--race-mode-text); border-color: transparent; box-shadow: none; }
.race-sum.is-dark .race-sum-meta, .race-sum.is-dark .race-sum-label, .race-sum.is-dark .race-sum-bar p { color: var(--race-mode-muted); }
.race-sum.is-dark .race-pill { background: var(--race-mode-soft); color: var(--race-mode-text); }
.race-sum.is-dark .race-pill.is-ok { color: #bbf7d0; background: rgba(34, 197, 94, 0.18); }
.race-sum.is-dark .race-sum-days { color: var(--race-mode-accent); }
.race-sum.is-dark a { color: var(--race-mode-text); }
.race-sum.is-dark .race-sum-bar { margin-top: 6px; }
.race-sum.is-dark .week-segments span { height: 8px; border-radius: 4px; background: var(--race-mode-empty); }
.race-sum.is-dark .week-segments .is-done { background: var(--race-mode-accent); }
.race-sum.is-dark .week-segments .is-now { background: var(--race-mode-text); }

/* "Add your result" (19d): a past race without a time */
.race-result-card { display: flex; flex-direction: column; gap: 12px; padding: 20px; border: 2px solid var(--accent); }
.race-result-card > * { margin: 0; }
.race-result-card h3 { margin: 2px 0 0; font-size: 1.25rem; }
.section-label.is-accent { margin: 0; color: var(--accent); font-weight: 700; }
.found-run { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.found-run-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.found-run-text .num { font-size: 1.6rem; }
.found-run .button { margin: 0; flex: none; width: auto; padding: 0 16px; min-height: 44px; }
.or-line { display: flex; align-items: center; gap: 10px; font-size: 0.8rem; color: var(--muted); }
.or-line::before, .or-line::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.result-form { display: flex; gap: 8px; align-items: flex-end; }
.result-form .field { flex: 1; min-width: 0; margin: 0; }
.result-form label { display: block; margin-bottom: 4px; font-weight: 600; }
.result-form input { width: 100%; margin: 0; }
.result-form .button { flex: none; width: auto; margin: 0; min-height: 48px; padding: 0 18px; }
.pb-offer { padding: 8px 12px; border-radius: 10px; background: var(--warn-bg); color: var(--warn-text); font-size: 0.9rem; }
.pb-offer[hidden] { display: none; }
.race-result-card .link-button { align-self: center; }

/* "Your run", notes, and the folded block / checklist rows of a past race */
.race-runs { padding: 0; overflow: hidden; }
.race-run { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 12px 16px; color: inherit; text-decoration: none; }
.race-run + .race-run { border-top: 1px solid var(--border); }
.race-run-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.race-notes p { margin: 0; white-space: pre-line; overflow-wrap: anywhere; }
.race-notes .section-label { margin: 0 0 4px; }
.race-folds { padding: 0; overflow: hidden; }
.race-fold-row { display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 16px; color: inherit; text-decoration: none; cursor: pointer; }
.race-fold-row > span { flex: 1; }
.race-folds > * + * { border-top: 1px solid var(--border); }
.race-fold > summary { list-style: none; }
.race-fold > summary::-webkit-details-marker { display: none; }
.race-fold[open] > summary .icon-chevron-down { transform: rotate(180deg); }
.race-fold-body { padding: 0 16px 16px; }
.race-fold-body > .card-head { display: none; }  /* the row above already says "Checklist" */

@media (min-width: 1000px) {
  .view:has(.race-page) { max-width: var(--page-wide); }
  .race-layout { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); grid-template-areas: "main side"; gap: 16px; align-items: start; }
  .race-layout .race-main { grid-area: main; }
  .race-layout .race-main > .card:last-child { margin-bottom: 0; }
  .race-layout .race-side { grid-area: side; }
  .race-layout .race-side .card:last-child { margin-bottom: 0; }
  .race-layout:not(:has(.race-side)) { grid-template-columns: minmax(0, 1fr); max-width: var(--page-narrow); margin-inline: auto; }
  .race-page:not(:has(.race-side)) .race-topline { max-width: var(--page-narrow); margin-inline: auto; }
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid .field-full { grid-column: 1 / -1; }
  .race-form .form-actions .button.primary { flex: 0 0 auto; width: auto; min-width: 160px; }
  .race-form .form-actions #delete { margin-left: auto; }
}

/* Log: List | Stats switch */
.log-page, .stats-page { display: flex; flex-direction: column; }
.log-switch { align-self: center; }
/* Log: sport chips scroll sideways on a phone instead of wrapping onto 3 lines */
.log-filters { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; margin-bottom: 12px; -webkit-overflow-scrolling: touch; }
.log-filters .chip-button { white-space: nowrap; }
/* Log search + type filter (27): one row, the search box takes the room left */
.log-search-row { display: flex; gap: 8px; margin-bottom: 12px; }
.log-search-row input, .log-search-row select { margin: 0; min-height: 44px; background: var(--surface); }
.log-search { flex: 1; min-width: 0; font-size: 1rem; /* 16px: iPhone doesn't zoom in on the box */ }
.type-filter { flex: none; width: auto; max-width: 45%; padding: 8px 12px; }
.type-filter[hidden] { display: none; }
/* Phone: not enough room for both, the type box gets its own line under the search */
@media (max-width: 699px) {
  .log-search-row { flex-wrap: wrap; }
  .type-filter { flex: 1 1 100%; max-width: none; }
}
.log-no-match { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.log-no-match p { margin: 0; }

/* Stats page */
.stats-filters { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.stats-filters .chip-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
.stats-filters .chip-button { white-space: nowrap; }
#stats-range { margin: 0 4px 12px; }
.stats-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.stats-grid > .card { margin-bottom: 0; }
.stats-card h2 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); margin-bottom: 12px; }
.stats-card h2 a { color: inherit; text-decoration: none; }
.stats-card a { color: var(--accent); }
.stats-card .stat-grid { margin-bottom: 8px; }
.sport-bars { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.sport-bars li { display: grid; grid-template-columns: 9em minmax(0, 1fr) 2.5em; gap: 8px; align-items: center; font-size: 0.92rem; }
.sport-bars li > span:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sport-bars li > span:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.accent-fill { background: var(--accent-strong) !important; }
.bar-chart { display: block; touch-action: pan-y; }
/* (not ".bar": that name is the shoes progress bar, whose height would squash these) */
.bar-chart .bc-bar { fill: var(--accent-strong); }
.bar-chart .bc-hit { fill: transparent; }
.bar-chart .grid { stroke: var(--border); stroke-width: 1; }
.bar-chart .axis { fill: var(--muted); font-size: 11px; }
.bar-chart .target { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 6 4; }
@media (min-width: 1000px) {
  .view:has(.stats-page) { max-width: var(--page-wide); }
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .stats-grid .stats-wide { grid-column: 1 / -1; }
  .stats-filters { flex-direction: row; justify-content: space-between; flex-wrap: wrap; }
}
.block-card.is-current { border-left: 4px solid var(--accent-strong); }

/* ---------- Step 20d: block page (summary first) + list rows ---------- */
.race-pill.is-accent { background: var(--accent); color: var(--accent-text); }
.block-sum .race-sum-bar p { align-items: baseline; }
.block-sum .race-sum-bar .num { font-size: 1.25rem; }
.block-sum .week-segments span { height: 8px; border-radius: 4px; }
.block-sum .race-sum-box p { margin: 2px 0 0; }
.block-page .section-label { margin-top: 4px; }
#block-stats .section-label { margin: 0 0 10px; }
.list-badge { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--accent); }
.list-days { flex: none; color: var(--accent); }
.list-days .num { font-size: 1.4rem; }
.list-days .unit { color: var(--accent); }
.note-week { color: var(--accent); font-weight: 600; }
.block-note .race-run-text { gap: 2px; }
/* Sport mix: one bar in the sport colours + a legend */
.mix-bar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; margin: 4px 0 8px; background: var(--segment-empty); }
.mix-bar span { background: var(--sport); }
.mix-legend { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 0.85rem; }
.mix-legend li { display: inline-flex; align-items: center; gap: 6px; }
.mix-legend .num { font-size: 1rem; }
.mix-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--sport); }
.shoe-km .num { font-size: 1.35rem; }
@media (min-width: 1000px) {
  .view:has(.block-page) { max-width: var(--page-narrow); }
}

/* ---------- Step 20e: Me = your athlete profile ----------
   A dark header glued to the top bar (like race mode), PBs, tiles, Settings. */
.me-page { display: flex; flex-direction: column; }
.me-page .dash-tiles { order: 0; }   /* (Home gives its tiles an order) */
.me-hero {
  margin: -16px -16px 16px; padding: 18px 16px 22px; border-radius: 0 0 28px 28px;
  background: var(--race-mode-bg); color: var(--race-mode-text);
  display: flex; flex-direction: column; gap: 18px;
}
.me-who { display: flex; align-items: center; gap: 14px; }
.me-avatar { flex: none; display: grid; place-items: center; width: 60px; height: 60px; border-radius: 50%;
  background: var(--race-mode-soft); color: #ffffff; font-size: 1.6rem; font-weight: 700; }
.me-name { margin: 0; font-size: 1.45rem; line-height: 1.15; overflow-wrap: anywhere; }
.me-tagline { margin: 2px 0 0; font-size: 0.85rem; color: var(--race-mode-muted); }
.me-year { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.me-year > span { display: flex; flex-direction: column; min-width: 0; }
.me-year .num { font-size: 1.9rem; }
.me-year-label { font-size: 0.75rem; color: var(--race-mode-muted); }
.me-pbs { display: flex; flex-direction: column; gap: 8px; color: inherit; text-decoration: none; }
.me-pbs .dash-head { margin: 0; align-items: center; }
.me-pbs .section-label { margin: 0; }
.me-pb-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.me-pb { display: flex; flex-direction: column; min-width: 0; }
.me-pb-label { font-size: 0.78rem; font-weight: 600; color: var(--muted); }
.me-pb .num { font-size: 1.35rem; white-space: nowrap; }
.me-pb .num.is-empty { color: var(--muted); }
.tile-name { font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.tile-bar { display: block; height: 5px; margin: 4px 0 2px; border-radius: 3px; background: var(--segment-empty); overflow: hidden; }
.tile-bar span { display: block; height: 100%; border-radius: 3px; background: var(--done-line); }
@media (max-width: 359px) { .me-pb-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 720px) {
  .me-hero { margin: 0 0 16px; border-radius: 20px; }
}

/* ---------- Hover (23b): what the mouse points at reacts ----------
   Only on devices with a real mouse (hover: hover). On a phone a hover look
   would stay "stuck" after a tap, so phones never get these rules. */
@media (hover: hover) {
  /* Cards that open a screen: lift a little (light) / brighter border (dark) */
  a.card, .dash-tile, .dash-card:has(h2 a), .dash-hero {
    transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  }
  a.card:hover, .dash-tile:hover, .dash-card:has(h2 a):hover {
    box-shadow: var(--shadow-hover); border-color: var(--card-border-hover); transform: translateY(-1px);
  }
  /* Planner sessions: a slightly darker grey + the same lift */
  .plan-card { transition: background-color 0.15s ease, box-shadow 0.15s ease; }
  .plan-card:hover { background: color-mix(in srgb, var(--text) 6%, var(--bg)); box-shadow: var(--shadow-hover); }
  /* Rows (log, menus, race / block rows): a light grey background */
  .activity-item:hover, .sheet-row:hover, .routine-row:hover, .race-fold-row:hover, .race-run:hover,
  .fold-row > summary:hover, .check-row:hover { background: var(--hover-bg); }
  .sheet-item:hover { border-color: var(--muted); }
  /* Buttons, chips and the log form's choices: a darker border */
  .button:not(.primary):not(:disabled):hover, .nav-button:hover, .day-add:hover,
  .chip-button:not([aria-pressed="true"]):not(:disabled):hover,
  .sport-tile input:not(:checked) + span:hover, .type-chip input:not(:checked) + span:hover { border-color: var(--muted); }
  .rpe-option input:not(:checked) + span:hover { box-shadow: inset 0 0 0 2px var(--rpe-text); }
  .button.primary:not(:disabled):hover, .hero-button:hover { filter: brightness(1.08); }
}

/* Keyboard shortcuts (29d): the keys drawn like little keys */
kbd {
  display: inline-block; min-width: 1.6em; padding: 1px 6px; border: 1px solid var(--border); border-bottom-width: 2px;
  border-radius: 6px; background: var(--bg); color: var(--text); font: inherit; font-size: 0.85em; font-weight: 600; text-align: center;
}
.shortcut-list { margin: 0 0 12px; }
.shortcut-list > div { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.shortcut-list dt { flex: none; width: 70px; margin: 0; }
.shortcut-list dd { margin: 0; }
