/* REPIN — premium minimal. Cool neutral ground, hairline borders, graphite ink.
   The workout colour (--wc) is the only accent; the interface accent (ink in
   light, teal in dark) carries focus, selection and glow. */

:root {
  --bg: #F4F5F7;
  --surface: #FFFFFF;
  --border: #E5E8EE;
  --line: #E5E8EE;        /* R06: referenced 27 times and never defined — those borders were falling back to the text colour */
  --border-strong: #D2D7E0;
  --ink: #12151A;
  --ink-2: #5F6774;
  --ink-3: #667080;         /* v2.110 (F06): 5.0:1 on white, 4.75:1 on surface-2 — small labels stay readable */
  --danger: #DC2626;
  --accent: #12151A;        /* interface accent: ink in light, teal in dark */
  --accent-ink: #FFFFFF;    /* text/icons on top of the accent */
  --accent-glow: rgba(18, 21, 26, 0.18);
  --surface-2: #F8F9FB;     /* hover / subtle raised surface */
  --hover: rgba(18, 21, 26, 0.05);
  --seg-bg: #E9ECF1;        /* segmented + progress tracks */
  --switch-off: #CBD2DC;
  --overlay-bg: rgba(18, 21, 26, 0.42);
  --tabbar-bg: rgba(255, 255, 255, 0.82);
  --toast-bg: rgba(18, 21, 26, 0.92);
  --toast-ink: #F4F5F7;
  --card-sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 38%);
  --wc: #F97316; /* overridden per workout */
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 1px 2px rgba(18, 21, 26, 0.05), 0 1px 1px rgba(18, 21, 26, 0.03);
  --shadow-hover: 0 6px 18px -6px rgba(18, 21, 26, 0.16), 0 2px 4px rgba(18, 21, 26, 0.05);
  --shadow-lift: 0 18px 44px -12px rgba(18, 21, 26, 0.28);
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur-fast: 140ms;   /* press, hover, focus */
  --dur: 220ms;        /* fades, view entrance */
  --dur-slow: 320ms;   /* sheets, springs */
  --radius-lg: 18px;
  --ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
  --tabbar-h: 58px;
  /* Spacing scale (v1.18) — every gap in the app comes from here */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-7: 32px;
  font-size: 16px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background: var(--bg); color-scheme: light; }
html, body { max-width: 100%; overflow-x: hidden; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; appearance: none; -webkit-appearance: none; }
button:disabled { cursor: not-allowed; }
input, select, textarea { font: inherit; color: inherit; } /* v1.71: textarea was missing — Coach box and note fields fell back to monospace */
h1, h2, h3, p, ul { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

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

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

#app { display: grid; grid-template-columns: 220px minmax(0, 1fr); min-height: 100dvh; min-width: 0; }

#sidebar {
  border-right: 1px solid var(--border);
  padding: 20px 14px;
  position: sticky; top: 0; height: 100dvh;
}
.brand { display: flex; align-items: center; gap: 10px; padding: 4px 10px 22px; }
.brand-mark { font-size: 20px; font-weight: 800; letter-spacing: -0.03em; }
.brand-ver { font-size: 11px; color: var(--ink-3); font-weight: 500; }

.side-nav { display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border-radius: var(--radius-sm);
  color: var(--ink-2); font-size: 14.5px; font-weight: 550;
  border: 1px solid transparent;
}
@media (hover: hover) and (pointer: fine) { .nav-item:hover { color: var(--ink); background: var(--hover); } }
.nav-item.active { color: var(--ink); background: var(--surface); border-color: var(--border); box-shadow: var(--shadow); }
.nav-item.active .icon { color: var(--accent); }

#view { width: 100%; max-width: 1000px; margin: 0 auto; padding: 28px 28px 64px; min-width: 0; }

#tabbar { display: none; }

html.route-runner #sidebar, html.route-runner #tabbar { display: none; }
html.route-runner #app { grid-template-columns: 1fr; }

@media (max-width: 899px) {
  #app { grid-template-columns: minmax(0, 1fr); }
  #sidebar { display: none; }
  #view { padding: calc(18px + env(safe-area-inset-top, 0px)) 16px calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 40px); }
  #tabbar {
    display: flex; align-items: stretch; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    background: var(--tabbar-bg);
    -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  html.route-runner #view { padding-bottom: 24px; }
  .tab-item {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 8px 0 6px; font-size: 10.5px; font-weight: 550; color: var(--ink-3);
  }
  .tab-item.active { color: var(--ink); }
  .tab-item.active .icon { color: var(--accent); }
}

/* ---------------- Icons ---------------- */

.icon { display: inline-flex; width: 20px; height: 20px; flex: none; }
.icon svg { width: 100%; height: 100%; }
.icon.soft { color: var(--ink-3); }
.icon-btn {
  width: 40px; height: 40px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); color: var(--ink-2);
}
@media (hover: hover) and (pointer: fine) { .icon-btn:hover { background: var(--hover); color: var(--ink); } }

/* ---------------- Page headers ---------------- */

.page-head { margin-bottom: 20px; }
.page-head h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }
.page-sub { color: var(--ink-2); font-size: 14.5px; margin-top: 5px; line-height: 1.4; }
.row-between { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.builder-head { display: flex; align-items: center; gap: 8px; }
/* the title block takes the width; anything after it (History's Share card)
   sits flush with the right content edge, and a long workout name wraps
   inside the space that is left instead of pushing the button off the line */
.builder-head-main { flex: 1 1 auto; min-width: 0; }
.builder-head-main h1 { font-size: 22px; overflow-wrap: break-word; }
.builder-autosave { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-3); }
.prog-needs { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--ink-2); font-size: 13px; font-weight: 600; }
.prog-needs .icon { width: 15px; height: 15px; flex: none; }
.work-pause-row { margin-top: 4px; }
.ctrl-scope { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ctrl-scope .ctrl-hint { flex: 1 1 200px; }
.section-title { font-size: 13.5px; font-weight: 650; color: var(--ink-2); margin: 28px 0 10px; }
.section-title.tight { margin: 0 0 12px; }
.eyebrow {
  font-size: 12.5px; font-weight: 650; letter-spacing: 0; color: var(--ink-3);
}
.eyebrow.wc { color: var(--wc); }

/* ---------------- Cards ---------------- */

.stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.stack.tight { gap: var(--sp-2); }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  position: relative; text-align: left;
}
.card.spine::before {
  content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--wc);
}
.card-body { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
/* v2.174: the status pill keeps one line and its own width; the title column is the part that may shrink.
   "Ended early" was wrapping mid-phrase inside the pill and making it two lines tall. */
.card-top > :first-child { min-width: 0; flex: 1 1 auto; }
.card-top > .done-badge { flex: 0 0 auto; }
.card-title { font-size: 18px; font-weight: 700; letter-spacing: -0.015em; }
.card-title.link { cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .card-title.link:hover { text-decoration: underline; text-underline-offset: 3px; } }
.card-meta { color: var(--ink-2); font-size: 13.5px; }
.card-meta.soft { color: var(--ink-3); }

.done-badge {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; /* v2.174: never wrap the status */
  font-size: 12px; font-weight: 650; color: var(--ink);
  background: var(--bg); border: 1px solid var(--border);
  padding: 5px 9px; border-radius: 999px;
}
.done-badge .icon { width: 14px; height: 14px; color: var(--wc); }

.preview-list { display: flex; flex-direction: column; }
.preview-list li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 14px;
}
.preview-list li:last-child { border-bottom: none; }
.preview-name { color: var(--ink); }
.preview-sets { color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: normal; min-width: 0; }

.rest-day { align-items: flex-start; }
.card:has(> .rest-day) { border-style: dashed; background: var(--surface-2); box-shadow: none; }
.rest-day .card-title { font-size: 20px; }

.workout-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
@media (max-width: 680px) { .workout-grid { grid-template-columns: 1fr; } }

.empty-note { color: var(--ink-2); font-size: 14px; padding: 10px 2px; }
.hint-note { color: var(--ink-2); font-size: 13px; }

/* ---------------- Buttons ---------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 18px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: 15px; font-weight: 620; letter-spacing: -0.01em;
}
.btn .icon { width: 17px; height: 17px; }
/* Variant colours + every interaction state live in ONE place: see the
   "Buttons — authoritative states" section at the end of this file (v1.22). */
.btn-block { width: 100%; }
.btn-sm { min-height: 36px; padding: 0 13px; font-size: 13.5px; }
.btn-lg { min-height: 50px; font-size: 16px; }
.btn-xl { min-height: 58px; font-size: 17px; border-radius: 13px; }
.btn-row { display: flex; align-items: stretch; gap: var(--sp-3); flex-wrap: wrap; }
.btn-row .grow { flex: 1; }

/* ---------------- Inputs ---------------- */

.field-label { display: block; font-size: 13px; font-weight: 620; color: var(--ink-2); margin: 6px 0 -4px; }
.input {
  width: 100%; min-height: 44px; padding: 10px 13px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); font-size: 15px;
}
.input:focus { outline: none; border-color: var(--ink); }
.input-title { font-size: 18px; font-weight: 650; }

.colour-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 2px 0; }
.colour-dot {
  width: 34px; height: 34px; border-radius: 50%; background: var(--wc); flex: none;
  transition: transform 0.1s ease;
}
@media (hover: hover) and (pointer: fine) { .colour-dot:hover { transform: scale(1.08); } }
.colour-dot.selected { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--wc); }

.segmented {
  display: inline-flex; background: var(--seg-bg); border-radius: var(--radius-sm); padding: 3px; gap: 2px;
}
.seg-btn {
  padding: 8px 16px; border-radius: 8px; font-size: 14px; font-weight: 620; color: var(--ink-2);
  min-height: 38px;
}
.segmented.small .seg-btn { padding: 6px 12px; font-size: 13px; min-height: 32px; }
.seg-btn.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
html.theme-dark .seg-btn.on { background: #2A2F38; }

.chip-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.chip-row.scroll-x { flex-wrap: nowrap; overflow-x: auto; padding: 2px 2px 6px; scrollbar-width: none; }
.chip-row.scroll-x::-webkit-scrollbar { display: none; }
.chip {
  padding: 7px 13px; min-height: 36px; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--surface);
  font-size: 13.5px; font-weight: 600; color: var(--ink-2);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.chip.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.weekday-row { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.wd-pill {
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid var(--border-strong); background: var(--surface);
  font-size: 12.5px; font-weight: 650; color: var(--ink-2);
}
.wd-pill.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.switch-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 15px; }
.switch-label.big-switch { padding: 6px 0; font-weight: 620; }
.switch-input { appearance: none; width: 46px; height: 28px; border-radius: 999px; background: var(--switch-off); position: relative; flex: none; cursor: pointer; transition: background-color 0.15s ease; margin: 0; }
.switch-input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease;
}
.switch-input:checked { background: var(--accent); }
.switch-input:checked::after { transform: translateX(18px); }

.sched-pane { display: flex; flex-direction: column; gap: 10px; }
.end-row { padding-top: 4px; }

/* ---------------- Steppers ---------------- */

.stepper { display: inline-flex; align-items: center; gap: 4px; }
.step-btn {
  width: 40px; height: 40px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center; color: var(--ink);
}
.step-btn:active { background: var(--surface-2); }
.step-btn .icon { width: 16px; height: 16px; }
.step-val {
  min-width: 58px; text-align: center; font-size: 16px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.stepper-big .step-btn { width: 52px; height: 52px; }
.stepper-big .step-val { font-size: 24px; min-width: 84px; }

.big-stepper { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.big-step-label {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3);
}
.big-step-row { display: flex; align-items: center; gap: 14px; }
.big-step-btn {
  width: 58px; height: 58px; border-radius: 16px;
  border: 1px solid var(--border-strong); background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
}
.big-step-btn:active { background: var(--surface-2); transform: scale(0.96); }
.big-step-btn .icon { width: 22px; height: 22px; }
.big-step-val {
  min-width: 120px; text-align: center;
  font-size: 44px; font-weight: 760; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* ---------------- Builder ---------------- */

.ex-list { margin-top: 16px; }
.ex-card { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.ex-card.dragging { opacity: 0.92; box-shadow: var(--shadow-lift); z-index: 5; }
.ex-head { display: flex; align-items: center; gap: 8px; }
.drag-handle {
  width: 36px; height: 36px; flex: none; color: var(--ink-3);
  display: inline-flex; align-items: center; justify-content: center;
  /* v1.52: touch-action must be none from the start. Once iOS has begun a
     scroll the touchmove is no longer cancelable, so the gesture cannot be
     claimed back — it has to be refused before it starts. The grip is a
     dedicated control; a touch anywhere else on the card still scrolls. */
  cursor: grab; touch-action: none; border-radius: 8px;
}
.drag-handle:active { cursor: grabbing; }
.ex-title { flex: 1; display: flex; align-items: center; gap: 9px; min-width: 0; }
.ex-title h3 { font-size: 16.5px; font-weight: 700; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.type-tag {
  font-size: 11.5px; font-weight: 650;
  color: var(--ink-3); border: 1px solid var(--border); padding: 3px 8px; border-radius: 6px; flex: none;
}
.ex-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 14px 22px; }
.ctrl { display: flex; flex-direction: column; gap: 7px; }
.ctrl-full { flex: 1 1 100%; }
.ctrl-label { font-size: 12px; font-weight: 650; color: var(--ink-2); }

.set-list { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.set-row {
  display: flex; align-items: center; gap: 10px; min-height: 48px;
  padding: 6px 2px; border-bottom: 1px solid var(--border);
  text-align: left; font-size: 14px;
}
.set-row:last-child { border-bottom: none; }
.set-open {
  flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 40px; padding: 4px 4px 4px 6px; border-radius: 8px; text-align: left;
  min-width: 0;
}
@media (hover: hover) and (pointer: fine) { .set-open:hover { background: var(--surface-2); } }
.set-rep-quick {
  min-width: 44px; min-height: 36px; padding: 4px 10px;
  border: 1px solid var(--border-strong); border-radius: 8px;
  background: var(--surface); font-weight: 700; font-size: 14.5px;
  font-variant-numeric: tabular-nums; text-align: center; flex: none;
}

.set-rep-input {
  width: 58px; min-height: 36px; padding: 4px 6px; flex: none;
  border: 1px solid var(--accent); border-radius: 8px; background: var(--surface);
  font-weight: 700; font-size: 14.5px; text-align: center;
  font-variant-numeric: tabular-nums; -moz-appearance: textfield; appearance: textfield;
}
.set-rep-input::-webkit-outer-spin-button, .set-rep-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.set-rep-word { color: var(--ink-2); font-size: 13px; flex: none; }
.set-n { font-weight: 650; color: var(--ink-3); flex: none; width: 48px; font-variant-numeric: tabular-nums; }
.set-desc { flex: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.add-ex-btn { margin-top: 16px; }

/* Picker */
.picker-list { display: flex; flex-direction: column; max-height: 44dvh; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.picker-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 13px; border-bottom: 1px solid var(--border); text-align: left;
}
.picker-row:last-child { border-bottom: none; }
@media (hover: hover) and (pointer: fine) { .picker-row:hover { background: var(--surface-2); } }
.picker-row.added { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); }
.picker-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.picker-name { font-size: 14.5px; font-weight: 620; }
.picker-sub { font-size: 12px; color: var(--ink-3); }
.custom-form { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--border); padding-top: 12px; }

/* ---------------- Runner ---------------- */

.runner { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: 22px; }
.runner-head { display: flex; flex-direction: column; gap: 12px; }
.runner-head-row { display: flex; align-items: center; gap: 8px; }
.runner-head-mid { flex: 1; text-align: center; min-width: 0; }
.runner-title { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.runner-sub { font-size: 12px; color: var(--ink-2); }
.runner-count { font-size: 13px; font-weight: 650; color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 40px; text-align: right; }
.prog { height: 4px; background: var(--seg-bg); border-radius: 999px; overflow: hidden; }
.prog-fill { height: 100%; width: calc(var(--prog) * 1%); background: var(--wc); border-radius: 999px; transition: width 0.3s ease; }

.runner-main {
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 26px 22px 24px; display: flex; flex-direction: column; align-items: center; gap: 16px;
  text-align: center;
}
.runner-ex { font-size: 24px; font-weight: 760; letter-spacing: -0.025em; }
.runner-target { font-size: 15px; color: var(--ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
.runner-prev, .runner-next { font-size: 13.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.runner-note { font-size: 13px; font-weight: 650; color: var(--ink-2); }

.giant-clock {
  font-size: clamp(76px, 24vw, 132px); font-weight: 780; letter-spacing: -0.045em;
  line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink);
  padding: 8px 0 2px;
}
.giant-clock.dim { color: var(--ink-3); }
.rest-main { border-color: var(--border); background: var(--surface-2); }
.rest-clock { color: var(--ink-2); }

.done-main { gap: 20px; }
.summary-rows { width: 100%; display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.summary-row {
  display: flex; align-items: baseline; justify-content: space-between; padding: 12px 2px;
  border-bottom: 1px solid var(--border); font-size: 14.5px; color: var(--ink-2);
}
.summary-row strong { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
/* v2.86 — set effort (RIR/RPE) and auto-progression */
.effort-row { width: 100%; display: flex; flex-direction: column; gap: 8px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; text-align: left; }
.effort-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.effort-q { font-size: 14px; font-weight: 650; color: var(--ink); }
.effort-hint { font-size: 12.5px; color: var(--ink-2); }
.effort-btns { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.effort-btn { min-height: 44px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font: inherit; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; }
.effort-btn.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.effort-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.set-effort { color: var(--ink-3); font-size: 13px; }
.prog-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); }
.prog-row.done { opacity: 0.7; }
.prog-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.prog-name { font-weight: 700; color: var(--ink); }
.prog-change { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.prog-why { font-size: 13px; color: var(--ink-2); }
.prog-intro { margin: 0 0 4px; font-size: 13.5px; color: var(--ink-2); }
.prog-actions { display: flex; gap: 6px; flex: none; }
.prog-applied { font-size: 13px; font-weight: 700; color: var(--ink-3); flex: none; }
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.prog-update { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0 4px; border-top: 1px solid var(--border); }
.prog-ctrl { display: flex; flex-direction: column; gap: 8px; }
.ctrl-hint { font-size: 13px; color: var(--ink-2); }
.prog-detail { display: flex; flex-direction: column; gap: 8px; }
.prog-range { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prog-range .stepper { flex: 0 1 auto; min-width: 0; }
.prog-range-lbl { font-size: 13px; color: var(--ink-2); }
@media (max-width: 360px) { .prog-range { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 10px; align-items: center; } .prog-range .stepper { flex: none; width: 100%; } }

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

/* v2.90/2.91 — workout invites */
.invite-when { margin: 0; font-size: 16px; font-weight: 700; color: var(--ink); }
.invite-going { color: var(--ink-2); min-width: 0; overflow-wrap: break-word; }
.invite-card .btn-row { margin-top: 4px; }
.invite-card .card-body { min-width: 0; }
.invite-text { min-width: 0; overflow-wrap: break-word; word-break: normal; } /* user-typed names, notes, workout names: wrap long unbroken tokens, never clip */
.invite-names { display: flex; flex-wrap: wrap; gap: 4px 6px; max-width: 100%; min-width: 0; margin-top: 6px; }
.invite-count { display: block; color: var(--ink); font-weight: 700; }
.invite-updated { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.invite-list { display: flex; flex-direction: column; gap: 6px; }
.invite-list-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); min-width: 0; }
.invite-list-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.invite-list-name { font-weight: 700; color: var(--ink); overflow-wrap: break-word; }
@media (max-width: 380px) { .invite-list-row { flex-direction: column; align-items: stretch; } .invite-list-row .prog-actions { justify-content: flex-end; } }
.settings-row-btn { width: 100%; text-align: left; background: transparent; border: 0; font: inherit; color: inherit; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.invite-name { display: inline-block; max-width: 100%; padding: 1px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface-2); font-size: 13px; color: var(--ink); min-width: 0; overflow-wrap: break-word; }
.invite-withdraw { align-self: flex-start; padding: 6px 0; }
.invite-when-line { font-weight: 650; color: var(--ink); }
.invite-preview-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 40px; padding: 6px 2px; border: 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); background: transparent; color: var(--ink-2); font: inherit; font-size: 14px; font-weight: 650; cursor: pointer; text-align: left; }
.invite-preview-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }
.invite-preview-toggle.open .compare-chevron { transform: rotate(-135deg); }
.invite-preview .share-preview { margin: 0; }
.invite-badge { display: inline-block; margin-left: 6px; padding: 1px 7px; border: 0; border-radius: 999px; background: color-mix(in srgb, var(--accent) 16%, var(--surface-2)); color: var(--ink); font: inherit; font-size: 11.5px; font-weight: 700; vertical-align: middle; white-space: nowrap; cursor: pointer; }
.invite-badge:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* v2.99 — read-only Workout View: a training prescription designed for reading.
   The overview is the workout's card (spine, colour); each exercise is a sub-card; sets are a quiet
   ledger — number, target, load, rest — in tabular figures. Nothing looks editable. */
.wv-head { display: flex; align-items: center; margin-bottom: 12px; }
.wv-back { padding: 6px 10px 6px 4px; margin-left: -6px; color: var(--ink-2); font-weight: 650; }
.wv-back .icon { width: 18px; height: 18px; }
.wv-overview .card-body { gap: 14px; }
.wv-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.wv-titles { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 6px; }
.wv-title { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; overflow-wrap: break-word; }
.wv-desc { margin: 0; color: var(--ink-2); font-size: 14.5px; line-height: 1.45; overflow-wrap: break-word; }
.wv-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (min-width: 600px) { .wv-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.wv-stat .stat-value { font-size: 20px; }
.wv-next { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--ink-2); font-size: 14px; font-weight: 600; }
.wv-next .icon { width: 16px; height: 16px; color: var(--ink-3); flex: none; }
/* the actions are a deliberate grid, never a content-driven wrap: the primary action alone on its row on a phone,
   the two secondary actions equal beneath it; three equal columns from 600px */
.wv-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.wv-actions .btn { min-width: 0; }
.wv-actions .btn-primary { grid-column: 1 / -1; }
.wv-actions .icon { width: 18px; height: 18px; }
@media (min-width: 600px) { .wv-actions { grid-template-columns: repeat(3, minmax(0, 1fr)); } .wv-actions .btn-primary { grid-column: auto; } }
.wv-section { margin: 20px 0 10px; font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.wv-exercises { display: flex; flex-direction: column; gap: 10px; }
.wv-exercise .card-body { gap: 10px; }
.wv-ex-head { display: flex; align-items: flex-start; gap: 10px; }
.wv-ex-index { flex: none; width: 26px; height: 26px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2); font-size: 12.5px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums; margin-top: 1px; }
.wv-ex-titles { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; }
.wv-ex-name { margin: 0; font-size: 17px; font-weight: 750; letter-spacing: -0.01em; line-height: 1.25; overflow-wrap: break-word; }
.wv-ex-meta { color: var(--ink-3); font-size: 12.5px; font-weight: 600; }
.wv-guide { flex: none; margin: -6px -6px 0 0; }
.wv-note { margin: 0; padding: 8px 12px; border-left: 3px solid color-mix(in srgb, var(--wc, var(--accent)) 55%, var(--border)); background: var(--surface-2); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; color: var(--ink-2); font-size: 14px; line-height: 1.45; overflow-wrap: break-word; }
.wv-sets { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.wv-set { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto auto; align-items: center; column-gap: 10px; padding: 9px 12px; background: var(--surface-2); font-variant-numeric: tabular-nums; }
.wv-set + .wv-set { border-top: 1px solid var(--border); }
.wv-set.warmup { background: var(--surface); }
.wv-set.warmup .wv-set-target { color: var(--ink-2); font-weight: 600; }
.wv-set-n { color: var(--ink-3); font-size: 12.5px; font-weight: 700; }
.wv-set-main { min-width: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.wv-set-target { color: var(--ink); font-size: 15px; font-weight: 700; }
.wv-tag { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); }
.wv-set-load { color: var(--ink); font-size: 14.5px; font-weight: 700; text-align: right; white-space: nowrap; }
.wv-set-load:empty, .wv-set-rest:empty { display: none; }
.wv-set-rest { color: var(--ink-3); font-size: 12.5px; font-weight: 600; text-align: right; white-space: nowrap; }
@media (max-width: 360px) { .wv-set { grid-template-columns: 30px minmax(0, 1fr) auto; } .wv-set-rest { grid-column: 2 / -1; text-align: left; } }
.wv-rule { display: flex; align-items: center; gap: 8px; color: var(--ink-2); font-size: 13px; font-weight: 600; }
.wv-rule .icon { width: 16px; height: 16px; color: var(--accent); flex: none; }
.wv-foot { margin: 16px 0 0; color: var(--ink-3); font-size: 13px; text-align: center; }

/* v2.85 — start-up recovery */
.boot-error { margin: var(--sp-5) auto; max-width: 480px; }
.boot-error-msg { margin: 0; color: var(--ink); font-size: 15px; line-height: 1.45; }

/* v2.83/2.84 — today vs last time: an inset surface built from the app's own primitives.
   Stat tiles two across (four when there is genuinely room), exercise sub-cards that wrap
   instead of squeezing, and a full-width disclosure row on the finish screen. */
.compare-host:empty { display: none; }
.compare { display: flex; flex-direction: column; gap: 10px; width: 100%; min-width: 0; text-align: left; align-items: stretch; }
.compare.inset { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-4); }
.compare-card .card-body { gap: 10px; }
.compare-first { margin: 0; color: var(--ink-3); font-size: 14px; }
/* R5: the column count follows the text's own size and the space this component actually has, not the viewport. The
   track minimum is in `ch`, so it grows with the reader's text size: at ordinary sizes two (or four) tiles fit as
   before, and at doubled text the tiles drop to one column instead of overrunning their boundaries. */
.compare-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13ch), 1fr)); gap: 8px; }
@media (min-width: 600px) { .compare-stats { grid-template-columns: repeat(auto-fit, minmax(min(100%, 11ch), 1fr)); } }
.compare-stat { min-width: 0; }
.compare-stat .stat-label, .compare-stat .stat-trend { white-space: normal; overflow-wrap: break-word; }
.compare-stat .stat-value { font-size: 20px; }
.compare-stat .stat-trend { min-height: 16px; }
.compare-toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 44px;
  margin-top: 2px; padding: 8px 2px; border: 0; border-top: 1px solid var(--border); background: transparent;
  color: var(--ink-2); font: inherit; font-size: 14px; font-weight: 650; cursor: pointer; text-align: left;
}
.compare-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }
.compare-chevron { width: 9px; height: 9px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform .15s ease; margin-right: 4px; }
.compare-toggle.open .compare-chevron { transform: rotate(-135deg); }
.compare-ex { display: flex; flex-direction: column; gap: 6px; }
.compare-ex-item { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px; min-width: 0; }
.compare-ex-name { color: var(--ink); font-size: 14px; font-weight: 700; flex: 1 1 140px; min-width: 0; overflow-wrap: break-word; }
.compare-ex-name.pr { color: var(--accent); }
.compare-ex-vals { display: flex; flex-direction: column; align-items: flex-end; flex: 0 1 auto; min-width: 0; }
.compare-ex-best { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.compare-ex-vals .stat-trend { margin-top: 0; }
.compare-ex-status { color: var(--ink-3); font-size: 13px; font-weight: 500; flex: 1 1 100%; }

.runner-sets { display: flex; flex-direction: column; gap: 6px; }
.runner-sets .eyebrow { padding-left: 2px; margin-bottom: 2px; }
.runner-set-row {
  display: flex; align-items: center; gap: 12px; min-height: 46px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 8px 12px; text-align: left; font-size: 14px;
}
.runner-set-row:disabled { cursor: default; color: var(--ink-2); }
.runner-set-row.current { border-color: var(--wc); box-shadow: 0 0 0 1px var(--wc); }
.runner-set-row.done .runner-set-desc { color: var(--ink); }
.runner-set-check {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong); color: var(--ink-3);
  font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.runner-set-row.done .runner-set-check { background: var(--wc); border-color: var(--wc); color: #fff; }
.runner-set-check .icon { width: 14px; height: 14px; }
.runner-set-desc { font-variant-numeric: tabular-nums; }

.resume-card .card-title { font-size: 20px; }

/* ---------------- Calendar ---------------- */

.cal-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.cal-nav { display: flex; align-items: center; gap: 4px; }
.cal-title { font-size: 19px; font-weight: 750; letter-spacing: -0.02em; flex: 1; min-width: 140px; }

.cal-layout { display: grid; gap: 18px; }
@media (min-width: 900px) { .cal-layout { grid-template-columns: 1fr 320px; align-items: start; } }

.month-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; } /* v2.170 (UI-04): a long name can never widen the grid */
.month-wd { font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); text-align: center; padding-bottom: 2px; }
.month-cell {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  min-height: 96px; padding: 7px 7px 6px; text-align: left;
  display: flex; flex-direction: column; gap: 4px; overflow: hidden;
}
@media (hover: hover) and (pointer: fine) { .month-cell:hover { border-color: var(--border-strong); } }
.month-cell.other { opacity: 0.45; }
.month-cell.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 0 0 5px var(--accent-glow); }
.cell-num { font-size: 12.5px; font-weight: 650; color: var(--ink-2); font-variant-numeric: tabular-nums; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; }
.month-cell.today .cell-num { background: var(--accent); color: var(--accent-ink); }

.cal-chip {
  display: flex; align-items: center; gap: 5px; min-width: 0;
  font-size: 11.5px; font-weight: 620; color: var(--ink);
  background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 2.5px 6px;
}
.chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--wc); flex: none; }
.chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-chip .chip-check { width: 12px; height: 12px; color: var(--wc); flex: none; margin-left: auto; }
.cal-chip.missed { color: var(--ink-3); }
.cal-chip.missed .chip-dot { opacity: 0.35; }
.chip-more { font-size: 11px; color: var(--ink-3); font-weight: 650; padding-left: 2px; }

@media (max-width: 640px) {
  .month-cell { min-height: 64px; padding: 5px; }
  /* month cells are too small for names; the week view has room and keeps them (v1.40) */
  .month-cell .cal-chip { padding: 2px; border: none; background: none; gap: 3px; }
  .month-cell .chip-name, .month-cell .cal-chip .chip-check { display: none; }
  .chip-dot { width: 8px; height: 8px; }
  .cal-chip.completed .chip-dot { box-shadow: 0 0 0 2px color-mix(in srgb, var(--wc) 30%, transparent); }
}

.week-wrap { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; } /* v2.170 (UI-04) */
@media (max-width: 899px) { .week-wrap { grid-template-columns: 1fr; } }
.week-day {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px; min-height: 120px; text-align: left;
  display: flex; flex-direction: column; gap: 10px;
}
/* the mobile row layout lives in one place — see the week-view block below */
.week-day.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 0 0 5px var(--accent-glow); }
.week-day-head { display: flex; flex-direction: column; }
.week-wd { font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); }
.week-num { font-size: 19px; font-weight: 750; font-variant-numeric: tabular-nums; }
.week-day.today .week-num { color: var(--wc, var(--ink)); }
.week-day.today .week-wd { color: var(--ink); }
.week-chips { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 0; }
.week-rest { color: var(--ink-3); font-size: 13px; flex: 1; }

.year-wrap { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.mini-month {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px; text-align: left; display: flex; flex-direction: column; gap: 8px;
}
@media (hover: hover) and (pointer: fine) { .mini-month:hover { border-color: var(--border-strong); } }
.mini-title { font-size: 13px; font-weight: 700; }
.mini-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.mini-cell {
  font-size: 9.5px; text-align: center; color: var(--ink-3);
  height: 20px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 5px; font-variant-numeric: tabular-nums;
}
.mini-cell.today { box-shadow: inset 0 0 0 1.5px var(--accent); color: var(--ink); font-weight: 700; }
.mini-cell.has { background: var(--wc); color: #fff; font-weight: 650; }
.mini-cell.has.missed { opacity: 0.35; }

.day-panel {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 18px; position: sticky; top: 20px;
  display: flex; flex-direction: column; gap: 14px;
}
.day-panel-title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.day-body { display: flex; flex-direction: column; gap: 10px; }
.day-occ { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; }
.day-occ-main { min-width: 0; }
.day-occ-name { font-size: 15px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.day-occ-status { font-size: 12.5px; color: var(--ink-2); }
.day-occ-status.missed { color: var(--ink-3); }
.day-occ-actions { display: flex; align-items: center; gap: 6px; flex: none; }

/* ---------------- History / lists ---------------- */

.history-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 16px; width: 100%; }
.history-main { min-width: 0; }
.history-name { font-size: 16px; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.inline-check { width: 15px; height: 15px; color: var(--wc); }
.history-meta { font-size: 13px; color: var(--ink-2); margin-top: 2px; font-variant-numeric: tabular-nums; }
.history-meta.strong { color: var(--ink); font-weight: 650; }

.session-ex-name { font-size: 16px; font-weight: 700; }
.session-set-list { display: flex; flex-direction: column; }
.session-set {
  display: flex; align-items: center; gap: 14px; padding: 7px 0; border-bottom: 1px solid var(--border);
  font-size: 14px; font-variant-numeric: tabular-nums;
}
.session-set:last-child { border-bottom: none; }
.session-set.skipped { color: var(--ink-3); }

.list-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 15px; width: 100%; }
@media (hover: hover) and (pointer: fine) { .list-row:hover { border-color: var(--border-strong); } }
.list-row-name { font-size: 15px; font-weight: 650; }
.list-row-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 1px; }

/* ---------------- Settings ---------------- */

.settings-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: 44px; }
.settings-label { font-size: 15px; font-weight: 620; }
.settings-note { font-size: 13px; color: var(--ink-2); margin-top: 1px; }
.settings-note.pad-b { margin-bottom: 4px; }
.settings-value { font-size: 14.5px; color: var(--ink-2); font-weight: 600; }

/* ---------------- Overlays ---------------- */

.overlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--overlay-bg);
  display: flex; align-items: flex-end; justify-content: center;
  opacity: 0; transition: opacity 0.18s ease;
}
.overlay.open { opacity: 1; }
/* SCROLL-03 (v2.266 iPhone review): sheets and their pickers scroll vertically only — `overflow-y: auto` alone
   computes `overflow-x: auto` too, which let a nested list shift sideways on iPhone — and their boundaries do not
   chain into the page behind. Deliberately horizontal strips inside keep their own rules. */
.sheet, .picker-list { overflow-x: hidden; overscroll-behavior: contain; }
body.scroll-locked { overflow: hidden; }
.sheet {
  background: var(--surface); width: 100%; max-width: 520px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  max-height: 90dvh; overflow-y: auto;
  padding: 10px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  transform: translateY(26px); transition: transform 0.18s ease;
  display: flex; flex-direction: column;
}
.overlay.open .sheet { transform: translateY(0); }
.sheet-wide { max-width: 640px; }
.sheet-head {
  display: flex; align-items: center; gap: 8px; padding: 6px 0 10px;
  /* stays put while a long sheet scrolls beneath it */
  position: sticky; top: 0; z-index: 2; background: var(--surface);
}
.sheet-grab {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 40px; height: 4px; border-radius: 999px; background: var(--border-strong);
}
.sheet-title { flex: 1; font-size: 17px; font-weight: 750; letter-spacing: -0.02em; padding-top: 10px; }
.sheet-close { margin-top: 6px; }
.sheet-body { display: flex; flex-direction: column; gap: 12px; padding-bottom: 6px; }

@media (min-width: 700px) {
  .overlay { align-items: center; padding: 24px; }
  .sheet { border-radius: 16px; box-shadow: var(--shadow-lift); }
  .sheet-grab { display: none; }
}

.dlg-msg { font-size: 14.5px; color: var(--ink-2); white-space: pre-line; }
.dlg-actions { display: flex; align-items: stretch; gap: 10px; padding-top: 8px; flex-wrap: wrap; }
.dlg-actions .btn { flex: 1; }

.choose-list { display: flex; flex-direction: column; gap: 6px; }
.choose-item {
  display: flex; align-items: center; gap: 12px; text-align: left;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 13px 14px; min-height: 50px; background: var(--surface);
}
@media (hover: hover) and (pointer: fine) { .choose-item:hover { border-color: var(--border-strong); background: var(--surface-2); } }
.choose-item.is-danger .choose-label { color: var(--danger); }
.choose-item .dot { width: 12px; height: 12px; border-radius: 50%; background: var(--wc); flex: none; }
.choose-main { display: flex; flex-direction: column; min-width: 0; }
.choose-label { font-size: 15px; font-weight: 650; }
.choose-sub { font-size: 12.5px; color: var(--ink-3); }

/* ---------------- Toasts, saved, resume ---------------- */

#toasts {
  position: fixed; left: 0; right: 0;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 14px);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  z-index: 80; pointer-events: none;
}
@media (min-width: 900px) { #toasts { bottom: 22px; } }
.toast {
  background: var(--toast-bg); color: var(--toast-ink); font-size: 13.5px; font-weight: 600;
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  padding: 10px 16px; border-radius: 999px; box-shadow: var(--shadow-lift);
  opacity: 0; transform: translateY(8px); transition: opacity 0.2s ease, transform 0.2s ease;
  max-width: min(90vw, 420px); text-align: center;
}
.toast.show { opacity: 1; transform: translateY(0); }

.saved-pill {
  position: fixed; top: calc(14px + env(safe-area-inset-top, 0px)); right: 14px; z-index: 70;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--ink-2); font-size: 12.5px; font-weight: 650;
  padding: 7px 12px; border-radius: 999px; box-shadow: var(--shadow);
  opacity: 0; transform: translateY(-6px); transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
}
.saved-pill.show { opacity: 1; transform: translateY(0); }

.resume-pill {
  position: fixed; right: 16px;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 16px);
  z-index: 40;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--ink); color: var(--bg);
  font-size: 14px; font-weight: 650;
  padding: 12px 18px; border-radius: 999px; box-shadow: var(--shadow-lift);
}
.resume-pill .icon { width: 15px; height: 15px; color: var(--wc); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--wc) 70%, transparent)); }
@media (min-width: 900px) { .resume-pill { bottom: 22px; right: 22px; } }

/* ---------------- Motion ---------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------------- Audit-round additions (v1.0.1) ---------------- */

/* P2-04: tappable stepper values for direct numeric entry */
.step-val-edit { border-radius: 8px; padding: 4px 6px; }
@media (hover: hover) and (pointer: fine) { .step-val-edit:hover { background: var(--hover); } }
.step-input, .big-step-input {
  border: 1px solid var(--ink); border-radius: 8px; background: var(--surface);
  text-align: center; -moz-appearance: textfield; appearance: textfield;
}
.step-input { width: 76px; padding: 4px 2px; }
.big-step-input { width: 150px; padding: 2px; }
.step-input::-webkit-outer-spin-button, .step-input::-webkit-inner-spin-button,
.big-step-input::-webkit-outer-spin-button, .big-step-input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}

/* P1-02: ended-early completions get a dimmed check */
.cal-chip.partial .chip-check { opacity: 0.4; }

/* P2-06: two workout colours per year-view cell */
.mini-cell.has.multi {
  background: linear-gradient(135deg, var(--wc) 0 50%, var(--wc2) 50% 100%);
}

.seg-btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---------------- Dark theme (v1.01): charcoal + teal accent ---------------- */

html.theme-dark {
  color-scheme: dark;
  --bg: #0F1114;
  --surface: #171A1F;
  --border: #242830;
  --line: #242830;        /* R06: the dark theme's value for the same token */
  --border-strong: #353B46;
  --ink: #E8EAEE;
  --ink-2: #9AA3B0;
  --ink-3: #8390A1;         /* v2.110 (F06): 5.4:1 on surface, 5.0:1 on surface-2 */
  --danger: #F87171;
  --accent: #2DD4BF;
  --accent-ink: #062621;
  --accent-glow: rgba(45, 212, 191, 0.32);
  --surface-2: #1D2128;
  --hover: rgba(255, 255, 255, 0.06);
  --seg-bg: #1F232A;
  --switch-off: #353B46;
  --overlay-bg: rgba(6, 8, 11, 0.62);
  --tabbar-bg: rgba(15, 17, 20, 0.78);
  --toast-bg: rgba(29, 33, 40, 0.86);
  --toast-ink: #E8EAEE;
  --card-sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 42%);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.03);
  --shadow-hover: 0 10px 28px -10px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  --shadow-lift: 0 24px 60px -16px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.03);
}
html.theme-dark .brand-mark { color: var(--ink); }
html.theme-dark .brand-ver { color: var(--accent); }
html.theme-dark .runner-set-row.done .runner-set-check { color: #0B1210; }
html.theme-dark .mini-cell.has { color: #0B1210; }
html.theme-dark .switch-input::after { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }

/* ---------------- Filter-row polish (Exercises view) ---------------- */

.filter-row {
  margin: 12px 0 14px;
  width: 100%; max-width: 100%; min-width: 0;
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-inline: contain;
  -webkit-overflow-scrolling: touch;
}
.filter-row .chip { flex: 0 0 auto; }
.exercise-search { margin-top: 2px; }

/* ---------------- Sharing (v1.03) ---------------- */

.share-link-box { font-size: 12.5px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; }
.share-preview { margin: 4px 0; }
.share-actions { margin-top: 16px; }
.error-note { color: var(--danger); }

/* ---------------- Compare (v1.04) ---------------- */

.cmp-table { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.cmp-row { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 8px; padding: 9px 12px; border-bottom: 1px solid var(--border); font-size: 13.5px; align-items: baseline; }
.cmp-row:last-child { border-bottom: none; }
.cmp-head { background: var(--surface-2); font-weight: 700; }
.cmp-head .cmp-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-sub { background: var(--surface-2); }
.cmp-sub .cmp-label { font-size: 12.5px; font-weight: 650; color: var(--ink-3); }
.cmp-label { color: var(--ink-2); }
.cmp-val { font-variant-numeric: tabular-nums; text-align: right; font-weight: 620; }
.cmp-group { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.cmp-diff { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
/* R13: both fields carry user-entered names, so they wrap normally and break a long unbroken token only as a last
   resort. Their ancestors may shrink too — without `min-width: 0` a flex parent refuses to let them narrow. */
.cmp-diff-name { font-size: 14.5px; font-weight: 700; margin-bottom: 2px; min-width: 0; white-space: normal; overflow-wrap: anywhere; }
.cmp-diff-line { font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 0; white-space: normal; overflow-wrap: anywhere; }
.cmp-diff, .cmp-diff-main, .cmp-row { min-width: 0; }

.preview-list.rich li { flex-direction: column; align-items: stretch; gap: 2px; }
/* R11: the shared-workout preview. A paired prescription is long enough that holding it on one line beside the name
   overflowed every phone width, so the name leads and the prescription sits beneath it where space requires. Both
   tracks may shrink; a long user-entered token breaks only as a last resort. Scoped to this preview. */
.preview-main { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.preview-main > .preview-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.preview-main > .preview-sets { flex: 1 1 100%; }
@media (min-width: 560px) {
  /* on a wide card the two sit together again, and the prescription keeps its own column */
  .preview-main > .preview-sets { flex: 0 1 auto; text-align: right; }
}
.preview-note { font-size: 12px; color: var(--ink-3); font-style: italic; }
.weights-badge { color: var(--ink); }
.weights-badge .icon { display: none; }


/* ===== v-next: warm-ups, ranges, skip/swap, notes, description ===== */
.wu-chip {
  flex: none; font-size: 10.5px; font-weight: 800; letter-spacing: 0.04em;
  color: var(--ink-2); border: 1px solid var(--border-strong);
  border-radius: 5px; padding: 1px 4px; line-height: 1.4;
}
.range-ctrl { display: inline-flex; align-items: center; gap: 6px; min-width: 0; flex-wrap: wrap; }
.range-max { display: inline-flex; align-items: center; gap: 6px; }
.range-max.hidden { display: none; }
.range-dash { color: var(--ink-2); font-weight: 700; }
.chip.tiny { padding: 4px 10px; font-size: 12px; min-height: 30px; }
.desc-input, .session-note-input {
  width: 100%; resize: vertical; min-height: 44px;
  font-size: 14px; line-height: 1.45;
}
.desc-input { margin-top: 8px; }
.session-note-input { margin: 4px 0 12px; }
.session-note-text { font-size: 14px; line-height: 1.5; white-space: pre-wrap; }
.skipped-label { font-weight: 600; }
.runner-ex-row { display: flex; align-items: flex-start; justify-content: center; gap: 6px; }
.runner-ex-row .runner-ex { min-width: 0; }
.ex-actions-btn { flex: none; }

/* ===== v1.09 ===== */
.set-rep-editor { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.set-rep-range-btn {
  min-width: 28px; min-height: 36px; padding: 0 6px; border-radius: 8px;
  border: 1px dashed var(--border-strong); background: transparent;
  color: var(--ink-2); font-weight: 800; font-size: 15px; line-height: 1;
}
.runner-set-row.skipped .runner-set-desc { color: var(--ink-3); text-decoration: line-through; }
.runner-set-row.skipped .runner-set-check { color: var(--ink-3); }


/* =====================================================================
   v1.11 — SaaS-grade polish: cool neutrals, accent glows, motion
   ===================================================================== */

::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); }
html { scrollbar-color: var(--border-strong) transparent; }
@media (min-width: 900px) {
  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-thumb { background: var(--border-strong); border: 3px solid var(--bg); border-radius: 999px; }
  ::-webkit-scrollbar-track { background: transparent; }
}

/* Focus — a soft halo, not a hard outline */
:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 80%, transparent);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--accent-glow);
  border-radius: 8px;
}
.input:focus, .input:focus-visible, .set-rep-input:focus, .step-input:focus, .big-step-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-glow);
  transition: box-shadow 0.15s var(--ease-out), border-color 0.15s var(--ease-out);
}

/* Screen entrance */
@keyframes view-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(8px) scale(0.995); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* fill-mode backwards: the entrance never pins a transform afterwards, so
   hover lifts and the builder's drag-reorder keep working. Lists that rebuild
   in place on every edit (.ex-list, .tight) are excluded so edits don't flicker. */
.view-inner { animation: view-in var(--dur) var(--ease-out) backwards; }
/* One orchestrated entrance per screen — the view itself. The per-card
   stagger that used to follow it read as decoration and made every screen
   feel like it was loading (polish pass). */

/* Headings */
.page-head h1 { font-weight: 800; letter-spacing: -0.03em; }
.brand-mark { letter-spacing: -0.04em; }
html.theme-dark .brand-mark { text-shadow: 0 0 22px rgba(45, 212, 191, 0.18); }

/* Cards — sheen, hover lift for interactive cards, glowing spine */
.card { background: var(--card-sheen), var(--surface); transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out), border-color 0.18s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  button.card:hover, .card.list-row:hover, .month-cell:hover, .week-day:hover, .mini-month:hover, .choose-item:hover, .picker-row:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-hover);
    border-color: var(--border-strong);
  }
}
button.card:active, .choose-item:active, .picker-row:active { transform: translateY(0) scale(0.995); }
.card.spine::before { width: 3px; box-shadow: 0 0 14px -2px color-mix(in srgb, var(--wc) 55%, transparent); }
html.theme-dark .card.spine::before { box-shadow: 0 0 18px -1px color-mix(in srgb, var(--wc) 65%, transparent); }
.resume-card { border-color: color-mix(in srgb, var(--wc) 45%, var(--border)); }
html.theme-dark .resume-card { box-shadow: var(--shadow), 0 0 32px -12px color-mix(in srgb, var(--wc) 55%, transparent); }
.done-badge { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.done-badge .icon { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--wc) 60%, transparent)); }
.inline-check { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--wc) 60%, transparent)); }

/* Buttons — glow on accents, press feedback everywhere */
.btn, .chip, .wd-pill, .step-btn, .big-step-btn, .seg-btn, .icon-btn, .colour-dot, .set-rep-quick, .runner-set-row, .tab-item, .nav-item,
.month-cell, .week-day, .mini-month, .choose-item, .picker-row, .list-row {
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out), background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.chip:active, .wd-pill:active, .step-btn:active, .seg-btn:active, .icon-btn:active, .set-rep-quick:active { transform: scale(0.965); }
.big-step-btn:active { transform: scale(0.94); }
.chip.on, .wd-pill.on { box-shadow: 0 6px 16px -8px var(--accent-glow); }
html.theme-dark .chip.on, html.theme-dark .wd-pill.on { box-shadow: 0 0 0 1px rgba(45, 212, 191, 0.25), 0 6px 18px -8px rgba(45, 212, 191, 0.55); }
.colour-dot { box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.25); }
.colour-dot.selected { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--wc), 0 0 16px 2px color-mix(in srgb, var(--wc) 45%, transparent); }
.switch-input { transition: background-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out); }
.switch-input::after { transition: transform 0.22s var(--ease-spring); }
.switch-input:checked { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent), 0 4px 14px -6px var(--accent-glow); }

/* Segmented control — inset track, lifted pill */
.segmented { box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06); }
.seg-btn.on { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 2px 8px -4px rgba(0, 0, 0, 0.12); }
html.theme-dark .segmented { box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5); }
html.theme-dark .seg-btn.on { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.06); }

/* Navigation — accent rail + glow on the active item */
.nav-item { position: relative; }
.nav-item.active::before {
  content: ""; position: absolute; left: -14px; top: 10px; bottom: 10px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--accent);
  box-shadow: 0 0 12px var(--accent-glow);
}
html.theme-dark .nav-item.active { background: color-mix(in srgb, var(--accent) 7%, var(--surface)); border-color: color-mix(in srgb, var(--accent) 22%, var(--border)); }
html.theme-dark .nav-item.active .icon { filter: drop-shadow(0 0 6px rgba(45, 212, 191, 0.55)); }
@media (max-width: 899px) {
  #tabbar { box-shadow: 0 -1px 0 var(--border), 0 -12px 30px -18px rgba(0, 0, 0, 0.25); }
  .tab-item { position: relative; }
  .tab-item::before {
    content: ""; position: absolute; top: 0; left: 50%;
    width: 22px; height: 2px; border-radius: 0 0 2px 2px; background: var(--accent);
    box-shadow: 0 0 10px var(--accent-glow);
    transform: translateX(-50%) scaleX(0); opacity: 0;
    transition: transform var(--dur) var(--ease-spring), opacity var(--dur-fast) var(--ease-out);
  }
  .tab-item.active::before { transform: translateX(-50%) scaleX(1); opacity: 1; }
  .tab-item .icon, .tab-item { transition: color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
  html.theme-dark .tab-item.active .icon { filter: drop-shadow(0 0 7px rgba(45, 212, 191, 0.6)); }
  .tab-item:active { transform: scale(0.94); }
}

/* Runner — the workout colour lights the stage */
.runner-main { border-radius: 20px; background: var(--card-sheen), var(--surface); }
.runner-main:not(.rest-main):not(.done-main) {
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--wc) 18%, transparent), 0 30px 60px -30px color-mix(in srgb, var(--wc) 40%, transparent);
}
html.theme-dark .runner-main:not(.rest-main):not(.done-main) {
  box-shadow: var(--shadow), 0 0 0 1px color-mix(in srgb, var(--wc) 22%, transparent), 0 40px 80px -30px color-mix(in srgb, var(--wc) 55%, transparent);
}
.eyebrow.wc { text-shadow: 0 0 12px color-mix(in srgb, var(--wc) 45%, transparent); }
html.theme-dark .giant-clock:not(.dim):not(.rest-clock) { text-shadow: 0 0 40px color-mix(in srgb, var(--wc) 28%, transparent); }
.prog { box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08); }
.prog-fill {
  background: linear-gradient(90deg, color-mix(in srgb, var(--wc) 75%, #fff), var(--wc));
  box-shadow: 0 0 12px color-mix(in srgb, var(--wc) 65%, transparent);
  transition: width 0.45s var(--ease-spring);
}
.runner-set-row.current {
  border-color: var(--wc);
  box-shadow: 0 0 0 1px var(--wc), 0 0 22px -6px color-mix(in srgb, var(--wc) 70%, transparent);
}
.runner-set-row.done .runner-set-check { box-shadow: 0 0 10px -2px color-mix(in srgb, var(--wc) 70%, transparent); }
.big-step-val { transition: transform 0.12s var(--ease-out); }
.done-main .runner-ex:not(.plain) { background: linear-gradient(90deg, var(--ink), color-mix(in srgb, var(--wc) 55%, var(--ink))); -webkit-background-clip: text; background-clip: text; color: transparent; }
.done-main .runner-target { max-width: 34ch; }

/* Sheets & overlays — glass and spring */
.overlay { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); transition: opacity var(--dur) var(--ease-out); }
.sheet { transform: translateY(40px); transition: transform var(--dur-slow) var(--ease-spring); box-shadow: var(--shadow-lift); }
@media (min-width: 700px) { .sheet { transform: translateY(14px) scale(0.985); } .overlay.open .sheet { transform: translateY(0) scale(1); } }
.sheet-grab { background: var(--border-strong); opacity: 0.9; }

/* Calendar */
.month-cell.today .cell-num { box-shadow: 0 0 12px var(--accent-glow); }
.mini-cell.has { box-shadow: 0 0 8px -2px color-mix(in srgb, var(--wc) 60%, transparent); }
.cal-chip { transition: transform 0.14s var(--ease-out), background-color 0.14s var(--ease-out); }
.chip-dot { box-shadow: 0 0 6px color-mix(in srgb, var(--wc) 60%, transparent); }
.cal-chip.missed .chip-dot { box-shadow: none; }

/* Builder rows */
.set-row { transition: background-color 0.14s var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .set-rep-quick:hover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); } }
.set-rep-input, .step-input, .big-step-input { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-glow); }
.wu-chip { background: var(--surface-2); }
.ex-card.dragging { box-shadow: var(--shadow-lift), 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }

/* Toasts / saved pill */
.toast { transition: opacity var(--dur) var(--ease-out), transform var(--dur-slow) var(--ease-spring); transform: translateY(12px) scale(0.98); }
.toast.show { transform: translateY(0) scale(1); }
.saved-pill { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }

/* Reduced motion honours the existing rule at the top of the Motion block */
@media (prefers-reduced-motion: reduce) {
  .view-inner, .view-inner > .stack > .card, .workout-grid > .card { animation: none !important; }
}

/* Value pop on big steppers (runner) */
@keyframes val-pop { 0% { transform: scale(1); } 35% { transform: scale(1.08); } 100% { transform: scale(1); } }
.big-step-val.pop { animation: val-pop 0.22s var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .big-step-val.pop { animation: none; } }


/* ===== v1.15 — durability + progress ===== */
.settings-value.warn { color: var(--wc); }
.nudge {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-bottom: 14px; padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  border-radius: var(--radius);
}
.nudge-main { min-width: 0; }
.nudge-title { font-size: 14px; font-weight: 700; }
/* v1.89: success variant — the inline top-up confirmation on the credit card */
.nudge.ok { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nudge.ok .nudge-title { color: var(--accent); }
.nudge-sub { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }
.nudge .btn { flex: none; }

.progress-card .card-body { gap: 14px; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.stat { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; min-width: 0; }
.stat-label { font-size: 12.5px; font-weight: 600; color: var(--ink-3); }
.stat-value { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; margin-top: 2px; }
.stat-sub { font-size: 12px; color: var(--ink-2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spark-wrap { display: flex; flex-direction: column; gap: 6px; }
.spark-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.spark-label { color: var(--ink-2); font-weight: 600; }
.spark-delta { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.spark-delta.up { color: var(--wc, var(--accent)); }
.spark-delta.down { color: var(--ink-2); }
.spark { width: 100%; height: 60px; display: block; color: var(--wc, var(--accent)); overflow: visible; }
.spark-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 6px color-mix(in srgb, currentColor 55%, transparent)); }
.spark-area { fill: currentColor; opacity: 0.09; }
.spark-dot { fill: currentColor; filter: drop-shadow(0 0 6px currentColor); }
.eyebrow.tight { margin-bottom: 8px; }
.cat-bars { display: flex; flex-direction: column; gap: 7px; }
.cat-bar-row { display: grid; grid-template-columns: 96px 1fr 32px; align-items: center; gap: 10px; font-size: 13px; }
.cat-bar-name { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-bar-track { height: 8px; background: var(--seg-bg); border-radius: 999px; overflow: hidden; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08); }
.cat-bar-fill { display: block; height: 100%; width: calc(var(--w) * 1%); border-radius: 999px; background: linear-gradient(90deg, color-mix(in srgb, var(--wc, var(--accent)) 70%, #fff), var(--wc, var(--accent))); box-shadow: 0 0 10px color-mix(in srgb, var(--wc, var(--accent)) 55%, transparent); }
.cat-bar-val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.pr-chip {
  margin-left: auto; flex: none; font-size: 10.5px; font-weight: 800; letter-spacing: 0.06em;
  color: var(--wc, var(--accent)); border: 1px solid color-mix(in srgb, var(--wc, var(--accent)) 45%, transparent);
  background: color-mix(in srgb, var(--wc, var(--accent)) 10%, transparent);
  border-radius: 6px; padding: 1px 6px; line-height: 1.5;
  box-shadow: 0 0 10px -2px color-mix(in srgb, var(--wc, var(--accent)) 60%, transparent);
}
.session-set .pr-chip { margin-left: auto; }
.suggest-pill {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--wc) 40%, var(--border));
  background: color-mix(in srgb, var(--wc) 9%, var(--surface));
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  box-shadow: 0 8px 22px -12px color-mix(in srgb, var(--wc) 60%, transparent);
}
.suggest-pill .icon { width: 18px; height: 18px; color: var(--wc); flex: none; filter: drop-shadow(0 0 5px color-mix(in srgb, var(--wc) 60%, transparent)); }
.suggest-pill > span:first-of-type { flex: 1; min-width: 0; }
.suggest-cta {
  flex: none; font-size: 13px; font-weight: 700;
  color: var(--wc); padding: 4px 10px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--wc) 55%, transparent);
}
.suggest-pill:active { transform: scale(0.985); }


/* ===== v1.18 — vertical rhythm ===== */
/* Direct children of a screen are separated by one consistent gap, so a card
   never sits flush against a list, another card, or a button row. Section
   titles get extra breathing room above; page heads keep their own margin. */
.view-inner > * + * { margin-top: var(--sp-4); }
.view-inner > .page-head { margin-bottom: 0; }
.view-inner > .page-head + * { margin-top: var(--sp-5); }
.view-inner > .section-title { margin: var(--sp-6) 0 0; }
.view-inner > .section-title + * { margin-top: var(--sp-3); }
.view-inner > .ex-list, .view-inner > .add-ex-btn { margin-top: var(--sp-4); }
.view-inner > .nudge { margin-bottom: 0; }
.settings-row { padding: var(--sp-3) 0; }
.settings-row + .settings-row { border-top: 1px solid var(--border); }
.card-body > .settings-note.pad-b { margin-bottom: 0; }


/* ===== v1.18 — AI Coach ===== */
@media (max-width: 899px) {
  .tab-item { min-width: 0; font-size: 10px; letter-spacing: -0.01em; }
  .tab-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
}
.coach-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); }
.nudge.warn { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); background: color-mix(in srgb, var(--danger) 8%, var(--surface)); }
.chat-log { display: flex; flex-direction: column; gap: var(--sp-3); }
.chat-msg { display: flex; flex-direction: column; gap: var(--sp-2); max-width: 88%; }
.chat-msg.user { align-self: flex-end; align-items: flex-end; }
.chat-msg.assistant { align-self: flex-start; align-items: flex-start; }
.chat-bubble {
  padding: 10px 14px; border-radius: 16px; font-size: 15px; line-height: 1.45; white-space: pre-wrap; word-break: break-word;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);
}
.chat-msg.user .chat-bubble { background: var(--accent); color: var(--accent-ink); border-color: transparent; border-bottom-right-radius: 5px; box-shadow: 0 8px 22px -12px var(--accent-glow); }
.chat-msg.assistant .chat-bubble { border-bottom-left-radius: 5px; }
.chat-bubble.thinking { color: var(--ink-2); font-style: italic; }
.chat-bubble.thinking::after { content: ''; display: inline-block; width: 6px; height: 6px; margin-left: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent-glow); animation: pulse 1.1s ease-in-out infinite; vertical-align: middle; }
@keyframes pulse { 0%, 100% { opacity: 0.25; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.15); } }
.chat-bubble.error { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); color: var(--danger); }
.chat-effects { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); }
.chat-effect {
  display: inline-flex; align-items: flex-start; gap: 6px; padding: 5px 10px 5px 8px; border-radius: 999px;
  max-width: 100%; min-width: 0; text-align: left; white-space: normal; overflow-wrap: break-word; line-height: 1.35; /* v2.170 (UI-06): the label wraps inside the conversation */
  font-size: 12.5px; font-weight: 700; color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}
.chat-effect .icon { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 2px; color: var(--accent); }
.chat-effects { max-width: 100%; }
.chat-intro { color: var(--ink-2); font-size: 14px; display: flex; flex-direction: column; gap: var(--sp-3); }
.chat-intro .chip { white-space: normal; text-align: left; height: auto; padding: 8px 12px; }
.chat-bar {
  position: sticky; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 8px);
  display: flex; flex-direction: column; gap: var(--sp-2); align-items: stretch; margin-top: var(--sp-4);
  padding: var(--sp-2); border-radius: 18px;
  background: var(--tabbar-bg); -webkit-backdrop-filter: blur(16px) saturate(160%); backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid var(--border); box-shadow: var(--shadow-hover);
}
.chat-entry { display: flex; gap: var(--sp-2); align-items: flex-end; min-width: 0; }
.chat-entry .chat-input { min-width: 0; font-size: 16px; }
.coach-photo-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.coach-photo-actions .btn { min-height: 44px; }
.coach-photo-preview { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.coach-photo-preview[hidden] { display: none; }
.coach-photo-preview img { width: 96px; height: 72px; object-fit: contain; border-radius: 8px; background: var(--surface); }
.coach-photo-status { margin: 0; font-size: 12px; color: var(--ink-2); line-height: 1.4; }
@media (min-width: 900px) { .chat-bar { bottom: 16px; } }
.chat-input { flex: 1; resize: none; min-height: 44px; max-height: 140px; line-height: 1.4; }
.chat-send { flex: none; width: 44px; height: 44px; padding: 0; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; }
.chat-send .icon { width: 20px; height: 20px; }
.ai-status { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.ai-status::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3); }
.ai-status.ok::before { background: var(--accent); box-shadow: 0 0 8px var(--accent-glow); }
.ai-status.bad::before { background: var(--danger); box-shadow: 0 0 8px color-mix(in srgb, var(--danger) 60%, transparent); }
.ai-status.warn::before { background: var(--wc, #F59E0B); }
.key-row { display: flex; align-items: stretch; gap: var(--sp-2); }
.key-row .input { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
.select { appearance: none; -webkit-appearance: none; padding-right: 34px; background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%); background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }


/* =====================================================================
   Buttons — authoritative states (v1.22)
   Order: base → variants → hover (fine pointers only) → active → disabled.
   Rules: a variant's background representation never changes kind between
   states (gradient stays gradient), no filter on interactive states, and
   every solid variant owns its own hover/active so the neutral .btn hover
   can never bleed through.
   ===================================================================== */
:root { --wc-ink: #0B0D10; }

/* base */
.btn { color: var(--ink); transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out), background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }

/* variants — FLAT fills. The fill never changes between normal, hover and
   active (v1.23): feedback comes from border, shadow and transform only, so
   the tested --wc-ink / --accent-ink contrast holds in every state and there
   is no background churn to flicker. The sheen is an inset highlight. */
.btn-primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
  box-shadow: 0 8px 22px -10px var(--accent-glow), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.btn-accent {
  background: var(--wc); border-color: var(--wc); color: var(--wc-ink);
  box-shadow: 0 8px 24px -8px color-mix(in srgb, var(--wc) 60%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.btn-xl.btn-accent { box-shadow: 0 14px 34px -10px color-mix(in srgb, var(--wc) 70%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.22); }
.btn-danger {
  background: var(--danger); border-color: var(--danger); color: #FFFFFF;
  box-shadow: 0 8px 22px -10px color-mix(in srgb, var(--danger) 45%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
html.theme-dark .btn-danger { color: #1A0B0B; }
.btn-danger-ghost { background: var(--surface); color: var(--danger); border-color: var(--border-strong); }

/* hover — pointer devices only; same fill, lifted */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--surface-2); border-color: var(--border-strong); }
  .btn-primary:hover {
    background: var(--accent); border-color: color-mix(in srgb, var(--accent) 70%, #fff);
    box-shadow: 0 10px 28px -8px var(--accent-glow), inset 0 1px 0 rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
  }
  .btn-accent:hover {
    background: var(--wc); border-color: color-mix(in srgb, var(--wc) 70%, #fff);
    box-shadow: 0 12px 30px -8px color-mix(in srgb, var(--wc) 72%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
  }
  .btn-danger:hover {
    background: var(--danger); border-color: color-mix(in srgb, var(--danger) 70%, #fff);
    box-shadow: 0 10px 26px -8px color-mix(in srgb, var(--danger) 55%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.24);
    transform: translateY(-1px);
  }
  .btn-danger-ghost:hover { background: color-mix(in srgb, var(--danger) 8%, var(--surface)); border-color: color-mix(in srgb, var(--danger) 45%, var(--border-strong)); }
}

/* active — same fill, pressed in */
.btn:active { transform: scale(0.965); background: var(--surface-2); }
.btn-primary:active { background: var(--accent); box-shadow: 0 3px 10px -6px var(--accent-glow), inset 0 2px 4px rgba(0, 0, 0, 0.18); transform: scale(0.965); }
.btn-accent:active { background: var(--wc); box-shadow: 0 3px 10px -6px color-mix(in srgb, var(--wc) 50%, transparent), inset 0 2px 4px rgba(0, 0, 0, 0.18); transform: scale(0.965); }
.btn-danger:active { background: var(--danger); box-shadow: 0 3px 10px -6px color-mix(in srgb, var(--danger) 45%, transparent), inset 0 2px 4px rgba(0, 0, 0, 0.18); transform: scale(0.965); }
.btn-danger-ghost:active { background: color-mix(in srgb, var(--danger) 12%, var(--surface)); }

/* disabled — one look for every control family, no hover/press reaction */
.btn:disabled, .icon-btn:disabled, .chip:disabled, .wd-pill:disabled, .step-btn:disabled, .big-step-btn:disabled,
.set-rep-quick:disabled, .colour-dot:disabled, .chat-send:disabled, .picker-row:disabled {
  opacity: 0.46; transform: none !important; box-shadow: none; pointer-events: none;
}
.picker-row:disabled.added { opacity: 0.8; } /* the "added" tick stays readable during its short lock */

/* coarse-pointer targets (v1.22): bigger hit areas on phones, desktop unchanged */
@media (pointer: coarse) {
  .icon-btn, .step-btn, .wd-pill, .set-rep-quick, .btn-sm, .segmented.small .seg-btn, .chip, .set-rep-range-btn, .desc-toggle { min-height: 44px; }
  .desc-toggle { min-width: 44px; display: inline-flex; align-items: center; }
  /* title keeps its visual rhythm; the hit area extends past the text */
  .card-title-btn { position: relative; }
  .card-title-btn::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
  .icon-btn, .step-btn, .wd-pill { min-width: 44px; }
  .colour-dot { position: relative; }
  .colour-dot::after { content: ''; position: absolute; inset: -6px; border-radius: 50%; } /* 46px hit area, 34px visible */
  .colour-row { gap: 14px; }
}


/* ===== v1.23 — Workout card hierarchy ===== */
.workout-card .card-body { gap: var(--sp-3); }
.card-head-text { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.workout-card .card-title { font-size: 19px; line-height: 1.2; }
.facts { display: flex; align-items: center; flex-wrap: wrap; gap: 5px 6px; }
.fact {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums;
  padding: 2px 8px 2px 6px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.fact .icon { width: 14px; height: 14px; color: var(--wc, var(--accent)); }
.card-lineup { font-size: 13.5px; color: var(--ink-2); line-height: 1.45; }
.card-desc-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.card-desc {
  font-size: 13.5px; line-height: 1.5; color: var(--ink-2); white-space: pre-line;
  padding: 8px 12px; border-left: 2px solid color-mix(in srgb, var(--wc) 55%, var(--border));
  background: color-mix(in srgb, var(--wc) 5%, var(--surface-2)); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  width: 100%;
}
.card-desc.clamped { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* v1.26 P2-01: neutral ink at readable contrast; the workout colour is a
   secondary cue (underline + hover wash), never the text colour itself. */
.desc-toggle {
  font-size: 12.5px; font-weight: 700; color: var(--ink-2);
  text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--wc, var(--accent)) 70%, transparent);
  text-decoration-thickness: 2px; text-underline-offset: 3px;
  padding: 4px 12px; min-height: 28px; border-radius: 999px;
}
.desc-toggle[hidden] { display: none; }
@media (hover: hover) and (pointer: fine) { .desc-toggle:hover { color: var(--ink); background: color-mix(in srgb, var(--wc, var(--accent)) 10%, transparent); } }
.desc-toggle:active { transform: scale(0.96); }
.card-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.card-last { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); }
.card-last .icon { width: 15px; height: 15px; }
.card-last.done { color: var(--ink-2); }
.card-last.done .icon { color: var(--wc, var(--accent)); filter: drop-shadow(0 0 5px color-mix(in srgb, var(--wc) 60%, transparent)); }
.workout-card .btn-accent { margin-top: 2px; }

/* native title button (v1.25 P2-03): inherits the heading look, real button semantics */
.card-title-btn { font: inherit; color: inherit; letter-spacing: inherit; text-align: left; cursor: pointer; border-radius: 6px; }
@media (hover: hover) and (pointer: fine) { .card-title-btn:hover { text-decoration: underline; text-underline-offset: 3px; } }


/* ===== v1.27 — calendar swipe + Today ===== */
.cal-main { transition: transform 0.16s var(--ease-out); will-change: transform; touch-action: pan-y; }
@keyframes calSlideR { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
@keyframes calSlideL { from { opacity: 0; transform: translateX(-26px); } to { opacity: 1; transform: none; } }
.cal-main.slide-in-right { animation: calSlideR 0.22s var(--ease-out) both; }
.cal-main.slide-in-left { animation: calSlideL 0.22s var(--ease-out) both; }
@media (prefers-reduced-motion: reduce) {
  .cal-main, .cal-main.slide-in-right, .cal-main.slide-in-left { animation: none; transition: none; }
}
.cal-hint { font-size: 12px; color: var(--ink-3); text-align: center; padding-top: var(--sp-2); }
@media (pointer: fine) { .cal-hint { display: none; } }
.danger-zone { margin-top: var(--sp-2); padding-top: var(--sp-3); border-top: 1px solid var(--border); }

.week-card .card-body { gap: var(--sp-4); }
.week-strip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.wk-day {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 0 6px; border-radius: var(--radius-sm);
  border: 1px solid transparent; color: var(--ink-3); min-width: 0;
}
.wk-wd { font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.wk-num { font-size: 15px; font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.wk-day.today { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.wk-day.today .wk-wd, .wk-day.today .wk-num { color: var(--ink); }
.wk-day.has-work .wk-num { color: var(--ink); }
.wk-dots { display: flex; gap: 3px; height: 7px; align-items: center; }
/* one dot per occurrence, each styled by its own state */
.wk-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--wc, var(--accent)); }
.wk-dot.done { box-shadow: 0 0 6px color-mix(in srgb, var(--wc, var(--accent)) 70%, transparent); }
.wk-dot.planned { background: transparent; border: 1.5px solid color-mix(in srgb, var(--wc, var(--accent)) 75%, transparent); width: 6px; height: 6px; }
.wk-dot.missed { background: transparent; border: 1.5px dashed color-mix(in srgb, var(--wc, var(--accent)) 55%, transparent); width: 6px; height: 6px; opacity: 0.75; }
.wk-dot.empty { background: var(--border-strong); width: 3px; height: 3px; }
.mini-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); }
.mini-stat { text-align: center; min-width: 0; }
.mini-val { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.mini-lbl { font-size: 11px; color: var(--ink-3); margin-top: 1px; line-height: 1.25; }
.next-card { opacity: 0.96; }
.next-card .card-title { font-size: 17px; }
@media (pointer: coarse) { .wk-day { min-height: 56px; } }


/* ===== v1.28 — exercise library browse ===== */
.group-row { display: flex; align-items: stretch; flex-wrap: wrap; gap: 6px; }
/* v2.274: the browse row is ONE line that scrolls horizontally within itself — the overflow belongs to the row, never
   to the page or the sheet (the iPhone side-to-side movement and pinch-zoom limits must not return). Native touch and
   trackpad scrolling, keyboard Tab through the pills, visible focus, aria-pressed on each. */
.group-row.group-row-scroll {
  flex-wrap: nowrap; width: 100%; max-width: 100%; min-width: 0;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  padding: 2px 2px 8px; scroll-padding-inline: 4px; scrollbar-width: thin;
  touch-action: pan-x pan-y pinch-zoom;
}
.group-row-scroll > .group-chip { flex: 0 0 auto; white-space: nowrap; min-height: 44px; border-radius: 999px; }
.group-row-scroll > .group-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.group-chip {
  flex: 1 1 auto; min-width: 0; text-align: center;
  padding: 8px 12px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 650; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--border);
  white-space: nowrap;
}
.group-chip.on {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
  box-shadow: 0 6px 18px -10px var(--accent-glow), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
@media (hover: hover) and (pointer: fine) {
  .group-chip:hover { border-color: var(--border-strong); color: var(--ink); }
  .group-chip.on:hover { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 70%, #fff); }
}
.group-chip:active { transform: scale(0.97); }
@media (pointer: coarse) { .group-chip { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; } }
.filter-row[hidden] { display: none; }
.lib-head {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin: var(--sp-3) 0 2px; padding: 6px 2px;
  font-size: 13px; font-weight: 650; color: var(--ink-3);
  background: var(--bg);
}
.lib-head:first-child { margin-top: 0; }
.lib-count { font-weight: 700; letter-spacing: 0; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.picker-head { background: var(--surface); margin: var(--sp-3) 0 2px; }
.picker-list .picker-head:first-child { margin-top: 0; }
.search-scope { font-size: 12.5px; color: var(--ink-3); padding: 2px 2px var(--sp-1); }


/* ===== v1.31 — per side / hidden ===== */
.runner-target.side-note { font-size: 13.5px; color: var(--wc, var(--accent)); font-weight: 650; }
.group-chip.hidden-chip { flex: 0 0 auto; color: var(--ink-3); }
.group-chip.hidden-chip.on { color: var(--accent-ink); }


/* ===== v1.32 — exercise content + review ===== */
.content-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.content-summary { font-size: 15px; line-height: 1.5; }
.content-block { display: flex; flex-direction: column; gap: 3px; }
.content-block h3 { font-size: 13px; font-weight: 700; color: var(--ink-3); }
.content-block p { font-size: 14.5px; line-height: 1.55; color: var(--ink-2); }
.content-focus { font-size: 13.5px; color: var(--ink-2); padding: 8px 12px; border-left: 2px solid color-mix(in srgb, var(--accent) 55%, var(--border)); background: var(--surface-2); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.unreviewed-chip { font-size: 12px; font-weight: 650; color: var(--ink-3); border: 1px solid var(--border-strong); border-radius: 999px; padding: 2px 9px; }
.review-meta { font-size: 12.5px; color: var(--ink-3); }
.review-block { display: flex; flex-direction: column; gap: 4px; }
.review-label { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; font-weight: 650; color: var(--ink-3); }
.review-count { font-weight: 700; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.review-count.over { color: var(--danger); }
.review-field { resize: vertical; line-height: 1.5; font-size: 14.5px; }
.review-actions { margin-top: var(--sp-2); }
.review-actions .grow { flex: 1; }
.review-field.missing { border-color: var(--danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 18%, transparent); }


/* ===== v1.37 — brand mark ===== */
.logo { display: inline-flex; color: var(--accent); flex: none; }
.logo svg { width: 100%; height: 100%; display: block; }
.brand-ver { align-self: baseline; }
.brand-logo { width: 26px; height: 26px; filter: drop-shadow(0 0 8px var(--accent-glow)); }
.rest-logo { width: 44px; height: 44px; opacity: 0.9; margin-bottom: 2px; filter: drop-shadow(0 0 10px var(--accent-glow)); }
.about-brand { display: flex; align-items: center; gap: 14px; padding: 4px 0 6px; }
.about-logo { width: 40px; height: 40px; filter: drop-shadow(0 0 10px var(--accent-glow)); }
.about-name { font-size: 18px; font-weight: 800; letter-spacing: -0.03em; }


/* ===== v1.38 — share QR ===== */
.qr-wrap {
  background: #FFFFFF; border-radius: var(--radius); padding: 12px;
  margin: 0 auto; width: min(100%, 360px); aspect-ratio: 1;
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.45);
}
.qr-wrap svg { width: 100%; height: 100%; display: block; }
.qr-hint { font-size: 13px; color: var(--ink-2); text-align: center; margin-top: var(--sp-3); }


/* ===== v1.40 — layout fixes ===== */
/* Buttons never stack their own label. If a row is too narrow the whole
   button wraps to the next line instead. */
.btn { white-space: nowrap; }
.btn-row { flex-wrap: wrap; }
.btn-row > .btn { flex: 1 1 auto; min-width: 0; }
.chat-effect { white-space: normal; } /* v2.171 (R02): the label wraps — the earlier nowrap rule clipped long confirmations */

/* Share sheet: the primary action alone, the two secondaries side by side. */
.share-actions { display: flex; flex-direction: column; gap: var(--sp-2); }
.share-actions .btn-row { flex-wrap: nowrap; }
.share-actions .btn-row > .btn { flex: 1 1 0; }

/* Share-card sheet (v2.114): the preview sits on a checkerboard so the
   see-through styles read as see-through; three style swatches, one on. */
.share-card-stage {
  padding: 12px; border-radius: var(--radius);
  background-color: #7A8290;
  background-image:
    linear-gradient(45deg, rgba(255,255,255,0.14) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.14) 75%),
    linear-gradient(45deg, rgba(255,255,255,0.14) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.14) 75%);
  background-size: 24px 24px; background-position: 0 0, 12px 12px;
}
.share-card-stage { display: flex; justify-content: center; }
/* v2.116: the preview is capped so the style swatches and the actions are on screen without scrolling — on a
   phone a full-width 4:5 preview filled the sheet and hid the options below the fold */
.share-card-img { display: block; width: auto; max-width: 100%; height: auto; max-height: 38dvh; border-radius: 8px; min-height: 120px; }
.share-styles { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); }
.share-style {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 10px 6px 9px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface);
  font-size: 13px; font-weight: 620; color: var(--ink-2);
}
.share-style.on { border-color: var(--accent); color: var(--ink); box-shadow: inset 0 0 0 1px var(--accent); }
.share-style-label { line-height: 1; }
.share-style-dot {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  border: 1px solid rgba(255,255,255,0.28); box-shadow: 0 1px 2px rgba(0,0,0,0.35);
}
.share-style-dot.dark { background: #0B0E12; }
.share-style-dot.glass {
  background:
    linear-gradient(135deg, rgba(255,255,255,0.58), rgba(255,255,255,0.10) 55%, rgba(255,255,255,0.02)),
    rgba(11,14,18,0.55);
  border-color: rgba(255,255,255,0.65);
}
.share-style-dot.transparent {
  background-color: #9CA3AF;
  background-image:
    linear-gradient(45deg, rgba(255,255,255,0.35) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.35) 75%),
    linear-gradient(45deg, rgba(255,255,255,0.35) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.35) 75%);
  background-size: 10px 10px; background-position: 0 0, 5px 5px;
}
.share-card-hint { margin-top: var(--sp-2); min-height: 2.6em; }
@media (max-height: 640px) { .share-card-img { max-height: 26dvh; } .share-card-hint { min-height: 0; } } /* v2.122 (P3-01): a 320×568 phone keeps Save/Share on screen */
.push-state { font-variant-numeric: tabular-nums; opacity: 0.85; }
.legacy-key { margin-bottom: var(--sp-3); }
.wear-why { opacity: 0.9; }
.write-failed { margin: 0 var(--sp-4) var(--sp-3); }
.coach-quarantine { margin-bottom: var(--sp-4); border-color: var(--accent); }

/* Runner exercise title: the options button anchors to the card corner so
   the centred title stays centred and the dots no longer sit beside its
   last word (v1.40). */
.runner-main { position: relative; }
.runner-ex-row { justify-content: center; padding: 0 44px; }
.ex-actions-btn { position: absolute; top: 10px; right: 10px; margin-top: 0; }
/* the exercise name is tappable — it opens the guide (v1.40) */
.runner-ex.guide-link { cursor: pointer; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--wc) 45%, transparent); text-decoration-thickness: 2px; text-underline-offset: 6px; }
.runner-ex.guide-link:active { opacity: 0.8; }

/* Week view on mobile: each day is a row — date block on the left at a fixed
   width, then chips or "Rest" filling the remainder.
   v1.43: `align-items: center` is what keeps the two columns on the same
   optical line. An earlier pass set `stretch` here, which let a single short
   line like "Rest" sit at the top of a stretched box while the date sat
   centred beside it. Both declarations lived in different blocks, so the
   later one silently won — they are merged here so there is one answer. */
@media (max-width: 899px) {
  .week-day { min-height: 0; flex-direction: row; align-items: center; gap: 10px; padding: 10px 12px; }
  .week-day-head { width: 92px; flex: none; flex-direction: row; align-items: baseline; gap: 6px; white-space: nowrap; }
  .week-wd { font-size: 11px; }
  .week-num { font-size: 18px; }
  .week-chips { flex-direction: column; flex: 1; }
  .week-rest { display: flex; align-items: center; }
  .week-day .cal-chip { padding: 3px 8px; }
}

/* ===== v1.40 — classes + guide sheet ===== */
.activity-card .card-title { font-size: 19px; }
.guide-body { display: flex; flex-direction: column; gap: var(--sp-3); }
.guide-meta { font-size: 12.5px; color: var(--ink-3); }

/* ===== v1.41 — records ===== */
.record-card .card-body { gap: var(--sp-2); }
.record-name { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; min-width: 0; }
.record-meta { font-size: 12px; color: var(--ink-3); }
.record-headline { display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.record-value { font-size: 28px; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.record-label { font-size: 13px; font-weight: 650; color: var(--ink-3); }
.record-when { font-size: 12.5px; color: var(--ink-2); }
.pin-btn { color: var(--ink-3); }
.pin-btn.on { color: var(--accent); }
.pin-btn.on .icon { filter: drop-shadow(0 0 6px var(--accent-glow)); }
.record-rows { display: flex; flex-direction: column; gap: var(--sp-2); }
.record-row {
  display: grid; grid-template-columns: 1fr auto auto; grid-template-areas: 'name spark value' 'label spark value';
  gap: 0 var(--sp-3); align-items: center; text-align: left;
  padding: 8px 10px; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px solid var(--border);
}
.record-row-name { grid-area: name; font-size: 14px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.record-row-label { grid-area: label; font-size: 12px; font-weight: 600; color: var(--ink-3); }
.record-row-value { grid-area: value; font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--accent); white-space: nowrap; }
.pr-summary {
  display: flex; flex-direction: column; gap: var(--sp-2); width: 100%;
  padding: var(--sp-3); border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--wc) 45%, var(--border));
  background: color-mix(in srgb, var(--wc) 9%, var(--surface));
  box-shadow: 0 10px 28px -14px color-mix(in srgb, var(--wc) 70%, transparent);
}
.pr-summary-head { display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 14px; font-weight: 800; }
.pr-summary-head .icon { color: var(--wc); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--wc) 65%, transparent)); }
.pr-summary-list { display: flex; flex-direction: column; gap: 4px; }
.pr-summary-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); font-size: 13.5px; }
.pr-summary-name { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-summary-val { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ===== v1.42 — API setup walkthrough ===== */
.setup-steps { display: flex; flex-direction: column; gap: var(--sp-3); }
.setup-step { display: flex; gap: var(--sp-3); align-items: flex-start; }
.setup-num {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 800; color: var(--accent-ink); background: var(--accent);
}
.setup-title { font-size: 14.5px; font-weight: 700; }
.setup-body { font-size: 13.5px; color: var(--ink-2); line-height: 1.5; margin-top: 2px; }
.dlg-actions a.btn { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }


/* ===== v1.45 — iOS double-tap zoom =====
   Safari waits ~300ms on every tap of an interactive element in case a second
   tap follows, and zooms if it does. Two taps in quick succession on a stepper
   or Complete set therefore zoomed the page mid-workout.
   `touch-action: manipulation` keeps pinch-zoom and scrolling but drops
   double-tap-to-zoom, so the accessibility of zooming is untouched — unlike
   user-scalable=no, which we deliberately do not use. */
button, a, label, input, select, textarea, summary,
.btn, .icon-btn, .chip, .group-chip, .wd-pill, .step-btn, .big-step-btn,
.seg-btn, .tab-item, .nav-item, .card.list-row, .picker-row, .choose-item,
.month-cell, .week-day, .mini-month, .colour-dot, .set-rep-quick, .set-open,
.record-row, .wk-day, .desc-toggle, .card-title-btn, .pin-btn, .cal-chip {
  touch-action: manipulation;
}

.warn-card { border-color: color-mix(in srgb, var(--amber, #F59E0B) 45%, var(--border)); background: color-mix(in srgb, #F59E0B 8%, var(--surface)); }
.warn-card .eyebrow { color: #F59E0B; }

/* ===== v1.46 — workout reordering ===== */
.workout-card { transition: box-shadow 0.15s var(--ease-out), opacity 0.15s var(--ease-out); }
.workout-card.dragging, .ex-card.dragging {
  position: relative; z-index: 5; opacity: 0.96;
  box-shadow: 0 18px 40px -14px rgba(0, 0, 0, 0.55);
  transition: none;                       /* the transform follows the finger */
}
.workout-card:not(.dragging), .ex-card:not(.dragging) { transition: transform 0.16s var(--ease-out); }
.workout-card .card-top { align-items: flex-start; }
.workout-card .drag-handle { margin-left: auto; }

.link-box { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; word-break: break-all; resize: none; }


/* ===== polish pass (v1.57) — cosmetic only; no layout properties here ===== */

/* Desktop scrollbars in the app's own palette rather than the OS default. */
@media (pointer: fine) {
  * { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
  *::-webkit-scrollbar { width: 10px; height: 10px; }
  *::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; border: 3px solid transparent; background-clip: padding-box; }
  *::-webkit-scrollbar-track { background: transparent; }
}

/* Every interactive row answers a press the same way a button does. */
.card.list-row, .picker-row, .choose-item, .record-row, .runner-set-row, .history-row, .week-day, .month-cell {
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.record-row:active, .history-row:active, .week-day:active { transform: scale(0.992); }

/* Chips and pills settle into their selected state instead of jumping. */
.chip, .group-chip, .wd-pill, .seg-btn, .colour-dot, .pin-btn, .switch-track, .switch-thumb {
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}

/* Inputs: a calm ring, the same on every field. */
.input, textarea.input, select.input { transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out); }

/* Big numbers everywhere share one voice: tight, tabular, heavy. */
.big-step-val, .stat-value, .mini-val, .record-value, .record-row-value, .runner-clock, .summary-row strong, .pr-summary-val {
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}

/* Progress fills ease to their new length. */
.review-bar-fill, .progress-fill, .bar-fill, .streak-fill { transition: width var(--dur-slow) var(--ease-out); }

/* Cards that the user can act on lift very slightly on a fine pointer; static
   cards do not, so the lift means "this is a control". */
@media (hover: hover) and (pointer: fine) {
  .workout-card:hover, .card.list-row:hover, .record-card:hover, .activity-card:hover { box-shadow: var(--shadow-hover); border-color: var(--border-strong); }
}

/* Reduced motion: every transition and animation above collapses to instant. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  .tab-item::before { transition: none; }
}


/* ===== v1.58 — foldable library sections ===== */
/* .lib-head is now a <button>; strip the UA button chrome and keep its look. */
.lib-fold { width: 100%; border: 0; cursor: pointer; font-family: inherit; text-align: left; }
@media (hover: hover) and (pointer: fine) { .lib-fold:hover { color: var(--ink); } .lib-fold:hover .lib-chev { color: var(--ink); } }
.lib-head-side { display: inline-flex; align-items: center; gap: 8px; }
.lib-chev { width: 15px; height: 15px; color: var(--ink-3); transition: transform var(--dur) var(--ease-out); transform: rotate(90deg); }
.lib-fold.folded .lib-chev { transform: rotate(0deg); }
/* 1fr → 0fr grid rows: height animates without measuring anything. */
.lib-sec { display: grid; grid-template-rows: 1fr; transition: grid-template-rows 0.28s var(--ease-out); }
.lib-sec-inner { overflow: hidden; min-height: 0; }
.lib-sec.folded { grid-template-rows: 0fr; }
@media (prefers-reduced-motion: reduce) { .lib-sec, .lib-chev { transition: none !important; } }


/* v1.67: the hidden attribute must always win. Author display rules (.stack's
   flex, .btn's inline-flex) otherwise override the UA's [hidden] and "hidden"
   elements render anyway — which put the code box on step one of the sign-in
   sheet in production. */
[hidden] { display: none !important; }

/* v1.71: calendar.js emits an empty .day-panel.hidden-mobile placeholder on
   phones (the day sheet replaces it there) but no rule ever hid it, so every
   phone showed an empty bordered box under the month grid. */
@media (max-width: 899px) { .hidden-mobile { display: none !important; } }

/* ===== v1.59 — accounts ===== */
.code-input {
  font-size: 26px; font-weight: 700; letter-spacing: 10px; text-align: center;
  font-variant-numeric: tabular-nums; padding-left: 10px;
}
.signin-err { font-size: 13.5px; color: var(--danger); font-weight: 600; }
.signin-err[hidden] { display: none; }
.signin-foot {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: var(--sp-4); font-size: 12.5px; line-height: 1.5; color: var(--ink-3);
}
.signin-foot .icon { width: 15px; height: 15px; flex: none; margin-top: 1px; }
.acct-email { font-size: 14px; font-weight: 600; word-break: break-all; text-align: right; }

/* ===== v1.63 — account bootstrap / conflict ===== */
.conflict-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); margin: var(--sp-2) 0; }
.conflict-side {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 12px; display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.conflict-label { font-size: 12px; font-weight: 700; letter-spacing: 0.4px; color: var(--ink-3); text-transform: uppercase; }
.conflict-when { font-size: 15px; font-weight: 700; color: var(--ink); }
.conflict-note { font-size: 12.5px; color: var(--ink-2); }

/* ===== v1.69 — #/debug diagnostics ===== */
.dbg-line { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.dbg-k { color: var(--ink-2); flex: none; max-width: 55%; }
.dbg-v { color: var(--ink); text-align: right; word-break: break-all; font-variant-numeric: tabular-nums; }
.dbg-line.ok .dbg-v { color: var(--accent); }
.dbg-line.bad .dbg-v { color: var(--danger); font-weight: 600; }

/* ===== v1.70 — welcome card ===== */
.welcome-card { --wk: var(--accent); }
.welcome-card .card-body { display: flex; flex-direction: column; gap: 10px; }
.welcome-card .card-meta { margin-bottom: 4px; }
.btn-link.welcome-signin {
  background: none; border: 0; cursor: pointer; padding: 8px 0 2px;
  font-family: inherit; font-size: 13.5px; font-weight: 600; color: var(--accent);
  text-align: center; width: 100%;
}

/* ===== v1.71 — workout groups ===== */
.group-head-row { display: flex; align-items: center; gap: 4px; margin-top: var(--sp-3); }
.group-head-row .lib-head { flex: 1; margin: 0; position: static; }
.group-manage { color: var(--ink-3); }
.group-head-row + .lib-sec .workout-grid { padding-top: var(--sp-2); }

/* ===== v1.78 — Coach credit strip ===== */
.coach-balance {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px; margin-bottom: var(--sp-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.coach-balance .cb-text { font-size: 13.5px; font-weight: 600; color: var(--ink-2); }
.coach-balance.low .cb-text { color: var(--danger); }
.btn.btn-xs { padding: 5px 12px; font-size: 12.5px; border-radius: 999px; }

/* ===== v1.86 — Coach credit block ===== */
/* One vertical rhythm for the whole card: 20px between blocks, 8px inside a
   block. The hero is the only centred element; everything below it is a normal
   left-aligned settings row, so the eye has one alignment edge to follow. */
.credit-hero {
  display: flex; flex-direction: column; align-items: center;
  padding: 22px 18px 20px; margin: 0 0 20px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.credit-num {
  font-size: 52px; font-weight: 800; line-height: 1; letter-spacing: -1.5px;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.credit-label {
  margin-top: 6px; font-size: 11px; font-weight: 700; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--ink-3);
}
.credit-hint {
  margin-top: 12px; font-size: 13px; line-height: 1.45; color: var(--ink-2);
  text-align: center; max-width: 30ch;
}
.credit-packs {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  width: 100%; margin-top: 18px;
}
.pack-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 12px 6px; height: auto; min-height: 62px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.pack-price { font-size: 18px; font-weight: 800; line-height: 1.1; color: var(--ink); }
.pack-credits { font-size: 11px; font-weight: 600; line-height: 1.1; color: var(--ink-3); }
.credit-foot { margin-top: 12px; font-size: 12px; color: var(--ink-3); text-align: center; }

/* the card's own rhythm */
.coach-card .card-body > * + * { margin-top: 20px; }
.coach-card .card-body > .credit-hero { margin-top: 18px; }
.coach-card .settings-note { line-height: 1.5; }
.coach-card .switch-label { margin: 0; }

.btn-link.advanced-toggle {
  background: none; border: 0; cursor: pointer; padding: 4px 0; width: 100%;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--ink-3);
  text-align: center;
}
.credit-hero[hidden] { display: none !important; }
.credit-hero .btn-primary { margin-top: 16px; width: 100%; }

/* ============================================================
   v2.09 — polish: onboarding hero, group presentation, motion
   ============================================================ */

/* Onboarding hero (Today, fresh install, signed out) */
.welcome-card { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.welcome-card .card-body { gap: 12px; }
.welcome-title { font-size: 22px; letter-spacing: -0.01em; }
.welcome-row { display: flex; gap: 8px; align-items: stretch; }
.welcome-row .input { flex: 1; min-width: 0; font-size: 16px; }
.welcome-row .btn { white-space: nowrap; }
.welcome-fine { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 12.5px; color: var(--ink-3); }
.welcome-fine .icon { width: 14px; height: 14px; flex: 0 0 auto; }
.welcome-alt .btn-link { padding: 4px 0; font-size: 13px; }
/* v2.76 — Coach sample conversation (static) and the post-first-session welcome */
.coach-preview-turn { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border); }
.coach-preview-turn.from-you { border-style: dashed; }
.coach-preview-turn.from-coach { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 7%, var(--surface-2)); }
.coach-preview-turn p { margin: 0; font-size: 14.5px; line-height: 1.45; }
.coach-preview-who { font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); }
.coach-preview .card-body { gap: 8px; }
.welcome-card.kept { --wk: var(--accent); }
@media (max-width: 420px) {
  .welcome-row { flex-direction: column; }
  .welcome-row .btn { width: 100%; }
}

/* Workout groups: a proper section header, not grey text */
.group-head {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin: var(--sp-4) 0 var(--sp-2); padding: 10px 12px 10px 14px;
  border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: inset 3px 0 0 var(--accent);
  font-size: 14px; font-weight: 700; letter-spacing: 0; color: var(--ink);
}
.group-head .lib-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--ink);
  font-size: 12px;
}
.group-head .lib-chev { color: var(--ink-2); }
.group-head.folded { opacity: 0.85; }
@media (hover: hover) and (pointer: fine) { .group-head:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); } }
/* the group's cards sit visibly inside their section */
.group-head + .lib-sec .lib-sec-inner { padding-left: 6px; border-left: 2px solid color-mix(in srgb, var(--accent) 18%, transparent); margin-left: 6px; }

/* Route entrance animation already lives above (view-in) — nothing to add. */

/* Device: no 13px inputs — iOS zooms the page on focus under 16px */
.key-row .input { font-size: 16px; }

/* v2.11: exercise illustrations — square, contained, never jumping the layout */
.ex-media {
  display: block; width: min(100%, 300px); aspect-ratio: 1 / 1; height: auto;
  margin: 4px auto 6px; border-radius: var(--radius-sm);
  background: #fff; border: 1px solid var(--line);
}

/* v2.13: the exercise name in the editor is the way into its guide */
.ex-name-btn {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left;
  cursor: pointer; border-radius: 6px;
}
.ex-name-btn .ex-name-info { width: 15px; height: 15px; flex: 0 0 auto; color: var(--ink-3); }
.ex-name-btn:active { opacity: 0.7; }
@media (hover: hover) and (pointer: fine) { .ex-name-btn:hover .ex-name-info { color: var(--accent); } }
.ex-name-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================
   v2.15 — Today sections, coming up, foldable workouts, progress
   ============================================================ */
.section-label { margin: 0 0 var(--sp-2); font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.today-section { margin-top: var(--sp-4); }
.today-section:first-child { margin-top: 0; }
.upcoming-card .card-body { gap: 0; padding: 4px 6px; }
.upcoming-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 10px; border: 0; background: none; color: inherit; font: inherit; text-align: left;
  border-radius: var(--radius-sm); cursor: pointer;
}
.upcoming-row + .upcoming-row { border-top: 1px solid var(--line); border-radius: 0; }
.upcoming-row:active { background: var(--surface-2); }
.upcoming-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--wc, var(--accent)); flex: 0 0 auto; box-shadow: 0 0 0 3px color-mix(in srgb, var(--wc, var(--accent)) 22%, transparent); }
.upcoming-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.upcoming-name { font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.upcoming-when { font-size: 13px; color: var(--ink-3); }
.upcoming-chev { width: 16px; height: 16px; color: var(--ink-3); flex: 0 0 auto; }

/* foldable workout cards */
.fold-btn .fold-chev { width: 18px; height: 18px; transition: transform var(--dur) var(--ease-out); }
.workout-card.folded .fold-btn .fold-chev { transform: rotate(-90deg); }
.workout-card.folded .facts, .workout-card.folded .card-body > :not(.card-top) { display: none; }
.workout-card.folded .card-body { padding-top: 12px; padding-bottom: 12px; }
.workout-card.folded .card-title { font-size: 16px; }
.fold-all-ic { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { .fold-btn .fold-chev { transition: none; } }

/* progress card */
.hero-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (min-width: 560px) { .hero-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.hero-stat { padding: 12px 12px 10px; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; }
.hero-val { font-size: 26px; font-weight: 750; letter-spacing: -0.02em; line-height: 1.05; font-variant-numeric: tabular-nums; }
.hero-unit { font-size: 13px; font-weight: 600; color: var(--ink-3); letter-spacing: 0; }
.hero-lbl { font-size: 12px; color: var(--ink-3); }
.stat-trend { font-size: 12px; font-weight: 650; margin-top: 2px; }
.stat-trend.up { color: var(--ok, #16a34a); }
.stat-trend.down { color: var(--ink-3); }
.stat-trend.flat { color: var(--ink-3); }
.spark-note { font-size: 12px; color: var(--ink-3); }
.consist-wrap, .vol-wrap { display: flex; flex-direction: column; gap: 8px; }
.consist-grid { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px; }
.consist-col { display: grid; grid-template-rows: repeat(7, 1fr); gap: 3px; }
.consist-cell { display: block; aspect-ratio: 1; border-radius: 3px; background: color-mix(in srgb, var(--ink) 7%, transparent); }
/* v2.264: the grid takes the most-trained workout's colour (--wc, set by the view); the theme accent is the fallback */
.consist-cell.l1 { background: color-mix(in srgb, var(--wc, var(--accent)) 45%, transparent); }
.consist-cell.l2 { background: color-mix(in srgb, var(--wc, var(--accent)) 70%, transparent); }
.consist-cell.l3 { background: var(--wc, var(--accent)); }
.consist-cell.today { box-shadow: inset 0 0 0 1.5px var(--ink); }
.consist-cell.future { opacity: 0.35; }
.vol-bars { display: flex; align-items: flex-end; gap: 4px; height: 56px; }
.vol-bar { flex: 1; height: calc(var(--h) * 1%); min-height: 2px; border-radius: 3px 3px 1px 1px; background: color-mix(in srgb, var(--accent) 55%, transparent); }
.vol-bar.now { background: var(--accent); }
.progress-card .card-body { gap: 16px; }

/* v2.18: wearables */
.wear-card { --wc: #2DD4BF; }
.wear-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.wear-table th, .wear-table td { text-align: right; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.wear-table th:first-child, .wear-table td:first-child { text-align: left; }
.wear-table th { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.btn-danger-outline { border-color: color-mix(in srgb, #ef4444 50%, var(--line)); color: #ef4444; }
.wear-today { border-left: 4px solid var(--accent); }
.wear-today.low { border-left-color: #f59e0b; }
.wear-today.high { border-left-color: #22c55e; }
.wear-row { display: flex; gap: 14px; align-items: flex-start; }
.wear-big { display: flex; align-items: baseline; gap: 2px; min-width: 64px; }
.wear-num { font-size: 34px; font-weight: 750; letter-spacing: -0.02em; line-height: 1; }
.wear-unit { font-size: 14px; font-weight: 600; color: var(--ink-3); }
.wear-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.wear-plan { color: var(--ink); }

/* privacy.html (v2.18) */
.privacy { max-width: 720px; margin: 0 auto; padding: 28px 20px 80px; line-height: 1.55; }
.privacy h1 { font-size: 26px; margin: 6px 0 4px; }
.privacy h2 { font-size: 16px; margin: 22px 0 6px; }
.privacy p { margin: 0 0 10px; color: var(--ink-2); }

/* ============================================================
   v2.19 — Coach access panel (the v2.17 block never shipped)
   ============================================================ */
.access-panel { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.access-panel > .settings-label { font-size: 16px; font-weight: 700; }
.access-panel > .settings-note { margin: -6px 0 2px; }
.access-group {
  display: flex; flex-direction: column;
  padding: 4px 12px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--line);
}
.access-group > .eyebrow { margin: 8px 0 2px; font-size: 11px; letter-spacing: 0.1em; color: var(--ink-3); }
.access-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 11px 0; margin: 0; border-bottom: 1px solid var(--line);
  font-size: 15px; cursor: pointer;
}
.access-row:last-child { border-bottom: 0; }
.access-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.access-label { display: block; font-weight: 650; line-height: 1.25; }
.access-sub { display: block; font-size: 12.5px; line-height: 1.35; color: var(--ink-3); }
.access-row .switch-input { width: 42px; height: 26px; flex: none; }
.access-row .switch-input::after { width: 20px; height: 20px; }
.access-row .switch-input:checked::after { transform: translateX(16px); }
.access-row.is-disabled { opacity: 0.5; cursor: default; }
.access-row.is-disabled .switch-input { cursor: default; }

/* v2.20: wearables page polish */
.wear-card .card-body { gap: 12px; }
.wear-brand { display: flex; align-items: center; gap: 10px; }
.wear-brand .card-title { margin: 0; font-size: 20px; letter-spacing: 0.02em; }
.status-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink-2); }
.status-pill.on { background: color-mix(in srgb, #2DD4BF 18%, transparent); color: #2DD4BF; }
.status-pill.on::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #2DD4BF; }
.wear-sync { margin: -4px 0 0; font-size: 13px; }
.wear-empty { padding: 14px; border-radius: var(--radius-sm); background: var(--surface-2); border: 1px dashed var(--line); }
.wear-empty-title { font-weight: 650; margin-bottom: 4px; }
.wear-foot { display: flex; justify-content: flex-end; padding-top: 6px; border-top: 1px solid var(--line); margin-top: 4px; }
.btn-link.danger { color: #ef4444; font-size: 13px; padding: 6px 0; }
.card .access-row { padding: 12px 0 14px; border-bottom: 0; }

/* v2.22: freshness */
.wear-today.stale { border-left-color: var(--ink-3); }
.wear-stale { color: #f59e0b; font-size: 13px; margin: -4px 0 0; }

/* v2.24: wearables page spacing */
.wear-stack { display: flex; flex-direction: column; gap: 14px; }
.wear-card .card-body { padding-right: 18px; }
.wear-brand { flex-wrap: wrap; row-gap: 6px; }
.wear-empty { margin-top: 2px; }
.wear-foot { margin-top: 8px; padding-top: 10px; }
.card .access-row { padding: 6px 0 10px; }

/* v2.25: workout groups read as groups; folded cards are a compact row */
/* v2.264: a group is a CONTAINER, not a rail. The children sit inside a distinct, slightly recessed surface with
   its own edge and radius; the header is the container's top bar rather than a floating pill; the group's colour
   is a swatch beside its name, so it no longer merges with the first card's own colour bar beside it. This is
   the grouped-list pattern (iOS grouped tables, Material sections): hierarchy is spatial — inside/outside — not
   inferred from a line. */
.group-block {
  margin: 20px 0 8px; padding: 0 12px 12px;
  background: color-mix(in srgb, var(--surface-2) 55%, var(--bg));
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.group-block:first-of-type { margin-top: 12px; }
.group-block.folded { padding-bottom: 0; }
.group-block .group-head-row { margin: 0 -12px 12px; }
.group-block .group-head {
  margin: 0; box-shadow: none; border: 0; border-bottom: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0;
  background: transparent; padding: 14px 12px 14px 16px;
}
.group-block .group-head::before {
  content: ''; width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto;
  background: var(--accent); margin-right: 2px;
}
.group-block .group-head > span:first-of-type { flex: 1 1 auto; text-align: left; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-block .group-head .lib-head-side { flex: 0 0 auto; }
.group-block.folded .group-head { border-bottom: 0; border-radius: var(--radius); }
.group-block.folded .group-head-row { margin-bottom: 0; }
/* the manage button sits in the same bar as the title: the bar is the ROW, so its divider runs under both */
.group-block .group-head-row { align-items: stretch; border-bottom: 1px solid var(--line); }
.group-block .group-head-row > .group-head { border-bottom: 0; }
.group-block .group-head-row > .icon-btn, .group-block .group-head-row > button:not(.group-head) { align-self: center; margin-right: 8px; }
.group-block.folded .group-head-row { border-bottom: 0; }
.group-block .lib-sec-inner { padding-left: 0; border-left: 0; margin-left: 0; }
.group-head + .lib-sec .lib-sec-inner { padding-left: 0; border-left: 0; margin-left: 0; }
/* v2.182 (review G1): an adjacent-sibling margin staggered the grid — in a desktop row the second and third cards
   sat 10 px below the first. The grid already has its own gap; extra breathing room in the single-column phone
   layout comes from a larger row-gap there, which cannot offset cards against each other. */
@media (max-width: 680px) { .workout-grid { row-gap: 24px; } }
.workout-card.folded .card-body { padding: 10px 12px 10px 16px; }
.workout-card.folded .card-top { align-items: center; gap: 8px; }
.workout-card.folded .card-head-text { display: flex; align-items: center; min-width: 0; }
.workout-card.folded .card-title { font-size: 16px; margin: 0; line-height: 1.2; }
.workout-card.folded .workout-card-actions { margin-left: auto; } /* v2.184: the group carries the auto margin now, not the first button inside it */

/* v2.26: in-page checkout */
.checkout-status { min-height: 22px; margin: 0; font-size: 14px; color: var(--ink-3); }
.checkout-gpay { min-height: 0; }
.checkout-gpay > * { width: 100%; }
.checkout-gpay:not(:empty) { margin-bottom: 10px; }
.checkout-paypal { min-height: 48px; }
.checkout-fallback { align-self: center; font-size: 13px; margin-top: 4px; }

/* v2.28: checkout polish — dark, even, no white strips */
.checkout-paypal, .checkout-gpay { background: transparent; }
.checkout-paypal iframe { border-radius: 10px; }
.checkout-gpay > button, .checkout-gpay .gpay-button { border-radius: 10px !important; height: 48px !important; min-height: 48px; }
.checkout-status:not(:empty) { padding: 8px 10px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line); color: var(--ink-2); line-height: 1.4; word-break: break-word; }

/* v2.29: PayPal's button iframes are transparent; Chrome paints white behind a
   light iframe embedded in a dark page. Declaring the container light removes
   the mismatch and the white strips. */
.checkout-paypal, .checkout-paypal iframe { color-scheme: light; background: transparent; }

/* multi-provider wearables */
.wear-provider-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.wear-provider .btn-link.danger { padding: 4px 0; }
.privacy h3 { font-size: 14px; margin: 16px 0 4px; color: var(--ink-2); }

/* wearables: in-testing notice */
.wear-notice { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); }
.wear-notice .card-body { gap: 6px; padding: 12px 14px; }
.wear-notice-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.wear-notice-badge { flex: none; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent); }
.wear-notice-title { font-weight: 650; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wear-notice-copy { margin: 0; font-size: 13px; line-height: 1.45; }
.wear-notice-link { color: var(--accent); font-weight: 600; text-decoration: none; white-space: nowrap; }

/* Google Health disclosure */
.disclosure-list { margin: 4px 0 8px 18px; padding: 0; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.disclosure-strong { color: var(--ink); font-weight: 600; }

/* skipped occurrences: visible, quiet */
.day-occ.is-skipped { opacity: 0.62; }
.day-occ.is-skipped .day-occ-name { text-decoration: line-through; text-decoration-color: var(--ink-3); }
.day-occ-status.skipped { color: var(--ink-3); }
.card.is-skipped { opacity: 0.7; }
.done-badge.skipped-badge { background: color-mix(in srgb, var(--ink) 10%, transparent); color: var(--ink-3); }

/* skipped: the fourth state on compact surfaces */
.cal-chip.skipped { color: var(--ink-3); opacity: 0.7; }
.cal-chip.skipped .chip-label, .cal-chip.skipped .chip-name { text-decoration: line-through; text-decoration-color: var(--ink-3); }
.cal-chip.skipped .chip-dot { opacity: 0.35; box-shadow: none; }
.wk-dot.skipped { background: transparent; border: 1.5px solid color-mix(in srgb, var(--ink-3) 70%, transparent); width: 6px; height: 6px; opacity: 0.55; }
.mini-cell.has.skipped { --wc: var(--ink-3); opacity: 0.6; }

/* plans */
.prog-card { text-align: left; width: 100%; cursor: pointer; font: inherit; color: inherit; }
.prog-card:active { transform: scale(0.995); }
.prog-card .card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.prog-chev { flex: none; margin-top: 4px; }
.prog-card .card-desc { margin: 0; }
.prog-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.prog-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; padding: 4px 10px 4px 8px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2); }
.prog-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--wc, var(--accent)); }
.prog-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin: 6px 0 8px; }
.prog-day { padding: 10px 0; border-radius: 10px; border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-3); font-weight: 650; font-size: 13px; }
.prog-day.on { background: color-mix(in srgb, var(--accent) 18%, transparent); border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--accent); }
.prog-entry { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.back-link { display: inline-flex; align-items: center; gap: 4px; margin-bottom: 6px; }
.icon.rot90 { transform: rotate(90deg); }
/* top of the header, centred on the title's first line (22px × 1.1 line-height against a 36px button), never shrunk by a long name */
.share-card-btn { align-self: flex-start; flex: none; margin-top: -6px; }

/* plan exercise rows open the guide */
.preview-link { display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%; padding: 0; background: none; border: 0; color: inherit; font: inherit; text-align: left; }
.preview-link .preview-name { text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--ink-3) 60%, transparent); text-underline-offset: 3px; }
.preview-link:active { opacity: 0.7; }

/* wearable provider cards */
.wear-provider .card-body { gap: 12px; }
.wear-provider-head { display: flex; align-items: center; gap: 14px; }
.wear-mark { flex: none; width: 48px; height: 48px; border-radius: 14px; background: var(--brand-bg); color: var(--brand); display: grid; place-items: center; overflow: hidden; border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); }
.wear-mark img { width: 72%; height: 72%; object-fit: contain; }
.wear-mark img + .wear-mono { display: none; }
.wear-mark img:not([src]) + .wear-mono { display: block; }
.wear-mono { font-weight: 800; font-size: 20px; letter-spacing: 0.02em; }
.wear-provider-text { min-width: 0; flex: 1; }
.wear-provider-name { display: flex; align-items: center; gap: 8px; font-size: 19px; font-weight: 700; line-height: 1.2; }
.wear-provider .card-meta { margin: 2px 0 0; }
.wear-notes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.wear-notes li { display: flex; gap: 8px; align-items: flex-start; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.wear-notes .icon { flex: none; width: 15px; height: 15px; margin-top: 2px; }
.wear-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.page-note { display: flex; gap: 8px; align-items: flex-start; margin: 12px var(--sp-2) 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-3); }
.page-note .icon { flex: none; width: 15px; height: 15px; margin-top: 2px; }
.wear-provider .fact .icon { color: var(--accent); }
.welcome-card { --wc: var(--accent); }

/* start here */
.start-here .card-body { gap: 10px; }
.start-option { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 12px 14px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border); color: inherit; font: inherit; }
.start-option.primary { border-color: color-mix(in srgb, var(--accent) 55%, var(--border)); background: color-mix(in srgb, var(--accent) 8%, var(--surface-2)); }
.start-option:active { transform: scale(0.99); }
.start-option-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.start-option-title { font-weight: 700; font-size: 15px; }
.start-option.primary .start-option-title { color: var(--accent); }
.start-option-sub { font-size: 13px; color: var(--ink-2); line-height: 1.4; }
.start-coach { margin: 2px 0 0; }
.start-coach .btn-link { display: inline; padding: 0; }
.start-coach .btn-link { color: var(--accent); font-weight: 600; }

/* welcome: secondary actions are buttons, not sentences */
/* v2.77: the secondary actions stay compact so "Get started" is the biggest thing on the card; they only stretch on narrow phones */
.welcome-alt { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 4px; }
.welcome-alt .btn { flex: 0 0 auto; justify-content: center; }
@media (max-width: 420px) { .welcome-alt .btn { flex: 1 1 auto; } }
.btn-quiet { background: transparent; border-color: var(--line); color: var(--ink-2); }
.icon.rot180 { transform: rotate(180deg); }

/* exercise guide */
.guide-facts { margin-bottom: 2px; }
.guide-facts .fact .icon { color: var(--accent); }
.guide-section { display: flex; flex-direction: column; gap: 6px; }
.guide-section h3 { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.guide-steps { margin: 0; padding: 0; list-style: none; counter-reset: step; display: flex; flex-direction: column; gap: 6px; }
.guide-steps li { counter-increment: step; display: flex; gap: 10px; align-items: flex-start; font-size: 14.5px; line-height: 1.5; color: var(--ink-2); }
.guide-steps li::before { content: counter(step); flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; font-weight: 700; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); margin-top: 1px; }
.guide-rep { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--accent) 8%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border)); font-size: 14px; line-height: 1.5; color: var(--ink); }
.guide-rep .icon { flex: none; color: var(--accent); margin-top: 2px; }
.guide-rep-label { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); margin-bottom: 2px; }
.guide-focus { padding: 8px 12px; border-left: 2px solid var(--line); font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.guide-focus-label { font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px; }

/* notifications */
.notif-part { display: contents; }
.notif-row { align-items: center; }
.notif-controls { display: flex; align-items: center; gap: 10px; flex: none; }
.notif-select { padding: 6px 28px 6px 10px; font-size: 13px; min-width: 0; background: var(--surface-2); color: var(--ink); border: 1px solid var(--border); border-radius: var(--radius-sm); appearance: none; -webkit-appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%), linear-gradient(135deg, var(--ink-3) 50%, transparent 50%); background-position: calc(100% - 14px) 55%, calc(100% - 9px) 55%; background-size: 5px 5px; background-repeat: no-repeat; }
.notif-time { background: var(--surface-2); color: var(--ink); border: 1px solid var(--border); border-radius: var(--radius-sm); color-scheme: dark; }
.notif-time { padding: 6px 8px; font-size: 13px; width: auto; }
.notif-controls > :disabled { opacity: 0.45; }
.notif-text { min-width: 0; flex: 1; }

/* v2.152/v2.157 — Coach "About you" card and the free first question */
.about-you { margin-bottom: var(--sp-3); }
.about-you-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.about-you-title { display: flex; align-items: baseline; gap: 4px; }
.about-you-optional { font-size: 12px; color: var(--ink-2); }
.about-you-summary { font-size: 15px; font-weight: 600; margin: var(--sp-1) 0; overflow-wrap: break-word; }
.about-you-form { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-2) 0; }
.about-you-field { display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto; align-items: center; column-gap: var(--sp-2); }
.about-you-label { font-size: 13px; color: var(--ink-2); }
.about-you-error { grid-column: 1 / -1; font-size: 12px; color: var(--danger); min-height: 0; }
.about-you-explain { margin: var(--sp-2) 0; }
.about-you-actions { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-2); }
.about-you-remove { margin-top: var(--sp-2); }
.coach-details-input { flex: 0 1 160px; min-height: 40px; max-width: 160px; text-align: right; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); color: var(--ink); font: inherit; }
select.coach-details-input { text-align: left; }
.coach-try-input { width: 100%; margin: var(--sp-2) 0; resize: none; min-height: 60px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2); color: var(--ink); font: inherit; line-height: 1.4; }
.card[data-coach-try] .chat-bubble { margin: var(--sp-2) 0; }
.coach-details-input.is-invalid { border-color: var(--danger); box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 25%, transparent); }


/* v2.158 — Plans sections and benchmark templates */
.plans-section { margin-top: var(--sp-4); }
.plans-section-sub { margin-top: -6px; margin-bottom: var(--sp-2); }
.bench-card .card-desc { margin-bottom: var(--sp-1); }
/* v2.166: the variation and option pickers are NOT the seven-column weekday grid — variations stack full width;
   short option choices wrap in a row; the block preview stacks its heading over its movements and wraps them */
.bench-variants { display: flex; flex-direction: column; gap: 8px; grid-template-columns: none; }
.bench-variants .prog-day { flex: 1 1 auto; width: 100%; text-align: left; height: auto; min-height: 44px; padding: 10px 12px; white-space: normal; line-height: 1.35; overflow-wrap: break-word; }
.bench-option .bench-variants { flex-direction: row; flex-wrap: wrap; }
.bench-option .bench-variants .prog-day { flex: 1 1 140px; width: auto; text-align: center; }
.bench-preview { margin: var(--sp-2) 0; }
.bench-preview li[data-block-kind] { flex-direction: column; align-items: stretch; gap: 4px; }
.bench-preview li[data-block-kind] .preview-name { font-weight: 600; }
.bench-preview .preview-sets { white-space: normal; overflow-wrap: break-word; line-height: 1.4; text-align: right; }
.bench-preview li[data-block-kind] .preview-sets { text-align: left; }
.runner-elapsed { font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; color: var(--accent); margin-top: 2px; }

/* v2.160 — the benchmark runner */
.bench-clock { font-size: 22px; letter-spacing: 0.02em; }
.bench-main { padding-bottom: var(--sp-4); }
.bench-block { display: flex; flex-direction: column; gap: var(--sp-2); }
.bench-score { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bench-total-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--sp-2); padding: var(--sp-2) 0; border-bottom: 1px solid var(--line); }
.bench-total-row.done { opacity: 0.6; }
.bench-total-name { font-weight: 600; }
.bench-total-count { font-variant-numeric: tabular-nums; font-weight: 700; }
.bench-total-btns { grid-column: 1 / -1; display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.bench-stations { width: 100%; max-width: 100%; border-collapse: collapse; font-size: 12px; font-variant-numeric: tabular-nums; table-layout: fixed; }
.bench-stations th, .bench-stations td { padding: 4px 6px; border-bottom: 1px solid var(--line); text-align: center; }
.bench-stations th:first-child, .bench-stations td:first-child { text-align: left; }
.bench-finish-row { margin-top: var(--sp-3); }
.bench-done .summary-rows { margin: var(--sp-3) 0; }
.bench-option { margin-top: var(--sp-2); }
.bench-banner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin: var(--sp-2) var(--sp-3); padding: 8px 12px; border-radius: 10px; background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--ink); font-size: 13px; }
.bench-cell { width: 56px; padding: 4px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface-2); color: var(--ink); font: inherit; text-align: center; }

/* v2.167 — Coach toolbar, Plans tabs, Settings folds */
.coach-toolbar { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-3); flex-wrap: wrap; }
.coach-toolbar .coach-balance { flex: 1 1 auto; margin: 0; }
.coach-toolbar .btn.has-info { border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--accent); }
.plans-tabs { margin: var(--sp-2) 0 var(--sp-3); }
.plans-tabs .seg-btn { flex: 1 1 0; }
.plans-panel { min-height: 120px; }
.plans-empty { padding: var(--sp-3) 0; }
.fold-head { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 0; margin: 0 0 var(--sp-2); border: 0; background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.fold-title { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.fold-chevron { transition: transform .15s ease; }
.card.folded .fold-chevron { transform: rotate(-90deg); }
.card.folded .fold-head { margin-bottom: 0; }
/* v2.178 (audit UI-01): SCOPED to Settings' own foldable cards. As `.card.folded` this also matched
   `.workout-card.folded` in the library — and, coming later in the file, it beat that card's own rule and hid
   `.card-top`, so a folded workout showed nothing at all and had no control to reopen it. `fold-card` is set by
   Settings' fold helper and by nothing else. */
.card.fold-card.folded > .card-body > :not(.section-title) { display: none; }
.section-title.foldable { margin: 0; }
.section-title.foldable .fold-head { margin: 0 0 var(--sp-2); }

/* v2.169 — summary rows with long labels never run into their value; the session's delete action */
.summary-row > span:first-child { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
/* v2.172 (audit A04): the value keeps its own width — it is a short score — and the long label wraps beside it.
   Letting the value shrink (flex: 0 1 auto) let "Time 35:45" and "180 reps + cals" run past the right edge. */
.summary-row > strong { flex: 0 0 auto; max-width: 60%; white-space: nowrap; margin-left: 12px; }
@media (max-width: 380px) { .summary-row:not(.stacked) { flex-wrap: wrap; } .summary-row:not(.stacked) > strong { margin-left: 0; } }
.summary-row.stacked { flex-direction: column; align-items: stretch; gap: 4px; }
.summary-row.stacked > strong { margin-left: 0; white-space: normal; overflow-wrap: break-word; font-weight: 600; line-height: 1.4; } /* v2.171 (R05): a prose value wraps under a full-width label */
.danger-zone { margin-top: var(--sp-4); }

/* v2.170 — reporting and the Terms agreement */
.report-reason { text-align: left; height: auto; padding: 10px 12px; white-space: normal; }
.report-reason.on { background: color-mix(in srgb, var(--accent) 16%, transparent); border-color: var(--accent); color: var(--accent); }
.signin-agree { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--ink-2); line-height: 1.4; padding: 2px 0; }
.signin-agree input { margin-top: 2px; flex: 0 0 auto; width: 18px; height: 18px; }
.chat-report { display: block; margin-top: 4px; font-size: 12px; color: var(--ink-3); }

/* v2.170 — UI audit fixes (UI-01, UI-04, UI-05, UI-07, UI-09) */
/* UI-01: on a phone the station grid becomes one row per station, with its round inputs beside it */
@media (max-width: 520px) {
  .bench-stations, .bench-stations thead, .bench-stations tbody, .bench-stations tfoot, .bench-stations tr, .bench-stations th, .bench-stations td { display: block; }
  .bench-stations thead { display: none; }
  .bench-stations tbody tr { display: grid; grid-template-columns: 44px repeat(2, minmax(0, 1fr)); gap: 6px 8px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line); }
  .bench-stations tbody td { border: 0; padding: 0; text-align: left; }
  .bench-stations tbody td:first-child { grid-column: 1; font-weight: 700; color: var(--ink-2); }
  .bench-stations tbody td::before { content: attr(data-station); display: block; font-size: 11px; color: var(--ink-3); margin-bottom: 2px; overflow-wrap: break-word; }
  .bench-stations tbody td:first-child::before { content: none; }
  .bench-stations tfoot tr { display: flex; justify-content: space-between; padding-top: 8px; font-weight: 700; }
  .bench-cell { width: 100%; }
}
/* UI-04: calendar content can shrink inside its tracks */
.week-day, .week-day-body, .month-day, .day-occ, .day-occ-main, .cal-chip { min-width: 0; }
.week-day .chip-name, .month-day .chip-name { min-width: 0; }
/* UI-05: a long name never pushes controls off a card or collides with them */
.card-head { align-items: flex-start; gap: 10px; }
.card-head-text { flex: 1 1 auto; min-width: 0; }
.card-title { overflow-wrap: break-word; }
.workout-card .card-title { overflow-wrap: break-word; }
.builder-head-main { min-width: 0; flex: 1 1 auto; }
.builder-head-main h1, .page-head h1 { overflow-wrap: break-word; hyphens: none; }
/* v2.176: a page heading is one or two whole words — it takes the width it needs and the buttons beside it wrap
   underneath on a narrow screen. Before this the heading was the item that shrank, giving "Workou / ts". */
.page-head.row-between { flex-wrap: wrap; row-gap: 10px; }
.page-head.row-between > :first-child { flex: 1 1 auto; min-width: 0; }
/* v2.179 (audit UI-02): `flex: 0 0 auto` let the group keep its intrinsic width, so at 320 px the Plans/Import/New
   row was ~341 px inside 288 px of usable space and New sat past the right edge — hidden by the page's own overflow
   clipping, which is why a zero-overflow measurement missed it. The group may now shrink and wrap into deliberate
   rows; the buttons keep their size and the heading keeps its own line. */
.page-head.row-between > .btn-row { flex: 0 1 auto; min-width: 0; max-width: 100%; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
@media (max-width: 430px) {
  .page-head.row-between > :first-child { flex: 1 1 100%; }
  .page-head.row-between > .btn-row { margin-left: 0; justify-content: flex-start; width: 100%; }
  .page-head.row-between > .btn-row > .btn { flex: 1 1 auto; }
  .page-head.row-between > .btn-row > .icon-btn { flex: 0 0 auto; }
}
.session-ex-name, .rec-ex-name { overflow-wrap: break-word; }
/* UI-07: on a phone the access description keeps the full width; the button drops to its own line */
@media (max-width: 560px) {
  .access-row { flex-wrap: wrap; }
  .access-row .access-text { flex: 1 1 100%; order: 1; }
  .access-row .switch-input { order: 2; }
  .access-row > .btn { order: 3; flex: 1 1 100%; margin-top: 8px; }
}
/* UI-09: the builder's exercise title wraps to two lines instead of being cut mid-word */
.ex-title h3 { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: break-word; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* v2.171 — UI retest fixes (R01, R05, R09, R10) */
/* R01: the whole card content path is bounded; long unspaced names wrap instead of widening the card */
.workout-card .card-body, .record-card .card-body, .session-card .card-body { min-width: 0; }
.card-title-btn { min-width: 0; overflow-wrap: break-word; }
.record-name, .record-headline, .record-row-name { overflow-wrap: break-word; min-width: 0; }
.record-row-name { white-space: normal; overflow: visible; text-overflow: clip; }
.record-head { min-width: 0; }
.prog-chip, .chip-name, .lineup-item { min-width: 0; overflow-wrap: break-word; }
.facts, .fact { min-width: 0; }
.fact > span { overflow-wrap: break-word; }
/* R09: four Plans tabs fit a 320 px screen */
.plans-tabs { flex-wrap: wrap; }
.plans-tabs .seg-btn { flex: 1 1 auto; min-width: 0; padding-left: 10px; padding-right: 10px; white-space: nowrap; } /* v2.176: never split a tab label */
@media (max-width: 420px) { .plans-tabs .seg-btn { flex: 1 1 40%; font-size: 13px; padding-left: 8px; padding-right: 8px; } } /* two tidy rows rather than four squeezed columns */
.del-alt { margin-top: var(--sp-2); gap: var(--sp-2); }

/* v2.172 — audit A02: the real lineup and History elements. v2.173 (audit B01): the grid keeps its meaningful minimum
   column width — the zero minimum I added here created twenty ~1 px tracks and collapsed every card to 2 px. Only the
   CONTENT of a card needs to be allowed to shrink, never the track. */
.workout-grid > * { min-width: 0; }
.card-lineup, .card-lineup * { min-width: 0; overflow-wrap: break-word; }
.card-lineup { white-space: normal; }
.history-name, .history-title, .history-row, .history-main { min-width: 0; overflow-wrap: break-word; }
/* v2.195: the chevron stays at the right and the text wraps inside its own column beneath itself. The v2.179
   `flex-wrap: wrap` let the whole row wrap instead, so a long meta line pushed the chevron onto a line of its own and
   the arrows no longer lined up down the list. The text column is the flexible part; the chevron never moves. */
.history-row { flex-wrap: nowrap; }
.history-row > .history-main { flex: 1 1 auto; min-width: 0; }
.history-row > .icon { flex: 0 0 auto; align-self: center; }
/* v2.174 (audit D04): a long action label wraps inside its button instead of spilling past the outline */
.btn.wrap-label { white-space: normal; height: auto; min-height: 44px; padding-top: 10px; padding-bottom: 10px; line-height: 1.3; overflow-wrap: break-word; }

/* v2.179 (audit UI-05): small orange labels failed contrast in the light theme — #F97316 is 2.80:1 on white and
   2.53:1 on the PR chip's own tint, both well under 4.5:1 for text this size. The light theme derives the TEXT from
   the same colour, darkened, so it works for every workout colour (worst case ~5.2:1) while the tint, border and the
   dark theme are untouched. */
/* v2.180 (review R3): the app toggles `theme-dark` only — there is no `theme-light` class, so the v2.179 rule never
   matched anything and the contrast fix did nothing at all. */
html:not(.theme-dark) .settings-value.warn { color: color-mix(in srgb, var(--wc) 55%, #000); }
html:not(.theme-dark) .pr-chip { color: color-mix(in srgb, var(--wc, var(--accent)) 55%, #000); }

/* v2.179 (audit UI-03) — long names people type.
   Two separate problems were conflated before. (a) A row sizes itself to its longest word, so a card GREW to fit a
   40-character name and spilled past the screen: the cure is `min-width: 0` on the flexible column, never a smaller
   font or hidden overflow. (b) A single word longer than the whole column has to break somewhere: these elements —
   and only these, all of them user-entered text — may break inside a word as a last resort. Ordinary wrapping at
   spaces happens first, so a spaced name never breaks mid-word. Fixed labels, headings, tabs and buttons keep
   `break-word` and are guarded by the test suite. */
.user-name,
.workout-card .card-title, .card-title-btn,
.history-name, .history-title,
.record-name, .record-row-name,
.session-ex-name, .ex-title h3,
/* R2: the exercise pickers and the workout chooser */
.picker-name, .choose-label,
.list-row-name, .list-row-main,
.chat-effect {
  overflow-wrap: anywhere; word-break: normal; min-width: 0;
}
/* the rows that hold them must be allowed to be narrower than the name */
.workout-card .card-top, .workout-card .card-top > :first-child,
.history-row, .history-main, .record-card .card-body, .record-head,
.ex-title, .list-row, .list-row-main, .chat-effect, .picker-row, .choose-item { min-width: 0; }
/* v2.181 (review C1): name the text column. `:first-child` was the colour dot on a workout choice, so the dot
   stretched to fill the row (about 39 px wide at 320 px, 109 px at 390 px) and every row's text began somewhere
   different. The dot keeps its 12 px circle; `.choose-main` and the picker's text column are the flexible parts. */
.picker-row > .picker-main, .picker-row > :first-child:not(.dot), .choose-main { min-width: 0; flex: 1 1 auto; }
.choose-item > .dot, .picker-row > .dot { flex: 0 0 12px; width: 12px; height: 12px; }
.picker-row > .btn, .picker-row > .icon-btn, .choose-item > .btn, .choose-item > .icon-btn { flex: 0 0 auto; }
.list-row > :first-child { min-width: 0; flex: 1 1 auto; }
.card-top > .card-head-text { min-width: 0; flex: 1 1 auto; }
/* and the controls beside them keep their own space */
/* v2.180 (review R1): name the CONTROLS that must keep their size, rather than everything that is not one known
   wrapper class. Today and the shared-workout preview put the title in a plain <div>, which this rule made rigid:
   the title clipped at the card edge and the Done badge was pushed out of sight. The first child of a card header is
   the text column wherever it appears, and it may always shrink. */
.card-top > :first-child { min-width: 0; flex: 1 1 auto; }
.card-top > .btn, .card-top > .icon-btn, .card-top > .done-badge, .card-top > .chip,
.card-top > .row-actions, .card-top > .card-actions,
.record-head > .pin-btn, .list-row > .btn, .list-row > .icon-btn { flex: 0 0 auto; }

/* v2.180 (review P1): a workout name gets a generous first row on a phone. At 320 px three header controls left the
   title about 160 px, so an ordinary spaced name ran to four or five lines. The title now spans the row and the
   controls sit beneath it, right-aligned — the same controls, the same sizes, nothing hidden. */
/* v2.181 (review P1): the card reacts to ITS OWN width, not the window's — a viewport rule missed a 305 px card in a
   1440 px grid, where an ordinary name still took four lines. The actions sit in the card's top-right corner and the
   name gets the full width: same controls, same sizes, nothing hidden. The editor header follows the same principle,
   where a 58-character name had about 109 px and ran to seven lines. */
.workout-card, .ex-card { container-type: inline-size; }
@container (max-width: 430px) {
  /* the exercise editor keeps this treatment; the workout card is title-first, below */
  /* Stage 1: re-evaluated for the folding header. v2.181 put the title AFTER the controls, which on a folded card
     leaves a blank strip above the name — the arrangement the design brief rules out. The name leads, the controls
     sit with it, and the title wraps within its own column instead of pushing them anywhere. */
  /* R08: a scoped GRID, not flex. The summary is a genuine second row at every width, and the name track is
     flexible with a fixed action column — so a name can never be squeezed to a one-character column and rendered
     as a vertical strip of letters, which is what `flex-basis: 100%` inside a non-wrapping flex parent produced. */
  .ex-card .ex-head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: 'label name actions' 'summary summary summary';
    align-items: center; column-gap: 6px; row-gap: 4px;
  }
  .ex-card .ex-head > .ss-member-label { grid-area: label; }
  .ex-card .ex-head > .ex-title { grid-area: name; min-width: 0; }
  .ex-card .ex-head > .ex-actions { grid-area: actions; }
  .ex-card .ex-head > .ex-summary { grid-area: summary; }
  /* a genuinely narrow card gives the action block its own row rather than starving the name */
  /* C01: the narrow layout now lives after the global header grid below, so it is not overridden. */
}
/* v2.184: title first. The name and the three controls share one centred row; the controls are one group, so when a
   long name leaves no room they wrap together BENEATH it rather than sitting above it or splitting up. The v2.181
   corner layout left an empty controls row above every name and made a collapsed card a tall empty box. */
.workout-card .card-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.workout-card .card-top > .card-head-text { display: contents; }
/* the wrap decision uses the title's MINIMUM width, not its full text width: an ordinary name therefore shares the
   row and wraps to a second line if it must, while a name whose longest word cannot fit beside the controls pushes
   the whole group below — which is the intended rule */
.workout-card .card-top .card-title { flex: 1 1 min-content; min-width: 0; max-width: 100%; order: 0; margin: 0; }
.workout-card .card-top .facts { flex: 1 1 100%; min-width: 0; order: 1; }
.workout-card-actions { display: flex; flex: 0 0 auto; align-items: center; gap: 2px; margin-left: auto; order: 0; }
.workout-card .workout-card-actions > .icon-btn, .workout-card .workout-card-actions > .drag-handle { flex: 0 0 auto; margin-left: 0; }
/* the editor's name was a single ellipsised line, so it could never use the width it was given */
.ex-title h3 { white-space: normal; overflow: visible; text-overflow: clip; }
/* v2.181 (review P2): the analytics consent prompt. Its two buttons kept their width and left the explanation about
   97 px wide at 320 px. On a narrow screen the text takes the full width and the two existing actions sit in a row
   beneath it. `.welcome-card .card-body > .row-between` — the v2.180 attempt — matched nothing: the prompt is
   `.nudge > .nudge-main` plus two buttons. Scoped to this prompt; other nudges are untouched. */
@media (max-width: 560px) {
  .consent-nudge { flex-wrap: wrap; row-gap: 10px; }
  .consent-nudge > .nudge-main { flex: 1 1 100%; min-width: 0; }
  .consent-nudge > .btn { flex: 1 1 auto; }
}

/* v2.183 (review 1): the Start actions in a desktop row started at different heights because each card's content
   column was only as tall as its own text. Grid items already stretch to the row's height, so the card and its body
   fill that height and the flexible space above the action pushes every Start to the same baseline. Card
   dimensions, text and the phone layout are unchanged. */
.workout-grid > .workout-card:not(.folded) { display: flex; }
.workout-grid > .workout-card:not(.folded) > .card-body { display: flex; flex-direction: column; flex: 1 1 auto; }
.workout-grid > .workout-card:not(.folded) > .card-body > .card-foot { margin-top: auto; }
.workout-grid > .workout-card.folded { align-self: start; } /* v2.184: a folded card stays compact beside an expanded one */

/* v2.183 (review 2): a long action label wraps at word boundaries and the button grows with it. `.btn` is nowrap by
   design, so this is opt-in on the two long Coach actions only — everything else keeps its single line. */
.btn.btn-wrap { white-space: normal; height: auto; min-height: 44px; padding-top: 10px; padding-bottom: 10px; line-height: 1.3; overflow-wrap: break-word; }

/* UX-02: the Calendar's Add session action. It takes its own row on a phone so the period controls keep their space,
   and never floats over the calendar. */
.cal-head { flex-wrap: wrap; row-gap: 8px; }
.cal-head > .cal-add { flex: 0 0 auto; margin-left: auto; }
@media (max-width: 560px) {
  .cal-head > .cal-add { flex: 1 1 100%; margin-left: 0; order: 3; }
  .cal-head > .segmented { order: 4; }
}

/* UX-03: the catalogue entry. Two lines of text inside one full-width control; the text column may shrink so a long
   translation wraps rather than pushing the icon out. */
.browse-entry { display: flex; align-items: center; gap: 10px; text-align: left; justify-content: flex-start; height: auto; min-height: 56px; padding-top: 10px; padding-bottom: 10px; }
.browse-entry > .ic { flex: 0 0 auto; }
.browse-entry-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.browse-entry-title { font-weight: 700; }
.browse-entry-sub { font-size: 13px; font-weight: 500; color: var(--ink-3); white-space: normal; }

/* UX-07: the per-turn cost. Subdued, beneath the answer, never competing with it. */
.chat-cost { margin-top: 4px; font-size: 12.5px; font-weight: 500; color: var(--ink-3); }

/* UX-08: searching the saved library. Matches are revealed by HIDING the rest — never by removing them, because the
   reorder code reads the cards in the DOM. Reordering is disabled outright while a query is active. */
.lib-search { margin: 10px 0 4px; }
.lib-search-row { display: flex; align-items: center; gap: 8px; }
.lib-search-row > .input { flex: 1 1 auto; min-width: 0; }
.lib-search-row > .lib-search-clear { flex: 0 0 auto; }
.lib-search-count { margin-top: 6px; font-size: 12.5px; font-weight: 500; color: var(--ink-3); min-height: 16px; }
.workout-grid > .workout-card.filtered-out, .activity-card.filtered-out, .group-block.filtered-out { display: none; }
.lib-search-reorder { font-size: 12.5px; color: var(--ink-3); margin-top: 4px; }
/* a collapsed group opens just far enough to show its matches; the saved fold preference is untouched */
.group-block.folded.search-open > .lib-sec, .group-block.folded.search-open .lib-sec { grid-template-rows: 1fr; }
.lib-filtering .drag-handle, .lib-filtering .fold-all-btn { opacity: 0.4; pointer-events: none; }
.lib-no-match { margin-top: 10px; }

/* UX-09: installation steps. Numbered, wrapping naturally, no fixed heights. */
.install-steps { margin: 6px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; }
.install-steps > li { font-size: 14.5px; line-height: 1.45; color: var(--ink-2); }

/* QA-01: at large text sizes a segmented control's buttons ran past the screen edge. The control wraps its options
   onto a second row instead — the same options, at the same size, none of them pushed out of reach. */
.segmented { flex-wrap: wrap; max-width: 100%; }
.segmented > .seg-btn { min-width: 0; }

/* Audit: preserve ordinary sizing; let enlarged or long content use additional lines. */
.browse-entry { white-space: normal; }
.browse-entry-title { overflow-wrap: break-word; }
.group-head-row > .lib-head { min-width: 0; }
.group-head-row .lib-head > span:first-child { min-width: 0; overflow-wrap: break-word; }
.group-head-row > .group-manage, .lib-head-side { flex-shrink: 0; }
.bench-card .fact { white-space: normal; min-width: 0; max-width: 100%; }
.bench-card .fact > span { min-width: 0; overflow-wrap: break-word; }
.bench-card .fact > .ic { flex-shrink: 0; }
.fold-card[data-section="data"] .btn-danger-ghost { white-space: normal; height: auto; min-height: 44px; }
.month-wd-short { display: none; }
@media (max-width: 430px) {
  .month-wd-long { display: none; }
  .month-wd-short { display: inline; }
  .month-wd { letter-spacing: 0; }
  .month-cell { padding-left: 2px; padding-right: 2px; }
}
.cell-num { width: max-content; min-width: 22px; height: auto; min-height: 22px; line-height: 1.2; padding: 2px; max-width: 100%; box-sizing: border-box; align-self: flex-start; }
.fold-heading { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fold-summary { font-size: 12.5px; font-weight: 500; color: var(--ink-3); line-height: 1.4; text-transform: none; letter-spacing: normal; overflow-wrap: break-word; }
.fold-card:not(.folded) .fold-summary { display: none; }

/* v2.207: the completion summary's labels shared no left edge. `.runner-main` centres its text, and each row's label
   inherits that centring inside a box whose width varies with its own value — so "Duration", "Exercises" and
   "Sets completed" each started somewhere different (measured 143.4 / 153.7 / 121.0 px at 390 px wide). The override
   is scoped to the summary rows: the celebratory heading above them stays centred, and no other runner screen or
   `.summary-row` elsewhere is touched. */
.done-main > .summary-rows > .summary-row { text-align: start; }
.done-main > .summary-rows > .summary-row > strong { text-align: end; }

/* v2.207: the Workouts header. Scoped to this screen's toolbar — the generic `.page-head.row-between > .btn-row > .btn`
   rule that makes every toolbar button flexible is left alone for every other screen. */
.page-head.row-between > .btn-row.wk-toolbar { gap: 8px; }
.wk-toolbar > .fold-all-btn {
  flex: 0 0 48px; width: 48px; height: 48px; min-height: 48px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.wk-toolbar > .btn { min-height: 48px; }
@media (max-width: 430px) { .wk-toolbar > .btn { flex: 1 1 auto; } }

/* the header's vertical rhythm, controlled as a whole rather than one declared margin at a time */
.view-inner > .page-head + .browse-entry { margin-top: 16px; }
.browse-entry + .lib-search { margin-top: 12px; margin-bottom: 0; }
/* R3: an ungrouped grid is always appended, even when every workout is in a group — so an EMPTY grid sat between the
   search area and the first real section, and its spacing added to the next section's. An empty grid takes no space
   at all, and the gap is applied to whichever section is actually first. */
.view-inner > .workout-grid:empty { display: none; }
.lib-search + .workout-grid, .lib-search + .group-block, .lib-search + .section-title,
.lib-search + .workout-grid:empty + .group-block,
.lib-search + .workout-grid:empty + .section-title { margin-top: 16px; }
.view-inner > .workout-grid:empty + .group-block, .view-inner > .workout-grid:empty + .section-title { margin-top: 16px; }
/* an empty status reserves no height: it stays mounted and polite, and takes its space only when it speaks */
.lib-search-count:empty { min-height: 0; margin-top: 0; }
.lib-search-count:not(:empty) { margin-top: 6px; }

/* R4: when a summary value wraps onto its own line, `text-align: end` inside an intrinsically sized <strong> does
   nothing — the box itself is only as wide as its text and sits at the line's start. Giving the wrapped value the
   full remaining width puts its trailing edge on the row's content edge, where the unwrapped values are. Scoped to
   the completion summary; stacked prose rows and the other runner screens keep their own behaviour. */
.done-main > .summary-rows > .summary-row:not(.stacked) { flex-wrap: wrap; }
.done-main > .summary-rows > .summary-row:not(.stacked) > strong { flex: 1 1 auto; min-width: 0; margin-left: auto; }

/* R6: a session header's action moves to its own row when the title and date cannot sit beside it comfortably.
   Scoped to the History session header — every other builder header keeps its single-row layout. */
/* v2.211 (section 3): the History session header. Back and the title/date stay together on the first row; Share card
   takes its own full-width row below, on the same gutter as the cards. The 16px separation is a ROW GAP, and the
   inherited -6px top margin is reset inside this header only so it cannot eat into it. Scoped to `.session-head`:
   `.builder-head`, `.page-head`, `.icon-btn` and `.share-card-btn` are unchanged for every other screen. */
.builder-head.session-head { flex-wrap: wrap; row-gap: 16px; column-gap: 12px; align-items: start; }
.builder-head.session-head > .builder-head-main { flex: 1 1 auto; min-width: 0; }
.builder-head.session-head > .icon-btn { flex: 0 0 44px; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.builder-head.session-head > .share-card-btn { margin-top: 0; }   /* the gap does this job now */
.builder-head.session-head > .btn, .builder-head.session-head > .btn-row { flex: 0 0 auto; }
@media (max-width: 430px) {
  /* a two-column first row is reliable regardless of how long the title or date runs */
  .builder-head.session-head { display: grid; grid-template-columns: 44px minmax(0, 1fr); }
  .builder-head.session-head > .btn, .builder-head.session-head > .btn-row,
  .builder-head.session-head > .share-card-btn { grid-column: 1 / -1; width: 100%; box-sizing: border-box; }
}

/* The search field offers one clear control: REPPIN's labelled button. Chromium also draws a native cancel glyph
   inside a type="search" input, so two appeared at once. Scoped to this field; search semantics are unchanged. */
#lib-search::-webkit-search-cancel-button, #lib-search::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

/* R3 (active search): a section showing nothing takes no space at all; the gap below the search area is applied once,
   to whichever section is actually first — an ungrouped grid, a group, the Classes heading or the no-results card.
   B (v2.210): the adjacent-sibling override that used to follow this line also changed the gap AFTER the first
   section, tightening grid-to-group from 16px and group-to-group from 24px. The established type-specific gaps are
   left alone; only the first visible section's own top margin is set here. */
.view-inner > .lib-section-empty { display: none; }
.view-inner > .lib-section-first { margin-top: 16px; }

/* A (v2.210): the completion panel is a centred flex column, so `.compare-host` sized itself around its grid instead
   of the width available — with an auto-fit grid inside, that collapsed the tiles to a single narrow column even at
   ordinary text on a desktop. The host takes the content width it already had; the grid's own responsive behaviour,
   padding, borders, type and colours are unchanged. */
.done-main > .compare-host { width: 100%; min-width: 0; align-self: stretch; }

/* Section 4: the catalogue header's Back control. Scoped to this header so no other page-head changes. */
.page-head.catalogue-head { display: flex; align-items: start; gap: 12px; }
.page-head.catalogue-head > .icon-btn { flex: 0 0 44px; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.page-head.catalogue-head > .catalogue-head-main { flex: 1 1 auto; min-width: 0; }

/* Stage 1 (supersets brief §2): folding and Organise in the workout editor. Component-scoped — no global `.card`,
   `.page-head`, `.ex-head` or button overrides, and the Workouts library cards are untouched. */
.ex-list-bar { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin: 4px 0 2px; flex-wrap: wrap; }
.ex-list-bar > .btn { min-height: 44px; }
.ex-summary { font-size: 12.5px; font-weight: 500; color: var(--ink-3); margin-top: 2px; display: none; flex: 1 1 100%; }
.ex-card.folded .ex-summary, .ex-list.organising .ex-summary { display: block; }
.ex-card .ex-title { flex-wrap: wrap; }
.ex-card.folded > :not(.ex-head) { display: none; }
.ex-card.folded .ex-fold-chev { transform: rotate(-90deg); }
.ex-fold-chev { transition: transform 0.15s var(--ease-out); }
.ex-head > .ex-fold-btn, .ex-head > .icon-btn { flex: 0 0 44px; width: 44px; height: 44px; }
/* Organise: a compact ordered list with the drag handles revealed; the saved fold state is not changed */
.ex-list.organising .ex-card > :not(.ex-head) { display: none; }
.ex-list.organising .ex-summary { display: block; }
.ex-list.organising .drag-handle { display: inline-flex; }
.ex-list.organising .ex-fold-btn { display: none; }
@media (prefers-reduced-motion: reduce) { .ex-fold-chev { transition: none; } }

/* Supersets brief §3 and §8: the group's appearance in the editor. One restrained boundary and a labelled header —
   no nested large cards, no second colour scheme. Component-scoped to `.ss-*`; the member cards are the ordinary
   `.ex-card` with a small stable label column added. */
.ss-group { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px; display: flex; flex-direction: column; gap: 8px; background: var(--surface-2, transparent); }
.ss-head { display: flex; align-items: center; gap: 8px; }
.ss-head-main { flex: 1 1 auto; min-width: 0; }
.ss-head > .icon-btn { flex: 0 0 44px; width: 44px; height: 44px; }
.ss-title { font-size: 14.5px; font-weight: 700; }
.ss-summary { font-size: 12.5px; font-weight: 500; color: var(--ink-3); margin-top: 2px; }
.ss-note { font-size: 12.5px; font-weight: 500; color: var(--ink-3); margin: 0; }
/* the member label is a stable leading column, not another control: it must not be swept to the end by the
   editor header's ordering rule */
.ss-member-label { flex: 0 0 26px; order: -1; font-size: 12.5px; font-weight: 700; color: var(--ink-3); align-self: flex-start; padding-top: 2px; }
.ss-group > .ex-card { border-left: 2px solid var(--line); }

/* R06/R08/R09: the editor card header's four parts. Component-scoped; no global card, button or page-head rule. */
.ex-actions { display: inline-flex; align-items: center; gap: 4px; }
.ex-actions > .icon-btn { flex: 0 0 44px; width: 44px; height: 44px; }
/* the summary gets the whole card width when folded, rather than competing with the title */
.ex-card .ex-title { flex-wrap: wrap; }
.ex-card .ex-head > .ex-summary { order: 2; flex: 1 1 100%; }
/* R09: reorder handles belong to Organise, not to every card all of the time */
.ex-card .drag-handle { display: none; }
.ex-list.organising .ex-card .drag-handle { display: inline-flex; flex: 0 0 44px; width: 44px; height: 44px; }
.ex-list.organising .ex-actions { display: none; }
/* a group is ONE restrained boundary: its members lose their own card frame inside it */
.ss-group > .ex-card { border: 0; border-left: 2px solid var(--line); border-radius: 0; padding-left: 10px; background: transparent; box-shadow: none; }
.ss-group.folded > .ex-card { display: none; }
.ss-fold-btn { flex: 0 0 44px; width: 44px; height: 44px; }

/* R08: the same grid outside the narrow container query, so a wide card behaves identically. */
.ex-card .ex-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: 'label name actions' 'summary summary summary';
  align-items: center; column-gap: 6px; row-gap: 4px;
}
.ex-card .ex-head > .ss-member-label { grid-area: label; align-self: center; padding-top: 0; }
.ex-card .ex-head > .ex-title { grid-area: name; min-width: 0; }
.ex-card .ex-head > .ex-actions { grid-area: actions; margin-left: 0; }
.ex-card .ex-head > .ex-summary { grid-area: summary; }
/* R09: a collapsed group still names its members */
.ss-members { font-size: 12.5px; font-weight: 500; color: var(--ink-3); margin-top: 2px; display: none; }
.ss-group.folded .ss-members, .ex-list.organising .ss-members { display: block; }
/* R11: the frozen superset context, in the established subdued type — no new panel */
.runner-ss { font-size: 13px; font-weight: 600; color: var(--ink-3); margin: 2px 0 0; }
/* R11: the frozen pairing on a saved session, in the established subdued type */
/* R11: a 60-character unspaced name must wrap, not be clipped. The block shrinks and breaks only where it must. */
.session-ss { font-size: 13px; font-weight: 600; color: var(--ink-3); margin: 0 0 8px; min-width: 0; white-space: normal; overflow-wrap: anywhere; word-break: normal; }
.runner-ss { min-width: 0; white-space: normal; overflow-wrap: anywhere; }

/* R06: reorder handles belong to Organise. A grouped member has none — the pair moves as a unit and A1/A2 order is
   changed with Swap order. A collapsed group keeps its controls so it can still be moved. */
.ss-group .ex-card .drag-handle { display: none !important; }
.ss-drag { display: none; }
.ex-list.organising .ss-drag { display: inline-flex; flex: 0 0 44px; width: 44px; height: 44px; }
.ex-list.organising .ss-group > .ss-head .ex-actions { display: inline-flex; }
.ss-group.folded > .ss-head { display: flex; }

/* R11: a user-entered exercise name inside prose wraps naturally, and breaks only where it must. Scoped to the
   name span so headings, buttons and the surrounding sentence keep their own typography. */
.runner-next, .runner-prev { min-width: 0; white-space: normal; }
.runner-next-name { overflow-wrap: anywhere; word-break: normal; }

/* C01: the intended narrow layout, placed AFTER the global header grid so it actually takes effect. Short names
   already fit at this width — this only gives the action block its own row so it never starves the name. */
@media (max-width: 360px) {
  .ex-card .ex-head {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: 'label name' 'actions actions' 'summary summary';
  }
  .ex-card .ex-head > .ex-actions { justify-self: end; }
}
/* R11: the pre-run superset line, in the established subdued type */
.wv-ss { font-size: 13px; font-weight: 600; color: var(--ink-3); margin: 4px 0 0; min-width: 0; overflow-wrap: anywhere; }

/* Stage 3 (brief §4): the drop-chain draft editor. Component-scoped; the ordinary set sheet is untouched. */
.drop-list { gap: 8px; }
.drop-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.drop-row:last-child { border-bottom: 0; }
.drop-row-label { flex: 0 0 64px; font-size: 13px; font-weight: 700; color: var(--ink-3); padding-top: 8px; }
.drop-row-body { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.drop-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.drop-weight, .drop-reps { width: 84px; min-width: 0; }
.drop-unit { font-size: 13px; color: var(--ink-3); }
.drop-main .drop-row-body, .drop-rest .drop-row-body { font-size: 13.5px; color: var(--ink-2); }
.drop-error { display: none; font-size: 13px; font-weight: 600; color: var(--danger, #e5484d); margin: 4px 0 0; }
.drop-error.shown { display: block; }
/* Stage 3: the runner's drop-segment line, in the established subdued type */
.runner-drop { font-size: 13px; font-weight: 600; color: var(--ink-3); margin: 2px 0 0; min-width: 0; overflow-wrap: anywhere; }
/* Stage 3: a drop segment sits beneath its parent set, clearly subordinate to it */
.session-drop { padding-left: 16px; }
.session-drop .set-n { color: var(--ink-3); font-size: 12.5px; }

/* A12: the drop chain shown before starting, beneath its parent set line */
.wv-set-drops { grid-column: 1 / -1; font-size: 12.5px; font-weight: 500; color: var(--ink-3); padding-left: 16px; min-width: 0; overflow-wrap: anywhere; }

/* Share progress sheet (spec §1). The card image is shown at its own aspect; controls sit beneath it. */
.share-stage { display: flex; justify-content: center; align-items: center; background: transparent; min-height: 120px; overflow: hidden; }
.share-img { width: 100%; max-width: 460px; height: auto; display: block; }
.share-img[hidden] { display: none; }
.share-customise { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.share-customise[open] > summary { margin-bottom: 4px; }
.share-customise-note { margin: 0 0 14px; }
.share-customise .progress-control + .progress-control { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.progress-records-row { gap: 12px; }
.progress-records-row .settings-note { margin: 0; }
.share-customise > summary { font-size: 14px; font-weight: 700; cursor: pointer; min-height: 32px; display: flex; align-items: center; }
.progress-share-sheet .sheet-body { gap: 14px; }
.progress-control { display: flex; flex-direction: column; gap: 6px; }
.progress-choices { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.progress-control .progress-choices > .btn { flex: 1 1 0; }
.progress-control select { width: 100%; min-height: 44px; }
.progress-style-hint { margin: 0; }
.progress-record-choice { white-space: normal; overflow-wrap: break-word; text-align: left; justify-content: flex-start; }
.progress-share-sheet .dlg-actions { position: sticky; bottom: calc(-20px - env(safe-area-inset-bottom, 0px)); margin-bottom: calc(-20px - env(safe-area-inset-bottom, 0px)); background: var(--surface); padding-top: 12px; padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); z-index: 1; }
.progress-share-sheet .dlg-actions > .btn-row { width: 100%; }
.progress-share-sheet .btn[hidden] { display: none; }

/* v2.264: records carry a sparkline and their originating workout's colour (--wc); month separators and a filter
   keep a long history readable */
/* the value carries the workout colour in a TEXT variant: darkened on the light theme so yellow, teal and orange
   clear 4.5:1 on the light record surface; the colour itself on dark, where it already does */
.record-row { --wc: var(--accent); --wc-text: color-mix(in srgb, var(--wc) 48%, #111); }
/* the app selects dark mode with the `theme-dark` class on <html>, not a data attribute; on the dark record surface the
   colour is LIGHTENED (70/30 with white) so brown, indigo and purple clear 4.5:1 — raw brown is 3.2:1 there */
html.theme-dark .record-row { --wc-text: color-mix(in srgb, var(--wc) 70%, #fff); }
.record-row-value { color: var(--wc-text); }
.record-spark { grid-area: spark; width: 88px; height: 28px; overflow: visible; }
.record-spark path { fill: none; stroke: var(--wc); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: 0.9; }
.record-spark circle { fill: var(--wc); }
.history-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 18px 0 6px; }
.history-filter { width: auto; min-width: 160px; padding: 8px 12px; font-size: 14px; }
.history-list { margin-top: 4px; }
.history-month { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); margin: 14px 0 2px; padding-left: 2px; }
.history-month:first-child { margin-top: 4px; }

/* v2.276: custom exercise descriptions */
.desc-field { margin-top: 6px; }
.exercise-desc { min-height: 96px; resize: vertical; white-space: pre-wrap; }
.desc-counter { text-align: right; margin-top: 4px; }
.desc-counter.over { color: var(--danger, #e5484d); font-weight: 600; }
.custom-description { white-space: pre-line; }
