:root {
  --ink: #17221e;
  --muted: #5a6761;
  --soft: #8b9691;
  --paper: #f7f5ef;
  --surface: #ffffff;
  --surface-2: #f0eee7;
  --line: #dedfd8;
  --green: #173f35;
  --green-2: #235849;
  --mint: #dcebe4;
  --mint-2: #edf5f0;
  --orange: #e86f3d;
  --orange-dark: #b94e25;
  --orange-soft: #fff0e8;
  /* CON-026b: the timed-format clock. Work is a clear green (white text
     5.02:1), rest a calm dark neutral (white text 12.58:1), never the brand
     green, so the two never look alike. */
  --timer-work: #15803d;
  --timer-rest: #2f3438;
  --timer-ink-soft: #e4e7ea;
  --warning: #8f4b1f;
  --warning-soft: #fff2df;
  --danger: #8d3028;
  --danger-soft: #fff0ed;
  /* ADM-012: the admin console's mark. Amber with dark ink (9.3:1), used for
     the ADMIN pill and the admin nav's top border and nothing else, so the
     console is recognizable at a glance while every painted primary stays
     orange. */
  --admin: #f2b33d;
  --admin-ink: #1f1a10;
  --shadow-sm: 0 1px 2px rgba(23, 34, 30, 0.06), 0 8px 24px rgba(23, 34, 30, 0.05);
  --shadow-lg: 0 18px 60px rgba(23, 34, 30, 0.11);
  --radius-sm: 12px;
  --radius: 20px;
  --radius-lg: 28px;
  --content: 980px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Helvetica, Arial, sans-serif;
}
/* CON-026b: the clock's two colors in a dark setting (white text 7.13:1 on
   work, 10.49:1 on rest). The rest of the page has no dark theme yet. */
@media (prefers-color-scheme: dark) {
  :root {
    --timer-work: #166534;
    --timer-rest: #3a4046;
    /* ADM-012: a slightly deeper amber, dark ink still 7.6:1. */
    --admin: #e0a02c;
    --admin-ink: #1f1a10;
  }
}

* { box-sizing: border-box; }
html { background: var(--paper); color: var(--ink); font-family: var(--font); line-height: 1.5; text-rendering: optimizeLegibility; }
body { margin: 0; min-height: 100vh; background: var(--paper); }
button, input, select, textarea { color: inherit; font: inherit; }
/* D-216 (owner, 2026-10-06): every visible radio is the app's green, never
   the browser's default blue. A rule below that names its own green wins. */
input[type="radio"],
input[type="checkbox"] { accent-color: var(--green); }
button, a, input, select, textarea { -webkit-tap-highlight-color: transparent; }
a { color: inherit; }
img { display: block; max-width: 100%; }
h1, h2, h3, p { margin-top: 0; }
h1 { margin-bottom: 12px; font-size: clamp(2rem, 6vw, 3.6rem); font-weight: 690; letter-spacing: -0.045em; line-height: 1.02; text-wrap: balance; }
h2 { margin-bottom: 8px; font-size: clamp(1.4rem, 4vw, 2rem); font-weight: 680; letter-spacing: -0.025em; line-height: 1.15; text-wrap: balance; }
h3 { margin-bottom: 6px; font-size: 1rem; }
p { margin-bottom: 0; }

.skip-link { position: fixed; z-index: 100; top: 8px; left: 8px; padding: 10px 14px; transform: translateY(-150%); border-radius: 8px; background: var(--ink); color: white; }
.skip-link:focus { transform: translateY(0); }

.topbar { position: sticky; z-index: 20; top: 0; display: flex; align-items: center; justify-content: space-between; min-height: calc(68px + env(safe-area-inset-top)); padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left)); border-bottom: 1px solid rgba(222, 223, 216, 0.8); background: rgba(247, 245, 239, 0.94); backdrop-filter: blur(18px); }
.prescribed-card .conditioning-start-form { margin-top: 14px; }
.prescribed-card > .text-link:last-child { margin-bottom: 0; }
.back-arrow { display: inline-flex; flex: none; width: 36px; height: 44px; align-items: center; justify-content: center; margin-left: -10px; color: var(--ink); text-decoration: none; }
.back-arrow svg { width: 0.78em; height: 0.78em; }
.brand { display: inline-flex; min-height: 44px; align-items: center; gap: 10px; color: var(--ink); font-size: 1.05rem; font-weight: 720; letter-spacing: -0.025em; text-decoration: none; }
.brand--large { font-size: 1.15rem; }
.brand-mark { display: block; width: 34px; height: 34px; flex: none; }
.brand--large .brand-mark { width: 40px; height: 40px; }
.profile-chip { display: grid; flex: none; width: 36px; height: 36px; overflow: hidden; place-items: center; border: 1px solid var(--line); border-radius: 50%; background: var(--surface); color: var(--green); font-weight: 750; text-decoration: none; }
.profile-chip img, .profile-avatar img { width: 100%; height: 100%; object-fit: cover; }
.profile-chip:focus-visible { outline: 4px solid rgba(35, 88, 73, 0.18); outline-offset: 2px; }

.app-frame { width: min(100%, 1240px); margin: 0 auto; }
.app-frame--solo { width: 100%; }
/* PWA-001: full screen from a home screen, the last control on a workout
   page clears the home indicator. */
.app-frame--solo .main-content { padding-bottom: calc(24px + env(safe-area-inset-bottom)); }
.main-content { width: 100%; max-width: var(--content); margin: 0 auto; padding: 14px 20px calc(104px + env(safe-area-inset-bottom)); outline: none; }
.side-nav { display: none; }
.bottom-nav { position: fixed; z-index: 30; right: 0; bottom: 0; left: 0; display: grid; grid-template-columns: repeat(4, 1fr); min-height: 70px; padding: 8px max(6px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(6px, env(safe-area-inset-left)); border-top: 1px solid var(--line); background: rgba(255, 255, 255, 0.97); box-shadow: 0 -10px 30px rgba(23, 34, 30, 0.06); backdrop-filter: blur(18px); }
/* NAV-001: four tabs in the person's bar; coach stage 1 (D-247): three in the coaching bar, Clients, Library, Account (the bell is the inbox). */
.bottom-nav--three { grid-template-columns: repeat(3, 1fr); }
.bottom-nav a, .side-nav a { display: flex; align-items: center; justify-content: center; color: var(--muted); text-decoration: none; }
.bottom-nav a { min-height: 52px; flex-direction: column; gap: 2px; border-radius: 12px; font-size: 0.69rem; font-weight: 620; }
.bottom-nav a[aria-current="page"], .side-nav a[aria-current="page"] { color: var(--green); }
.bottom-nav a[aria-current="page"] { background: var(--mint-2); }
.nav-symbol { min-width: 24px; text-align: center; font-size: 1.05rem; font-weight: 800; letter-spacing: -0.08em; }

.notice { position: fixed; z-index: 60; top: auto; right: 16px; bottom: calc(80px + env(safe-area-inset-bottom)); left: 16px; display: flex; max-width: 520px; align-items: flex-start; gap: 10px; margin: 0 auto; padding: 13px 15px; border: 1px solid #bed7ca; border-radius: var(--radius-sm); background: var(--mint-2); color: var(--green); font-size: 0.9rem; font-weight: 590; box-shadow: var(--shadow-lg); transition: opacity 180ms ease, transform 180ms ease; }
.notice.is-leaving { opacity: 0; transform: translateY(8px); }
.notice-dot { width: 8px; height: 8px; margin-top: 7px; flex: 0 0 auto; border-radius: 50%; background: #3f806b; }
.eyebrow { margin-bottom: 7px; color: var(--green-2); font-size: 0.72rem; font-weight: 780; letter-spacing: 0.13em; text-transform: uppercase; }
.lede { max-width: 680px; color: var(--muted); font-size: 1.02rem; }
.page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 22px; margin: 0 0 6px; }
.page-header h1 { max-width: 760px; margin-bottom: 4px; display: flex; align-items: center; gap: 0; }
.page-header--today h1 { font-size: clamp(2rem, 6vw, 3.1rem); }
.page-header--compact { margin: 2px 0 16px; }
.page-header--compact h1 { margin: 0; font-size: clamp(1.55rem, 5vw, 2.2rem); }

.card { margin-bottom: 16px; padding: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.card--accent { border-color: #bcd6c8; background: linear-gradient(145deg, #ffffff 50%, #f0f7f3); }
.card--warning { border-color: #eac59f; background: var(--warning-soft); }
.card--warning h2 { color: #633317; }
.card--warning .supporting { margin-top: 14px; color: #77472d; font-size: 0.88rem; }
.card-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 22px; }
/* The four older forms, 2026-09-27: a form or the one-line "No coach yet." under a card heading sits 8px below it, as the heading rule holds every list to. */
.card-heading:has(+ form), .card-heading:has(+ .coach-card__empty) { margin-bottom: 0; }
.card-heading + .coach-card__empty { margin-bottom: 0; }
.card-heading + .coach-card__empty + .coach-invite { margin-top: 8px; }
.time-hint { flex: 0 0 auto; padding: 6px 9px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 0.74rem; font-weight: 650; }
.card-footer-note { display: flex; gap: 10px; margin-top: 18px; padding-top: 17px; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.86rem; }
.info-dot { display: grid; width: 20px; height: 20px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--mint); color: var(--green); font-size: 0.72rem; font-weight: 800; }

.field-grid { display: grid; gap: 16px; }
.field { min-width: 0; }
.field label, .field legend, .choice-group legend, .quick-question legend { display: block; margin-bottom: 8px; color: var(--ink); font-size: 0.88rem; font-weight: 680; }
.field input:not([type="radio"]):not([type="checkbox"]), .field select, .field textarea, .coach-invite input { width: 100%; min-height: 44px; padding: 9px 14px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); outline: none; background: var(--surface); transition: border-color 160ms ease, box-shadow 160ms ease; }
.field textarea { resize: vertical; }
.field input[type="date"], .field input[type="time"] { height: 44px; }
/* A number box holds a few digits, so it keeps less side padding than a text box. */
.field input:not([type="radio"]):not([type="checkbox"])[type="number"] { padding-right: 8px; padding-left: 10px; }
.field input::placeholder, .field textarea::placeholder { color: #99a19d; }
.field input:focus, .field select:focus, .field textarea:focus, .coach-invite input:focus { border-color: var(--green-2); box-shadow: 0 0 0 4px rgba(35, 88, 73, 0.13); }
.field-help { margin-top: 8px; color: var(--muted); font-size: 0.81rem; }
/* STR-043, section 19.1, ruling 4: one muted word under a pre-filled field
   saying where the number came from. Nothing else is added. */
.field-source { display: block; margin-top: 4px; color: var(--muted); font-size: 0.74rem; }
.optional { color: var(--soft); font-size: 0.75rem; font-weight: 520; }
.input-suffix { display: flex; align-items: center; min-height: 44px; overflow: hidden; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); }
.input-suffix:focus-within { border-color: var(--green-2); box-shadow: 0 0 0 4px rgba(35, 88, 73, 0.13); }
.field .input-suffix input:not([type="radio"]):not([type="checkbox"]) { min-width: 0; min-height: 42px; padding-right: 4px; border: 0 !important; border-radius: 0; box-shadow: none !important; }
.input-suffix > span { padding: 0 14px; color: var(--muted); font-size: 0.82rem; font-weight: 650; }
.input-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.choice-group, .quick-question { min-width: 0; margin: 0; padding: 0; border: 0; }
.segmented { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; padding: 5px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-2); }
.segmented--three { grid-template-columns: repeat(3, 1fr); }
.segmented label { min-width: 0; margin: 0; cursor: pointer; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span { display: grid; min-height: 44px; place-items: center; padding: 7px; border-radius: 10px; color: var(--muted); font-size: 0.83rem; font-weight: 660; text-align: center; }
.segmented input:checked + span { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.segmented input:focus-visible + span { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }

.button { display: inline-flex; min-height: 50px; align-items: center; justify-content: center; padding: 12px 20px; border: 1px solid transparent; border-radius: var(--radius-sm); cursor: pointer; font-weight: 720; text-decoration: none; transition: transform 120ms ease, background 120ms ease, box-shadow 120ms ease; }
.button:active { transform: translateY(1px); }
.button:focus-visible { outline: 4px solid rgba(232, 111, 61, 0.25); outline-offset: 2px; }
.button--primary { background: var(--orange); color: #24140d; box-shadow: 0 8px 22px rgba(232, 111, 61, 0.22); }
.button--primary:hover { background: #ef7c4b; }
.button--quiet { border-color: var(--line); background: var(--surface); color: var(--green); }
.button--full { width: 100%; }
.button:disabled { cursor: not-allowed; opacity: 0.52; box-shadow: none; }
.stack-form { display: grid; gap: 16px; }
.stack-form > .button { justify-self: start; }
.admin-form { max-width: 480px; }
/* SAF-001: the health-check pages read as one column of questions, so they
   are capped where a line of text stops being comfortable and their buttons
   are as wide as their labels. Under 430px a button is full width, because
   a thumb is not a pointer. */
.health-check-card { max-width: 480px; }
.health-check-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 4px; }
.today-health-check { margin-bottom: 14px; color: var(--muted); font-size: 0.86rem; }

.onboarding-shell { padding: 10px 0 24px; }
.onboarding-header { max-width: 700px; margin: 0 auto 22px; }
.onboarding-header .brand { margin-bottom: 18px; }
.onboarding-header h1 { max-width: 660px; }
.onboarding-form { max-width: 760px; margin: 0 auto; padding: 24px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-lg); }
.section-heading { margin-bottom: 16px; }
.section-heading h2 { margin-bottom: 6px; }
.section-heading > p:last-child { max-width: 620px; color: var(--muted); }
.form-step { display: grid; gap: 20px; }
.form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 30px; padding-top: 20px; border-top: 1px solid var(--line); }
.form-actions .button--primary { min-width: 148px; }
.step-progress { max-width: 760px; margin: 0 auto 12px; }
.step-progress__track { height: 4px; overflow: hidden; border-radius: 999px; background: #dfe1db; }
.step-progress__track span { display: block; width: 25%; height: 100%; border-radius: inherit; background: var(--orange); transition: width 220ms ease; }
.step-progress p { display: flex; justify-content: space-between; margin-top: 8px; color: var(--muted); font-size: 0.76rem; font-weight: 640; }
.option-cards { display: grid; gap: 10px; }
.option-card { position: relative; min-width: 0; margin: 0; cursor: pointer; }
.option-card > input { position: absolute; opacity: 0; pointer-events: none; }
.option-card > span { display: flex; min-height: 76px; flex-direction: column; justify-content: center; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease; }
.option-card strong { font-size: 0.92rem; }
.option-card small { margin-top: 3px; color: var(--muted); font-size: 0.77rem; }
.option-card input:checked + span { border-color: var(--green-2); background: var(--mint-2); box-shadow: inset 0 0 0 1px var(--green-2); }
.option-card input:focus-visible + span { outline: 4px solid rgba(35, 88, 73, 0.16); outline-offset: 2px; }
.option-cards--compact { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; }
.option-cards--compact .option-card > span { min-height: 60px; padding: 9px 11px; }
.option-cards--compact .option-card strong { font-size: 0.79rem; }
.option-cards--compact .option-card small { font-size: 0.68rem; }
.day-picker { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.day-picker label { min-width: 0; cursor: pointer; }
.day-picker input { position: absolute; opacity: 0; }
.day-picker span { display: grid; min-height: 58px; place-items: center; padding: 6px 2px; border: 1px solid var(--line); border-radius: 11px; background: var(--surface); font-weight: 720; }
.day-picker small { display: none; color: var(--muted); font-size: 0.62rem; font-weight: 520; }
.day-picker input:checked + span { border-color: var(--green); background: var(--green); color: white; }
.day-picker input:checked + span small { color: #dbe9e3; }
.day-picker input:focus-visible + span { outline: 3px solid rgba(35, 88, 73, 0.2); outline-offset: 2px; }
.starter-callout { display: grid; gap: 3px; padding: 15px 16px; border-left: 4px solid var(--orange); border-radius: 5px var(--radius-sm) var(--radius-sm) 5px; background: var(--orange-soft); }
.starter-callout strong { font-size: 0.88rem; }
.starter-callout span { color: #74422c; font-size: 0.81rem; }
/* EQP-020 (owner, 2026-10-06/07): Equipment is a short checklist. Four groups,
   each a card that is a details element: the heading is its summary (name,
   the count of ticked items, a chevron), the rows are one 44px line each with
   the box at the right, and a ticked item's boxes sit under its row. */
.equipment-header { align-items: center; margin: 0 0 4px; }
.equipment-fill { margin: 0; flex: none; padding: 0; border: 0; background: none; font: inherit; font-size: 0.86rem; font-weight: 700; cursor: pointer; }
.equipment-edit-form { display: grid; gap: 12px; max-width: 480px; }
.equipment-group { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.equipment-group > .equipment-group__heading { display: flex; min-height: 56px; align-items: center; justify-content: space-between; gap: 12px; padding: 0 16px; font-size: 1.05rem; font-weight: 750; cursor: pointer; list-style: none; }
.equipment-group > .equipment-group__heading::-webkit-details-marker { display: none; }
.equipment-group > .equipment-group__heading::after { content: ""; flex: none; width: 8px; height: 8px; margin-right: 4px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(-45deg); transition: transform 120ms ease; }
.equipment-group[open] > .equipment-group__heading::after { transform: rotate(45deg); }
.equipment-group > .equipment-group__heading:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.3); outline-offset: -3px; border-radius: var(--radius); }
.equipment-group__count { color: var(--muted); font-weight: 600; text-decoration: none; white-space: nowrap; }
.equipment-group + .equipment-group { margin-top: 12px; }
.equipment-rows { display: grid; gap: 0; padding: 0 0 8px; }
.equipment-option { display: grid; align-content: start; margin: 0 16px; border-top: 1px solid var(--line); }
.equipment-rows .equipment-row { display: grid; grid-template-columns: minmax(0, 1fr) 22px; align-items: center; gap: 12px; min-height: 44px; margin: 0; padding: 6px 0; font-size: 1rem; font-weight: 400; cursor: pointer; }
.equipment-rows .equipment-row > input { position: static; width: 22px; height: 22px; grid-column: 2; grid-row: 1; margin: 0; justify-self: end; align-self: center; accent-color: var(--green); }
.equipment-rows .equipment-row > span { display: block; grid-column: 1; grid-row: 1; margin: 0; padding: 0; }
.equipment-rows .equipment-row input:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.3); outline-offset: 2px; }
.equipment-rows .equipment-row strong { margin: 0; font-size: 1rem; font-weight: 650; }
/* A ticked item's details are a sub-row under its own line. */
.increment-field { margin: 0 0 10px; padding: 0; border-radius: 0; background: none; }
.equipment-rows .increment-field { padding: 0 0 6px; }
.increment-field label { font-size: 0.78rem; }
.inline-choice { display: grid; gap: 7px; margin: 12px 0 0; padding: 0; border: 0; }
.inline-choice legend { margin-bottom: 2px; font-size: 0.76rem; }
.inline-choice label { display: flex; align-items: flex-start; gap: 7px; margin: 0; color: var(--muted); font-weight: 560; }
.inline-choice input { margin-top: 3px; }
.equipment-presets { margin: 0; }
/* The weights a person owns wrap as chips, as wide as their numbers: the phone
   rule that gives every chip half the row runs before the base rule sets the
   row back to flex, which left one chip per line here. */
.equipment-rows .load-chips { display: flex; grid-template-columns: none; }
.equipment-rows .load-chips .chip { width: auto; min-width: 52px; min-height: 44px; }
/* One Save: it stays at the bottom of a phone, above the bottom bar, and on
   a wide screen it is as wide as its label (the bar is gone at 880px). */
.equipment-edit-form > .form-actions { position: sticky; bottom: calc(78px + env(safe-area-inset-bottom)); z-index: 5; justify-content: flex-start; margin: 4px 0 0; padding: 8px 0 0; border-top: 0; background: linear-gradient(rgba(247, 245, 239, 0), var(--paper) 30%); }
.equipment-edit-form > .form-actions .button--primary { min-width: 0; }
@media (max-width: 599px) {
  .equipment-edit-form > .form-actions .button { width: 100%; }
}
@media (min-width: 880px) {
  .equipment-edit-form > .form-actions { position: static; bottom: auto; padding-top: 0; background: none; }
}
.review-card { display: flex; gap: 18px; align-items: center; padding: 20px; border: 1px solid #bad3c7; border-radius: var(--radius); background: var(--mint-2); }
.review-card__number { display: grid; width: 58px; height: 58px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--green); color: white; font-size: 1rem; font-weight: 800; }
.review-card p, .safety-note p { margin-top: 4px; color: var(--muted); font-size: 0.84rem; }
.safety-note { padding: 18px; border-radius: var(--radius-sm); background: var(--surface-2); }
.error-summary { display: grid; gap: 4px; max-width: 760px; margin: 0 auto 18px; padding: 16px 18px; border: 1px solid #e0a79f; border-radius: var(--radius-sm); background: var(--danger-soft); color: var(--danger); }
.error-summary strong { font-size: 0.91rem; }
.error-summary span { font-size: 0.84rem; }
.error-summary--safety { border-color: #e5bd8c; background: var(--warning-soft); color: #71401e; }

/* WEL-001. An accepted save with a caveat. Deliberately not the error style:
   the plan was changed, and a person who reads red will think it wasn't. */
.notice-line { display: grid; gap: 6px; max-width: 480px; margin: 0 auto 18px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--muted); font-size: 0.86rem; }

/* WEL-001. The three "this week" rows on the Progress home. A count, never a
   bar and never a colour that means failure. */
/* COA-006d, owner 2026-09-26: a card that lists things reads as a list,
   on the setup card's row pattern. A row's lines sit 4px apart; rows sit
   8px either side of the hairline between them. `scripts/shots.py`
   measures both. */
.row-list { display: grid; margin: 0; padding: 0; list-style: none; }
.row-list > li { display: grid; gap: 4px; padding: 8px 0; border-top: 1px solid var(--line); }
.row-list > li:first-child { padding-top: 0; border-top: 0; }
.row-list > li:last-child { padding-bottom: 0; }
.row-list > li > p { margin: 0; }
.process-goal-row strong { font-size: 0.9rem; font-weight: 640; }
.process-goal-row span { color: var(--muted); font-size: 0.84rem; }
.process-goal-row--untracked span { font-style: italic; }
.process-goals-card .card-heading { margin-bottom: 0; }
.progress-body-rows a { display: grid; gap: 4px; color: inherit; text-decoration: none; }
.benchmark-rows a { text-decoration: none; }
.progress-body-rows strong { font-size: 0.9rem; font-weight: 640; }
.progress-body-rows span { color: var(--muted); font-size: 0.84rem; }

/* WEL-001. The smoothed lines on the Body page. A `<progress>` element is the
   bar this codebase already uses for a proportion (PRG-007), so the trend
   rows reuse it rather than inventing a chart. */
.trend-rows { display: grid; gap: 8px; }
.trend-row { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: 12px; font-size: 0.84rem; }
.trend-row time { color: var(--muted); }
.trend-row progress { width: 100%; height: 8px; appearance: none; border: 0; border-radius: 999px; background: #dfe1db; }
.trend-row progress::-webkit-progress-bar { border-radius: inherit; background: #dfe1db; }
.trend-row progress::-webkit-progress-value { border-radius: inherit; background: var(--orange); }
.trend-row span { font-variant-numeric: tabular-nums; }
@media (max-width: 430px) {
  .trend-row { grid-template-columns: 1fr auto; }
  .trend-row progress { grid-column: 1 / -1; }
}

/* MSG-004. The urgent bar: above the topbar, on every signed-in page, with
   no dismiss on it because an urgent notice that can be put away is not one.
   Not sticky - it is the first thing on the page and it is meant to be read
   once, and a bar that follows you down a workout screen is a nag. */

.urgent-bar {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 20px;
  background: var(--ink);
  color: white;
  font-size: 0.88rem;
  line-height: 1.5;
}

.urgent-bar strong { color: white; font-weight: 760; }

.urgent-bar__flag {
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--orange);
  color: var(--ink);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.urgent-bar__text { color: rgba(255, 255, 255, 0.9); }

/* The compose preview shows the bar in a card rather than across the page,
   so it gets the card's corners and nothing else changes. */
.urgent-bar--preview { border-radius: var(--radius-sm); }

.checkin-form { display: grid; gap: 20px; }
.quick-question { display: grid; gap: 1px; }
.status-strip { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; padding: 14px 16px; border: 1px solid #bdd6c9; border-radius: var(--radius-sm); background: var(--mint-2); }
.status-strip div, .privacy-note p { display: grid; }
.status-strip strong { font-size: 0.88rem; }
.status-strip span:last-child { color: var(--muted); font-size: 0.78rem; }
.status-check { display: grid; width: 27px; height: 27px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--green); color: white; font-size: 0.8rem; font-weight: 800; }
.workout-card { overflow: hidden; padding: 0; }
.workout-hero { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 22px; background: var(--green); color: white; }
.workout-hero .eyebrow { color: #a8d0bf; }
.workout-hero p:last-child { color: #d0e2da; font-size: 0.86rem; }
.session-letter { display: grid; width: 58px; height: 58px; flex: 0 0 auto; place-items: center; border: 1px solid rgba(255,255,255,0.32); border-radius: 18px 18px 18px 6px; background: rgba(255,255,255,0.09); font-size: 1.55rem; font-weight: 780; }
.movement-list { margin: 0; padding: 8px 22px 0; list-style: none; }
.movement-list li { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 11px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line); }
.movement-list li:last-child { border-bottom: 0; }
.movement-number { display: grid; width: 30px; height: 30px; place-items: center; border-radius: 9px; background: var(--surface-2); color: var(--muted); font-size: 0.75rem; font-weight: 700; }
.movement-list div { display: grid; }
.movement-list div > span { color: var(--muted); font-size: 0.75rem; }
.movement-dose { justify-items: end; text-align: right; }
.movement-dose strong { font-size: 0.85rem; }
/* COA-006d: a movement name is one line beside its dose, never two. */
.movement-name > strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The owner, 2026-09-30: the equipment notice keeps the card's inset. */
.workout-card > .boundary-note { margin: 16px 22px 0; }
.calibration-note { display: grid; gap: 2px; margin: 4px 22px 18px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--mint-2); }
.calibration-note strong { font-size: 0.8rem; }
.calibration-note span { color: var(--muted); font-size: 0.75rem; }
.today-adjustment-summary { display: flex; align-items: flex-start; gap: 10px; margin: 16px 22px 14px; padding: 11px 13px; border-radius: var(--radius-sm); background: var(--surface-2); }
.today-adjustment-summary > span { display: grid; width: 21px; height: 21px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--green); color: white; font-size: 0.68rem; font-weight: 800; }
.today-adjustment-summary p { display: grid; color: var(--muted); font-size: 0.75rem; }
.today-adjustment-summary strong { color: var(--ink); font-size: 0.79rem; }
.today-adjust { margin: 0 22px 18px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.today-adjust > summary { display: flex; min-height: 50px; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 14px; cursor: pointer; color: var(--green); font-size: 0.86rem; font-weight: 720; }
.today-adjust > summary small { color: var(--muted); font-size: 0.72rem; font-weight: 540; text-align: right; }
.today-adjust__form { display: grid; gap: 18px; padding: 15px; border-top: 1px solid var(--line); background: var(--mint-2); }
.today-equipment-list { display: grid; gap: 7px; }
.today-equipment-list label { position: relative; margin: 0; cursor: pointer; }
.today-equipment-list input { position: absolute; opacity: 0; pointer-events: none; }
.today-equipment-list span { display: flex; min-height: 42px; align-items: center; padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--muted); font-size: 0.8rem; font-weight: 650; }
.today-equipment-list input:checked + span { border-color: var(--green-2); background: var(--green); color: white; }
.today-equipment-list input:focus-visible + span { outline: 3px solid rgba(35, 88, 73, 0.2); outline-offset: 2px; }
.workout-card .card-footer-note { margin: 0 22px 20px; }
.workout-cta { display: grid; gap: 12px; padding: 18px 22px 22px; border-top: 1px solid var(--line); }
.workout-cta p { color: var(--muted); font-size: 0.82rem; text-align: center; }
.section-block { margin-top: 34px; }
.section-block--first { margin-top: 0; margin-bottom: 30px; }
.section-title { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.section-title h2 { margin: 0; font-size: 1.2rem; }
.section-title > span { color: var(--muted); font-size: 0.78rem; }
.action-grid { display: grid; gap: 10px; }
.action-card { display: grid; grid-template-columns: 40px 1fr 20px; gap: 12px; align-items: center; min-height: 72px; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); text-decoration: none; box-shadow: var(--shadow-sm); }
.action-card div { display: grid; }
.action-card div span { color: var(--muted); font-size: 0.76rem; }
.action-card > span:last-child { color: var(--soft); font-size: 1.4rem; }
.action-symbol { display: grid; width: 38px; height: 38px; place-items: center; border-radius: 11px; background: var(--mint-2); color: var(--green); font-weight: 800; }

.history-list { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.history-list article { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 16px 18px; border-bottom: 1px solid var(--line); }
.history-list article:last-child { border-bottom: 0; }
.history-row { display: flex; align-items: center; justify-content: space-between; gap: 18px; min-height: 68px; padding: 13px 16px; border-bottom: 1px solid var(--line); text-decoration: none; }
.history-row:last-child { border-bottom: 0; }
.history-row > div { display: grid; gap: 2px; }
.history-row span { color: var(--muted); font-size: 0.76rem; }
.history-list time { color: var(--muted); font-size: 0.8rem; }
.history-list article div { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 13px; font-size: 0.84rem; }
.empty-state { display: grid; min-height: 220px; place-items: center; align-content: center; padding: 30px; border: 1px dashed #c7cbc3; border-radius: var(--radius); color: var(--muted); text-align: center; }
.empty-state > span { display: grid; width: 48px; height: 48px; margin-bottom: 12px; place-items: center; border-radius: 50%; background: var(--surface-2); color: var(--green); font-size: 1.2rem; font-weight: 800; }
.empty-state h3 { color: var(--ink); }
.empty-state p { max-width: 350px; font-size: 0.86rem; }
.empty-state .button { margin-top: 18px; }

.consistency-grid { display: grid; gap: 16px; }
.consistency-card { display: grid; gap: 16px; margin-bottom: 0; }
.consistency-card > div { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; }
.consistency-card .eyebrow { margin: 0 0 3px; }
.consistency-card > div > strong { color: var(--green); font-size: 2.35rem; letter-spacing: -0.06em; line-height: 1; }
.consistency-card progress { display: block; width: 100%; height: 8px; overflow: hidden; border: 0; border-radius: 999px; appearance: none; background: #dfe1db; }
.consistency-card progress::-webkit-progress-bar { border-radius: inherit; background: #dfe1db; }
.consistency-card progress::-webkit-progress-value { border-radius: inherit; background: var(--orange); }
.consistency-card progress::-moz-progress-bar { border-radius: inherit; background: var(--orange); }
.consistency-card > p, .metric-note { color: var(--muted); font-size: 0.81rem; }
.metric-note { margin: 11px 2px 0; }
/* COA-006e: 8px from the heading block to the first row, which is the title's own margin. */
.aerobic-ledger-card { display: grid; gap: 0; }
.aerobic-ledger-card .card-heading { margin-bottom: 0; }
.aerobic-ledger-total { display: flex; align-items: baseline; gap: 8px; }
.aerobic-ledger-total strong { color: var(--green); font-size: 2.6rem; letter-spacing: -0.06em; line-height: 1; }
.aerobic-ledger-total span { color: var(--muted); font-weight: 700; }
.aerobic-ledger-row > progress { display: block; width: 100%; height: 10px; overflow: hidden; border: 0; border-radius: 999px; appearance: none; background: #dfe1db; }
.aerobic-ledger-row > progress::-webkit-progress-bar { border-radius: inherit; background: #dfe1db; }
.aerobic-ledger-row > progress::-webkit-progress-value { border-radius: inherit; background: var(--orange); }
.aerobic-ledger-row > progress::-moz-progress-bar { border-radius: inherit; background: var(--orange); }
.aerobic-ledger-rows p { color: var(--muted); }
.aerobic-ledger-details summary { color: var(--green); cursor: pointer; font-weight: 750; }
.aerobic-ledger-details p { color: var(--muted); font-size: 0.82rem; }
.aerobic-ledger-details ul { display: grid; gap: 8px; margin: 10px 0; padding: 0; list-style: none; }
.aerobic-ledger-details li { display: flex; justify-content: space-between; gap: 12px; font-size: 0.82rem; }
.aerobic-ledger-details li span { color: var(--muted); }
.aerobic-ledger-details code { color: var(--soft); font-size: 0.68rem; }
.calibration-card { margin-top: 30px; background: var(--mint-2); }
.calibration-card > p { color: var(--muted); font-size: 0.88rem; }
.calibration-count { display: grid; min-width: 58px; height: 58px; place-items: center; border-radius: 18px 18px 18px 6px; background: var(--green); color: white; font-size: 0.98rem; font-weight: 760; }
.calibration-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 18px 0 13px; }
.calibration-facts span { display: grid; padding: 13px; border: 1px solid #c9ddd4; border-radius: var(--radius-sm); background: rgba(255,255,255,0.65); color: var(--muted); font-size: 0.76rem; }
.calibration-facts strong { color: var(--green); font-size: 1.15rem; }
.calibration-card .supporting { font-size: 0.78rem; }
.change-list { display: grid; gap: 10px; }
.change-card { padding: 18px; border: 1px solid var(--line); border-left: 4px solid var(--green-2); border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-sm); }
.change-card--progress { border-left-color: var(--orange); }
.change-card--regress, .change-card--recover, .change-card--substitute { border-left-color: var(--warning); }
.change-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 10px; }
.change-card__top > div { display: grid; gap: 7px; }
.change-card__top h3 { margin: 0; }
.change-card__top time { flex: 0 0 auto; color: var(--muted); font-size: 0.75rem; }
.outcome-chip { width: fit-content; padding: 3px 7px; border-radius: 999px; background: var(--mint-2); color: var(--green); font-size: 0.65rem; font-weight: 770; letter-spacing: 0.07em; text-transform: uppercase; }
.change-card--progress .outcome-chip { background: var(--orange-soft); color: var(--orange-dark); }
.change-card > strong { font-size: 0.92rem; }
.change-card details { margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--line); }
.change-card summary { display: flex; min-height: 44px; align-items: center; cursor: pointer; color: var(--green); font-size: 0.78rem; font-weight: 700; }
.change-card details p { color: var(--muted); font-size: 0.8rem; }
.change-card code { display: inline-block; margin-top: 9px; color: var(--soft); font-size: 0.65rem; overflow-wrap: anywhere; }
.workout-history-list { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.workout-history-row { display: grid; grid-template-columns: 42px minmax(0, 1fr) auto 14px; gap: 12px; align-items: center; min-height: 78px; padding: 13px 15px; border-bottom: 1px solid var(--line); text-decoration: none; }
.workout-history-row:last-child { border-bottom: 0; }
.workout-history-row:focus-visible { outline: 4px solid rgba(35, 88, 73, 0.16); outline-offset: -4px; }
.history-letter { display: grid; width: 40px; height: 40px; place-items: center; border-radius: 12px 12px 12px 4px; background: var(--green); color: white; font-weight: 780; }
.workout-history-row > div { display: grid; min-width: 0; }
.workout-history-row time, .history-dose span { color: var(--muted); font-size: 0.72rem; }
.history-dose { justify-items: end; text-align: right; }
.history-dose strong { font-size: 0.8rem; }
.history-arrow { color: var(--soft); font-size: 1.35rem; }

.nutrition-result { margin-bottom: 18px; padding: 26px; border-radius: var(--radius-lg); background: var(--green); color: white; box-shadow: var(--shadow-lg); }
.nutrition-result .eyebrow { color: #a8d0bf; }
.nutrition-result > p:last-child { max-width: 580px; color: #c7ddd3; font-size: 0.84rem; }
.protein-target { display: flex; align-items: center; gap: 14px; margin: 28px 0 20px; }
.protein-target strong { font-size: clamp(3rem, 14vw, 5.2rem); font-weight: 690; letter-spacing: -0.07em; line-height: 0.8; }
.protein-target span { color: #d0e2da; font-size: 0.85rem; line-height: 1.3; }
.guidance-grid { display: grid; gap: 10px; margin-bottom: 24px; }
.mini-card { padding: 18px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.mini-card__index { color: var(--orange-dark); font-size: 0.69rem; font-weight: 780; }
.mini-card h3 { margin-top: 10px; }
.mini-card p { color: var(--muted); font-size: 0.82rem; }

.upload-card { padding: 18px; }
.photo-drop { position: relative; display: grid; min-height: 250px; overflow: hidden; place-items: center; border: 1.5px dashed #aeb7b1; border-radius: var(--radius); background: var(--mint-2); text-align: center; }
.photo-drop:focus-within { outline: 4px solid rgba(35, 88, 73, 0.14); }
.photo-drop input { position: absolute; z-index: 2; inset: 0; width: 100%; height: 100%; cursor: pointer; opacity: 0; }
.photo-drop__prompt { display: grid; gap: 4px; justify-items: center; padding: 24px; pointer-events: none; }
.photo-drop__prompt > span { color: var(--muted); font-size: 0.84rem; }
.photo-drop__prompt small { margin-top: 7px; color: var(--soft); font-size: 0.72rem; }
.upload-symbol { display: grid; width: 52px; height: 52px; margin-bottom: 8px; place-items: center; border-radius: 16px; background: var(--green); color: white !important; font-size: 1.55rem !important; font-weight: 400; }
.photo-preview { width: 100%; height: 300px; object-fit: contain; background: #d9dedb; pointer-events: none; }
.privacy-note { display: flex; align-items: flex-start; gap: 10px; padding: 14px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.81rem; }
.privacy-note p { gap: 2px; color: var(--muted); }
.privacy-note strong { color: var(--ink); }
.photo-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.photo-tile { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-sm); }
.photo-tile__image { aspect-ratio: 3 / 4; overflow: hidden; background: #e5e7e2; }
.photo-tile__image img { width: 100%; height: 100%; object-fit: cover; }
.photo-tile > div:last-child { display: grid; padding: 12px; }
.photo-tile time { color: var(--muted); font-size: 0.72rem; }
.photo-tile p { margin-top: 6px; color: var(--muted); font-size: 0.75rem; }

.profile-grid { display: grid; gap: 12px; }
.compact-page-header { margin-bottom: 20px; }
.profile-form-card { max-width: 680px; }
.avatar-editor { display: grid; grid-template-columns: 76px minmax(0, 1fr); gap: 16px; align-items: center; padding-bottom: 16px; border-bottom: 1px solid var(--line); }
.profile-avatar { display: grid; overflow: hidden; place-items: center; border-radius: 50%; background: var(--green); color: white; font-weight: 780; }
.profile-avatar--large { width: 72px; height: 72px; font-size: 1.5rem; }
.avatar-editor input[type="file"] { width: 100%; font-size: 0.8rem; }
.avatar-cropper { display: grid; gap: 16px; padding: 18px; border: 1px solid #c9ddd4; border-radius: var(--radius); background: var(--mint-2); }
.avatar-cropper h2 { margin-bottom: 4px; font-size: 1.2rem; }
.avatar-cropper > div:first-child > p:last-child { color: var(--muted); font-size: 0.82rem; }
.avatar-crop-viewport { position: relative; width: min(100%, 320px); aspect-ratio: 1; overflow: hidden; justify-self: center; border: 3px solid var(--surface); border-radius: 50%; background: #d7ddd9; box-shadow: 0 0 0 1px var(--line), var(--shadow-sm); cursor: grab; touch-action: none; user-select: none; }
.avatar-crop-viewport.is-dragging { cursor: grabbing; }
.avatar-crop-viewport img { position: absolute; max-width: none; pointer-events: none; user-select: none; }
.avatar-crop-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: end; }
.avatar-crop-controls input[type="range"] { width: 100%; min-height: 40px; accent-color: var(--green); }
.avatar-cropper .field-help { margin: 0; text-align: center; }
.avatar-save-result { margin-top: 8px; color: var(--green); font-size: 0.78rem; font-weight: 700; }
.inline-button { min-height: 44px; margin-top: 8px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 9px; background: var(--surface-2); color: var(--green); cursor: pointer; font-size: 0.78rem; font-weight: 680; }
.progress-home-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 28px; }
.progress-home-card { display: grid; grid-template-columns: 28px minmax(0, 1fr) 8px; gap: 6px; align-items: center; min-height: 100px; padding: 14px 10px 14px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); text-decoration: none; box-shadow: var(--shadow-sm); }
.progress-home-card > div { display: grid; min-width: 0; }
.progress-home-card > div > strong { color: var(--green); font-size: 1.5rem; line-height: 1; }
.progress-home-card > div > span { margin-top: 4px; font-size: 0.84rem; font-weight: 700; }
.progress-home-card small { color: var(--muted); font-size: 0.68rem; }
.progress-home-card > span:last-child { color: var(--soft); font-size: 1.2rem; }
.goal-progress-card .card-heading { margin-bottom: 6px; }
.goal-progress-card .card-heading a { color: var(--green); font-size: 0.82rem; font-weight: 700; }
.goal-pace-line { margin-bottom: 8px; color: var(--muted); font-size: 0.82rem; }
.goal-progress-list { display: grid; border-top: 1px solid var(--line); }
.goal-progress-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.goal-progress-row > div { display: grid; gap: 2px; }
.goal-progress-row > div:last-child { justify-items: end; text-align: right; }
.goal-progress-row span, .goal-progress-row small { color: var(--muted); font-size: 0.75rem; }
.goal-status { font-weight: 700; }
.goal-status--target_reached { color: var(--green) !important; }
.goal-empty { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.goal-empty p { color: var(--muted); font-size: 0.82rem; }
.progress-home-symbol { display: grid; width: 28px; height: 28px; place-items: center; border-radius: 10px; background: var(--mint-2); color: var(--green); font-weight: 760; }
.profile-form-card > p { margin-bottom: 8px; color: var(--muted); font-size: 0.86rem; }
/* Training setup, 2026-09-27: the heading sits 8px over its one sentence, rows 8px apart, help lines 8px under the list. */
.profile-form-card .card-heading { margin-bottom: 0; }
.preference-list + .field-help { margin-top: 8px; }
.compact-form { display: grid; gap: 16px; }
.compact-form > .button--quiet { justify-self: start; }
.compact-form .field input:not([type="radio"]):not([type="checkbox"]), .compact-form .field select { padding: 9px 11px; }
.preference-list { display: grid; margin-top: 0; border-top: 1px solid var(--line); }
.preference-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: end; padding: 8px 0; border-bottom: 1px solid var(--line); }
.preference-row .field { margin: 0; }
.preference-row select { min-height: 44px; padding: 9px 11px; }
.preference-row .button { min-height: 44px; padding: 9px 14px; }
.compact-check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.compact-check-grid label, .target-toggle { display: flex; min-width: 0; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--surface); cursor: pointer; }
.compact-check-grid span { font-size: 0.82rem; font-weight: 650; }
.compact-check-grid input:disabled + span { color: var(--soft); }
.pace-options { display: grid; gap: 8px; }
.pace-options label { cursor: pointer; }
.pace-options input { position: absolute; opacity: 0; }
.pace-options span { display: grid; gap: 2px; padding: 11px 13px; border: 1px solid var(--line); border-radius: 11px; }
.pace-options small, .target-toggle small, .goal-targets summary small { color: var(--muted); font-size: 0.76rem; font-weight: 500; }
.pace-options input:checked + span { border-color: var(--green); background: var(--mint); }
.pace-options input:focus-visible + span { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.goal-targets { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.goal-targets summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 15px; cursor: pointer; list-style: none; }
.goal-targets summary::-webkit-details-marker { display: none; }
.goal-targets__chevron { display: inline-block; transition: transform 120ms ease; }
.goal-targets[open] .goal-targets__chevron { transform: rotate(180deg); }
.goal-targets summary > span:first-child { display: grid; gap: 2px; }
.goal-targets__body { display: grid; gap: 10px; padding: 0 12px 12px; }
.target-toggle { background: var(--surface-2); }
.target-toggle > span { display: grid; gap: 1px; }
.target-panel { display: grid; gap: 12px; margin-top: -10px; padding: 14px; border: 1px solid var(--line); border-top: 0; border-radius: 0 0 11px 11px; background: var(--surface); }
.field-grid--two { grid-template-columns: 1fr; gap: 16px; }
.preservation-note { margin: 2px 0 0; color: var(--muted); font-size: 0.8rem; }
.text-link { display: inline-flex; min-height: 44px; align-items: center; margin: 0 0 18px; color: var(--green); font-size: 0.86rem; font-weight: 700; }
.stacked-choices { display: grid; gap: 7px; }
.stacked-choices label { position: relative; margin: 0; cursor: pointer; }
.stacked-choices input { position: absolute; opacity: 0; pointer-events: none; }
.stacked-choices span { display: grid; gap: 2px; min-height: 54px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.stacked-choices strong { font-size: 0.84rem; }
.stacked-choices small { color: var(--muted); font-size: 0.74rem; }
.stacked-choices input:checked + span { border-color: var(--green-2); background: var(--mint-2); box-shadow: inset 0 0 0 1px var(--green-2); }
.stacked-choices input:focus-visible + span { outline: 3px solid rgba(35, 88, 73, 0.2); outline-offset: 2px; }
.readiness-form { margin-top: 0; }
.profile-card h2 { font-size: 1.35rem; }
.profile-card > p:last-child { color: var(--muted); font-size: 0.84rem; }
.equipment-summary { display: grid; gap: 8px; }
.equipment-summary > div { display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.equipment-summary .status-check { width: 25px; height: 25px; }
.narrow-page { max-width: 600px; margin: 80px auto; }
.standalone-shell .onboarding-header { max-width: 520px; }
.standalone-card { display: grid; gap: 18px; max-width: 520px; margin: 0 auto; }
.standalone-card p { margin: 0; }
/* LEGAL-001, 2026-09-28. Privacy and Terms: one section heading per idea
   group, small enough to read as a label in a long page, 12px between
   paragraphs and 24px above each heading, so a section reads as one block. */
.legal { display: grid; gap: 12px; }
.legal h2 { margin: 12px 0 0; font-size: 1.05rem; letter-spacing: -0.01em; line-height: 1.3; }
.legal ul { display: grid; gap: 6px; margin: 0; padding-left: 1.2em; }
.legal .field-help { margin-top: 12px; }
/* A link inside a sentence stays the sentence's size: `.inline-link` is a
   44px control and would open a gap in the paragraph around it. */
.legal a { color: var(--green); font-weight: 620; }
/* SUP-001. Privacy, Terms and Help under every signed-out page. */
.standalone-foot { max-width: 520px; margin: 18px auto 0; color: var(--muted); font-size: 0.82rem; text-align: center; }
.standalone-foot a { color: var(--green); font-weight: 620; text-decoration: none; }
.standalone-foot a:hover { text-decoration: underline; }
/* HOM-005: the copyright line under the three links. */
.standalone-foot__copyright { margin: 4px 0 0; }

/* SUP-001 and D-126, the help page: a FAQ first, one contact card after.

   A question is a `<details>`; there is no script on this page and there is
   no need for one. The summary is 44 px tall so it is a real tap target, and
   the marker is the browser's own triangle, which already rotates and
   already says open or closed to a screen reader. */
.help-lede { max-width: 640px; margin: 0 0 24px; color: var(--muted); font-size: 0.96rem; }

.help-faq { max-width: 640px; margin: 0 0 28px; }

.help-faq__group {
  margin: 26px 0 6px;
  color: var(--soft);
  font-size: 0.72rem;
  font-weight: 780;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.help-faq__group:first-child { margin-top: 0; }

/* HLP-010: the finish note's "support" link is a word in a sentence, not a
   44 px target, the same reasoning as a link in a help answer. */
.review-form .field-help .inline-link {
  display: inline;
  min-height: 0;
  font-size: inherit;
}

/* HLP-010: the known-issues group's two sub-headings, one step below the
   group label and in sentence case so they read as labels, not groups. */
.help-faq__subgroup {
  margin: 14px 0 2px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 720;
}

.faq-item { border-bottom: 1px solid var(--line); }

.faq-item > summary {
  display: flex;
  min-height: 44px;
  align-items: center;
  padding: 10px 0;
  color: var(--ink);
  cursor: pointer;
  font-size: 0.94rem;
  font-weight: 650;
}

.faq-item > summary:hover { color: var(--green); }

/* An answer is prose, so a link in it is a word and not a 44 px tap target:
   `.inline-link`'s own height was pushing one line of an answer apart from
   the two around it. The answers are short and nothing else in them is
   tappable, so there is no target being taken away from a thumb. */
.faq-item > p .inline-link {
  display: inline;
  min-height: 0;
  font-size: inherit;
  font-weight: 680;
}

.faq-item > p {
  margin: 0 0 14px;
  padding-right: 8px;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.6;
}

/* The one contact card. Sized to its own content rather than to the column,
   and the button sized to its label (D-119). */
.help-contact { max-width: 480px; margin: 0; }
.help-contact__lede { margin: 6px 0 16px; color: var(--muted); font-size: 0.92rem; }
.help-contact .button { margin: 0; }
.help-contact .field-help { margin-top: 12px; }
body[data-page="help"] .standalone-shell .onboarding-header,
body[data-page="help"] .standalone-card,
body[data-page="help"] .standalone-foot { max-width: 680px; }

.workout-shell__header { display: grid; grid-template-columns: 44px 1fr 48px; gap: 12px; align-items: center; margin: -10px 0 13px; }
.workout-shell__header > div { display: grid; text-align: center; }
.workout-shell__header > div span { color: var(--muted); font-size: 0.72rem; font-weight: 620; text-transform: uppercase; letter-spacing: 0.08em; }
.workout-shell__header > div strong { font-size: 0.92rem; }
.workout-back { display: grid; width: 44px; height: 44px; place-items: center; border: 1px solid var(--line); border-radius: 50%; background: var(--surface); color: var(--green); font-size: 1.8rem; line-height: 1; text-decoration: none; }
.workout-percent { color: var(--green); font-size: 0.8rem; font-weight: 760; text-align: right; }
.workout-progress { display: block; width: 100%; height: 5px; margin-bottom: 30px; overflow: hidden; border: 0; border-radius: 999px; appearance: none; background: #dfe1db; }
.workout-progress::-webkit-progress-bar { border-radius: inherit; background: #dfe1db; }
.workout-progress::-webkit-progress-value { border-radius: inherit; background: var(--orange); }
.workout-progress::-moz-progress-bar { border-radius: inherit; background: var(--orange); }
/* STR-040c, ruling 1: the links sit 8px under the name and the card
   follows 14px after them. The title row carries no margin of its own. */
.exercise-hero { margin: 0 0 14px; }
.exercise-hero h1 { margin-bottom: 8px; }
/* STR-040b, ruling 1: nothing ever draws a ring around the movement's
   name. Nothing focuses it any more either, so this is the second lock. */
.exercise-hero h1:focus, .exercise-hero h1:focus-visible { outline: none; box-shadow: none; }
.exercise-hero > p:last-of-type { color: var(--muted); }
/* Ruling 2: the pattern word stays, small and muted, after the name. */
/* STR-040f, ruling 5: the eyebrow is plain text and carries no link. */
/* WRM-004 ruling 1: there is no clock at all, so nothing is highlighted and
   nothing counts. Ruling 2: 24px between the heading block and the first
   card, and no gap larger than 8px inside a card. */
.warmup-heading { margin: 8px 0 24px; }
.warmup-steps { display: grid; gap: 10px; margin: 0 0 18px; padding: 0; list-style: none; }
.warmup-steps li { display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 12px; align-items: start; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.warmup-steps li > span { display: grid; min-height: 38px; place-items: center; padding: 7px 8px; border-radius: 12px; background: var(--mint-2); color: var(--green); font-size: 0.74rem; font-weight: 720; line-height: 1.3; text-align: center; overflow-wrap: anywhere; }
.warmup-steps strong { display: block; margin-bottom: 3px; }
.warmup-steps p { color: var(--muted); font-size: 0.84rem; line-height: 1.45; }
.warmup-step-note { margin-top: 6px; }
/* WRM-004 ruling 2: one line holds "How to do it" and the choice link, 8px
   under the instruction, inline at every width with 16px between them. It
   wraps only when the phone leaves no room for the two side by side. */
/* WRM-005 ruling 6: 8px under the instruction (margin-top), 16px between the
   disclosure and the choice link on one line, and when they wrap at 375 the
   second line sits 4px under the first (row-gap). */
.warmup-step-aside { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin-top: 8px; }
.warmup-how-to { margin: 0; }
/* WRM-005 ruling 6 again, and this time it draws. The `row-gap` above was
   already 4px, but both halves of the line were tap targets wearing a
   min-height much taller than their own text, so the two wrapped lines sat
   about 20px apart on the screen while the boxes measured 4px: the disclosure
   took `min-height: 34px` from `.movement-aside > summary`, which is later in
   this file and beat the 30px that used to sit here, and the choice link took
   `min-height: 30px` from a rule of its own that STR-048 folded into this one. Here the two are words in a
   sentence rather than buttons, so each collapses to its line box and the 4px
   between them is the whole distance, the same override the week-declaration,
   day-sheet and movement-list surfaces already make for `.inline-link`. The
   selectors are scoped to this line and carry enough weight to win wherever
   the rule they override happens to sit. No text gets smaller. */
.warmup-step-aside > .warmup-how-to > summary { display: block; min-height: 0; padding: 0; }
/* The form around the choice link has to give up its own line box too. A
   button stays inline-level whatever it is told, so it sat on a text line
   whose strut was taller than the button, and the form kept 4px of that strut
   under the link. As a flex container the form is exactly its button. */
.warmup-step-aside > .warmup-step-choice { display: flex; }
.warmup-step-aside > .warmup-step-choice > button { display: inline; min-height: 0; padding: 0; border: 0; background: none; color: var(--green); font: inherit; font-size: 0.82rem; font-weight: 600; text-decoration: underline; cursor: pointer; }
.warmup-how-to .movement-aside__panel { padding: 8px 0 0; }
/* An open disclosure takes the whole line so its panel gets the card's
   width; the choice link drops under it rather than beside a wall of text. */
.warmup-step-aside > .warmup-how-to[open] { flex: 1 0 100%; }
.warmup-step-choice { margin: 0; }
.boundary-note--warmup { margin-bottom: 18px; }
.workout-exit { margin-top: 14px; }
.technique-help, .session-plan, .finish-early { margin-bottom: 18px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.technique-help summary, .session-plan summary, .finish-early summary { min-height: 50px; padding: 13px 16px; cursor: pointer; color: var(--green); font-size: 0.86rem; font-weight: 700; }
/* ACC-001: every disclosure inside the runner is a full-size target. */
[data-voice-select] { min-height: 44px; }
.technique-help > p, .technique-help > ul, .finish-early > p, .finish-early > form { margin: 0 16px 16px; }
.technique-help > p, .technique-help li, .finish-early > p { color: var(--muted); font-size: 0.82rem; }
.technique-help ul { padding-left: 20px; }
.help-reasons { display: grid; gap: 10px; margin: 0 16px 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.help-reasons > div { display: grid; gap: 2px; }
.help-reasons strong { font-size: 0.79rem; }
.help-reasons span { color: var(--muted); font-size: 0.78rem; }
.control-form { display: grid; gap: 13px; }
.control-form--inline { grid-template-columns: minmax(0, 1fr); }
.boundary-note { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 18px; padding: 13px 15px; border-radius: var(--radius-sm); background: var(--surface-2); }
.boundary-note > span { display: grid; width: 22px; height: 22px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--green); color: white; font-size: 0.7rem; font-weight: 800; }
.boundary-note p { color: var(--muted); font-size: 0.78rem; }
.boundary-note strong { color: var(--ink); }
/* STR-040b, ruling 2: the set's facts are the card's heading row and the
   range is the boldest thing on the card. */
/* STR-040c, ruling 2: the set's facts go up to the card-heading size
   used elsewhere, and keep their weight of 800. */
.set-card__heading { margin: 0; font-size: 1.15rem; }
/* Ruling 5: the Sound switch is right aligned on this row, and nothing
   else shares it. */
.set-card__heading-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; width: 100%; }
.set-card__heading-row > .set-card__heading { flex: 1 1 auto; min-width: 0; }
.set-card__heading-row > .sound-switch__button { flex: 0 0 auto; padding: 0; }
.set-card__heading strong { font-weight: 800; letter-spacing: -0.01em; }
.set-form { display: grid; gap: 14px; justify-items: start; }
.set-input-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.set-input-grid--single { grid-template-columns: 1fr; }
@media (max-width: 599px) {
  .set-input-grid { grid-template-columns: 1fr; }
}

/* STR-040: the set card is one row, and every field on it is sized to
   what it holds rather than to the column it used to share. Reps is
   first in the document so the keyboard reaches it first; `order` puts
   the load stepper back on its left. */
.set-form .set-input-grid { display: flex; flex-wrap: wrap; align-items: start; gap: 12px; width: 100%; grid-template-columns: none; }
.set-form .set-input-grid .field { display: grid; gap: 6px; }
.set-form .field--load { order: -3; }
.set-form .field--resistance { order: -2; }
.set-form .load-stepper { gap: 6px; }
.set-form .load-stepper .input-suffix { flex: 0 0 auto; }
.set-form .input-suffix > span { padding: 0 8px; }
.set-form .field--load .input-suffix input { flex: 0 0 auto; width: 5rem; }
.set-form .field--reps .input-suffix input { flex: 0 0 auto; width: 3.5rem; }
.set-form .field--reps > input { width: 3.5rem; min-height: 44px; }
/* Under 600px the whole row still has to be one line: the 44px targets are
   not negotiable, so the weight field gives up the half rem. */
@media (max-width: 599px) {
  .set-form .field--load .input-suffix input { width: 4.5rem; }
}
.set-form .field--resistance select { width: 9rem; }
/* STR-040d, ruling 2: the clock is part of the card rather than a screen
   of its own, so it keeps the green block and the tabular digits at a size
   the card can hold, at both widths. */
.set-clock { width: 100%; }
.set-clock__timer { padding: 20px; }
.set-clock__timer strong { font-size: clamp(2.6rem, 12vw, 3.4rem); }
/* The one primary button, with Resume and Reset beside it once the clock
   has stopped. They are quiet links, so they never read as a second thing
   to press. */
.set-card__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; width: 100%; }
.set-clock__links { display: flex; gap: 20px; margin: 0; }
/* They are links, so they carry none of a button's chrome. */
.set-clock__links .inline-link { padding: 0; border: 0; background: none; cursor: pointer; }
.set-clock__links .inline-link:hover { text-decoration: underline; }
/* STR-040d, ruling 4: a timed input is about 4.5rem wide and its unit sits
   tight against the number, the way "lb" sits in the load field. */
.set-form .field--seconds .input-suffix input { width: 4.5rem; }
.field--seconds .input-suffix > span { padding: 0 8px; }
.field--seconds .input-suffix input { width: 4.5rem; }
.set-form .set-cue { max-width: 480px; }
/* STR-040c, ruling 3: the line is outside the card now, 8px under its
   edge, and the card gives up its own bottom margin so the gap is the
   one this rule sets. */
.set-form.card { margin-bottom: 0; }
.set-first-workout { max-width: 480px; margin: 8px 0 0; color: var(--muted); font-size: 0.78rem; line-height: 1.45; }

/* The three quiet links under Save. Each one is a native disclosure whose
   summary is the link, so nothing on the card itself opens or closes. */
/* STR-040c, ruling 4: the two links sit 14px under the line, or under
   the card when there is no line. */
.set-links { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 14px 0 24px; }
/* STR-040b, ruling 5: "Something hurt?" on the left, "End workout" on the
   right, and either one takes the whole width once it is open. */
.set-links--pair { justify-content: space-between; }
.set-links--pair > .set-links__item[open] { flex: 1 1 100%; }
.set-links__item { flex: 0 0 auto; margin: 0; border: 0; border-radius: 0; background: none; }
.set-links__item > summary { display: inline-flex; min-height: 44px; align-items: center; padding: 0; cursor: pointer; color: var(--green); font-size: 0.84rem; font-weight: 700; }
.set-links__item[open] { flex: 1 1 100%; padding-bottom: 8px; }
.set-links__item[open] > summary { margin-bottom: 10px; }
/* The second link is a link to a page now, not a disclosure, so it is
   given the same target size and the same quiet weight as the first. */
.set-links__link { display: inline-flex; min-height: 44px; align-items: center; color: var(--green); font-size: 0.84rem; font-weight: 700; text-decoration: none; }
.set-links__link:hover { text-decoration: underline; }

.pain-declaration { display: flex; align-items: center; gap: 10px; font-size: 0.86rem; font-weight: 700; }
.pain-declaration input { width: 22px; height: 22px; flex: 0 0 auto; margin: 0; }

/* The two links on the title line. Closed, each is only its own words;
   open, it takes the whole width and its panel drops under the title. */
/* STR-040b, ruling 3: a quiet line directly under the name, left aligned,
   and lighter than the range inside the card. */
.movement-title-row { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: flex-start; gap: 0 6px; margin: 0; }
/* STR-040c, ruling 1: a muted bar, not a link, with a space each side.
   It steps aside while a panel is open and the row is one link wide. */
.movement-title-row__bar { color: var(--muted); font-size: 0.82rem; font-weight: 400; }
.movement-aside { flex: 0 0 auto; margin: 0; border: 0; border-radius: 0; background: none; }
.movement-aside > summary { display: inline-flex; min-height: 34px; align-items: center; padding: 0; cursor: pointer; color: var(--green); font-size: 0.82rem; font-weight: 600; }
/* STR-040e, ruling 2: the line never grows. "How to do it" keeps its own
   width open or closed, and its panel is a sibling that drops under the
   whole row, so Swap is never pushed onto a second line. */
.movement-title-row__link { display: inline-flex; min-height: 34px; align-items: center; color: var(--green); font-size: 0.82rem; font-weight: 600; text-decoration: none; }
.movement-title-row__link:hover { text-decoration: underline; }
.movement-aside__panel { display: grid; gap: 12px; padding: 14px 0 4px; }
.movement-aside__panel.movement-title-row__panel { display: none; flex: 1 1 100%; }
.movement-title-row details[open] ~ .movement-aside__panel.movement-title-row__panel { display: grid; }
/* STR-043, section 19.4: the pair's title line carries two movements, so an
   open disclosure drops only its own panel. The lead word names what the two
   links are for, once per line. */
.movement-title-row--pair .movement-aside__panel.movement-title-row__panel { display: none; }
.movement-title-row--pair details:nth-of-type(1)[open] ~ .pair-panel--1 { display: grid; }
.movement-title-row--pair details:nth-of-type(2)[open] ~ .pair-panel--2 { display: grid; }
.movement-title-row__lead { color: var(--muted); font-size: 0.82rem; font-weight: 600; }
/* STR-048, 27.1: a superset card's two title lines, "How to do it" and
   "Swap", sit 4px apart. Each link gives up the 34px line box a single
   movement's title line keeps, the disclosure drops the strut its own line
   box would add under the summary, and the second line starts 4px under
   the first. */
.movement-title-row--tight > .movement-aside > summary,
.movement-title-row--tight > .movement-title-row__link { min-height: 0; padding: 0; }
/* STR-049, 29.4: the tap target comes back to 34px without moving the
   lines. Each link grows by the same padding above and below its line and
   takes it back with a negative margin of the same size, so the drawn 4px
   gap between the two lines stays. */
.movement-title-row--tight > .movement-aside > summary,
.movement-title-row--tight > .movement-title-row__link {
  --title-link-reach: calc((34px - 1lh) / 2);
  padding-block: var(--title-link-reach);
  margin-block: calc(-1 * var(--title-link-reach));
}
.movement-title-row--tight + .movement-title-row--tight { margin-top: 4px; }
.movement-title-row--tight > .movement-aside { display: flex; }
.movement-aside__panel > p, .movement-aside__panel li { color: var(--muted); font-size: 0.82rem; }
.movement-aside__panel > ul { margin: 0; padding-left: 20px; }
.movement-aside__panel .help-reasons, .movement-aside__panel .boundary-note { margin: 0; }

.pain-fields { display: grid; gap: 18px; padding: 18px; border: 1px solid #e5bd8c; border-radius: var(--radius-sm); background: var(--warning-soft); }
.workout-error { margin-bottom: 18px; }
/* STR-040b, ruling 4: closed by default and opened by the fragment the
   eyebrow points at. No script opens or closes it. */
/* The fragment focuses the panel it opened, so a reader lands in it
   rather than at the top of the page; it is not a ring to draw. */
.session-plan ol { margin: 0; padding: 0 16px 10px; list-style: none; }
.session-plan li { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 0; border-top: 1px solid var(--line); }
.session-plan li > div { display: grid; }
.session-plan li > div span, .session-plan li > span { color: var(--muted); font-size: 0.74rem; }
.session-plan li.is-current > span { color: var(--orange-dark); font-weight: 720; }
.session-plan li.is-muted { opacity: 0.58; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* STR-043, section 19.3 as amended by STR-044, 21.4 and STR-045, rulings 2 to
   6: a bracket is drawn only where the session has a superset, and then every
   movement wears the same one, "A" over a single row and "Superset B" over a
   superset's two. Ruling 3: the bracket is pulled back out to sit close to the
   card's edge, and its own padding carries the rows to where the card's
   content already started, so nothing is indented twice. Ruling 4: no padding
   under the last row, so the bracket ends at its last row's bottom and the
   card's own bottom padding is the only space beneath it. Ruling 6: the label
   sits tight to the bracket's top and to its first row. */
.session-plan li.session-plan-group { display: block; margin-left: -12px; padding: 4px 0 0 10px; border-left: 2px solid var(--green); border-radius: 6px 0 0 6px; }
.session-plan-group__label { margin: 0; color: var(--green); font-size: 0.7rem; font-weight: 720; letter-spacing: 0.06em; text-transform: uppercase; }
/* Named through `.session-plan` so it outranks the card's own `ol` padding,
   which was indenting the rows a second time (ruling 3) and hanging 10px of
   the bracket below its last row (ruling 4). */
.session-plan .session-plan-group__rows { margin: 0; padding: 0; list-style: none; }
.session-plan-group__rows li:first-child { border-top: 0; padding-top: 2px; }
.session-plan-group__rows li:last-child { padding-bottom: 0; }
/* 16px is the separator between groups, so the rule that used to draw one
   between rows goes: a bracket next to a plain row would otherwise carry a
   line that starts at the bracket and stops short of the row's right end.
   STR-045, ruling 1: it is a bracket-to-bracket rule, so a session with no
   superset keeps the plain ruled list it drew before STR-044. */
.workout-plan .session-plan-list > li.session-plan-group + li.session-plan-group { margin-top: 16px; border-top: 0; }
/* STR-045, ruling 5: two fixed columns inside a bracket. The slot is the
   first, one width whatever it holds ("A", "B1", "C2"), at body size and
   muted; the name starts at the same x on every row because the column never
   changes width. Monospaced, so the digit and the bare letter sit alike. */
.session-plan-row__slot { flex: 0 0 1.6rem; align-self: center; color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.95rem; font-weight: 600; }
.pair-fatigue-note { display: block; color: var(--muted); }
.universal-stop { max-width: 620px; margin: 24px auto 0; color: var(--muted); font-size: 0.75rem; text-align: center; }
.conditioning-grid { display: grid; gap: 16px; }
.conditioning-card { display: grid; gap: 18px; }
.conditioning-card--locked { background: var(--surface-2); }
.conditioning-card__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.conditioning-card__heading > div { display: grid; gap: 4px; }
.status-pill { flex: 0 0 auto; padding: 6px 9px; border-radius: 999px; background: #e5e9e7; color: var(--muted); font-size: 0.7rem; font-weight: 760; }
.status-pill--ready { background: var(--mint-2); color: var(--green); }
.conditioning-dose { display: flex; gap: 12px; }
.conditioning-dose > div { display: grid; min-width: 100px; padding: 13px 15px; border-radius: var(--radius-sm); background: var(--mint-2); }
.conditioning-dose strong { color: var(--green); font-size: 1.45rem; }
.conditioning-dose span { color: var(--muted); font-size: 0.72rem; }
.cue-callout { padding: 12px 14px; border-left: 3px solid var(--orange); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; background: var(--orange-soft); font-weight: 650; }
/* D-193 (owner, 2026-10-02): the attention color belongs to the one
   recommendation on a row, never to a description. */
.advice-callout { margin: 0; padding: 12px 14px; border-left: 3px solid var(--orange); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; background: var(--orange-soft); font-weight: 650; font-size: 0.92rem; }
.advice-callout a { color: inherit; }
.today-pain-line { margin: 0 0 12px; text-align: left; }
/* Owner, 2026-10-02: the finish screen asks nothing about pain; "Something
   hurt" is a quiet tick that reads like a link and opens the fields. */
.pain-reveal { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--green); font-weight: 700; cursor: pointer; }
.pain-reveal input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.pain-reveal span { text-decoration: underline; text-underline-offset: 3px; }
.pain-reveal:has(input:checked) span { text-decoration: none; }
.pain-reveal:has(input:checked) span::after { content: " · recorded"; color: var(--muted); font-weight: 400; }
.pain-reveal:has(input:focus-visible) span { outline: 2px solid var(--green); outline-offset: 2px; }
/* Owner, 2026-10-03: the tick opens the fields with or without the script. */
[data-conditioning-form] .pain-fields { display: none; }
[data-conditioning-form]:has(.pain-reveal input:checked) .pain-fields { display: grid; }
/* CON-030 pass B: the log form's effort switch, hidden where a kind has one. */
.log-walk__effort[hidden] { display: none; }
/* CON-029k: the conditioning page sized to its content on a desktop. */
.main-content:has(.hub-groups) { max-width: 680px; }
.today-pain-choices { display: flex; flex-direction: column; gap: 8px; }
.today-pain-choices form { display: flex; }
.today-pain-choices .button { width: 100%; }
.today-pain-lighter { text-align: center; margin: 8px 0 0; }
@media (min-width: 600px) { .today-pain-choices { flex-direction: row; align-items: center; } .today-pain-choices form { flex: 0 0 auto; } .today-pain-choices .button { width: auto; } .today-pain-lighter { text-align: left; } }
.gate-list { display: grid; gap: 6px; margin: 0; padding-left: 20px; color: var(--muted); font-size: 0.78rem; }

/* The wall-sit module (VAS-001). It is one card among the conditioning
   options visually, but it is a separate opt-in, so its boundary line is
   given the same weight as its summary rather than being footnoted. */
.module-card { display: grid; gap: 16px; }
.boundary-copy { margin: 0; color: var(--green); font-size: 0.85rem; }
.module-week { margin: 0; color: var(--muted); font-size: 0.78rem; font-weight: 700; }
.optional-metrics-note { display: grid; gap: 6px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.82rem; }
/* BIL-001: the read-only tail where the Start button was. Quiet on
   purpose - it is a statement, not a warning, and nothing about it
   nags or counts down. */
.read-only-notice { display: grid; gap: 6px; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.85rem; text-align: left; }
.read-only-notice strong { color: var(--ink); }
.read-only-notice span { color: var(--muted); }
.hold-ratings { display: grid; gap: 18px; text-align: left; }
.format-brief { display: grid; gap: 10px; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); text-align: left; }
.format-brief ol { display: grid; gap: 10px; margin: 12px 0 0; padding-left: 22px; }
.format-brief li span { display: block; margin-top: 2px; color: var(--muted); font-size: 0.74rem; }
.format-brief > p { color: var(--muted); font-size: 0.74rem; }
.format-round-form { display: grid; gap: 12px; text-align: left; }
.format-round-count { display: flex; align-items: baseline; gap: 8px; margin: 0; color: var(--muted); font-size: 0.82rem; }
.format-round-count strong { color: var(--ink); font-size: 2rem; line-height: 1; }
.format-round-button { min-height: 44px; }
/* CON-023c, 16.2 and 16.3: a label beside its field is 8px from it at
   every width, which the set card's line already is under 600px. */
.format-compose-form .movement-row__line, .format-done .movement-row__line { column-gap: 8px; }
.format-movement-list { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.format-movement { display: grid; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.format-movement:last-child { border-bottom: 0; }
.format-movement__choice { display: flex; align-items: center; gap: 12px; min-height: 44px; cursor: pointer; }
.format-movement__choice input { width: 22px; height: 22px; flex: 0 0 auto; margin: 0; }
.format-movement__choice small { display: block; color: var(--muted); font-size: 0.74rem; }
.format-movement__targets { display: grid; gap: 12px; padding-left: 34px; }
.format-movement__targets[hidden] { display: none; }
.hold-rating-form { display: grid; gap: 12px; }
.conditioning-start-form, .conditioning-complete-form { display: grid; gap: 20px; }
.conditioning-runner { display: grid; gap: 12px; max-width: 480px; margin: 0 auto 24px; padding: 14px 0; text-align: center; }
.conditioning-runner .sound-switch, .format-live > .sound-switch { justify-self: end; margin: -8px 0 -8px; }
/* Owner, 2026-10-03: the session column is 480 wide like every form; the
   back link lines up with it and the action under the clock is centered. */
.main-content:has(.conditioning-runner) .workout-topbar,
.main-content:has(.format-runner) .workout-topbar { max-width: 480px; margin-inline: auto; }
/* For time v3 (owner, 2026-10-10): the "In progress" line gets 24px of
   room above the clock card and the result card, once, for every timed
   format's screen. */
.main-content:has(.format-runner) .workout-topbar { margin-bottom: 24px; }
.main-content:has(.format-runner) .format-runner,
.main-content:has(.format-runner) .format-runner--amrap.is-running { padding-top: 0; }
.summary-stat-grid + .button, .summary-stat-grid + .pain-stop-message { margin-top: 12px; }
.log-walk__submit { align-self: flex-end; }
.conditioning-runner__heading { display: grid; gap: 7px; }
.conditioning-runner__heading > p:last-child { color: var(--muted); text-wrap: balance; }
.conditioning-timer { display: grid; gap: 6px; padding: 30px 20px; border-radius: var(--radius); background: var(--green); color: white; box-shadow: var(--shadow); }
.conditioning-timer > span, .conditioning-timer > small { color: #d9ebe3; }
.conditioning-timer strong { font-variant-numeric: tabular-nums; font-size: clamp(3.2rem, 18vw, 6rem); line-height: 1; letter-spacing: -0.05em; }
.conditioning-timer.is-finished { background: var(--orange-dark); }
.conditioning-timer.is-sprint, .conditioning-timer.is-work { background: var(--timer-work); }
.conditioning-timer.is-sprint > span, .conditioning-timer.is-sprint > small,
.conditioning-timer.is-work > span, .conditioning-timer.is-work > small { color: white; }
/* CON-026b: the timed-format clock (and a REHIT's, which shares it) is the
   rest color on every stage but work, with one big word beside the digits:
   GO, REST, WARM UP, COOL DOWN or READY. CON-026c: the word is always
   beside the digits, never above them; a word that does not fit on one
   line stacks on two ("COOL" over "DOWN") at the same size. An EMOM
   minute has no word, and an empty word takes no room. */
.conditioning-timer--go, .conditioning-timer--go.is-finished { background: var(--timer-rest); }
.conditioning-timer--go > span, .conditioning-timer--go > small { color: var(--timer-ink-soft); }
/* Owner, 2026-10-04: green while a clock runs, gray while it is paused. */
.conditioning-timer.is-paused { background: var(--timer-rest); }
.conditioning-timer.is-paused > span, .conditioning-timer.is-paused > small { color: var(--timer-ink-soft); }
.timer-readout { display: flex; flex-wrap: nowrap; align-items: center; gap: 12px; }
.timer-readout > strong { flex: 0 0 auto; }
.conditioning-runner .timer-readout { justify-content: center; }
.timer-word { color: white; font-size: clamp(1.6rem, 9vw, 3rem); font-weight: 800; line-height: 1; letter-spacing: 0.02em; text-transform: uppercase; }
.timer-word:empty { display: none; }
/* CON-023a, section 2: the timed-format runner is left aligned like every
   session screen, one column capped at 680 px on desktop. The card lists
   the plan as rows; the dark clock block keeps everything left inside it. */
.main-content:has(.format-runner) { max-width: 680px; }
.format-runner { display: grid; gap: 12px; max-width: 480px; margin: 0 auto 24px; padding: 14px 0; text-align: left; }
/* Owner, 2026-10-03: the rounds page reads like every other timer page:
   a centered heading and clock, one action spot, sound under it. */
.format-runner__heading { display: grid; gap: 7px; text-align: center; }
.format-runner__heading h1 { margin: 0; }
.format-runner__card { margin: 0; }
/* CON-025a2, ruling 5: a Tabata's step list on the row pattern, 4px between
   a row's lines and 8px each side of the hairline. The pickups' own steps
   show only while theirs is the current row. */
.format-plan[data-plan-ahead="all"] .movement-row { gap: 4px; padding: 8px 0; }
.format-plan[data-plan-ahead="all"] .movement-row:first-child { padding-top: 0; }
.format-plan[data-plan-ahead="all"] .movement-row:last-child { padding-bottom: 0; }
.movement-row > .format-plan__step { display: none; }
.movement-row--current > .format-plan__step { display: flex; }
.format-clock { justify-items: center; gap: 4px; padding: 20px; text-align: center; }
.conditioning-timer > .format-clock__stage { color: white; font-size: 1.12rem; font-weight: 750; line-height: 1.3; }
.conditioning-timer > .format-clock__cue { font-size: 0.82rem; line-height: 1.4; }
.format-clock .timer-readout { margin-top: 8px; }
.format-clock strong { font-size: clamp(3.2rem, 16vw, 4.6rem); }
.format-clock .timer-word { font-size: clamp(1.6rem, 8vw, 2.3rem); }
.conditioning-timer > .format-clock__line { font-size: 0.82rem; font-variant-numeric: tabular-nums; }
/* CON-026c, ruling 2: a title or line with nothing to say takes no room. */
.format-clock > :empty { display: none; }
.format-runner__actions { display: grid; gap: 8px; justify-items: stretch; }
.format-runner__actions [hidden] { display: none; }
.format-runner__actions:not(:has(> :not([hidden]))) { display: none; }
.format-done { display: grid; gap: 12px; }
/* CON-023b, section 14 ruling 5: Stop now (quiet, left) and the sound
   switch (right) share one row, each a 44 px target, no extra gap. */
.format-runner__controls { display: grid; gap: 12px; }
.format-runner__controls .sound-switch { justify-self: end; }

.format-runner__controls .sound-switch { margin: 0; }
.format-runner__controls .sound-switch__button { min-height: 44px; }
.sound-switch__icon { flex: 0 0 auto; }
.format-live { display: grid; gap: 16px; }
.format-live[hidden], .format-finish[hidden] { display: none; }
.format-finish { display: grid; gap: 16px; }
.format-finish > h2 { margin: 0; }
.format-finish > .button--full-phone { justify-self: center; }
.format-runner .stop-line { text-align: center; }
/* The finish is one card; what sits inside it is not a card of its own. */
.format-finish .format-runner__card { padding: 0; border: 0; box-shadow: none; background: none; }
/* CON-023c, section 16.2: the format page is one card, the set card's. */
.card.format-card { max-width: 480px; }
/* CON-025a2: the Swap card's heading sits 8px over its list (COA-006e). */
.format-card .card-heading:has(.field-help):has(+ .format-swap-form) { margin-bottom: 8px; }
.format-swap-form > .button { margin-top: 16px; }
.format-swap-form > .format-rope-question { margin-top: 8px; }
.format-rope-question__ask { margin: 4px 0 0; color: var(--muted); font-size: 0.84rem; }
.format-slot__links { display: inline-flex; gap: 16px; }
.format-slot__links .text-link, .format-add-link { display: inline-flex; min-height: 44px; align-items: center; margin: 0; }
/* Owner, 2026-09-26: the setup card's rows keep the set card's rhythm. The
   fields line holds Reps and Weight side by side and never wraps a label
   away from its box; the Add row and the Rounds row carry no extra air. */
.format-compose-form .format-fields { align-items: center; gap: 6px 10px; }
.format-compose-form .format-fields > .movement-row__label { flex: 0 0 auto; }
.format-compose-form .format-fields > .movement-row__fields { flex: 0 0 auto; }
.format-compose-form .format-fields > .movement-row__label + .movement-row__fields + .movement-row__label { margin-left: 6px; }
.format-compose-form .movement-row--add { padding: 2px 0; }
.format-compose-form .movement-row--rounds { gap: 8px; }
.format-compose-form .format-rope-note { margin: 0; font-size: 0.82rem; align-self: center; }
/* Owner, 2026-09-26, second look: the name line and the fields line sit
   close. The Swap and Remove links keep their 44px tap height but overlap
   the row's air, the row gap is 4px, and a Tabata's "20 s" is one short
   line under the name. */
.format-compose-form .movement-row { gap: 4px; padding: 8px 0; }
.format-compose-form .movement-row:first-child { padding-top: 0; }
.format-compose-form .format-slot__links .text-link, .format-compose-form .format-rope-question .inline-link { margin: -10px 0; }
/* CON-025a: the rope question is one row, the question beside Yes and No. */
.format-compose-form .format-rope-question { flex-wrap: nowrap; align-items: center; }
.format-compose-form .format-rope-question > .movement-row__label { flex: 1 1 auto; font-weight: 600; }
.format-compose-form .format-rope-question > .format-slot__links { flex: 0 0 auto; }
.format-compose-form .movement-row__line > .movement-row__target { line-height: 1.2; }
.format-compose-form .movement-row--add { padding: 0; }
.format-compose-form .movement-row--add .format-add-link { margin: -6px 0; }
/* CON-024, owner 2026-09-26: a preset row reads as a row. The name at body
   size, hairlines above and below the list, Start no taller than the row. */
.format-presets { margin: 4px 0 12px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.format-presets .movement-row { padding: 10px 0; }
.format-presets .movement-row:first-child { padding-top: 10px; border-top: 0; }
/* Owner, 2026-09-26: the name and the minutes stack on the left at body
   size, the two lines as tall as the Start beside them; nothing wraps. */
.format-presets .movement-row__line { flex-wrap: nowrap; align-items: center; }
.format-preset__name { display: grid; gap: 2px; min-width: 0; flex: 1 1 auto; }
.format-preset__name .movement-row__label { font-size: 0.92rem; overflow-wrap: anywhere; }
.format-preset__name .movement-row__target { font-size: 0.8rem; }
.format-presets .format-slot__links { flex: 0 0 auto; }
.format-presets .format-slot__links .button { min-height: 36px; padding: 6px 14px; }
.format-presets .format-slot__links .text-link { margin: -4px 0; min-height: 36px; }
.format-compose-form .format-preset-row { width: 100%; }
/* CON-025a2, ruling 1: the Tabata card is one short card. Hairlines only
   between rows: Add a second movement sits under its movement with no rule
   above it, Save as a preset sits 8px under the last row with no rule, and
   Start follows 16px under it. The quiet links keep their 44px tap height
   inside the neighbors' air. */
.format-compose-form--tabata { gap: 8px; }
.format-compose-form--tabata .movement-row--add { margin-top: -8px; border-top: 0; }
.format-compose-form--tabata .format-preset-row { padding: 0; border-top: 0; }
.format-compose-form--tabata .format-preset-row .format-add-link { margin: -12px 0; }
.format-compose-form--tabata > .button--primary { margin-top: 8px; }
/* CON-026, design 22.2: the Timing row, the word and the four steps on one
   line, drawn like the version switch. The chosen step is raised and
   carries aria-current, so the state is not color alone. */
.format-compose-form .movement-row--timing > .movement-row__line { flex-wrap: nowrap; align-items: center; gap: 12px; }
.movement-row--timing > .movement-row__line > .movement-row__label { flex: 0 0 auto; font-weight: 600; }
.format-timing { display: grid; flex: 1 1 auto; grid-template-columns: repeat(4, 1fr); gap: 4px; max-width: 320px; margin-left: auto; padding: 4px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.format-timing a { display: grid; min-height: 44px; place-items: center; padding: 0 4px; border-radius: 8px; color: var(--muted); font-size: 0.83rem; font-weight: 660; text-decoration: none; white-space: nowrap; }
.format-timing a.is-chosen { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.format-timing a:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }
.format-timing__advice { margin: 0; }
/* CON-026, design 22.3: the end card's numbers. The name and its stepper on
   one line; the machine's unit question is a line of quiet choices above;
   "Didn't track it" hides the steppers. */
.format-scores { display: grid; gap: 8px; }
.format-scores .movement-row { gap: 4px; padding: 8px 0; }
.format-scores .movement-row:first-child { padding-top: 0; }
.format-scores .format-score, .format-scores .format-unit { flex-wrap: nowrap; align-items: center; justify-content: space-between; gap: 8px; }
.format-scores .format-score > .movement-row__label, .format-scores .format-unit > .movement-row__label { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.format-scores .format-score > .load-stepper { flex: 0 0 auto; gap: 4px; }
.format-scores .format-score .input-suffix { flex: 0 0 auto; width: 6.5rem; }
.format-scores .format-score .input-suffix input { flex: 1 1 auto; width: 100%; min-width: 0; border: 0; border-radius: 0; box-shadow: none; }
.format-scores .format-score .input-suffix > span { padding: 0 8px; }
.format-scores .format-unit .format-slot__links { flex: 0 0 auto; gap: 8px; align-items: center; }
.format-score__note { display: block; color: var(--muted); font-size: 0.8rem; font-weight: 500; }
.format-scores > .format-untracked { margin: -12px 0; }
.format-unit__choice { display: inline-flex; min-height: 44px; align-items: center; color: var(--green); font-size: 0.86rem; font-weight: 700; cursor: pointer; }
.format-unit__choice:has(input:checked) { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
.format-unit__choice:has(input:focus-visible), .format-untracked:has(input:focus-visible) { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.format-score__caption { display: none; }
.format-score__caption--chosen { display: inline; }
.format-scores li:has(input[value="WATTS"]:checked) .format-score__caption,
.format-scores li:has(input[value="METERS"]:checked) .format-score__caption { display: none; }
.format-scores li:has(input[value="WATTS"]:checked) .format-score__caption--watts,
.format-scores li:has(input[value="METERS"]:checked) .format-score__caption--meters { display: inline; }
.format-untracked { display: inline-flex; min-height: 44px; align-items: center; justify-self: start; color: var(--green); font-size: 0.86rem; font-weight: 700; cursor: pointer; }
.format-untracked__on { display: none; }
.format-untracked:has(input:checked) .format-untracked__on { display: inline; }
.format-untracked:has(input:checked) .format-untracked__off { display: none; }
.format-scores:has(.format-untracked input:checked) > .movement-rows { display: none; }
.format-results { display: grid; gap: 4px; margin: 0 0 16px; padding: 0; list-style: none; }
@media (min-width: 600px) {
  .format-runner__actions { justify-items: center; }
  .format-runner__controls > .button { justify-self: center; }
  .hold-action { display: grid; justify-items: center; }
  .hold-action > .button--full-phone,
  .format-runner__actions > .button--full-phone,
  .conditioning-complete-card .button--full-phone { justify-self: center; }
}
/* REG-007: the maximal-hold clock counts up rather than down. */
.hold-timer { display: grid; gap: 6px; padding: 30px 20px; border-radius: var(--radius); background: var(--green); color: white; box-shadow: var(--shadow); }
.hold-timer > span, .hold-timer > small { color: #d9ebe3; }
/* Owner, 2026-10-03: green only while holding; waiting and done are the
   rest color, as on every other clock. */
.hold-timer[data-hold-timer-running="0"] { background: var(--timer-rest); }
.hold-timer > small:empty { display: none; }
.hold-timer .timer-readout { justify-content: center; }
.hold-timer .timer-word:empty { display: none; }
.hold-timer strong { font-variant-numeric: tabular-nums; font-size: clamp(3.2rem, 18vw, 6rem); line-height: 1; letter-spacing: -0.05em; }
/* EXE-014: the one Sound switch, a quiet control sitting under its clock.
   It sizes to its label on a desktop and goes full width on a phone. */
/* STR-040b, ruling 6: a small quiet control sized to its own words, right
   aligned under Start set, at every width. It was a full-width bordered
   button, which read as a second thing to press. */
.sound-switch { display: flex; justify-content: flex-end; margin: 4px 0; }
/* STR-040c, ruling 5: on the guided card the post is detached and only
   its button is drawn, on the card's heading row. */
.sound-switch--detached { display: none; }
.sound-switch[hidden] { display: none; }
.sound-switch__button { display: inline-flex; min-height: 34px; white-space: nowrap; align-items: center; gap: 6px; width: auto; padding: 4px 0; border: 0; background: none; color: var(--green); font-size: 0.82rem; font-weight: 600; }
.sound-switch__button[aria-pressed="false"] { color: var(--muted); }
.sound-switch__button:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 4px; }
@media (max-width: 599px) {
}
.stop-conditions { display: grid; gap: 8px; margin: 8px 0 0; padding-left: 22px; color: var(--muted); font-size: 0.9rem; }
.round-splits { margin-top: 12px; max-height: 40vh; overflow-y: auto; }
.round-splits ol { display: grid; gap: 6px; margin: 8px 0 0; padding-left: 22px; font-variant-numeric: tabular-nums; font-size: 0.9rem; }
.presentation-mode-line { margin: 0; color: var(--muted); font-size: 0.78rem; }
/* EXE-012: the mode toggle sits directly above the one primary action and
   reads as one control with it. Each option is its own form so the toggle
   works with no JavaScript. */
.mode-toggle { display: flex; gap: 6px; padding: 5px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-2); }
.mode-toggle form { min-width: 0; flex: 1 1 0; }
.mode-toggle__option { display: grid; width: 100%; min-height: 44px; place-items: center; padding: 7px; border: 0; border-radius: 10px; background: none; color: var(--muted); cursor: pointer; font-size: 0.83rem; font-weight: 660; text-align: center; }
.mode-toggle__option[aria-pressed="true"] { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.mode-toggle__option:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }
.optional-metrics { border-top: 1px solid var(--line); padding-top: 4px; }
.optional-metrics summary { display: flex; min-height: 44px; align-items: center; cursor: pointer; color: var(--green); font-size: 0.82rem; font-weight: 700; }
.optional-metrics[open] summary { margin-bottom: 14px; }
.ruck-load { display: inline-grid; justify-self: center; gap: 2px; min-width: 150px; padding: 12px 18px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.ruck-load span, .runner-save-note { color: var(--muted); font-size: 0.78rem; }
.conditioning-complete-card { max-width: 480px; margin-inline: auto; }
.conditioning-runner > .conditioning-complete-card { width: 100%; margin: 0; text-align: left; }
.tag-row { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-row span { padding: 5px 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 0.66rem; font-weight: 700; }
.benchmark-details { margin: 0; }
.benchmark-movements, .benchmark-brief ol { display: grid; gap: 10px; margin: 12px 0 0; padding-left: 22px; }
.benchmark-movements li, .benchmark-brief li { padding-left: 3px; }
.benchmark-movements li span, .benchmark-brief li span { display: block; margin-top: 2px; color: var(--muted); font-size: 0.74rem; }
.benchmark-brief__one { margin: 0; }
.benchmark-brief__one span { display: block; margin-top: 2px; color: var(--muted); font-size: 0.74rem; }
.attestation { display: flex; align-items: flex-start; gap: 10px; padding: 12px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.78rem; }
.attestation input { width: 20px; height: 20px; flex: 0 0 auto; margin: 0; }
.benchmark-brief { display: grid; gap: 10px; padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); text-align: left; }
.benchmark-brief[hidden], [data-before-start][hidden] { display: none; }
.benchmark-brief > p { color: var(--muted); font-size: 0.74rem; }
.benchmark-score { display: grid; gap: 3px; margin-bottom: 18px; padding: 18px; border-radius: var(--radius); background: var(--mint-2); text-align: center; }
.benchmark-score > span, .benchmark-score > small { color: var(--muted); }
.benchmark-score > strong { color: var(--green); font-size: 2.25rem; line-height: 1; }
.benchmark-score > p { margin-top: 8px; color: var(--muted); font-size: 0.76rem; }
.benchmark-entry { padding-top: 2px; }
.safety-note { display: grid; gap: 4px; margin-top: 22px; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--warning-soft); color: #74422c; font-size: 0.77rem; }
/* D-150: the full stop paragraph above a hard session's Start takes the
   form's own gap rather than the footer's margin. */
.stop-notice { margin-top: 0; }
/* D-150: the short stop line sits just under Stop now: the runner's gap
   less 8px, so 8px under the format runner's controls. */
.stop-line { margin-top: -8px; }
.rest-panel { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 24px; padding: 16px 18px; border: 1px solid #bcd6c8; border-radius: var(--radius); background: var(--mint-2); box-shadow: var(--shadow-sm); }
.rest-panel > div { display: grid; }
.rest-panel .eyebrow { margin: 0; }
.rest-panel strong { color: var(--green); font-size: 2rem; line-height: 1; }
.rest-panel span { margin-top: 5px; color: var(--muted); font-size: 0.78rem; }
.rest-panel.is-finished { border-color: #efc2ab; background: var(--orange-soft); }
.completion-hero { display: grid; justify-items: center; max-width: 620px; margin: 28px auto 26px; text-align: center; }
.completion-mark { display: grid; width: 72px; height: 72px; margin-bottom: 22px; place-items: center; border-radius: 50%; background: var(--green); color: white; font-size: 2rem; }
.completion-hero > p:last-child { max-width: 480px; color: var(--muted); }
.card--danger { border-color: #dda49e; background: var(--danger-soft); color: var(--danger); }
.summary-stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.summary-stat-grid > div { display: grid; padding: 18px; border-radius: var(--radius-sm); background: var(--surface-2); text-align: center; }
.summary-stat-grid strong { font-size: 1.8rem; }
.summary-stat-grid span { color: var(--muted); font-size: 0.75rem; }
/* STR-032 and STR-033: the one line on every set card, and the finish
   screen's card. The card's buttons are sized to their labels, the
   proposal's Yes on the left. */
.set-cue { color: var(--muted); font-size: 0.86rem; line-height: 1.45; margin: 0; }

/* STR-041, section 16.6: where the logged numbers already decided the next
   prescription, the final row states it in one sentence instead of asking.
   It is a statement and not a proposal, so it reads as body text rather than
   as a card or a callout, and sits a touch above the cue's muted weight. */
.movement-decided { font-size: 0.95rem; line-height: 1.5; margin: 0; }

/* Owner, 2026-09-19: the card follows the day sheet's one gap (14px), its
   header row is the eyebrow alone, and "Decide later" is a quiet line under
   whichever stage's buttons are showing. No empty row and no 44px inline
   box: the eyebrow's own margin is the header's whole height. */
.progression-card { display: grid; gap: 14px; }
.progression-card .card-heading { margin-bottom: 0; }
.progression-card .card-heading .eyebrow { margin-bottom: 0; }
.progression-card__later-form { margin: 0; }

.progression-card__text { font-size: 0.95rem; line-height: 1.5; margin: 0; }

.progression-card__later { background: none; border: 0; padding: 0; cursor: pointer; }

/* STR-038: the session-level card. The names under the one question, the
   ticks that narrow it, and the list of proposals with one button for all
   of them. Yes keeps the left and No is pushed to the right end of the
   row, as everywhere else. */
.progression-card__names { margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.5; }

.progression-card__actions .progression-card__no { margin-left: auto; }

/* A quiet Stay is a word beside the line it belongs to, so it sheds the
   button chrome the browser gives every submit, as Later already does. */
.progression-card__stay { background: none; border: 0; padding: 0; cursor: pointer; }

.progression-card__ticks { display: grid; gap: 4px; margin: 0 0 4px; padding: 0; list-style: none; }
.progression-card__ticks label { display: flex; min-height: 44px; align-items: center; gap: 10px; font-size: 0.9rem; }
.progression-card__ticks input { width: 20px; height: 20px; accent-color: var(--green); }

.progression-card__list { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.progression-card__list > li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding-top: 9px; border-top: 1px solid var(--line); }
.progression-card__list > li:first-child { padding-top: 0; border-top: 0; }
.progression-card__list p { flex: 1 1 14rem; margin: 0; font-size: 0.9rem; line-height: 1.5; }
.progression-card__list form { margin: 0; }
/* A step down is its own offer, so its pair takes the full width under the
   line rather than sitting beside it like the quiet Stay. */
.progression-card__down .advice-card__actions { flex-basis: 100%; }
.progression-card__coached { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }

@media (max-width: 599px) {
  /* Under 600px the answers fill the row, which is the app's rule for a
     phone, and the yes-shaped one keeps the left. */
  .progression-card__actions .progression-card__no { margin-left: 0; }
  .progression-card__actions form { flex: 1 1 auto; min-width: min(100%, max-content); }
  .progression-card__actions .button { width: 100%; }
  .progression-card__list > li { align-items: flex-start; }
}

.decision-list { display: grid; gap: 9px; margin-top: 18px; }
.decision-list > div { display: grid; padding-top: 11px; border-top: 1px solid var(--line); }
.decision-list span { color: var(--green-2); font-size: 0.7rem; font-weight: 760; text-transform: uppercase; letter-spacing: 0.08em; }
.decision-list strong { margin-top: 2px; font-size: 0.82rem; }
.session-review { display: grid; gap: 20px; max-width: 620px; margin-inline: auto; }
/* ADM-009: the optional state is one disclosure line with the app's own
   chevron, and the card's padding belongs to the summary and the body
   rather than to the details, so a closed card is one row high. */
.session-review--optional { padding: 0; }
.session-review--optional > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: 14px 22px; cursor: pointer; font-weight: 700; list-style: none; }
.session-review--optional > summary::-webkit-details-marker { display: none; }
.session-review--optional[open] > summary .goal-targets__chevron { transform: rotate(180deg); }
.session-review--optional > .review-form { padding: 0 22px 22px; }
.review-form { display: grid; gap: 20px; }
/* The optional state's quiet submit is sized to its label at every width;
   the expected state's primary one is `button--full-phone`, which is the
   app's own rule (full under 600px, sized to its label above it). */
.review-form > .button--quiet { justify-self: start; }
.duration-evidence { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.78rem; }
.duration-evidence span { color: var(--muted); }
.first-session-exit__options { display: grid; gap: 10px; margin-top: 6px; }
.review-saved { display: flex; align-items: center; gap: 12px; max-width: 620px; margin-inline: auto; }
.review-saved > div { display: grid; }
.review-saved span:last-child { color: var(--muted); font-size: 0.76rem; }
.preflight-list { display: grid; gap: 14px; }
.preflight-list > div { display: flex; align-items: flex-start; gap: 11px; }
.preflight-list > div > div { display: grid; }
.preflight-list span:last-child { color: var(--muted); font-size: 0.78rem; }
.status-warning { display: grid; width: 24px; height: 24px; flex: 0 0 auto; place-items: center; border-radius: 50%; background: var(--warning-soft); color: #74422c; font-weight: 800; }
.testing-boundary { margin-top: 18px; padding: 13px 15px; border-radius: var(--radius-sm); background: var(--warning-soft); color: #74422c; font-size: 0.77rem; }
.evidence-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.evidence-grid .card { display: grid; gap: 2px; margin: 0; padding: 16px; }
.evidence-grid strong { color: var(--green); font-size: 1.7rem; }
.evidence-grid span { color: var(--muted); font-size: 0.72rem; }
.history-list > a { display: flex; min-height: 64px; align-items: center; justify-content: space-between; gap: 14px; padding: 13px 16px; border-bottom: 1px solid var(--line); }
.history-list > a:last-child { border-bottom: 0; }
.history-list > a > div { display: grid; }
.history-list > a span { color: var(--muted); font-size: 0.74rem; }
.weekly-review { margin-top: 28px; }
.weekly-review p:not(.eyebrow) { color: var(--muted); }
.is-hidden { display: none !important; }
/* EQP-001, and WRM-004 ruling 5: Lightest, Heaviest and Step sit side by
   side at every width. Three short numbers fit a phone row, and stacking
   them turned one question into three screens of scrolling. */
.load-set-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.load-set-row .field { margin: 0; }
.load-set-row .input-suffix > span { padding: 0 8px; }
/* A layout rule must never outrank the hidden attribute. */
[hidden] { display: none !important; }
.cue-caption:empty { display: none; }
/* Owner, 2026-09-28: on the timed runner the clock's own line says what is next, so the spoken-cue caption is kept for screen readers only. */
main:has(.format-runner) .cue-caption:not(.cue-caption--alert) { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.cue-caption { margin: 0 0 14px; padding: 10px 14px; border: 1px solid var(--line); border-left: 3px solid var(--green); border-radius: var(--radius-sm); background: var(--surface); font-size: 0.82rem; font-weight: 700; }
/* A safety cue is assertive, so it is read at once and looks urgent too. */
.cue-caption--alert { border-color: #e5bd8c; border-left-color: var(--warning); background: var(--warning-soft); color: var(--warning); }
.checkbox-row, .field label.checkbox-row { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; font-size: 0.85rem; }
.checkbox-row input { width: 20px; height: 20px; flex: none; margin: 0; accent-color: var(--green); }

@media (min-width: 560px) {
  .main-content { padding-right: 28px; padding-left: 28px; }
  .field-grid--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .standalone-card .button--full { width: auto; justify-self: start; min-width: 180px; }
  .field--wide { grid-column: 1 / -1; }
  .option-cards--goals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .day-picker small { display: block; }
  .checkin-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .checkin-form .field, .checkin-form .button { grid-column: 1 / -1; }
  .guidance-grid, .profile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .consistency-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .progress-home-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .photo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
  .conditioning-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .evidence-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .conditioning-card:first-child, .conditioning-card:nth-child(2) { grid-column: span 1; }
  .control-form--inline { grid-template-columns: minmax(0, 1fr) auto; align-items: end; }
  .control-form--inline .button { min-height: 44px; }
  body[data-page="workout"] .main-content { max-width: 680px; }
}

@media (max-width: 430px) {
  .main-content { padding-top: 10px; }
  .health-check-actions { flex-direction: column-reverse; align-items: stretch; }
  .health-check-actions .button { width: 100%; }
  .input-suffix > span { padding: 0 11px; }
  .compact-check-grid { grid-template-columns: 1fr; }
  .unlock-question__row { flex-direction: column; align-items: stretch; }
  .unlock-question__row .button { width: 100%; }
  .segmented { gap: 4px; padding: 4px; }
  .segmented span { padding: 5px; font-size: 0.8rem; }
  .mode-toggle { gap: 4px; padding: 4px; }
  .mode-toggle__option { padding: 5px; font-size: 0.8rem; }
  .option-card > span { min-height: 64px; padding: 11px 13px; }
  .page-header--compact { margin-top: 0; }
  .page-header--compact .eyebrow { margin-bottom: 3px; }
  .workout-hero { padding: 18px; }
  .workout-hero h2 { margin-bottom: 5px; }
  .session-letter { display: none; }
  .movement-list { padding-right: 16px; padding-left: 16px; }
  .calibration-note, .today-adjustment-summary, .today-adjust { margin-right: 16px; margin-left: 16px; }
  .movement-list li { grid-template-columns: 30px minmax(0, 1fr) auto; }
  .equipment-option { min-width: 0; }
  /* Ruling 5: the three inputs stay side by side here too, so each one is
     sized to its four digits and its unit rather than to the row. */
  .load-set-row { gap: 6px; }
  .load-set-row .input-suffix > span { padding: 0 4px; }
  .load-set-row .field .input-suffix input { padding: 9px 6px; }
  /* Two columns, not one chip per row: twenty full-width chips is a
     screen and a half of scrolling before the field they are helping
     with (owner, 2026-09-12). */
  .load-chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .load-chips .chip { width: 100%; min-height: 44px; }
  .load-chips-other input { max-width: none; flex: 1; }
  .workout-history-row { grid-template-columns: 42px minmax(0, 1fr) 14px; }
  .history-dose { grid-column: 2; justify-items: start; text-align: left; }
  .history-arrow { grid-column: 3; grid-row: 1 / span 2; }
}

@media (min-width: 880px) {
  .topbar { display: none; }
  .bottom-nav { display: none; }
  .app-frame { display: grid; min-height: 100vh; grid-template-columns: 220px minmax(0, 1fr); }
  .app-frame--solo { display: block; }
  .side-nav { position: sticky; top: 0; display: flex; height: 100vh; flex-direction: column; gap: 6px; padding: 34px 22px; border-right: 1px solid var(--line); }
  .side-nav::before { content: "Axial Fit"; min-height: 34px; margin: 0 12px 48px; padding-left: 44px; color: var(--ink); font-size: 1.16rem; font-weight: 760; letter-spacing: -0.03em; line-height: 34px; background: url("/static/brand/logo.svg") no-repeat left center / 34px 34px; }
  .side-nav a { min-height: 48px; justify-content: flex-start; gap: 12px; padding: 0 13px; border-radius: 11px; font-size: 0.86rem; font-weight: 650; }
  .side-nav a[aria-current="page"] { background: var(--mint-2); }
  .main-content { padding: 28px 42px 80px; }
  .onboarding-shell { padding: 20px 20px 40px; }
  .onboarding-form { padding: 38px 42px; }
  .photo-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  /* A session cue is a text change and nothing else here. Sound is not a
     motion preference and is deliberately untouched (D-085 ruling 2). */
  .cue-caption, .conditioning-timer, .rest-panel, .set-clock { transition: none !important; animation: none !important; }
}

@media (forced-colors: active) {
  .brand-mark, .status-check, .session-letter, .review-card__number { border: 1px solid CanvasText; }
}

/* EQP-004: the weights people actually own, one tap each. A chip is sized
   to its label and never full width on a wide screen. */
.load-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.load-chips .chip { min-height: 36px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); font-size: 0.8rem; font-weight: 650; cursor: pointer; }
.load-chips .chip[aria-pressed="true"] { border-color: var(--green); background: var(--mint-2); color: var(--green); }
.load-chips .chip:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.18); outline-offset: 2px; }
.load-chips-other { display: flex; gap: 6px; align-items: center; margin: 0 0 8px; }
.load-chips-other input { max-width: 110px; }
.load-chips-other .button { width: auto; min-height: 44px; }

.load-stepper {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.load-stepper .input-suffix {
  flex: 1;
}

.load-stepper__button {
  min-width: 44px;
  min-height: 44px;
  border: 1px solid var(--line, #d5d8de);
  border-radius: 0.6rem;
  background: var(--surface, #fff);
  color: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.load-stepper__button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Warm-up sets (MTH-002): preparation listed above the first working set. */
.warmup-set-list {
  list-style: none;
  margin: 0.75rem 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

.warmup-set-list > li {
  display: grid;
  gap: 0.5rem;
  padding: 0.75rem;
  border: 1px solid rgba(23, 63, 53, 0.18);
  border-radius: 0.6rem;
}

.warmup-set-list > li.is-done {
  opacity: 0.65;
}

.warmup-set-list > li > div {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.warmup-set-form {
  display: grid;
  gap: 0.5rem;
}

.demo-figure {
  margin: 0.75rem 0;
}

.demo-media {
  position: relative;
  width: 100%;
  max-width: 240px;
  aspect-ratio: 9 / 16;
  border-radius: 0.6rem;
  overflow: hidden;
  background: #000;
}

.demo-media > .demo-clip,
.demo-media > .demo-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.demo-poster {
  display: none;
}

.demo-play {
  min-height: 44px;
  min-width: 44px;
  margin-top: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
  .demo-figure:not([data-demonstration-playing]) .demo-clip {
    display: none;
  }

  .demo-figure:not([data-demonstration-playing]) .demo-poster {
    display: block;
  }
}

/* CON-014: the flat conditioning hub. One row per thing you do, 48 px
   summaries, 44 px targets, and no horizontal overflow at 375 px. */

.hub-row {
  /* WEB-003: 68 px of sticky topbar plus 16 px of air, so an anchor jump
     stops hiding the row's own title under the header. Above 720 px the
     topbar is not displayed and the extra margin is harmless. */
  scroll-margin-top: 84px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.hub-row > summary {
  display: flex;
  min-height: 48px;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  cursor: pointer;
  font-size: 0.88rem;
}

.hub-row__name {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 700;
}

/* The row's small line under its name, where the name alone is a label
   ("10-minute test"). */
.hub-row__subtitle { color: var(--muted); font-size: 0.76rem; font-weight: 500; }

.hub-row__dose {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.78rem;
}

.hub-row__chip {
  flex: 0 0 auto;
  padding: 5px 9px;
  border-radius: 999px;
  background: #e5e9e7;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 760;
  text-align: center;
}

.hub-row__chip--ready {
  background: var(--mint-2);
  color: var(--green);
}

.hub-row__body {
  display: grid;
  gap: 10px;
  padding: 12px 14px 14px;
  border-top: 1px solid var(--line);
}
.unlock-question { display: grid; gap: 8px; }
.unlock-question p { margin: 0; font-size: 0.86rem; }
.unlock-question__row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.unlock-question__row .button { flex: none; }

.hub-row__body > p {
  font-size: 0.86rem;
}

.hub-drafts {
  margin-top: 6px;
}

.hub-drafts > summary {
  display: flex;
  min-height: 44px;
  align-items: center;
  cursor: pointer;
  color: var(--green);
  font-size: 0.82rem;
  font-weight: 700;
}

.version-switch { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; padding: 5px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-2); }
.version-switch a { display: grid; min-height: 44px; place-items: center; padding: 7px; border-radius: 10px; color: var(--muted); font-size: 0.83rem; font-weight: 660; text-align: center; text-decoration: none; }
.version-switch a.is-chosen { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.version-switch a:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }
.version-switch small { display: block; color: var(--muted); font-size: 0.72rem; font-weight: 500; }

/* D-096 (5): the card states the session in one line under its name. */

.prescribed-line {
  font-size: 0.95rem;
  font-weight: 700;
}

/* CON-013: a warning is a note with an acknowledgement, never a disabled
   control. Nothing here hides or blocks the Start below it. */

.overload-warning {
  display: grid;
  gap: 4px;
  padding: 12px 14px;
  border: 1px solid #eac59f;
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
  color: #71401e;
  font-size: 0.82rem;
}

.overload-warning strong {
  font-size: 0.88rem;
}

/* PRG-008: the one cadence line Today shows above the signal tiles. It is
   text with links, never a button, and each link is a 44 px target. */
.measurement-prompt {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0 8px;
  margin: -4px 0 12px;
  color: var(--muted);
  font-size: 0.84rem;
  white-space: nowrap;
}

.measurement-prompt a {
  display: inline-flex;
  align-items: center;
  padding: 12px 0;
  color: var(--green);
  font-weight: 700;
}

/* PRF-003: the profile's read-only weight, which is changed on Body. */
.field--readout .field-label {
  display: block;
  margin-bottom: 8px;
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 680;
}

.readout-line {
  margin: 0;
  color: var(--muted);
  font-size: 0.92rem;
}

.readout-line strong {
  color: var(--ink);
}

.inline-link {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  color: var(--green);
  font-size: 0.86rem;
  font-weight: 700;
}

/* PLN-003 (D-094): the declared week on Plan. One 48 px row per session,
   44 px targets, and no horizontal overflow at 375 px. */

.week-declaration { display: grid; gap: 8px; }

.week-declaration__line { font-size: 1rem; font-weight: 700; line-height: 1.4; }

.week-declaration__form { display: grid; max-width: 480px; gap: 14px; padding-top: 4px; }

/* The links inside this form are words in a sentence, and an inline link with
   a 44 px tap height opens every line it sits on to 44 px (PLN-010). */
.week-declaration__form .inline-link { display: inline; min-height: 0; }

/* PLN-016: the day-sheet spacing, applied to Training days. 14 px between
   blocks, a count directly after its label on one line, and a family row
   that is a checkbox, a label and one muted line under it. Nothing here is a
   44 px line box: a description is text, not a tap target. */
.week-count { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

.week-count label { margin: 0; font-size: 0.86rem; font-weight: 650; }

.week-family-list { display: grid; gap: 12px; margin-top: 10px; }

.week-family { display: grid; grid-template-columns: 20px minmax(0, 1fr); align-items: center; column-gap: 10px; row-gap: 2px; }

.week-family__check { width: 20px; height: 20px; margin: 0; accent-color: var(--green); }

.week-family__pick { margin: 0; font-size: 0.86rem; font-weight: 650; cursor: pointer; }

.week-family__about { grid-column: 2; margin: 0; color: var(--muted); font-size: 0.8rem; line-height: 1.45; }

/* The conditioning section has no heading of its own: its count row is the
   heading, styled like "Walks a week" above it, and the families follow
   directly under it (owner, 2026-09-18). */
.week-rotation { display: grid; }

.week-rotation__note { margin: 10px 0 0; }

/* A legend keeps the browser's own 2px of side padding, which leaves
   "Days" a couple of pixels right of "Walks a week" in the same form.
   Everything on Training days starts at the form's left edge. */
.week-declaration__form legend,
.onboarding-form legend { padding-inline: 0; }

.week-time-list { display: grid; gap: 8px; }

.week-time { display: flex; min-height: 48px; align-items: center; justify-content: space-between; gap: 10px; }

.week-time label { margin: 0; font-size: 0.86rem; font-weight: 650; }

.week-time--usual { justify-content: flex-start; gap: 14px; }

/* 44 px, and 44 px exactly. These boxes are not inside a `.field`, so they
   were left with the platform's own control metrics stacked on top of a
   `min-height`, which is what rendered them about 52 px tall on iOS. The box
   is declared here instead of inherited, and the rule is scoped to this form
   so no other form's inputs move. Both are sized to their content. */
.week-declaration input[type="number"],
.week-declaration input[type="time"] {
  height: 44px;
  min-height: 0;
  padding: 0 10px;
  border: 1px solid #cfd2ca;
  border-radius: var(--radius-sm);
  outline: none;
  background: var(--surface);
  appearance: none;
  -webkit-appearance: none;
  line-height: 42px;
}

.week-declaration input[type="number"]:focus,
.week-declaration input[type="time"]:focus {
  border-color: var(--green-2);
  box-shadow: 0 0 0 4px rgba(35, 88, 73, 0.13);
}

.week-declaration input[type="number"] { width: 4.5rem; text-align: center; }
.week-declaration input[type="time"] { width: auto; min-width: 7.5rem; }

.week-strength { max-width: 240px; }

/* D-134: the week switcher, two tabs and the only control in the header.
   The segmented pattern above is radio buttons inside a form; these are two
   addresses, so they are links wearing the same clothes. */
.week-tabs { display: inline-grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; padding: 5px; margin: 0 0 12px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-2); }

.week-tab { display: grid; min-height: 44px; place-items: center; padding: 7px 18px; border-radius: 10px; color: var(--muted); font-size: 0.83rem; font-weight: 660; text-align: center; text-decoration: none; }

.week-tab--current { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }

.week-tab:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }

/* PLN-018: the calendar week's dates on one line under the tabs, a day that
   has gone as a muted record (no link, no color), and the quiet line for a
   week with nothing left. */
.week-range { margin: 0 0 12px; color: var(--muted); font-size: 0.82rem; }
/* PLN-023 (D-205): the week's label on the dates' line, nothing between it
   and the first day. Suggested is orange, the person's week green, a week
   they plan themselves and have not planned is neutral. */
.week-range:has(.week-status) { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.week-status { padding: 4px 10px; border-radius: 999px; font-size: 0.82rem; font-weight: 750; white-space: nowrap; }
.week-status--suggested { background: var(--orange-soft); color: var(--warning); }
.week-status--yours { background: #e6f2ec; color: var(--green); }
.week-status--none { background: #eeece6; color: var(--muted); }
.week-start-actions { display: flex; gap: 10px; margin: 0 0 12px; }
.week-start-actions form { flex: 1; display: flex; }
.week-start-actions .button { flex: 1; }
.week-links { display: flex; align-items: center; gap: 10px; margin: 14px 2px; font-size: 0.95rem; white-space: nowrap; }
.week-links__form { display: inline-flex; margin: 0; }
.week-links .text-link { margin: 0; padding: 0; border: 0; background: none; font: inherit; font-weight: 650; color: var(--green); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.week-links__bar { color: var(--soft); }
.week-start-line { margin: 4px 2px 14px; color: var(--muted); font-size: 0.95rem; }
.week-save + .week-start-line { margin-top: 0; }
.week-start-lines .week-start-line { margin: 4px 2px 6px; }
.week-start-lines { margin-bottom: 8px; }
.week-start__choices { border: 0; margin: 0 0 14px; padding: 0; }
.week-start__choices legend h2 { margin: 0 0 12px; }
.week-start__choice { display: flex; gap: 10px; align-items: flex-start; padding: 12px; margin-bottom: 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; }
.week-start__choice:has(input:checked) { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }
.week-start__choice input { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--green); }
.week-start__choice span { display: grid; gap: 2px; }
.week-start__choice small { color: var(--muted); font-size: 0.92rem; }
.week-start--today { margin-bottom: 16px; }
.today-week-line { margin: 0 0 14px; color: var(--muted); font-size: 0.95rem; }
/* PLN-025b (D-215): the workout style's answers carry a typical time. */
.week-start__choice .style-choice__time { color: var(--green); font-weight: 700; font-size: 0.85rem; }
.style-form__when { margin: -4px 0 12px; color: var(--muted); }
.style-form__note { margin: 0 0 14px; }
@media (min-width: 768px) { .style-form { max-width: 480px; } }

.week-row--past { background: transparent; box-shadow: none; }

.week-row--past .week-row__when strong,
.week-row--past .week-row__name { color: var(--muted); font-weight: 600; }

.week-row__status--past-done,
.week-row__status--past-not-logged,
.week-row__status--past { color: var(--muted); font-weight: 600; }

.week-row__today { color: var(--green); font-weight: 700; }

.week-done { margin: 12px 0 0; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }

.week-done .inline-link { display: inline; min-height: 0; font-size: inherit; }

/* A form is never full width on a desktop, and a button is never wider than
   its own label there. Under 600 px a thumb wants the whole row. */
.week-save { display: flex; }
.week-save .button { width: auto; }

/* Save starts at the form's left edge and is sized to its label (PLN-010). */
.form-actions--start { justify-content: flex-start; margin-top: 4px; padding-top: 0; border-top: 0; }
.form-actions--start .button--primary { min-width: 0; }
/* Owner, 2026-09-28: the account page's small forms carry no divider band
   above their button, and a quiet link that ends a card leaves no extra air
   under it (the 44px tap target overlaps the card's padding). */
.account-card .compact-form .form-actions { justify-content: flex-start; margin-top: 0; padding-top: 0; border-top: 0; }
.account-card > form:last-child > .text-link, .account-card > .text-link:last-child { margin-bottom: -12px; }
/* Owner, 2026-09-28: Download my data and Delete account are buttons, each
   as wide as its words at every width; Delete sits on the right of its card
   with the red outline of an action that removes something, never a fill. */
.account-card__action { display: flex; margin: 12px 0 0; }
.account-card__action--end { justify-content: flex-end; }
.account-button { width: auto; min-height: 44px; padding: 8px 16px; }
.button--remove { border-color: var(--danger); color: var(--danger); }

@media (max-width: 599px) {
  .week-save .button { width: 100%; }
  .form-actions--start .button { width: 100%; }
}

.week-list { display: grid; gap: 8px; }

.week-row {
  display: grid;
  gap: 2px;
  padding: 4px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.week-row__top {
  display: flex;
  min-height: 48px;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.week-row__when { display: grid; flex: 0 0 auto; }

.week-row__when strong { font-size: 0.82rem; font-weight: 720; }

.week-row__when small { color: var(--muted); font-size: 0.74rem; }

.week-row__name { flex: 1 1 auto; min-width: 0; font-size: 0.88rem; font-weight: 700; }

.week-row__dose { flex: 0 0 auto; color: var(--muted); font-size: 0.76rem; }

.slot-chip {
  flex: 0 0 auto;
  padding: 5px 9px;
  border-radius: 999px;
  background: #e5e9e7;
  color: var(--muted);
  font-size: 0.66rem;
  font-weight: 760;
  text-transform: uppercase;
}

.slot-chip--approved { background: var(--mint-2); color: var(--green); }
.slot-chip--completed { background: var(--mint-2); color: var(--green); }
.slot-chip--missed { background: var(--warning-soft); color: #71401e; }
.slot-chip--flagged { background: var(--danger-soft); color: var(--danger); }

/* Owner, 2026-09-16: every row is the strip's row and a link to the day
   sheet, with no control on it. Ruling 9: no Proposed and no Approved; the
   one word that survives is Completed or Missed on a day that has passed. */
.week-row--list { color: var(--text); text-decoration: none; }
/* PLN-023: a day that can be changed carries a chevron, the phone's usual
   "tap to open", with room kept for it so it never sits on the sets. */
.week-row--list.week-row--link { position: relative; padding-right: 34px; }
.week-row--link::after { content: "\203A"; position: absolute; right: 13px; top: 50%; transform: translateY(-50%); color: var(--soft); font-size: 1.5rem; line-height: 1; }

.week-row--list .week-row__dose { margin-left: 0; }

.week-row__status {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 720;
}

.week-row__status--approved, .week-row__status--completed { color: var(--green); }
.week-row__status--missed { color: #71401e; }
.week-row__status--flagged { color: var(--danger); }

.week-row__check { font-weight: 800; }

.week-empty { color: var(--muted); font-size: 0.86rem; }

/* PLN-007 (D-127): the recommended week, its ramps, and the honesty line.

   The button is full width on a phone and sized to its label from 600 px up,
   which is D-119's rule and the standing no-full-width-on-desktop one. The
   ramps and the honesty line are quiet text: the only thing on this block
   that looks like an action is the one tap that accepts something. */

.week-declaration__optional { color: var(--muted); font-size: 0.8rem; margin: 0; }

/* Amendment 4: the day's suggestion for an account with no declared week.
   Quiet by construction. It carries no button, because Today already has
   its one primary action and a suggestion is not a second one. */

/* GOA-002: the benchmark rotation's card, and the read-only cardio target
   the goals form keeps. The actions row puts the list link and Dismiss on
   one line where there is room and stacks them on a phone; the button is
   sized to its label everywhere but the narrowest width. */
.benchmark-suggestion__actions { align-items: center; display: flex; flex-wrap: wrap; gap: 12px 16px; }
.benchmark-suggestion__actions form { margin: 0; }
.target-kept { border: 1px solid var(--line); border-radius: 10px; display: grid; gap: 8px; padding: 12px 14px; }
.target-kept p { font-size: 0.86rem; line-height: 1.5; margin: 0; }

@media (max-width: 599px) {
  .benchmark-suggestion__actions { align-items: stretch; flex-direction: column; }
  .benchmark-suggestion__actions .button { width: 100%; }
}

.week-recommendation__summary { font-size: 0.92rem; line-height: 1.5; margin: 0; }

.week-recommendation__apply { margin: 4px 0 0; }

.button--full-phone { width: 100%; }

/* D-134: one muted line under an unsaved proposal, and only while there is
   something to do about it. The saved week has nothing here at all. */
.week-note { display: grid; gap: 8px; justify-items: start; }

.week-leftout { display: grid; gap: 8px; justify-items: start; margin-top: 8px; }

.week-leftout__line { color: var(--muted); font-size: 0.8rem; line-height: 1.45; margin: 0; }

.week-leftout__line .inline-link { display: inline; min-height: 0; font-size: inherit; }

.week-note__line { color: var(--muted); font-size: 0.8rem; line-height: 1.45; margin: 0; }

/* The same rule the day sheet's about block and the FAQ answers use: a link
   that is words inside a sentence is inline, because an inline-flex link
   carries a 44px minimum and opens every line it sits on to 44px. */
.week-note__line .inline-link { display: inline; min-height: 0; font-size: inherit; }

.week-note__accept { margin: 0; }

.week-note__accept .button,
.week-experienced .button { min-height: 44px; padding: 10px 16px; }

.week-experienced { display: grid; gap: 8px; justify-items: start; margin: 0; }

@media (min-width: 600px) {
  .button--full-phone { width: auto; justify-self: start; min-width: 200px; }
  .conditioning-runner > .button--full-phone { justify-self: center; }
  .week-recommendation__summary,
  .week-note__line,
  .week-leftout__line,
  .week-experienced .field-help,
  .week-declaration__optional { max-width: 480px; }
}

/* Ruling 9 (owner, 2026-09-16): one list, a usual start time above it and
   one Save under it. The field, the list and the button are one form. A rest
   day is a quiet row that still opens its sheet. */
.week-save-form { display: grid; gap: 12px; margin-top: 4px; }

.week-usual { max-width: 480px; }

.week-usual .field-help { margin-top: 6px; }

.week-row--rest .week-row__name { color: var(--muted); font-weight: 600; }

.week-save__hint { color: var(--muted); font-size: 0.8rem; margin: 0; }

/* The "Plan your week" link on the session card's eyebrow: the same words
   as the eyebrow, underlined, and readable on the dark hero. */
.workout-hero__link { color: inherit; font: inherit; letter-spacing: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* AUTH-001: the account page. One device per row at 44 px, a quiet control
   beside it, and nothing on the page that needs JavaScript. */

.device-list { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }

.device-row {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.device-row > div { display: grid; gap: 2px; min-width: 0; }

.device-row strong { font-size: 0.94rem; }

.device-row span { color: var(--muted); font-size: 0.8rem; }

.device-row .button { min-height: 44px; padding: 8px 14px; font-size: 0.84rem; }

.plain-list {
  display: grid;
  gap: 6px;
  margin: 0;
  padding-left: 18px;
  color: var(--muted);
  font-size: 0.9rem;
}

/* The admin surface (AUTH-004, ADM-006, D-121). One layout system for five
   pages: a twelve-column grid, one card, one table, one pill, one row.

   All of it is scoped to the admin surface. Nothing here reaches the app's
   own pages: the tokens are borrowed rather than replaced, which is what the
   nav has done since D-103.

   The four tokens below are the whole vocabulary. `--content` is overridden
   on the body rather than by a second `.main-content` rule, so the app's own
   pages keep their 980 px and the admin pages get the width an operator's
   laptop has. */
body[data-page^="admin_"],
.admin-page {
  --admin-width: 1120px;
  --admin-gap: 16px;
  --admin-pad: 20px;
  --admin-row: 44px;
}

body[data-page^="admin_"] { --content: var(--admin-width); }

/* It wraps rather than pushing the page sideways: five names do not fit on a
   phone in one line, and every admin page used to scroll horizontally at
   375 px because of it. The row gap makes the wrap look deliberate. */
.admin-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  row-gap: 10px;
  gap: 16px;
  margin: 4px 0 20px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  /* ADM-012: the console marks itself, a 4px amber top border. */
  border-top: 4px solid var(--admin);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.86rem;
}

/* ADM-012: the ADMIN eyebrow is an amber pill. Bold, 4px 8px, rounded. */
.admin-nav__title {
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--admin);
  color: var(--admin-ink);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  line-height: 1.2;
  text-transform: uppercase;
}

.admin-nav a { color: var(--muted); font-weight: 650; text-decoration: none; }

.admin-nav a[aria-current="page"] { color: var(--green); }

.admin-nav__exit { margin-left: auto; }

/* Above 600 px the break is not there at all. */
.admin-nav__break { display: none; }

/* Two rows on a phone (D-126). Six items on one wrapping line put "Back to
   the app" wherever it happened to land, which was usually alone under the
   five names, reading as a sixth section. Now the first row is what this
   surface is and the way out of it, and the second row is the surface. */
@media (max-width: 599px) {
  .admin-nav { column-gap: 14px; row-gap: 12px; }

  .admin-nav__title { order: -3; font-size: 0.78rem; }

  /* A quiet pill, so the way out reads as a control and not as a link in the
     same list as the five that stay here. */
  .admin-nav__exit {
    order: -2;
    padding: 6px 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--muted);
    font-size: 0.8rem;
  }

  /* Order, not document position: the span is last in the markup so that
     nothing before the five links can be focused out of reading order. */
  .admin-nav__break {
    order: -1;
    display: block;
    height: 0;
    flex: 1 0 100%;
    margin: 0;
  }
}

/* The grid. Four spans and no more: four are all five pages need, and a span
   class nobody uses is a rule nobody maintains. `stretch` on the track plus
   a flex column on the card is what makes two cards in a row the same
   height, which answers the review's "the cards are all different sizes". */
.admin-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--admin-gap);
  align-items: stretch;
}

.admin-span-3,
.admin-span-4,
.admin-span-6,
.admin-span-12 { grid-column: 1 / -1; }

@media (min-width: 600px) {
  .admin-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .admin-span-3 { grid-column: span 3; }
  .admin-span-4 { grid-column: span 3; }
}

@media (min-width: 880px) {
  .admin-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .admin-span-3 { grid-column: span 3; }
  .admin-span-4 { grid-column: span 4; }
  .admin-span-6 { grid-column: span 6; }
}

/* The card. `.card`'s own 24 px bottom margin is what makes a grid that also
   has a gap look unevenly spaced, so the grid owns the spacing outright. */
.admin-card {
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
  padding: var(--admin-pad);
}

.admin-card h2 { font-size: 1.05rem; }

.admin-card__note { margin: 0; color: var(--muted); font-size: 0.86rem; }

.admin-card > .lede { margin-bottom: 16px; }

.admin-card__foot { margin-top: auto; padding-top: 14px; }

.admin-card__foot .admin-card__note { margin: 0; }

@media (max-width: 599px) {
  .admin-card { --admin-pad: 16px; }
}

/* The stat tile: a number, a label, a supporting line, and the whole tile is
   the anchor so the tap target is the card. Never a pill on a tile. */
.admin-tile {
  display: flex;
  min-height: calc(var(--admin-row) * 2);
  flex-direction: column;
  gap: 2px;
  color: inherit;
  text-decoration: none;
}

.admin-tile__label {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 780;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.admin-tile__figure {
  font-size: 2rem;
  font-weight: 720;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.admin-tile__line { color: var(--muted); font-size: 0.86rem; }

/* The table in a card. A fixed layout, a width per column declared by the
   page, and `anywhere` on the one cell that holds an arbitrary address: that
   is what stops a table pushing its own card sideways, which is the review's
   "the Security table's rules run past the edge of its card". */
.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
  table-layout: fixed;
  text-align: left;
}

.admin-table th {
  padding: 0 12px 8px 0;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.admin-table td {
  padding: 12px 12px 12px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

.admin-table tr:last-child td { border-bottom: 0; }

.admin-table .button { min-height: 40px; padding: 6px 12px; font-size: 0.82rem; }

.admin-table--dense { font-size: 0.82rem; }

.admin-table--dense td { padding: 10px 12px 10px 0; }

.admin-cell--date { white-space: nowrap; font-variant-numeric: tabular-nums; }

.admin-cell--wrap { overflow-wrap: break-word; }
/* Column widths for the admin tables. Inline style attributes are blocked by
   the content-security policy (style-src 'self'), so widths are classes. */
.admin-w-6 { width: 6%; }
.admin-w-10 { width: 10%; }
.admin-w-12 { width: 12%; }
.admin-w-14 { width: 14%; }
.admin-w-16 { width: 16%; }
.admin-w-18 { width: 18%; }
.admin-w-20 { width: 20%; }
.admin-w-22 { width: 22%; }
.admin-w-24 { width: 24%; }
.admin-w-26 { width: 26%; }
.admin-w-28 { width: 28%; }
.admin-w-30 { width: 30%; }
.admin-w-34 { width: 34%; }
.admin-w-36 { width: 36%; }
.admin-w-40 { width: 40%; }
.admin-w-60 { width: 60%; }
.admin-w-70 { width: 70%; }


/* THE ROW-CARD, stated once (D-126).

   Under 600 px a `.admin-table` row is ONE LINE where the data allows, and
   never a stack of four lines with white space down the right of them. What
   milestone 89 shipped was a bordered box per row with one cell per line,
   which on a two-column table meant a card holding "Sign-ins" and "12" on
   separate lines, three quarters of it empty.

   So the row is a flex line: cells sit side by side, wrap only when they run
   out of room, and the one fact that belongs at the right edge says so with
   `--end`. The box becomes a hairline, because a border around one line of
   text is a box drawn around a sentence.

   Two shapes and no more. `--facts` is label left, number right, and
   everything else is the default line. (`--sentence` went with the
   Dashboard's Recent activity table, which is a row list since ADM-010.)
   A third shape means a third rule in this block, not a class invented
   beside the page that needed it. */
@media (max-width: 599px) {
  .admin-table,
  .admin-table tbody,
  .admin-table td { display: block; }

  .admin-table thead,
  .admin-table colgroup { display: none; }

  .admin-table tr {
    position: relative;
    display: flex;
    min-height: var(--admin-row);
    flex-wrap: wrap;
    align-items: center;
    margin: 0;
    padding: 9px 0;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    gap: 2px 10px;
  }

  .admin-table tr:last-child { border-bottom: 0; }

  .admin-table td {
    min-width: 0;
    padding: 0;
    border-bottom: 0;
    overflow-wrap: break-word;
  }

  .admin-table tr:last-child td { border-bottom: 0; }

  /* Scoped to the table, because `.admin-table td` turning every cell into a
     block is the more specific rule it has to beat. */
  .admin-table .admin-col--desk { display: none; }

  /* The fact that belongs at the right edge: a pill, a status, a control.
     `order` rather than a different order in the markup, because the
     desktop's column order is the one its header row names. */
  .admin-table .admin-cell--end {
    order: 9;
    margin-left: auto;
    text-align: right;
  }

  /* Two columns: a label and a number on one line with a hairline under it.
     Security last 24 hours, and the Deployment table. */
  .admin-table--facts tr { min-height: 0; padding: 10px 0; }

  .admin-table--facts td:first-child { flex: 1 1 auto; color: var(--muted); }

  .admin-table--facts td:last-child { margin-left: auto; text-align: right; }

  /* An invite URL cannot share a line with anything at 375 px, so a Links
     row is deliberately two: the note, the uses, the expiry and Cancel, then
     the URL under them. There is no Copy button, because adding one means
     adding a script to a surface that has none, and a phone already copies
     selectable text on its own. */
  .admin-table .admin-cell--url {
    order: 10;
    flex: 1 1 70%;
    margin-top: 2px;
  }

  /* Cancel sits at the right of the URL's line rather than the facts' line.
     At 375 px the note, the uses and the expiry already fill the first line,
     so a button pinned to its right edge wrapped to a line of its own and
     the row became three. Beside the URL it is still the right edge of the
     row, it is still the last thing read, and the row is two lines. */
  .admin-table .admin-cell--end-url {
    order: 11;
    margin-left: auto;
    text-align: right;
  }

  .admin-table--rowlink tr { padding-right: 22px; }

  .admin-table--rowlink tr::after {
    position: absolute;
    top: 50%;
    right: 2px;
    color: var(--soft);
    content: "\203a";
    transform: translateY(-50%);
  }

  /* The whole row is the link, so the tap target is the row. */
  .admin-rowlink::after {
    position: absolute;
    content: "";
    inset: 0;
  }

  .admin-table .button { min-height: 34px; padding: 4px 11px; font-size: 0.78rem; }

  /* `.inline-link` is 44 px tall because a link a thumb has to find is a
     tap target. A link inside a row-card is not that link: it is a word in
     a line, and 44 px of it is what turned a two-line People row into
     eighty-five pixels. The tap target is the row, which keeps its own
     44 px `min-height` and, where the table is `--rowlink`, is the anchor. */
  .admin-table .inline-link {
    display: inline;
    min-height: 0;
    font-size: inherit;
    font-weight: 660;
  }

  /* A pill on a row-card is a word at the end of a line, so it is sized to
     sit inside one rather than to be a control of its own: at its shipped
     height it added a line to every People row it appeared on. */
  .admin-table .admin-pill,
  .admin-table .admin-flag {
    padding: 1px 8px;
    font-size: 0.7rem;
    line-height: 1.5;
  }
}


/* An invite URL wraps rather than pushing its card sideways: it was `nowrap`
   while the table had a scrolling wrapper to escape into, and that wrapper is
   what the review asked for the removal of. */
.admin-code { overflow-wrap: anywhere; color: var(--green); font-size: 0.82rem; }

.admin-flag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--mint);
  color: var(--green);
  font-size: 0.7rem;
  font-weight: 720;
}

/* The pill. One class, three modifiers, and nothing else: a pill is a state,
   never a fact. An address, a date, a kind of access and a hostname are
   facts and are plain text. A pill that wraps is a sentence wearing a pill,
   so none of them wrap. */
.admin-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--line);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}

.admin-pill--good { background: var(--mint); color: var(--green); }

.admin-pill--bad { background: var(--danger-soft); color: var(--danger); }

/* The person page's own actions sit side by side and wrap on a phone. */
.admin-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.admin-actions form { margin: 0; }

.admin-actions .button { white-space: nowrap; }

/* A settings row: label, value, sentence, source, button. The button sits on
   the row's own baseline from 600 px up and goes full width below it, which
   is the account page's row shape (D-119) reused rather than reinvented. The
   separator lives inside the card, between two rows, never between cards. */
.admin-setting { display: grid; gap: 6px; padding: 16px 0; }

.admin-setting:first-of-type { padding-top: 0; }

.admin-setting:last-of-type { padding-bottom: 0; }

.admin-setting + .admin-setting { border-top: 1px solid var(--line); }

.admin-setting__label {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 680;
}

.admin-setting__value { margin: 0; font-size: 1.05rem; font-weight: 720; }

.admin-setting__sentence { margin: 0; color: var(--ink); font-size: 0.9rem; }

.admin-setting__source { margin: 0; color: var(--soft); font-size: 0.78rem; }

.admin-setting__action { margin: 4px 0 0; }

.admin-setting__action .button { width: 100%; min-height: var(--admin-row); }

@media (min-width: 600px) {
  .admin-setting {
    grid-template-columns: 190px minmax(0, 1fr) auto;
    align-items: start;
    column-gap: 16px;
  }

  .admin-setting__label { grid-row: 1; grid-column: 1; line-height: 1.9; }
  .admin-setting__value { grid-row: 1; grid-column: 2; }

  .admin-setting__action {
    grid-row: 1;
    grid-column: 3;
    margin: 0;
    justify-self: end;
  }

  .admin-setting__sentence,
  .admin-setting__source { grid-column: 2 / 4; }
  .admin-setting .admin-confirm { grid-column: 1 / -1; }
  .admin-setting__action .button { width: auto; }

  /* Milestone 92. A setting that is the only thing in its own card has the
     card's heading as its label, so it stays one stacked column at every
     width: the three-column row above is for two settings sharing a card,
     and there is no longer a page where that happens. The modifier is on the
     row rather than on the card so a future card holding two of them gets
     the row shape back by leaving it off. */
  .admin-setting--solo {
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
  }

  .admin-setting--solo .admin-setting__value,
  .admin-setting--solo .admin-setting__sentence,
  .admin-setting--solo .admin-setting__source { grid-column: 1; }

  .admin-setting--solo .admin-setting__action {
    grid-row: auto;
    grid-column: 1;
    margin: 6px 0 0;
    justify-self: start;
  }
}

/* ADM-005, D-119. The confirmation opens under the row it belongs to and
   pushes the next row down rather than replacing the page. Yes on the left
   and No on the right; both go full width only under 600 px, Yes first. */
.admin-confirm {
  margin: 16px 0 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.admin-confirm p { margin: 0 0 10px; }

.admin-confirm__buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
}

.admin-confirm__buttons form { margin: 0; }

.admin-confirm__buttons .button { min-height: var(--admin-row); }

@media (max-width: 599px) {
  .admin-confirm__buttons { display: block; }
  .admin-confirm__buttons form { margin: 0 0 10px; }
  .admin-confirm__buttons .button { display: block; width: 100%; }
}

/* The Access page's Billing card: a state name on the left, its count on the
   right, and the whole row a link into the people who are in it. */
.admin-counts { display: flex; flex-direction: column; }

.admin-count {
  display: flex;
  min-height: var(--admin-row);
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border-bottom: 1px solid var(--line);
  color: inherit;
  font-size: 0.9rem;
  text-decoration: none;
}

.admin-count:last-child { border-bottom: 0; }

.admin-count__total { font-variant-numeric: tabular-nums; font-weight: 720; }

.admin-count--danger .admin-count__total { color: var(--danger); }

/* The People page's filter bar: one GET form, so a filtered view is an
   address that reloads and shares. No script anywhere on it. */
.admin-filters { display: grid; gap: 12px; margin: 0; }

/* The fieldset is there for the visually hidden legend and nothing else: a
   browser's default box around it would be a second card inside a card. */
.admin-filters fieldset {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  border: 0;
}

.admin-filters__selects {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

/* Milestone 92. The search input and the button sit on one baseline and the
   help line goes under the whole bar, because a help line between an input
   and the button that acts on it reads as a note about the button. Every
   control in here is 44px tall, which is the row height the rest of the
   admin surface already uses. */
.admin-filters__search {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.admin-filters__search .field { flex: 1 1 220px; margin: 0; }
.admin-filters__search input { min-height: var(--admin-row); }
.admin-filters__selects select { min-height: var(--admin-row); }
.admin-filters__note { margin: 0; color: var(--soft); font-size: 0.8rem; }

.admin-filters .button { min-height: var(--admin-row); }

.admin-filters__buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

@media (min-width: 600px) {
  .admin-filters__search {
    grid-template-columns: minmax(0, 340px) auto;
    align-items: end;
  }

  .admin-filters__buttons { padding-bottom: 2px; }
}

/* AUTH-001 (owner, 2026-09-12): the account page as grouped cards of rows.
   A row is label-left, value-right, on one baseline and 44 px tall; the
   separator lives inside a card and never between two of them; nothing
   sits under a row unless it changes what you would do. Buttons are as
   wide as their labels, and every row stacks under 430 px. */

.account-card { max-width: 560px; padding: 18px 20px; }

.account-card--last { margin-top: 0; }

.account-card h2 {
  margin-bottom: 4px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.account-card__lede { margin-top: 10px; color: var(--muted); font-size: 0.9rem; }

.account-card__lede strong { color: var(--ink); }

.account-rows { display: grid; margin-top: 6px; }

.account-row {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding: 6px 0;
  border-top: 1px solid var(--line);
}

.account-rows > .account-row:first-child { border-top: 0; }

.account-row__label {
  min-width: 0;
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 660;
}

.account-row__value {
  display: flex;
  gap: 14px;
  align-items: center;
  min-width: 0;
  color: var(--ink);
  font-size: 0.9rem;
  text-align: right;
  overflow-wrap: anywhere;
}

.account-row__value--quiet { color: var(--muted); font-size: 0.84rem; }

.account-row__action { margin: 0; }

.account-row--actions { gap: 10px; justify-content: flex-start; padding-top: 14px; }

.account-row--actions form { margin: 0; }

.account-row--actions .button { min-height: 44px; padding: 10px 18px; }

.account-actions { display: flex; gap: 10px; max-width: 560px; margin-top: 18px; }

.account-actions form { margin: 0; }

/* AUTH-005 (owner, 2026-09-28): one line per fact at every width. The
   label on the left, its value, switch or quiet link on the right of the
   same line; rows 8px apart and no divider. A value too long for the line
   wraps under its label rather than the whole row stacking. A quiet link
   keeps its 44px target by giving the extra back as negative margin. */
.account-lines { display: grid; gap: 8px; margin-top: 8px; }
.account-card > .account-line { margin-top: 8px; }
.account-line { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.account-line__label { flex: 0 1 auto; min-width: 0; color: var(--ink); font-size: 0.9rem; font-weight: 660; }
.account-line__value { min-width: 0; margin-left: auto; color: var(--ink); font-size: 0.9rem; text-align: right; overflow-wrap: anywhere; }
.account-line__muted { color: var(--muted); font-size: 0.84rem; font-weight: 400; }
/* A long sign-in address ends in "..." on one line rather than breaking
   mid-word; the full address is its title (owner, 2026-09-28). */
.account-line__label--keep { flex: none; }
.account-line__value--clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
.account-line > form { flex: 0 0 auto; margin: 0 0 0 auto; }
.account-line .text-link { margin: -12px 0; }
.account-line__note { margin: 4px 0 0; color: var(--muted); font-size: 0.84rem; }

/* The date of birth on one line: label, box, Save (the COA-009e button
   rule below sizes Save). */
.account-birthday { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 0; }
.account-birthday label { flex: 0 0 auto; margin: 0; color: var(--ink); font-size: 0.9rem; font-weight: 660; }
.account-birthday input { flex: 1 1 144px; min-width: 0; max-width: 240px; min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); outline: none; background: var(--surface); font: inherit; }
.account-birthday input:focus { border-color: var(--green-2); box-shadow: 0 0 0 4px rgba(35, 88, 73, 0.13); }

/* Sign out, the page's one painted button, with Sign out everywhere as a
   quiet link beside it. */
.account-signout { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; margin-top: 16px; }
.account-signout form { margin: 0; }
.account-signout .button { width: auto; min-height: 44px; padding: 8px 16px; }
.account-signout .text-link { margin: -12px 0; }

/* Privacy and Terms, under every card. */
.account-footer { display: flex; align-items: baseline; gap: 8px; max-width: 560px; margin: 0; }
.account-footer .text-link { color: var(--muted); font-size: 0.82rem; font-weight: 600; }
.account-footer__bar { color: var(--muted); font-size: 0.82rem; }
/* HOM-005: the copyright line, under Privacy and Terms, as quiet as they are. */
.account-footer__copyright { max-width: 560px; margin: 0; color: var(--muted); font-size: 0.82rem; }

/* A form's submit that reads as the text link it is: the password change
   and a per-device sign-out are POSTs, and a POST must not be a link. */
.text-link {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--green);
  cursor: pointer;
  font-size: 0.86rem;
  font-weight: 700;
  text-decoration: none;
}

.text-link:hover { text-decoration: underline; }

.text-link:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }

/* Owner, 2026-09-12: deleting an account must read as destructive, and as
   text rather than a red button - a button invites a press, and the page
   this opens is the real confirmation. `--danger` is the palette token that
   was already on `:root`; nothing else here needs a red. */
.text-link--danger { color: var(--danger); }

@media (max-width: 430px) {
  .account-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 10px 0;
  }

  .account-row__value { text-align: left; }

  .account-row--actions { align-items: stretch; gap: 10px; }

  .account-row--actions .button { width: 100%; }

  .account-actions { flex-direction: column; }
}

/* MSG-001: the announcement card on Today, the compose page's preview, and
   the one switch on the account page. The card is the ordinary card with
   paragraph spacing inside its body; the Dismiss button under it is sized to
   its label, because it is not the action of the page. */
.announcement-card .announcement-body { margin: 2px 0 16px; }
.announcement-body p { margin: 0 0 12px; }
.announcement-body p:last-child { margin-bottom: 0; }
.announcement-body a { color: var(--green); text-decoration: underline; }
.announcement-preview { max-width: 560px; margin: 0 0 18px; }
.admin-error { margin: 0 0 18px; padding: 12px 14px; border: 1px solid #e0c3b3; border-radius: var(--radius-sm); background: #fbf1ec; color: #7d3a17; font-size: 0.9rem; font-weight: 590; }
.admin-preview { max-width: 560px; margin: 0 0 18px; padding: 14px; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font-size: 0.84rem; white-space: pre-wrap; }
/* The account page's one switch. A form POST with `aria-pressed` set on the
   server, so it works with JavaScript off and says whatever the database
   says. Sized to its label like every other button in this product. */
.switch { display: inline-flex; min-width: 62px; min-height: 36px; align-items: center; justify-content: center; padding: 0 14px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--muted); font-size: 0.86rem; font-weight: 700; cursor: pointer; }
.switch[aria-pressed="true"] { border-color: #bed7ca; background: var(--mint-2); color: var(--green); }
.switch:focus-visible { outline: 4px solid rgba(232, 111, 61, 0.25); outline-offset: 2px; }
/* The two review pages (PRG-007, PRG-008). A bar here is a <progress>
   element and never a div with an inline width: the CSP is style-src 'self',
   so the percentage width every other implementation of a bar uses is
   refused exactly as an inline script would be. */
.review-stats {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin: 18px 0 6px;
}

.review-stats > div {
  display: grid;
  gap: 4px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.review-stats strong { font-size: 1.5rem; }

.review-stats span { color: var(--muted); font-size: 0.76rem; }

/* `minmax(0, 1fr)`, not the default `auto`: an auto track's floor is its
   item's min-content width, so one long card would widen the column past a
   375 px phone and take the whole page sideways with it. The class is
   `review-panel` and not `review-card`, which the session-review card at
   the top of this file already owns and lays out as a flex row. */
.review-panels { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr); }

.review-panel { min-width: 0; margin-bottom: 0; }

.review-panel .card-heading { margin-bottom: 14px; }

.review-panel h3 { margin: 0; font-size: 1.05rem; }

.review-panel details { margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--line); }

.review-panel summary { display: flex; min-height: 44px; align-items: center; cursor: pointer; color: var(--green); font-size: 0.78rem; font-weight: 700; }

.review-panel details p { color: var(--muted); font-size: 0.8rem; }

/* The reason code is one long unbroken token and a phone is 375 px wide: it
   wraps mid-word here, or it pushes the whole page sideways. */
.review-panel code { display: inline-block; margin-top: 9px; color: var(--soft); font-size: 0.65rem; overflow-wrap: anywhere; }

.review-dose {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  margin-bottom: 12px;
}

.review-dose > div { display: grid; gap: 3px; }

.review-dose span { color: var(--muted); font-size: 0.74rem; }

.review-dose strong { font-size: 0.94rem; }

.review-ceiling {
  margin: 4px 0 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--mint-2);
  color: var(--green);
  font-size: 0.84rem;
}

.review-pause {
  margin: 4px 0 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
  color: #71401e;
  font-size: 0.84rem;
}

.review-trend { margin: 14px 0 4px; }

.review-trend__title { margin: 0 0 8px; font-size: 0.8rem; font-weight: 700; }

.review-trend__row {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  margin-bottom: 6px;
  color: var(--muted);
  font-size: 0.76rem;
}

.review-trend__row strong { color: var(--ink); font-size: 0.8rem; }

.review-trend__row progress { width: 100%; }

.review-weeks { display: grid; gap: 8px; margin-bottom: 12px; }

.review-weeks__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.78rem;
}

.review-weeks__row:last-child { border-bottom: 0; }

.review-weeks__row strong { color: var(--ink); font-size: 0.86rem; }

.review-weeks__row span { grid-column: 1 / -1; }

.review-alternatives { margin-top: 12px; color: var(--muted); font-size: 0.82rem; }

.review-paging { display: flex; gap: 18px; margin-top: 14px; font-size: 0.86rem; }

.review-paging a { min-height: 44px; display: inline-flex; align-items: center; }

/* MSG-003: the bell, its badge, and the inbox.

   The badge is the count and is absent at zero — the template renders no
   element at all rather than an empty one, so there is nothing to hide. It
   is `aria-hidden`, because the bell's own label already says "Messages, 3
   unread" and a screen reader should hear that once. */
.topbar-end { display: flex; align-items: center; gap: 12px; }
.bell { position: relative; display: inline-flex; width: 40px; height: 40px; flex: none; align-items: center; justify-content: center; border-radius: 50%; color: var(--ink); text-decoration: none; }
.bell:hover { background: var(--surface-2); }
.bell[aria-current="page"] { color: var(--green); }
.bell:focus-visible { outline: 4px solid rgba(35, 88, 73, 0.18); outline-offset: 2px; }
.bell__badge { position: absolute; top: 2px; right: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--orange); color: white; font-size: 0.66rem; font-weight: 760; line-height: 18px; text-align: center; }

/* A row is 60 px, separators live only inside the card, and the unread
   distinction is weight and a dot as well as colour — never colour alone. */
.message-actions { display: flex; margin-bottom: 14px; }
.message-actions .button { width: auto; }
.message-list { padding: 4px 0; }
.message-row { display: flex; min-height: 60px; align-items: center; gap: 12px; padding: 12px 20px; border-bottom: 1px solid var(--line); color: inherit; text-decoration: none; }
.message-list .message-row:last-child { border-bottom: 0; }
.message-row:hover { background: var(--surface-2); }
.message-row:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.18); outline-offset: -3px; }
.message-row__dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: transparent; }
.message-row--unread .message-row__dot { background: var(--orange); }
.message-row__text { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 2px; }
/* D-220: the subject is the "(unread)" label's containing block, so the label,
   placed after a long subject that the ellipsis cuts, is clipped with it rather
   than widening the page past a 375px phone. */
.message-row__subject { position: relative; overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.message-row--unread .message-row__subject { font-weight: 760; }
.message-row__sender { color: var(--muted); font-size: 0.8rem; }
.message-row__when { flex: none; color: var(--soft); font-size: 0.78rem; }
.message-empty { padding: 16px 20px; color: var(--muted); }

.message-body p { margin-bottom: 14px; }
.message-body p:last-child { margin-bottom: 0; }
.message-error { margin-bottom: 12px; color: var(--danger); font-weight: 640; }
/* Never full width on a desktop: the box caps at 480 px and the button is as
   wide as its label. Under 430 px both fill the row, which is where a thumb
   needs them to. */
.message-reply textarea { display: block; width: 100%; max-width: 480px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); resize: vertical; }
.message-reply__actions { display: flex; max-width: 480px; margin-top: 12px; }
.message-reply__actions .button { width: auto; }

@media (max-width: 430px) {
  .message-actions .button, .message-reply__actions .button { width: 100%; }
  .message-row__when { display: none; }
}

@media (forced-colors: active) {
  .bell__badge, .message-row--unread .message-row__dot { border: 1px solid CanvasText; }
}

/* ADM-010 and ADM-011 (owner, 2026-09-28): the admin person page by
   importance. The header is the name, the state and one muted facts line.
   Under 1024px the page is one column in its HTML order (Access and
   Coaching, Messages, Account, Features and Devices, Recent activity and
   Admin actions); from 1024px the work (Messages, then Recent activity and
   Admin actions) is the wider left column and the facts (Access and
   Coaching, then Features, Account and Devices) the narrower right one.
   Adjacent cards of one column are one grid item. Messages sizes the first
   row, and Access with Coaching spans it and the second, so Recent activity
   starts right under Messages and Account right under Coaching; the last
   row is `1fr`, so neither column pushes the other's last group down. */
.admin-person-header__name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.admin-person-header__name h1 { margin: 0; }
.admin-person-header__name .admin-flag { margin-left: 4px; vertical-align: middle; }
.admin-person-header__facts { margin: 8px 0 0; color: var(--muted); font-size: 0.9rem; }
.admin-dashboard__mode { margin: 8px 0 0; color: var(--muted); font-size: 0.9rem; }

.admin-person { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
.admin-person__group { display: grid; gap: 16px; }
.admin-person .card { max-width: none; margin: 0; }

@media (min-width: 1024px) {
  .admin-person { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); grid-template-rows: auto auto 1fr; }
  .admin-person__messages { grid-area: 1 / 1; }
  .admin-person__group--first-facts { grid-area: 1 / 2 / 3 / 3; }
  .admin-person__group--history { grid-area: 2 / 1 / 4 / 2; }
  .admin-person__group--more-facts { grid-area: 3 / 2; }
}

/* The heading rule (COA-006e): 8px from the heading block to the first row
   or the first label. */
.admin-person .card-heading { margin-bottom: 8px; }
.admin-person .card-heading h2 { margin: 0; }

/* Access in one plain sentence, and the processor's rows under it only for
   somebody who pays. */
.admin-person__fact { margin: 0; color: var(--ink); font-size: 0.9rem; }
.admin-person__fact + .admin-person__after-fact { margin-top: 8px; }

/* The row pattern: label and value on one line, 4px between a row's lines
   when it wraps, 8px either side of the hairline (`.row-list`). A value
   that fits sits at the right edge; one too long for the line drops under
   its label and reads left to right. */
.admin-rows > li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; }
.admin-rows__label { min-width: 0; color: var(--ink); font-size: 0.9rem; font-weight: 660; }
.admin-rows__value { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; min-width: 0; margin-left: auto; color: var(--muted); font-size: 0.84rem; overflow-wrap: anywhere; }
.admin-rows__value--ink { color: var(--ink); font-size: 0.9rem; }
.admin-rows form { margin: 0; }

.admin-person__note { margin: 8px 0 0; color: var(--muted); font-size: 0.84rem; }

/* The Dashboard's Recent activity and the person page's lists (ADM-010,
   ADM-011, one line per row by the owner's ruling of 2026-09-28): the short
   date in a muted fixed column, then the thing in words, and "· who" muted
   at its end where who matters. A long line wraps under the words with a
   hanging indent, never under the date. Hairlines between rows. */
.admin-card__note + .admin-activity { margin-top: 8px; }
.row-list.admin-activity > li { grid-template-columns: 4.5rem minmax(0, 1fr); align-items: baseline; column-gap: 12px; }
.admin-activity__when { color: var(--muted); font-size: 0.82rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.admin-activity__what { min-width: 0; font-size: 0.9rem; overflow-wrap: anywhere; }
.admin-activity__who { color: var(--muted); font-size: 0.82rem; }
/* A name inside a row's sentence is a word in it: a 44px inline link would
   open the line it sits on (PLN-010). */
.admin-activity .inline-link, .admin-rows .inline-link { display: inline; min-height: 0; font-size: inherit; }
.admin-person__empty { margin: 0; color: var(--muted); font-size: 0.9rem; }

/* ADM-012: a security event's row carries a time as well as a date, so its
   muted column is wider; everything else is the admin row pattern. */
.row-list.admin-activity--timed > li { grid-template-columns: 8rem minmax(0, 1fr); }
.admin-person__note + .admin-activity { margin-top: 8px; }
.admin-security__help { margin-top: 12px; }
/* The Dashboard's Security card: its heading is the way in, at the heading's
   own size, and each kind is a word link that keeps the row one line tall. */
.admin-card h2 .inline-link { min-height: 0; font-size: inherit; font-weight: inherit; }
.admin-table--facts .inline-link { min-height: 0; display: inline; font-size: inherit; }
.admin-security__code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; }
.admin-security__pages { display: flex; gap: 16px; margin: 12px 0 0; }
.admin-security__filters { align-items: end; }
.admin-security__filters .admin-filters__buttons { padding-bottom: 2px; }
/* The table's headers are gone under 600px, so its cells say what they are
   there, and a row's time sits over its sentence rather than beside it. */
.admin-security__phone { display: none; }
@media (max-width: 599px) {
  .admin-security__phone { display: inline; }
  .row-list.admin-activity--timed > li { grid-template-columns: minmax(0, 1fr); row-gap: 4px; }
}

/* A card's buttons, at its bottom (ADM-011): bordered, as wide as their
   words, 8px apart. An action that removes or stops something has a red
   outline, and never a red fill. A form that needs typing is a `details`
   whose summary is the button; its panel follows the card's other buttons
   and drops under the whole row while the disclosure is open. Each card
   holds at most one disclosure. */
.admin-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 16px; }
.admin-actions form { margin: 0; }
.admin-actions details { margin: 0; }
.admin-actions summary { list-style: none; }
.admin-actions summary::-webkit-details-marker { display: none; }
.admin-button { width: auto; min-height: 44px; padding: 8px 12px; font-size: 0.84rem; }
.admin-button--remove { border-color: var(--danger); color: var(--danger); }
.admin-button--small { min-height: 32px; padding: 4px 12px; }
.admin-actions__panel { display: none; flex: 1 1 100%; gap: 8px; padding-top: 8px; }
.admin-actions__toggle[open] ~ .admin-actions__panel { display: grid; }
.admin-actions__panel .admin-person__note { margin: 0; }

/* A small form whose every field is its label and its box on one line,
   8px apart, capped at 480px, and its button as wide as its label under
   the boxes. MSG-003's write, the free-access grant and the reasons. */
.admin-lines { display: grid; gap: 16px; max-width: 480px; }
.field.admin-line { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr); align-items: center; gap: 8px; }
.field.admin-line > label { margin: 0; }
.field.admin-line--top { align-items: start; }
.field.admin-line--top > label { padding-top: 12px; }
.field.admin-line input[type="date"] { width: auto; justify-self: start; }
.admin-lines__actions { display: flex; padding-left: calc(4.5rem + 8px); }
.admin-lines__actions .button { width: auto; }

@media (max-width: 430px) {
  .admin-lines__actions { padding-left: 0; }
  .admin-lines__actions .button { width: 100%; }
}

/* PLN-008 (D-127, amendment 5, ruling 9): the week as one list above Save.

   The same `.week-list` and `.week-row` the declared week uses, so the week
   somebody accepts and the week they then read look like one thing. A strip
   row carries no chip and no control, so its own rule only gives the kind
   room to breathe and keeps the time quiet at the end of the row. It stacks
   on a phone the way every other row does and sits across at 1280 because
   `.week-row__top` is a wrapping flex row, which is one markup for both. */

.week-strip { margin: 4px 0 2px; }

.week-row--strip .week-row__top { min-height: 44px; }

.week-row--strip .week-row__dose { margin-left: auto; }

@media (min-width: 600px) {
  .week-strip { max-width: 480px; }
}

/* PLN-008 (D-127): Today reads the approved schedule. `.today-later__row`
   is the quiet row of design section 6.2, a 44 px target that opens the
   session's own page and never a second primary action (D-093 (2)). Every
   card around it is the one Today card (TDY-002, at the end of this file). */

.today-later__row {
  display: flex;
  min-height: 44px;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 700;
  text-decoration: none;
}

/* ADV-001: a line, not a card. It sits between the finished session and the
   one still ahead, and it never takes a control of its own. */
.today-pair-note {
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.45;
  margin: 0 0 10px;
}


/* PRG-001, D-130: advice, the day sheet, and the onboarding question.

   An advice card is never the page's primary action and never a warning: one
   sentence, then one row of two same-height quiet buttons, accept and
   dismiss, with the plain-words "Why ..." link pushed to the row's right end
   (owner, 2026-09-16). Under 600 px the link takes its own line. The dismiss
   carries the sentence's own closing clause as its label, so pressing it is
   agreeing with something the person can read. Every target is at least 44 px
   and every button is sized to its label from 600 px up, which is why none
   of these carry `button--full`. */

.advice-list { display: grid; gap: 0; }

.advice-card { display: grid; gap: 8px; }
.advice-card > .advice-card__label { margin: 0; font-size: 0.72rem; line-height: 1.4; }

.advice-card__reason {
  color: var(--text);
  font-size: 0.88rem;
  line-height: 1.5;
  margin: 0;
}

.advice-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.advice-card__actions form { margin: 0; }

.advice-card__actions .button { min-height: 44px; padding: 10px 16px; }

.advice-card__why {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  margin-left: auto;
  font-size: 0.82rem;
}

@media (max-width: 599px) {
  .advice-card__why { flex-basis: 100%; min-height: 32px; margin: 0; }
}

/* D-130 (4): one quiet line for a screen that has not been answered yet. It
   blocks nothing, so it is styled as the health-check line beside it and not
   as an alert. */
.today-screen-pending {
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.5;
}

/* PLN-011 (3): what is left of "I already train this way" is one line. */
.week-experienced-line {
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
  margin: 0;
}

/* PLN-010: the day sheet. A plain form page, capped like every other form.
   "What is it?" is one grouped dropdown (owner, 2026-09-16), and the quiet
   "Cancel this session" sits under the form as its own small form. */
.day-sheet__state { color: var(--muted); font-size: 0.82rem; margin: 0 0 12px; }

/* Ruling 10: what the day was recommended as, and what the chosen session
   is, each one quiet line. */
.day-sheet__recommended { color: var(--muted); font-size: 0.86rem; margin: 0 0 12px; }

.day-sheet__summary { margin-top: 6px; }

.week-row__summary { display: block; color: var(--muted); font-size: 0.76rem; line-height: 1.4; margin-top: 2px; }

/* Owner, 2026-09-17: a real grid, everything top-aligned. Date and time in
   a fixed first column, the name on the date's line with what it is under
   it, the minutes on the same line at the right. */
.week-row--list { padding: 10px 13px; }

.week-row__grid {
  display: grid;
  grid-template-columns: 5.4rem minmax(0, 1fr) auto;
  align-items: start;
  gap: 2px 10px;
}

.week-row__grid .week-row__when { display: grid; gap: 1px; line-height: 1.25; }

/* The list or the line sits under the name on a wide screen and takes the
   whole row on a phone, where the name column is too narrow for a movement
   and its dose to share a line. */
.week-row__grid .week-row__items, .week-row__grid .week-row__summary { grid-column: 2 / -1; }

/* Owner, 2026-09-18: on a phone the week is not a card of cards. The outer
   card gives its 40px of padding back to the rows, its heading becomes a
   plain heading on the page, and the date takes its own line above the
   name so the name and the minutes have the whole row. Nothing changes at
   600px and up. */
@media (max-width: 599px) {
  .week-row__grid .week-row__items, .week-row__grid .week-row__summary { grid-column: 1 / -1; margin-top: 4px; }
  .week-tabs { width: 100%; margin-bottom: 10px; }
  /* The week page only (PLN-010 section 4): cards within cards leave the
     day rows too narrow on a phone. Training days shares the field styles
     and has no inner cards, so it keeps its own. */
  .week-declaration:not(.week-declaration__form) { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
  .week-row__grid { grid-template-columns: minmax(0, 1fr) auto; }
  .week-row__grid .week-row__when { grid-column: 1 / -1; display: flex; gap: 8px; align-items: baseline; }
}

.week-row__grid .week-row__name { min-width: 0; font-size: 0.88rem; font-weight: 700; line-height: 1.25; }

/* PLN-014: a day with two sessions is still one row. The second name sits
   under the first, in the same columns, with its own time beside it and its
   own length at the right. The date column stays empty so the eye keeps one
   date per row. */
.week-row__grid--more { margin-top: 6px; }

.week-row__at { color: var(--muted); font-size: 0.74rem; font-weight: 500; }

@media (max-width: 599px) {
  .week-row__grid--more .week-row__when { display: none; }
  .week-row__grid--more { grid-template-columns: minmax(0, 1fr) auto; }
}

.week-row__right { display: grid; justify-items: end; gap: 2px; text-align: right; }

.week-row__grid .week-row__dose { line-height: 1.25; padding-top: 1px; }

.week-row__items, .day-sheet__items {
  margin: 2px 0 0;
  padding-left: 1.05rem;
  list-style: disc;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.45;
}

.week-row__items li, .day-sheet__items li { display: flex; justify-content: space-between; gap: 10px; }

.week-row__items li::marker, .day-sheet__items li::marker { color: var(--muted); }

.week-row__item-dose, .day-sheet__item-dose { flex: 0 0 auto; color: var(--text); font-variant-numeric: tabular-nums; }

.day-sheet__items { margin-top: 8px; color: var(--text); font-size: 0.86rem; }
/* Owner, 2026-10-06: Today's card lists a circuit's movements like the Plan. */

.day-sheet__summary, .day-sheet__recommended { line-height: 1.45; }

/* The day sheet: one spacing between blocks, no divider before the
   buttons, the description directly under its field. */
.compact-form.day-sheet { gap: 16px; }

.day-sheet .form-actions { margin-top: 4px; padding-top: 0; border-top: 0; }

.day-sheet__recommended { margin: 0; }

.day-sheet__summary { margin-top: 6px; }

/* PLN-014: "Add another session" and the two Removes are quiet links, not
   buttons, and they submit because the app carries no script. They size to
   their labels and never stretch, at any width. */
.day-sheet__quiet {
  display: inline-flex;
  width: auto;
  min-height: 44px;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--green);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 700;
  cursor: pointer;
}

.day-sheet__add { margin: 0 0 4px; }

/* ADV-001: a note, never a card and never a gate. One quiet line above
   Save, which still saves whatever was asked for. */
.day-sheet__second {
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.day-sheet__note {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.45;
}

/* Owner, 2026-09-18 (D-134 step 3b): there is no move action on the day
   sheet and there will not be one, so the sheet says where moving happens. */
.day-sheet__no-move { margin: 0; font-size: 0.82rem; }

.today-screen-pending { margin: 0 0 14px; }

/* Owner, 2026-09-18, `docs/designs/pln-010-day-sheet-layout.md`. The rest
   day form holds only hidden fields now; its button rides in the action row
   above and names it through `form=`. */
.day-sheet__cancel { display: none; }

/* Item 1: the session line and its equipment tag are one block, 6px under
   the select, 2px apart. */
.day-sheet__about { display: grid; gap: 2px; margin-top: 6px; }
.day-sheet__about p { margin: 0; }
/* The links in it read as words in a sentence, as they do in a FAQ answer
   and in the week head: an inline-flex link with a 44px minimum would open
   every line it sits on to 44px, which was the air the owner saw. */
.day-sheet__about .inline-link { display: inline; min-height: 0; font-size: inherit; }

/* Item 5: a time is 9rem wide, at every width, with Remove beside it. */
.day-sheet__time { display: flex; align-items: center; gap: 14px; }
.compact-form .field .day-sheet__time input[type="time"] { width: 9rem; flex: 0 0 auto; }

/* D-134: the Session select is sized to a session name, 16rem, at every
   width, the same treatment the Time field got. The movement list under
   it keeps the whole row. */
.compact-form .field select.day-sheet__session { width: 16rem; max-width: 100%; }

/* Item 3: the plus beside "Add another session". */
.day-sheet__plus { flex: 0 0 auto; margin-right: 6px; }

/* Item 4: Save then Cancel from the left edge, sized to their labels, and
   the rest day a quiet link at the right end of the same row. On a phone
   Save and Cancel share the row at half width each and the rest day is a
   centred line under them. */
.day-sheet .form-actions { justify-content: flex-start; flex-wrap: wrap; }
.day-sheet .form-actions .button--primary { min-width: 0; }
.day-sheet__rest { margin-left: auto; }

@media (max-width: 599px) {
  .day-sheet .form-actions .button { flex: 1 1 0; width: auto; }
  .day-sheet__rest { flex: 1 1 100%; justify-content: center; margin: 2px 0 0; }
}

/* Design section 9.1: Yes on the left and No on the right, two submits of one
   form, and neither of them the recommended answer. */
.schedule-question__answers { display: flex; gap: 12px; }

.schedule-question__answers .button { flex: 1 1 0; min-height: 44px; }

/* The question itself, which is a question and not a headline: the page
   header names the step and this names what is being asked. */
.schedule-question__ask {
  margin: 0 0 16px;
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.4;
}

.schedule-question__skip { margin: 12px 0 0; }

/* A way past, not a third answer, so it reads as a link rather than a
   button even though it has to be a submit to write nothing. */
.schedule-question__skip .inline-button {
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0.86rem;
  text-decoration: underline;
}

.schedule-ways { display: grid; gap: 20px; }

.schedule-ways__choice { display: grid; gap: 6px; justify-items: start; }

.schedule-ways__choice .button { min-height: 44px; }

@media (min-width: 600px) {
  .advice-card__reason,
  .today-screen-pending,
  .week-experienced-line { max-width: 720px; }
  .day-sheet { max-width: 480px; }
  .schedule-question__answers .button { flex: 0 0 auto; min-width: 120px; }
  /* A form column is capped at 480px on a wide screen, like every other
     form in the app: a two-word answer does not need 900 pixels. */
  .schedule-card { max-width: 480px; }
}

/* --- Routines and the routine editor (STR-036, D-134 step 2) ---------- */

/* The rotation as a list of cards, in order. It is an `ol` because the order
   is the rotation and a screen reader should hear that, but the markers are
   off: a number beside a card that already says "next up" is a second claim
   about the same thing, and on a phone its gutter is 1.4em the rows need. */
/* Owner, 2026-09-18: the list is the same width as the editor. A page of
   cards is still a form-shaped page, so it takes the 480px cap every other
   form on this app takes and goes full width only on a phone. */
.routine-list { display: grid; gap: 14px; margin: 0 0 18px; padding: 0; list-style: none; max-width: 480px; }
.routine-card { display: grid; gap: 10px; }
.routine-card__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.routine-card__name { margin: 0; font-size: 1.02rem; }
/* "Next up" is a marker and not a status chip: the rotation resolves on the
   day, so this says which one is coming and claims nothing else. */
.routine-card__next {
  margin: 0;
  color: var(--green);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: lowercase;
}
.routine-card__movements { display: grid; gap: 3px; margin: 0; padding: 0; list-style: none; }
.routine-card__movements li { display: flex; justify-content: space-between; gap: 12px; font-size: 0.86rem; }
.routine-card__dose { color: var(--muted); white-space: nowrap; }
/* One row of controls, left-aligned with the card's text, each sized to its
   label: the same rule the day sheet's actions follow. */
.routine-card__actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.routine-card__actions .day-sheet__quiet[disabled] { color: var(--muted); cursor: default; }
.routine-card__edit { font-size: 0.86rem; font-weight: 700; }
/* Owner, 2026-09-18: cards at the list's own gap (the card's page margin
   would stack on it), a hairline before each card's Up, Down and Edit row,
   and "New routine" as the quiet plus action directly under the last card. */
.routine-list .card { margin-bottom: 0; }
/* Owner, 2026-09-18 (step 3): a movement name that opens its card is a
   word in a list row, not a 44px inline-flex box, on all three surfaces;
   the row is the tap target. Same rule as the day sheet's description. */
.routine-card__movements .inline-link, .day-sheet__items .inline-link, .movement-list .inline-link {
  display: inline; min-height: 0; font-size: inherit; font-weight: inherit; text-decoration: none; color: var(--green);
}
.routine-card__actions { padding-top: 10px; border-top: 1px solid var(--line); }
.routine-new { margin: 0; max-width: 480px; }
.routine-new a.day-sheet__quiet { text-decoration: none; font-size: 0.92rem; }

/* The editor is a form, so it is capped at 480px like every other form. */
.routine-editor { max-width: 480px; }
.routine-editor__rows { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }
.routine-editor__row { display: grid; gap: 8px; }
/* Each movement is one block: "Movement 1" with Remove at the right on the
   same line, a hairline above every block after the first. */
.routine-editor__row + .routine-editor__row { padding-top: 14px; border-top: 1px solid var(--line); }
.routine-editor__row-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.routine-editor__index { font-size: 0.88rem; font-weight: 680; color: var(--ink); }
.routine-editor__remove { min-height: 0; }
/* Owner, 2026-09-18 (D-134 step 3b): sets, reps and the weight are one row
   at every width, on the card and in the editor alike. Each input holds
   three characters, the joining words sit between them, and the weight ends
   the row with its unit after it. Nothing wraps: four inputs fit 375. */
.routine-editor__dose, .movement-card__dose { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; flex-wrap: nowrap; }
.dose-group { display: grid; gap: 4px; min-width: 0; }
.dose-group__label { font-size: 0.88rem; font-weight: 680; color: var(--ink); white-space: nowrap; }
.dose-fields { display: flex; align-items: center; gap: 6px; }
.dose-join, .dose-unit { font-size: 0.88rem; color: var(--muted); white-space: nowrap; }
.compact-form .dose-fields input { width: 3.5rem; flex: 0 0 auto; padding-left: 8px; padding-right: 4px; text-align: center; }
.field--narrow { width: 5.5rem; flex: 0 0 auto; }
.compact-form .field--narrow input { width: 100%; }
.routine-editor__add { margin: 0; }
.routine-editor__retire { margin: 14px 0 0; max-width: 480px; }

/* STR-036: the small word under an unpinned strength day that is still
   ahead, saying the name is what the rotation will resolve to. */
.week-row__next { color: var(--muted); font-size: 0.72rem; font-weight: 600; }

/* EXE-012 (D-134 step 3): the movement card is a form, so it takes the same
   480px cap the editor and the Routines list take, and its buttons are sized
   to their labels until the page is narrower than a phone. */
.movement-card { max-width: 480px; }
.movement-card__choices { border: 0; margin: 0; padding: 0; display: grid; gap: 8px; }
.movement-card__choices legend { padding: 0; font-size: 0.88rem; font-weight: 680; color: var(--ink); }
.movement-card__choice { display: flex; align-items: center; gap: 10px; font-size: 0.95rem; }
.movement-card__choice input { margin: 0; }
.movement-card__propose { margin: 0; }
.movement-card__remove { display: flex; gap: 14px; flex-wrap: wrap; margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); }

@media (max-width: 599px) {
  .movement-card { max-width: none; }
  /* Four inputs and their joining words have to fit 375 inside the
     card, so the gaps close up rather than the row breaking. */
  .routine-editor__dose, .movement-card__dose { gap: 6px; }
  .dose-fields { gap: 3px; }
  .compact-form .dose-fields input { padding-left: 6px; padding-right: 2px; }
  /* Three full-width buttons need somewhere to go, so the row wraps
     and the two Removes stack under it. */
  .movement-card .form-actions { flex-wrap: wrap; }
  .movement-card__remove { flex-direction: column; align-items: flex-start; gap: 6px; }
  .routine-editor, .routine-editor__retire, .routine-list, .routine-new { max-width: none; }
}

/* STR-037 (D-134 step 4): the unlogged-session card. One row per session,
   the sentence over its two answers, Yes on the left and No pushed to the
   right end of the row. A second question raised by a No is indented under
   the row it belongs to and separated by a rule, so the card reads as one
   question per session rather than as a list of buttons. Both buttons are
   quiet: Today keeps its single primary action. */
.unlogged-card__row + .unlogged-card__row { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }

/* Indented only when it sits under the row it belongs to. A second question
   that is the whole card, because the row above was answered on an earlier
   visit, is the card's one question and aligns with everything else. */
.unlogged-card__row + .unlogged-card__row--follow-up { padding-left: 14px; }

.unlogged-card__question { margin: 0 0 10px; }

/* PLN-019 review: the buttons size to their labels at every width, both
   Yes answers on the left and No at the right end of its line (a second line
   on a phone), inside the usual 480px form cap. */
.unlogged-card__actions { max-width: 480px; }
.unlogged-card__actions .unlogged-card__no { margin-left: auto; }
/* Owner, 2026-10-05: the question on the left, Yes and No together on the
   right; a two-line question sits at about the height of the buttons. When
   Yes is open its two choices take the row under the question. */
.unlogged-card__row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.unlogged-card__row .unlogged-card__question { flex: 1 1 0; min-width: 0; margin: 0; }
.unlogged-card__row .unlogged-card__actions { flex: 0 0 auto; flex-wrap: nowrap; gap: 8px; margin: 0; }
.unlogged-card__row .unlogged-card__actions .unlogged-card__no { margin-left: 0; }
.unlogged-card__row:has(.unlogged-card__yes[open]) .unlogged-card__actions { flex-basis: 100%; }
/* Owner, 2026-10-05: Yes opens the two ways to say what was done; No skips. */
.unlogged-card__yes summary { list-style: none; cursor: pointer; }
.unlogged-card__yes summary::-webkit-details-marker { display: none; }
.unlogged-card__yes[open] { flex-basis: 100%; }
.unlogged-card__actions:has(.unlogged-card__yes[open]) .unlogged-card__no { display: none; }
.unlogged-card__yes[open] summary { display: none; }
.unlogged-card__more { display: flex; flex-wrap: wrap; gap: 8px; }

/* STR-037 (D-134 step 4c): the away card and the lighter-week offer. The
   same shape as one unlogged row, because they are the same kind of thing:
   one sentence, Yes on the left and No at the right end, both quiet. They
   are two cards rather than one, so a person can answer the first without
   being asked the second in the same breath. */
.away-card__question, .return-lighter-card__question { margin: 0 0 10px; }

.away-card__actions .away-card__no,
.return-lighter-card__actions .return-lighter-card__no { margin-left: auto; }

@media (max-width: 599px) {
  .away-card__actions .away-card__no,
  .return-lighter-card__actions .return-lighter-card__no { margin-left: 0; }
  .away-card__actions form,
  .return-lighter-card__actions form { flex: 1 1 auto; min-width: min(100%, max-content); }
  .away-card__actions .button,
  .return-lighter-card__actions .button { width: 100%; }
}

/* ADV-003 rule three (D-134 step 5): the usual-week card. One question and
   two answers, the same shape as the unlogged card's row and deliberately
   its own card: the two are never merged, so they read as two questions.
   Yes on the left, No at the right end, both quiet. */
.usual-week-card__question { margin: 0 0 10px; }

.usual-week-card__actions .usual-week-card__no { margin-left: auto; }

@media (max-width: 599px) {
  .usual-week-card__actions .usual-week-card__no { margin-left: 0; }
  .usual-week-card__actions form { flex: 1 1 auto; min-width: min(100%, max-content); }
  .usual-week-card__actions .button { width: 100%; }
}

/* Rule two's quiet link, on its own line under the no-move hint, and the
   third-day note under the Session select. Both are lines the person reads
   in passing, so neither sizes or colours like a control. */
.day-sheet__usual { margin: 10px 0 0; }

.day-sheet__third-day { margin: 8px 0 0; }

/* STR-040c, ruling 10: End workout is its own page. One question, the
   two buttons with the yes-shaped one on the left, a quiet Cancel, and
   the safety sentence under them, once. */
.workout-end { max-width: 480px; margin: 8px 0 0; }
.workout-end h1 { margin-bottom: 8px; }
.workout-end__line { margin-bottom: 22px; color: var(--muted); }
.workout-end__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.workout-end__cancel { margin: 16px 0 0; }
.workout-end__cancel a { color: var(--green); font-size: 0.84rem; font-weight: 600; }
.workout-end .universal-stop { margin: 18px 0 0; text-align: left; }
@media (max-width: 599px) {
  .workout-end__actions { flex-direction: column; align-items: stretch; }
}

/* STR-040e, rulings 1 and 3: the Swap page and the full-workout plan page.
   Both are read at a comfortable measure rather than edge to edge, and
   their buttons size to their labels until the screen is a phone. */
.workout-swap { max-width: 480px; }
.workout-swap__cancel { margin: 0; }
.workout-swap__cancel a { color: var(--green); font-size: 0.84rem; font-weight: 600; }
.workout-swap__skip { margin: 12px 0 0; }
/* STR-045, ruling 4: the bracket stops at its last row, so the space under
   the list is the card's own bottom padding and nothing else. */
.workout-plan { max-width: 480px; margin-bottom: 20px; padding-bottom: 16px; }
.workout-plan .session-plan-list { margin: 0; padding: 0; }
.workout-plan li:first-child { border-top: 0; }
/* STR-040f: the plan page is the workout overview. Its rows are links
   while the movement is still ahead, and the two workout-level actions
   are closed disclosures whose summary is sized like a heading row. */
.workout-overview__title { max-width: 480px; margin-bottom: 14px; }
.workout-overview__progress { margin: 4px 0 0; color: var(--muted); font-size: 0.82rem; font-weight: 620; }
.session-plan-row { display: flex; flex: 1 1 auto; align-items: center; justify-content: space-between; min-height: 44px; gap: 14px; color: inherit; text-decoration: none; }
/* STR-045, ruling 5: the name is the second fixed column, so it takes the
   width the slot and the status leave rather than being pushed around by
   `space-between`; that is what starts every name at the same x. */
.session-plan-row > div { display: grid; flex: 1 1 auto; min-width: 0; }
.session-plan-row > div span, .session-plan-row > span { color: var(--muted); font-size: 0.74rem; }
.session-plan-row > span:last-child { flex: 0 0 auto; white-space: nowrap; }
.session-plan-list li.is-current .session-plan-row > span:last-child { color: var(--orange-dark); font-weight: 720; }
a.session-plan-row > div strong { color: var(--green); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.workout-plan__action { max-width: 480px; margin-bottom: 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.workout-plan__action > summary { min-height: 50px; padding: 13px 16px; cursor: pointer; color: var(--green); font-size: 0.86rem; font-weight: 700; }
.workout-plan__panel { padding: 0 16px 16px; }
.workout-plan__panel > p { margin: 0 0 12px; color: var(--muted); font-size: 0.82rem; }
.workout-plan__panel .control-form > .button { justify-self: start; }

/* STR-040g, ruling 6: the ramp's skip is the same boxed disclosure, so it
   shares the class outright and adds only the 16px under the ramp card.
   The set form it opens drops its own card chrome, because a card inside a
   box reads as two boxes. Ruling 5: 24px above the button, the same gap the
   answers and the pain switch already have. */
.ramp-card { margin-bottom: 0; }
.ramp-skip { margin-top: 16px; }
/* STR-041, section 16.3: one card per movement, its sets as rows. Each row
   is one line, label left and what it is worth right; the one current row
   opens under its line with the fields and, on a timed movement, the clock.
   Ruling 5 puts the rest on the current row's own line. */
.movement-card { margin-bottom: 0; }
.movement-rows { display: grid; gap: 0; width: 100%; margin: 0; padding: 0; list-style: none; }
.movement-row { display: grid; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.movement-row:first-child { border-top: 0; padding-top: 0; }
.movement-row__line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0; font-size: 0.9rem; }
.movement-row__label { font-weight: 700; }
.movement-row--done .movement-row__label, .movement-row--todo .movement-row__label { color: var(--muted); font-weight: 600; }
.movement-row__value { color: var(--ink); }
.movement-row__target { color: var(--muted); }
.movement-row__rest { display: inline-flex; align-items: baseline; gap: 10px; margin-left: auto; color: var(--green); font-weight: 600; }
.movement-row__rest strong { font-variant-numeric: tabular-nums; }
.movement-row__skip { padding: 0; border: 0; background: none; color: var(--green); font-size: 0.82rem; font-weight: 600; cursor: pointer; }
.movement-row__skip:hover { text-decoration: underline; }
.movement-row__instruction { max-width: 480px; margin: 0; color: var(--muted); font-size: 0.86rem; line-height: 1.45; }
.movement-row.is-resting .movement-row__fields { opacity: 0.55; }
/* STR-044, section 21.2, ruling 2: a row is one line. The open row's fields
   sit on that line, so the fields block is inline rather than a row of its
   own, and it never pushes the rest off the right end. Ruling 4: the rest
   stays at the row's right end, which `margin-left: auto` above still does.
   Ruling 3: the source word sits 2px under its own box and left-aligned to
   it, which is what `.field` being a grid with a 2px gap gives it. */
.movement-row__line > .movement-row__fields { flex: 0 1 auto; width: auto; }
.set-form .movement-row__line .set-input-grid { gap: 6px 10px; }
.set-form .movement-row__line .field { gap: 2px; align-items: start; justify-items: start; }
.set-form .movement-row__line .field > .field-source { margin-top: 0; }
.movement-row--current .movement-row__label { align-self: center; }
/* The unit word after the box, the same muted weight the suffix inside the
   stepper already carries, so "Set 1 [ 10 ] reps" reads as one sentence. */
.set-form .movement-row__line .field--reps { grid-template-columns: auto auto; }
.set-form .movement-row__line .field--reps > input { grid-column: 1; }
.set-form .movement-row__line .field--reps > .field-unit { grid-column: 2; grid-row: 1; align-self: center; color: var(--muted); font-size: 0.82rem; font-weight: 650; }
.set-form .movement-row__line .field--reps > .field-source { grid-column: 1 / -1; }
/* STR-044, 21.4: the superset's split is one quiet link at the bottom of
   the card, the same weight as Skip and beside nothing else. */
.movement-card__split { align-self: start; padding: 0; border: 0; background: none; color: var(--green); font-size: 0.82rem; font-weight: 600; cursor: pointer; }
.movement-card__split:hover { text-decoration: underline; }
/* Under 600px the whole row still has to be one line, and the 44px targets
   are not negotiable, so the two number fields give up the width instead:
   the weight box holds "10.0" and the reps box two digits, which is every
   number either of them is ever asked to show. */
@media (max-width: 599px) {
  .set-form .movement-row__line .set-input-grid { gap: 6px; }
  .set-form .movement-row__line .load-stepper { gap: 4px; }
  .set-form .movement-row__line .field input { padding-right: 3px; padding-left: 3px; text-align: center; }
  .set-form .movement-row__line .field--load .input-suffix input { width: 3.5rem; }
  .set-form .movement-row__line .field--reps > input { width: 3.2rem; }
  .set-form .movement-row__line .field--seconds .input-suffix input { width: 3.5rem; }
  .set-form .movement-row__line .input-suffix > span { padding: 0 5px; font-size: 0.76rem; }
  .set-form .movement-row__line .field--reps > .field-unit { font-size: 0.76rem; }
}
.movement-card__aside { margin: 10px 0 0; }
.movement-card__aside .inline-link { padding: 0; border: 0; background: none; color: var(--green); font-size: 0.82rem; font-weight: 600; cursor: pointer; }
.ramp-skip > .set-form.card { margin: 0; padding: 0 16px 16px; border: 0; border-radius: 0; background: none; box-shadow: none; }
.ramp-save { margin-top: 24px; }
/* STR-049, 29.2: one 16px gap above Save on the movement card, single or
   superset. The button's own 24px no longer stacks on the form's 14px grid
   gap; that gap plus 2px is the whole distance from what sits last above
   the button to its top. */
.movement-card .set-card__actions .ramp-save { margin-top: 0; }
.movement-card > .set-card__actions { margin-top: 2px; }
/* STR-040h, ruling 1: the skip's two submits are the Swap page's scope pair.
   Stacked at 375 with the primary on top, side by side from 600px, each one
   sized to its own label rather than to a shared column.
   One primary per screen: an open skip quiets the ramp card's own button.
   The card is drawn above the skip, so `details[open] ~` cannot reach it;
   `:has()` is that same sibling test run backwards, and it needs no script. */
.ramp-scope-pair { display: flex; flex-wrap: wrap; gap: 10px; width: 100%; }
.ramp-scope-pair .button { flex: 1 0 100%; width: 100%; }
.movement-card:has(~ .ramp-skip[open]) .ramp-save,
.movement-card:has(~ .ramp-skip[open]) .ramp-save:hover {
  border-color: var(--line);
  background: var(--surface);
  color: var(--green);
  box-shadow: none;
}
/* STR-040h, ruling 4: the same muted line the first-workout note uses, with
   Settings inline inside the sentence rather than as a 44px block. */
.set-ramps-off { max-width: 480px; margin: 8px 0 0; color: var(--muted); font-size: 0.78rem; line-height: 1.45; }
.set-ramps-off a { color: var(--green); font-weight: 600; }
.ramp-answers-note { margin: 10px 0 0; color: var(--muted); font-size: 0.82rem; }
.workout-plan__end { margin: 18px 0 0; }
.workout-plan__end a { color: var(--green); font-size: 0.84rem; font-weight: 600; }
@media (max-width: 599px) {
  .workout-swap .form-actions { flex-wrap: wrap; }
  .workout-swap .form-actions .button { flex: 1 0 100%; width: 100%; }
  .workout-plan__panel .button { width: 100%; }
}
@media (min-width: 600px) {
  /* STR-040h, ruling 1: side by side at desktop, each sized to its label. */
  .ramp-scope-pair .button { flex: 0 0 auto; width: auto; }
}
.workout-plan__continue { margin: 16px 0; }
@media (max-width: 599px) { .workout-plan__continue .button { width: 100%; } }
/* STR-050, ruling 1: the dose line sits 8px above the first row on every
   movement card, however many lines it wraps to. The form's 14px grid gap
   less 6px; the heading paragraph carries no margin of its own. */
.movement-card > .set-card__heading-row + .movement-rows { margin-top: -6px; }
.movement-card .set-card__heading { margin: 0; }
/* STR-050, ruling 2: "How do I judge this?" is a small link at the right end
   of the "How did that feel?" line. The summary is lifted onto the legend's
   line; the text it opens flows below the three answers. No box. */
.movement-row__answers { position: relative; }
.movement-row__answers > legend { float: left; width: 100%; padding: 0 9.5rem 0 0; }
.ramp-judge { margin: 0; }
.ramp-judge > summary { position: absolute; top: 0; right: 0; list-style: none; padding: 0; color: var(--green); font-size: 0.78rem; font-weight: 600; line-height: calc(0.88rem * 1.5); cursor: pointer; }
.ramp-judge > summary::-webkit-details-marker { display: none; }
.ramp-judge > summary:hover { text-decoration: underline; }
.ramp-judge > p { max-width: 480px; margin: 10px 0 0; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }
/* STR-050, ruling 1: the feeler row is one line at 375 too, "Feeler
   [ - 10.0 lb each hand + ]", so under 600px its label sits 8px from the
   stepper and the weight box gives up a little width. */
@media (max-width: 599px) {
  .set-form [data-load-ramp] > .movement-row__line { column-gap: 8px; }
  .set-form [data-load-ramp] .movement-row__line .field--load .input-suffix input { width: 3.5rem; }
}

/* STR-051, section 34: the movement question after the set is saved. One
   small card at the top of the next screen, at the form measure. Save is the
   screen's primary, left; Skip is a quiet link, right. While the card is on
   screen the movement card's Save and the finish screen's "Return to today"
   step down, so there is still one painted primary: the same `:has()` test
   the ramp's skip uses, run from the page. */
.after-save-question { display: grid; gap: 14px; max-width: 480px; margin-bottom: 16px; padding: 16px; }
.after-save-question .quick-question { margin: 0; padding: 0; border: 0; min-width: 0; }
.after-save-question__heading { font-size: 1rem; font-weight: 720; }
.after-save-question__actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.after-save-question__skip { padding: 0 4px; border: 0; background: none; cursor: pointer; font-size: 0.86rem; }
.after-save-question__skip:hover { text-decoration: underline; }
.main-content:has(.after-save-question) .movement-card .ramp-save,
.main-content:has(.after-save-question) .movement-card .ramp-save:hover,
.main-content:has(.after-save-question) .after-save-question ~ .button--primary,
.main-content:has(.after-save-question) .after-save-question ~ .button--primary:hover {
  border-color: var(--line);
  background: var(--surface);
  color: var(--green);
  box-shadow: none;
}
/* STR-051, ruling 5: on a row whose field carries a source word ("last
   time", "target"), the label and the unit sit on the middle of the field
   box, and the word hangs under the box. The line's items align to its top
   and the label takes the box's own height, so neither the label nor the
   unit is centered on the box and the word together. */
.set-form .movement-row__line:has(.field-source) { align-items: flex-start; }
.set-form .movement-row__line:has(.field-source) > .movement-row__label { display: flex; align-self: flex-start; align-items: center; min-height: 44px; }
.set-form .movement-row__line:has(.field-source) > .movement-row__rest { align-self: flex-start; min-height: 44px; align-items: center; }
/* At 375 a loaded rep row, "Set 1 [ - 10.0 lb + ] [ 8 ] reps", overran its
   line by a few pixels and dropped the fields under the label. The label's
   gap is 8px under 600px, as the feeler row's already is (STR-050). */
@media (max-width: 599px) {
  .set-form .movement-row__line { column-gap: 8px; }
}

/* CON-022: "Log a walk you already did", under the suggestion. */
.log-walk h2 { font-size: 1.05rem; }
.log-walk > p { margin-top: 4px; }
.log-walk__form { margin-top: 12px; gap: 12px; }
.log-walk__fields { display: flex; flex-wrap: wrap; gap: 16px 12px; align-items: flex-end; }
.log-walk__effort { margin: 0; padding: 0; border: 0; min-width: 0; }
.log-walk__effort legend { display: block; margin-bottom: 4px; font-size: 0.8rem; font-weight: 700; color: var(--muted); }
.swim-log { gap: 12px; }
.swim-log__fields { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
.swim-log .pain-fields { display: none; }
.swim-log:has(.pain-reveal input:checked) .pain-fields { display: grid; }
.compact-form .log-walk__minutes input { width: 5.5rem; }
.compact-form .log-walk__kind select { width: 11rem; max-width: 100%; }
.compact-form .log-walk__when select { width: 9rem; max-width: 100%; }
.action-card div small.action-card__note { margin-top: 4px; color: var(--muted); font-size: 0.74rem; line-height: 1.35; }
.week-everyday { margin-top: 0; color: var(--muted); font-size: 0.84rem; }

/* AI-003 and AI-003b: Eve, as a chat. The conversation fills the page,
   newest at the bottom; Eve's bubbles sit left beside her mark and the
   person's right, with no names. The context line and its way back sit at
   the top; the composer, one field and Send, is pinned to the bottom above
   the phone's bottom navigation. What the rules made of a reply sits under
   Eve's words in the muted voice, and the stored explanation in its own
   inset so it never reads as the model's prose. While a confirm card is on
   screen, Confirm is the one painted primary and Send steps down, by the
   same `:has()` test the set card uses. */
/* Owner, 2026-09-25: the composer sits 16px above the bottom bar (70px), so
   the chat page gives back the frame's 104px bottom padding and keeps 86px. */
body[data-page="assistant"] .main-content { padding-bottom: calc(86px + env(safe-area-inset-bottom)); }
.eve { position: relative; display: flex; flex-direction: column; gap: 14px; max-width: 480px; min-height: calc(100dvh - 164px - env(safe-area-inset-bottom)); }
.eve > * { flex: none; }
/* The #latest anchor is not a flex item, so it takes no gap under the composer. */
.eve > #latest { position: absolute; bottom: 0; }
.eve .eve-push { margin-top: auto; }
.eve-where { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; }
.eve-where .back-arrow { flex: none; }
.eve-where h1 { margin: 0; font-size: 1.05rem; line-height: 1.3; overflow-wrap: anywhere; }
.eve__coach-line { margin: 0; color: var(--muted); font-size: 0.82rem; }
/* AI-010 section 2.1: one sentence about what Eve sees and keeps, only while
   today has no messages yet. */
.eve__about { margin: 0 0 8px; color: var(--muted); font-size: 0.82rem; }
/* The sentence's link is a word in it, not a tap target of its own row. */
.eve__about .inline-link { display: inline; min-height: 0; font-size: inherit; }
.eve__turns { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.eve-turn { display: flex; align-items: flex-end; gap: 8px; max-width: 92%; }
.eve-turn--eve { justify-self: start; }
.eve-turn--mine { justify-self: end; }
.eve-turn > .eve-mark { flex: none; margin-bottom: 2px; }
.eve-bubble { min-width: 0; padding: 10px 14px; border-radius: 14px; overflow-wrap: anywhere; scroll-margin-bottom: 160px; }
.eve-bubble p { margin: 0; }
.eve-bubble--eve { border: 1px solid var(--line); background: var(--surface); border-bottom-left-radius: 4px; }
.eve-bubble--mine { background: var(--surface-2); border-bottom-right-radius: 4px; }
.eve-bubble .eve-bubble__engine { margin-top: 6px; color: var(--muted); font-size: 0.82rem; }
.eve-explain { margin-top: 8px; padding: 10px 12px; border-left: 3px solid var(--green); border-radius: 6px; background: var(--surface-2); font-size: 0.9rem; }
.eve-bubble .eve-explain__label { color: var(--green); font-size: 0.74rem; font-weight: 700; }
.eve-confirm { display: grid; gap: 10px; padding: 16px; }
.eve-confirm__line { margin: 0; font-weight: 700; }
.eve-confirm .field-help { margin: 0; }
.eve-confirm__actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.eve-confirm__actions form { margin: 0; }
.eve-note { margin: 0; color: var(--muted); font-size: 0.9rem; }
/* AI-008 section 5: the accountability line's fixes, each a quiet link to
   the page where the person makes the change, and one quiet Not now. */
.eve-options { display: grid; gap: 8px; margin: 12px 0 0; padding: 0; list-style: none; font-size: 0.9rem; }
.eve-options a { font-weight: 600; }
.eve-options__not-now { margin: 12px 0 0; }
.eve-composer { position: sticky; z-index: 10; bottom: calc(86px + env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 8px; margin: 0; padding: 8px; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); box-shadow: 0 6px 20px rgba(23, 34, 30, 0.08); }
.eve-composer input { flex: 1; min-width: 0; min-height: 44px; border: 0; background: transparent; }
.eve-composer input:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.18); outline-offset: 2px; border-radius: 10px; }
.eve-composer .button { flex: none; min-height: 44px; }
.eve-error { margin: 0; }
.main-content:has(.eve-confirm) .eve-send,
.main-content:has(.eve-confirm) .eve-send:hover {
  border-color: var(--line);
  background: var(--surface);
  color: var(--green);
  box-shadow: none;
}
/* The header mark: a link the size of a tap target around the 28 px circle,
   beside the bell. On the workout pages it sits after the percentage. */
.eve-mark { display: block; }
.eve-mark-link { display: inline-flex; width: 44px; height: 44px; flex: none; align-items: center; justify-content: center; border-radius: 50%; }
.eve-mark-link:focus-visible { outline: 4px solid rgba(35, 88, 73, 0.18); outline-offset: 0; }
.topbar-end .eve-mark-link { margin-right: -8px; }
.workout-shell__header { grid-template-columns: 44px 1fr minmax(48px, auto); }
.workout-shell__header > .workout-shell__end { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }
.workout-shell__header .workout-shell__end .workout-percent { color: var(--green); font-size: 0.8rem; font-weight: 760; letter-spacing: 0; text-transform: none; }
.workout-shell__end .eve-mark-link { margin-right: -8px; }
.side-nav .side-nav__eve .nav-symbol { display: inline-flex; }
/* COA-001a: the consent screen (Agree left, Not now right) and the coach
   forms, one 480px column. Moved here from AI-003b's Eve consent stub. */
.coach-consent { display: grid; gap: 16px; max-width: 480px; }
.coach-consent__actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.coach-consent__actions form { margin: 0; }
/* COA-001b: the coaching screens and Settings on the approved row pattern
   (CON-023 section 18): switches as a tight list at 8px, the sentence under
   a list close to it, a person as a name with the state muted beside it and
   quiet links on the same row, hairlines between rows, and the invite form
   on one line. The links keep 44px by overlapping the row's air. */
/* Owner, 2026-09-26: a switch list reads as a list. The rows keep a 44px tap
   height by overlapping each other's air; the text lines sit 8px apart. */
.switch-list { display: grid; gap: 0; }
.switch-list > .checkbox-row { min-height: 36px; margin: -2px 0; }
.switch-list > legend { margin-bottom: 4px; }
.coach-consent__form > .field-help { margin: -8px 0 0; }
.coach-rows { margin: 0; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.coach-rows .movement-row:first-child { padding-top: 0; border-top: 0; }
.coach-rows .movement-row:last-child { padding-bottom: 0; }
.coach-rows .movement-row__line { flex-wrap: nowrap; align-items: center; }
.coach-row__name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.coach-rows .format-slot__links { flex: 0 0 auto; align-items: center; gap: 8px; }
.coach-rows form { display: inline-flex; margin: 0; }
.coach-rows .text-link { margin: -12px 0; }
.coach-row__bar { color: var(--muted); font-size: 0.82rem; font-weight: 400; }
.coach-card__empty { margin: 0; color: var(--muted); font-size: 0.9rem; }
.coach-invite { display: flex; align-items: center; gap: 8px; max-width: 480px; margin: 16px 0 0; }
.coach-invite label { flex: 0 0 auto; margin: 0; color: var(--ink); font-size: 0.88rem; font-weight: 680; }
.coach-invite input { flex: 1 1 auto; width: auto; min-width: 0; min-height: 44px; padding: 8px 12px; }
.coach-settings > .coach-settings__who { margin: 0 0 12px; color: var(--ink); font-size: 0.9rem; }
/* D-155: while the coach's access is frozen for review the status says so
   and the switches are disabled (owner, 2026-09-28). */
.coach-settings .checkbox-row:has(input:disabled) { color: var(--muted); cursor: not-allowed; }
.coach-settings__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.coach-log { display: grid; gap: 4px; margin: 16px 0 0; padding: 12px 0 0; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.81rem; list-style: none; }
.settings-form .form-actions { margin-top: 0; padding-top: 16px; }
.settings-form .settings-form__lede { margin: 0 0 8px; }
.settings-form .field-grid--two { gap: 16px; }
.settings-form:has(+ .coach-settings) { margin-bottom: 16px; }
/* COA-006 and COA-002: the roster's second line and one client's page on the
   same row pattern. A row's two lines sit 4px apart; the name link, Dismiss,
   the tab links and a session's summary keep 44px by overlapping the row's
   air; the tabs are one row of quiet links with the current one underlined;
   stacked cards sit 16px apart. */
.coach-rows .movement-row { gap: 4px; }
.coach-row__link { display: inline-flex; min-height: 44px; align-items: center; margin: -12px 0; color: inherit; text-underline-offset: 4px; }
.coach-row__detail { color: var(--muted); font-size: 0.82rem; }
.coach-row__end { margin-left: auto; }
.coach-client > .card { margin-bottom: 16px; }
.coach-client__state { color: var(--muted); font-size: 1rem; font-weight: 500; }
.coach-flag { display: flex; align-items: center; gap: 12px; margin: 4px 0 0; }
.coach-flag__sentence { margin: 0; color: var(--ink); font-size: 0.86rem; }
.coach-flag form { display: inline-flex; margin: 0; }
.coach-flag .text-link { margin: -12px 0; }
.coach-client__empty { margin: 0; color: var(--muted); }
.coach-tabs { display: flex; align-items: center; gap: 8px; margin: -12px 0 4px; }
.coach-tab { display: inline-flex; min-height: 44px; align-items: center; color: var(--muted); font-size: 0.9rem; font-weight: 650; text-decoration: none; }
.coach-tab--current { color: var(--ink); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 8px; }
.coach-tab-card__heading { margin: 0 0 8px; font-size: 1rem; }
.coach-tab-card__more { margin: 4px 0 -12px; }
.coach-tab-card__more .text-link { margin: 0; }
.coach-history summary { min-height: 44px; margin: -12px 0; cursor: pointer; list-style: none; }
.coach-history summary::-webkit-details-marker { display: none; }
.coach-history__lines { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; color: var(--muted); font-size: 0.82rem; list-style: none; }
/* COA-006b: an expanded session lists each movement with its change at the
   end, then the session's grouped sentence 8px under the list. */
.coach-history__moves { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; font-size: 0.86rem; list-style: none; }
.coach-history__moves li { display: flex; justify-content: space-between; gap: 12px; }
.coach-history__change { color: var(--muted); white-space: nowrap; }
.coach-photos { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
/* COA-006b: the digest's lines are rows with a hairline between them. */
.message-lines { margin: 0; padding: 0; list-style: none; }
.message-lines li { padding: 12px 0; border-top: 1px solid var(--line); font-size: 0.9rem; }
.message-lines li:first-child { padding-top: 0; border-top: 0; }
.message-lines li:last-child { padding-bottom: 0; }
.message-lines + .message-body__link { margin-top: 16px; }
.coach-photo img { display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius-sm); }
/* COA-006b: the Body readings, on the Body page and a coach's Body tab. A
   heading, its one cadence sentence 4px under it, the trend line 8px under
   that, then the readings as rows; a photo carries its date 4px under it. */
.body-readings > .card { margin-bottom: 16px; }
.body-rows { padding-bottom: 0; border-bottom: 0; }

.body-card__heading { margin: 0 0 4px; font-size: 1rem; }
.body-card__note { margin: 0; color: var(--muted); font-size: 0.82rem; }
.body-card__trend { margin: 8px 0 12px; color: var(--ink); font-size: 0.9rem; font-weight: 650; }
.body-card > .coach-card__empty { margin-top: 8px; }
.coach-photo { color: var(--muted); font-size: 0.78rem; text-decoration: none; }
.coach-photo__date { display: block; margin-top: 4px; }
@media (min-width: 880px) {
  body[data-page="assistant"] .main-content { padding-bottom: 80px; }
  .eve-composer { bottom: 16px; }
  .eve { min-height: calc(100dvh - 104px); }
}
/* NAV-001 section 3: Progress's Body section carries its two quiet links on
   the heading's line. Section 4: a pair rule on the Body form is the field
   group's own error, 8px under it. */
.progress-body-actions { display: flex; flex-wrap: wrap; gap: 16px; }
.progress-body-actions .text-link { margin: -12px 0; }
.field-error { margin: 8px 0 0; color: var(--danger); font-size: 0.81rem; font-weight: 640; }
/* MSG-005: the coaching thread reuses the Eve bubbles; the composer is capped
   at 480px, 16px under the lines; the context links are one quiet line. */
.coach-thread > .card { margin-bottom: 16px; }
.coach-thread__text { white-space: pre-line; }
.coach-thread__composer { max-width: 480px; }
.coach-thread__closed { margin: 0; color: var(--muted); font-size: 0.9rem; }
.coach-thread > .error-summary { margin: 0 0 16px; max-width: 480px; }
.coach-client__message { margin: 4px 0 0; }
/* AUTH-005: "Birthday today", muted, under the client's name. */
.coach-client__birthday { margin: 4px 0 0; color: var(--muted); font-size: 0.86rem; }
.coach-client__message .text-link { margin: -12px 0; }
.coach-message-link { margin: 16px 0 0; }
.coach-message-link .text-link { margin: 0; }
/* COA-006d, owner 2026-09-26: the Body form is the setup card's way. Each
   field is its label and its box on one line, 8px apart, the box sized to
   what it holds, and a help line or an error small under the box. */
.body-lines { display: grid; gap: 16px; }
.field.body-line { display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: 4px 8px; }
.field.body-line > label { margin: 0; }
.field.body-line > .field-help, .field.body-line > .field-error { grid-column: 2 / -1; margin: 0; font-size: 0.75rem; }
.field.body-line .input-suffix input { width: 4.5rem; }
.field.body-line--short .input-suffix input { width: calc(3ch + 28px); }
.field.body-line select { width: auto; }
/* NAV-001 section 9 (COA-006d): the Plan calendar sits in the glyph's box. */
.nav-symbol:has(> .plan-icon) { display: inline-flex; height: 1lh; align-items: center; justify-content: center; }
.plan-icon { display: block; }
/* COA-009: the coach's Plan tab writes and "Your coach set this." */
.coach-plan-form { max-width: 480px; }
.coach-plan-form .format-fields { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.coach-plan-form .field--load, .coach-plan-form .field--reps { flex: 0 0 auto; margin: 0; }
.coach-plan-form .field--load .input-suffix input { width: calc(5ch + 28px); }
.coach-plan-form .format-fields > .movement-row__label { flex: 0 0 auto; min-width: 5em; }
.coach-plan-form .format-fields > .movement-row__fields { flex: 0 0 auto; }
.coach-plan-form .format-fields select, .coach-plan-form__note { flex: 1 1 160px; min-width: 0; }
.coach-plan-form__actions { display: flex; align-items: center; gap: 16px; margin-top: 16px; }
.coach-plan-form__actions .button { width: auto; }
.coach-plan__notice { margin: 0 0 8px; color: var(--muted); font-size: 0.86rem; }
.coach-plan__set, .week-row__coach { display: block; color: var(--muted); font-size: 0.82rem; }
.week-row__coach { margin-top: 4px; }
.day-sheet__coach { margin-bottom: 8px; }
.set-card__coach { color: var(--muted); font-size: 0.86rem; line-height: 1.45; margin: 0 0 8px; }
@media (max-width: 599px) { .coach-plan-form__actions .button { width: 100%; } }
.coach-plan-form .movement-row { gap: 4px; row-gap: 4px; }
.coach-plan-form .movement-row .movement-row__line + .movement-row__line { margin-top: 0; }
/* COA-009b: the coach plans on the calendar. The week links sit under the
   client's tabs; a day is a row whose date and session open the day sheet;
   a movement's four boxes wrap as label-and-box pairs, never splitting a
   label from its box. */
.coach-weeks { margin: -8px 0 4px; }
.coach-week__day { display: inline-flex; min-height: 44px; align-items: center; margin: -12px 0; color: inherit; text-decoration: none; }
.coach-week__day:hover .movement-row__label { text-decoration: underline; }
.coach-week__minutes { flex: 0 0 auto; margin-left: auto; color: var(--muted); font-size: 0.86rem; }
.coach-week__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.coach-week__actions form { display: inline-flex; margin: 0; }
.coach-week__actions .text-link { margin: 0; }
.coach-plan-form .coach-move__fields { gap: 4px 8px; }
.coach-move__pair { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.coach-move__pair > .movement-row__label { font-weight: 400; }
.coach-plan-form .coach-move .field--reps > input, .coach-plan-form .coach-move .field--reps .input-suffix input { width: calc(3ch + 28px); min-height: 44px; padding: 8px 12px; }
.coach-plan-form .coach-move .field--load .input-suffix input, .coach-plan-form .coach-move .field--reps .input-suffix input { min-height: 42px; }
.coach-plan-form .coach-move .input-suffix { min-height: 44px; }
.coach-plan-form .coach-move .input-suffix > span { padding: 0 8px; }
.coach-plan-form .coach-move .movement-row__rest .text-link { margin: -12px 0; }
.coach-day__time { width: auto; min-height: 44px; }
.coach-day__rest { margin: 0 0 0 auto; }
.coach-invite__templates { flex: 0 0 auto; margin: 0; }
.coach-templates__new { margin-top: 16px; }
.coach-templates__new .button { width: auto; }
.coach-template__days .movement-row { gap: 4px; }
/* COA-009b: a hub card's heading line to its first sentence is the
   helper's 8px, Tabata's included. */
.hub-row__body { padding-top: 8px; }
.hub-row__body > p:first-child { margin-top: 0; }
.coach-template .card-heading { margin-bottom: 0; }
.coach-week__actions { column-gap: 16px; row-gap: 0; }
.coach-plan-form .coach-move .field--reps .input-suffix input { width: calc(4ch + 16px); }
.coach-plan-form__actions { flex-wrap: wrap; }
.coach-day__rest { white-space: nowrap; }
.coach-plan-form .format-fields select, .coach-day__time { min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); }
.coach-plan-form .coach-move .input-suffix input { padding: 8px; }
.coach-plan-form .coach-move .field--reps .input-suffix input { width: calc(4ch + 16px); }
.coach-plan-form__note { min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); }
.coach-plan-form .coach-move .field--reps .input-suffix input { width: calc(6ch + 16px); }

/* COA-009c (coaching design section 22): the coach's workouts. The day
   sheet's and the editor's boxes run on one line on a wide screen and two
   to a line on a phone ("Weight [ ] lb  Sets [ ]" then "Reps [ ]  Rest [ ] s"),
   with no separator dots. */
.hub-row__about > p { margin: 0; font-size: 0.86rem; }
.week-tools { display: grid; gap: 12px; }
.week-tools__heading { margin: 0; font-size: 1rem; }
.week-tools__copy { margin: 0; }
.week-tools__copy .text-link { min-height: 44px; }
.week-tools__save { display: grid; justify-items: start; gap: 8px; margin: 0; }
.week-tools__save label { flex: 0 0 auto; font-size: 0.88rem; font-weight: 680; }
.week-tools__save input { width: 100%; min-width: 0; min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); }
.week-tools__label { margin: 0; font-size: 0.88rem; font-weight: 680; }
.day-sheet__save-workout { display: grid; gap: 8px; max-width: 480px; margin-top: 16px; }
.day-sheet__save-workout-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; }
.day-sheet__save-workout-row .button { flex: 0 0 auto; width: auto; min-height: 44px; padding: 8px 12px; }
.day-sheet__save-workout label { flex: 0 0 auto; font-size: 0.88rem; font-weight: 680; }
.day-sheet__save-workout input { flex: 1 1 200px; min-width: 0; min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); }
.hub-row__about > .hub-row__advice { margin-top: 8px; font-size: 0.81rem; }
.coach-invite__links { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 8px; }
.coach-move__tag { display: block; }
.coach-plan-form .coach-move__fields { gap: 8px 16px; }
@media (max-width: 599px) {
  .coach-invite:has(.coach-invite__links) { flex-wrap: wrap; }
  .coach-invite__links { flex-basis: 100%; }
  .coach-plan-form .coach-move__fields { display: grid; grid-template-columns: repeat(2, max-content); gap: 8px 16px; }
}

/* COA-009d (coaching design section 24): warm-up and rest travel with the
   workout. The editor's Warm-up rows under Name; a hairline, 8px above and
   below, before the first movement and hairlines round every one. A
   movement's line one is weight, sets and reps, three narrow boxes on one
   line at every width with small muted captions; line two, 4px under it,
   is "Rest between sets" left and its box right, the rules' rest a muted
   placeholder. */
.coach-workout__warmup { display: grid; gap: 8px; margin-top: 8px; }
.coach-workout__help { margin: -4px 0 0; color: var(--muted); font-size: 0.82rem; }
.coach-workout__steps { display: grid; gap: 8px; }
.coach-workout__steps label { font-size: 0.88rem; font-weight: 680; }
.coach-workout__steps textarea { width: 100%; min-height: 88px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); font: inherit; font-size: 0.9rem; }
.coach-workout__sets.checkbox-row { margin: 0; }
.coach-workout .movement-rows { margin-top: 8px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.coach-workout .movement-rows > .movement-row:first-child { border-top: 0; }
.coach-plan-form .coach-move { gap: 4px; padding: 8px 0; }
.coach-workout__add { margin-top: 8px; flex-wrap: nowrap; }
.coach-workout__add select { flex: 1 1 auto; min-width: 0; }
.coach-move__boxes { display: flex; flex-wrap: nowrap; gap: 12px; }
.coach-move__box { display: grid; justify-items: start; gap: 4px; }
.coach-move__caption { color: var(--muted); font-size: 0.76rem; font-weight: 400; line-height: 1.2; }
.coach-plan-form .coach-move .field--load, .coach-plan-form .coach-move .field--reps, .coach-plan-form .coach-move .field--rest { flex: 0 0 auto; margin: 0; }
.coach-plan-form .coach-move .field--reps > input { width: calc(3ch + 24px); min-height: 44px; padding: 8px 12px; }
.coach-plan-form .coach-move .field--load .input-suffix input, .coach-plan-form .coach-move .field--rest .input-suffix input { width: calc(4ch + 16px); min-height: 42px; padding: 8px; }
.coach-plan-form .coach-move .input-suffix > span { padding: 0 8px 0 0; }
.coach-move__rest { flex-wrap: nowrap; align-items: center; column-gap: 8px; }
.coach-move__rest > .movement-row__label { font-weight: 400; }
.coach-move input::placeholder { color: var(--muted); opacity: 1; }
.warmup-steps li.warmup-step--own { grid-template-columns: minmax(0, 1fr); }
.warmup-step--own strong { margin-bottom: 0; }
/* COA-009d: Your weeks reads as one list of three rows, a hairline between
   each, rows at 8px; a 44px target overlaps the row's air. */
.week-tools { gap: 0; }
.week-tools__heading { margin-bottom: 8px; }
.week-tools__copy, .week-tools__save, .week-tools__apply { padding: 8px 0; border-top: 1px solid var(--line); }
.week-tools__apply { padding-bottom: 0; }
.week-tools__copy .text-link { margin: -12px 0; }
.week-tools__apply .week-tools__label { margin-bottom: 4px; }
.week-tools__rows { padding-bottom: 0; border-bottom: 0; }
.week-tools__rows .movement-row { padding: 8px 0; }
.week-tools__rows .format-slot__links .text-link { margin: -12px 0; }
.coach-move input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
.coach-move input[type="number"]::-webkit-inner-spin-button, .coach-move input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

/* COA-009e (UI-UX standard, coaching design section 24): a button beside a
   select or text box in one row takes the field's height (44), 12px sides
   and the width of its label, top-aligned with the field. One rule for
   every such row. */
:is(.format-fields, .coach-invite, .week-tools__save, .day-sheet__save-workout, .coach-workout__add, .account-birthday) > .button { flex: 0 0 auto; align-self: flex-start; width: auto; min-height: 44px; padding: 8px 12px; }
.coach-workout__add { align-items: flex-start; margin-bottom: 8px; }
/* The workout editor's warm-up: the rules' line under "The usual warm-up",
   the steps box and its minutes under "Your own steps", switched by the
   select itself with :has(), no script. */
.coach-workout__help, .coach-workout__steps { display: none; }
.coach-workout__warmup:has(select option[value="RULES"]:checked) .coach-workout__help { display: block; }
.coach-workout__warmup:has(select option[value="OWN"]:checked) .coach-workout__steps { display: grid; }
.coach-workout__minutes { flex-wrap: nowrap; align-items: center; column-gap: 8px; }
.coach-workout__minutes > .movement-row__label { font-size: 0.88rem; font-weight: 400; }
.coach-workout__minutes .input-suffix { min-height: 44px; }
.coach-workout__minutes .input-suffix input { width: calc(3ch + 16px); min-height: 42px; padding: 8px; border: 0; outline: none; background: transparent; font: inherit; appearance: textfield; -moz-appearance: textfield; }
.coach-workout__minutes .input-suffix input::-webkit-inner-spin-button, .coach-workout__minutes .input-suffix input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.coach-workout__minutes .input-suffix input::placeholder { color: var(--muted); opacity: 1; }
.coach-workout__minutes .input-suffix > span { padding: 0 8px 0 0; }
.week-tools__save input, .day-sheet__save-workout input { flex-basis: 120px; }
/* The "Update coming days?" card: heading, sentence, answers 16px apart. */
.coming-days { display: grid; gap: 16px; }
.coming-days > * { margin: 0; }
/* COA-010: the client's line where the gate would stop them, its Continue
   and the quiet way back to the questions 8px under it. */
.coach-attested { display: grid; gap: 8px; }
.coach-attested > * { margin: 0; }
.coach-attested .text-link { margin: 0; }
/* COA-010: the Plan tab's one gate row stands alone in its card, so no
   hairline under it. */
.coach-rows.coach-gate { padding-bottom: 0; border-bottom: 0; }

/* NAV-002: the avatar opens the account menu, the browser's own popover.
   Exactly one of the two avatars is shown: the button where popovers work,
   the link to Profile where they do not (Safari before 17), and the menu
   itself never renders as a plain block in a browser that cannot open it. */
@supports selector(:popover-open) {
  .topbar-end .you-link, .side-nav .you-link { display: none; }
}
@supports not selector(:popover-open) {
  .you-menu, .account-menu { display: none !important; }
}
button.profile-chip { padding: 0; font: inherit; font-weight: 750; cursor: pointer; }
.account-menu { position: fixed; inset: auto; top: calc(68px + env(safe-area-inset-top) + 8px); right: 16px; width: 240px; margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.account-menu__who { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.account-menu__face, .side-nav__face { display: grid; flex: none; overflow: hidden; place-items: center; border: 1px solid var(--line); border-radius: 50%; background: var(--surface); color: var(--green); font-weight: 750; }
.account-menu__face { width: 40px; height: 40px; }
.account-menu__face img, .side-nav__face img { width: 100%; height: 100%; object-fit: cover; }
.account-menu__id { display: grid; min-width: 0; }
.account-menu__name, .account-menu__email, .side-nav__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-menu__name { font-size: 0.94rem; font-weight: 600; }
.account-menu__email { color: var(--muted); font-size: 0.82rem; }
.account-menu__links { margin: 0; padding: 4px 0; list-style: none; }
.account-menu__out { margin: 0; padding: 4px 0; border-top: 1px solid var(--line); }
.account-menu__links a, .account-menu__out button { display: flex; width: 100%; min-height: 44px; align-items: center; padding: 0 16px; border: 0; background: none; color: var(--ink); font: inherit; font-size: 0.92rem; font-weight: 600; text-align: left; text-decoration: none; cursor: pointer; }
.account-menu__links a:hover, .account-menu__out button:hover { background: var(--surface-2); }
.account-menu__links a[aria-current="page"] { color: var(--green); }
.account-menu__links a:focus-visible, .account-menu__out button:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: -3px; }
.side-nav__face { width: 28px; height: 28px; font-size: 0.8rem; }
@media (min-width: 880px) {
  /* Upward from the foot of the side menu, on its padding: 34px of padding,
     the 48px row, then 8px of air. The frame is centered past 1240px. */
  .account-menu { top: auto; right: auto; bottom: 90px; left: calc((100vw - min(100vw, 1240px)) / 2 + 22px); }
  .side-nav .side-nav__you { margin-top: auto; color: var(--ink); }
  button.side-nav__you { display: flex; width: 100%; min-height: 48px; align-items: center; gap: 12px; padding: 0 13px; border: 0; border-radius: 11px; background: none; font: inherit; font-size: 0.86rem; font-weight: 650; text-align: left; cursor: pointer; }
  button.side-nav__you:hover { background: var(--surface-2); }
  button.side-nav__you:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
}

/* PRF-004: Profile as three cards in one form, capped at 480px. The small
   uppercase heading and 8px under it are the account page's; fields are
   16px apart, and Birthday, Height and Weight sit on one line with their
   label. */
.profile-form { display: grid; gap: 16px; max-width: 480px; }
.profile-form > .card { margin: 0; }
.profile-error { max-width: 480px; margin: 0 0 16px; }
.profile-card { display: grid; gap: 16px; padding: 16px; }
.profile-card > h2 { margin: 0 0 -8px; color: var(--muted); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.profile-card .field input:not([type="radio"]):not([type="checkbox"]):not([type="range"]), .profile-card .field select { padding: 8px 12px; }
.profile-card .input-suffix { min-height: 44px; }
.profile-card .field .input-suffix input { min-height: 42px; }
.profile-card .avatar-save-result { margin: 0; }
.profile-photo { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.profile-photo__change { width: auto; min-height: 44px; padding: 8px 16px; }
.profile-photo__input:focus-visible + .profile-photo__change { outline: 4px solid rgba(232, 111, 61, 0.25); outline-offset: 2px; }
.profile-line { display: grid; grid-template-columns: 72px minmax(0, 1fr); align-items: center; gap: 8px; }
.field .profile-line > label, .field.profile-line > label { margin: 0; }
.profile-share { margin-top: 8px; }
.profile-weight { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; align-items: center; gap: 8px; }
.profile-weight__label { color: var(--ink); font-size: 0.88rem; font-weight: 680; }
.profile-weight__value { display: grid; gap: 4px; min-width: 0; font-size: 0.9rem; }
.profile-weight__when { color: var(--muted); font-size: 0.84rem; }
.profile-weight .button, .profile-actions .button { width: auto; min-height: 44px; padding: 8px 16px; }
.profile-actions { display: flex; gap: 8px; }
@media (max-width: 599px) {
  .profile-actions .button { flex: 1 1 0; }
}

/* COA-005 005a: accepting the terms and the privacy policy (/accept, the
   standalone shell), the coach agreement, the coach's credentials and the
   credential block a client reads. Spacing is 4, 8, 12 or 16px only. */
.legal-back { margin: 0; }
.accept-change { display: grid; gap: 4px; }
.accept-change h2 { margin: 0; font-size: 1.05rem; line-height: 1.3; }
.accept-change p { margin: 0; }
.accept-change__updated { color: var(--muted); font-size: 0.84rem; }
.accept-change__lines { display: grid; gap: 4px; margin: 4px 0; padding-left: 16px; }
.accept-form { margin: 0; }
.accept-ways-out { padding-top: 12px; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.84rem; }
.accept-ways-out__form { display: inline; margin: 0; }
/* Words in a sentence: an inline link with a 44px tap height would open every
   line it sits on to 44px (the PLN-010 rule), and sign out reads as the link
   beside it. */
.accept-ways-out .inline-link { display: inline; min-height: 0; font-size: inherit; }
.accept-ways-out .text-link { display: inline; min-height: 0; margin: 0; font-size: inherit; text-decoration: underline; }
.coach-agreement__card { display: grid; gap: 16px; max-width: 680px; }
.coach-agreement__card > p, .coach-agreement__card > form { margin: 0; }
/* Owner, 2026-09-29: the summary on top, the full text in a box about half
   the viewport tall with I agree right under it. The box scrolls on its own
   and takes keyboard focus, so its outline shows where the arrow keys go. */
.coach-agreement__summary h2 { margin: 0 0 4px; font-size: 1rem; }
.coach-agreement__summary ul { display: grid; gap: 4px; margin: 0; padding-left: 16px; font-size: 0.92rem; line-height: 1.4; }
.coach-agreement__full { max-height: clamp(240px, 50vh, 560px); overflow-y: auto; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); overscroll-behavior: contain; }
.coach-agreement__full:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.coach-agreement__full > p { margin: 12px 0 0; }
/* On a phone the box gives up some height so the summary, the box and I
   agree fit one 812px screen above the bottom bar. */
@media (max-width: 879px) {
  .coach-agreement__card { padding: 16px; }
  .coach-agreement__full { max-height: clamp(200px, 30vh, 560px); }
}
.coach-agreement__changes h2 { margin: 0 0 4px; font-size: 1rem; }
.coach-agreement__changes ul { display: grid; gap: 4px; margin: 0; padding-left: 16px; }
.coach-agreement__clauses { margin: 0; padding-left: 16px; }
.coach-agreement__clauses li { padding-left: 4px; }
.coach-agreement__clauses li::marker { font-weight: 700; }
.coach-agreement__clauses h2 { margin: 12px 0 4px; }
.coach-agreement__clauses li:first-child h2 { margin-top: 0; }
.coach-agreement__clauses p { margin: 0; }
.coach-agreement__agreed { color: var(--muted); font-size: 0.9rem; }
.coach-agreement__actions .text-link, .coach-profile__edit .coach-consent__actions .text-link { margin: 0; }
.coach-credentials { display: grid; gap: 4px; }
.coach-credentials p { margin: 0; }
.coach-credentials__name { color: var(--ink); font-size: 0.95rem; font-weight: 700; }
.coach-credentials__line { color: var(--ink); font-size: 0.9rem; }
/* ADM-012 section 1: in parentheses, smaller and muted, the same on the
   consent screen and in Settings so the two never disagree. */
.coach-credentials__note { color: var(--muted); font-size: 0.8rem; }
.coach-settings__credentials { margin: -8px 0 12px; }
.coach-consent__changes { display: grid; gap: 4px; margin: 0; padding-left: 16px; }
.coach-card__foot { margin: 12px 0 0; }
.coach-card__foot .text-link { margin: -12px 0; }
.coach-profile { max-width: 680px; }
.coach-profile__add, .coach-profile__edit { display: grid; gap: 12px; max-width: 480px; margin: 16px 0 0; }
.coach-profile__edit { margin: 0; }
.coach-profile__add .field, .coach-profile__edit .field { margin: 0; }
.coach-profile__line { display: flex; align-items: flex-start; gap: 8px; }
.coach-profile__line input { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 8px 12px; }
.coach-profile__line .button { flex: 0 0 auto; min-height: 44px; padding: 8px 16px; }
.coach-profile .error-summary { margin: 0 0 8px; }
.admin-people__waiting { margin: 0 0 12px; }
/* COA-013: a coach's own client agreement, as a link. The host sits muted
   beside every link so the client sees where it goes; the actions are quiet
   links split by a bar, 44px tall by overlapping the row's air. */
.coach-row__detail--ink { color: var(--ink); }
.client-agreement { display: grid; gap: 4px; margin: 0; }
.client-agreement__line { margin: 0; font-size: 0.9rem; overflow-wrap: anywhere; }
.client-agreement__host { color: var(--muted); }
/* A link inside a sentence stays inline: the sentence is its target. */
.client-agreement__line .text-link, .client-agreement-card__line .text-link { display: inline; min-height: 0; margin: 0; font-size: inherit; }
.client-agreement .checkbox-row { margin: 0; }
.client-agreement .field-error { margin: 0; }
.client-agreement-card__row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
.client-agreement-card__line { flex: 1 1 240px; margin: 0; font-size: 0.9rem; overflow-wrap: anywhere; }
.client-agreement-card__actions { flex: 0 0 auto; align-items: center; gap: 8px; }
.client-agreement-card__actions .text-link { margin: -12px 0; }
.client-agreement-card__actions form, .coach-settings__agreement form { display: inline-flex; margin: 0; }
/* ADM-012 section 1: "Client agreement" alone on its line, and when this
   client agreed on its own muted line under it, never wrapping into the
   link's line. The 44px link overlaps the air around it. */
.coach-settings__agreement { display: grid; justify-items: start; gap: 4px; margin: 0 0 12px; }
.coach-settings__agreement p { margin: 0; }
.coach-settings__agreement .text-link { margin: -12px 0; }
.coach-settings__agreed { color: var(--muted); font-size: 0.86rem; }
.coach-profile + .coach-profile { margin-top: 16px; }
.coach-profile > .card-heading { margin-bottom: 0; }
.coach-profile > .card-heading + .coach-profile__add { margin-top: 0; }
/* The Optional tag and the link's 44px target sit lower than a plain line,
   so the card's first field and row come up by that much. */
#client-agreement > .card-heading + .coach-profile__add { margin-top: -4px; }
#client-agreement > .card-heading + .coach-profile__rows { margin-top: -2px; }
.coach-profile > .coach-profile__rows:last-child { padding-bottom: 0; border-bottom: 0; }
.admin-person__agreement { margin-top: 0; padding-top: 8px; border-top: 1px solid var(--line); }
/* COA-005 005b, design section 1.3: `/signup`'s starts. Each is one link
   and one tap, a bordered row with the choice in ink and one muted line
   under it; full width on a phone and capped with the card above it. */
.signup-choices { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.signup-choice { display: grid; gap: 4px; min-height: 44px; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); text-decoration: none; }
.signup-choice:hover { border-color: var(--green-2); }
.signup-choice:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.signup-choice span { color: var(--muted); font-size: 0.9rem; }
/* COA-005 005b: Become a coach. The form width, Become a coach on the left
   and Not now on the right, both sized to their labels. */
.coach-start { max-width: 480px; }
.coach-start .coach-card__empty { margin: 0; }
.coach-start__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin: 16px 0 0; }
.coach-start__actions .button { width: auto; }
@media (max-width: 599px) { .coach-start__actions .button { width: 100%; } }
/* The account page's "Coach people here": one quiet line between cards. */
.account-quiet { margin: 0 0 16px; }
/* COA-005 005b, section 2.1: the Access page's Make a link. What the link
   does is two radio rows; Invite a coach swaps the account link's fields and
   button for the coach link's with `:has`, and no script. The hidden group
   still posts, and the route reads only the fields of the kind chosen. */
.admin-link-kind { display: grid; gap: 8px; margin: 0; padding: 0; border: 0; }
.admin-link-kind legend { margin: 0 0 8px; padding: 0; font-weight: 650; }
.admin-link-kind .checkbox-row { margin: 0; }
.admin-link-form:not(:has(input[name="kind"][value="COACH"]:checked)) .admin-link--coach,
.admin-link-form:has(input[name="kind"][value="COACH"]:checked) .admin-link--account { display: none; }
.admin-link__note { display: block; margin-top: 4px; color: var(--muted); font-size: 0.8rem; }
.admin-flag--coach { background: var(--surface-2); color: var(--ink); }
/* COA-005 005b, section 1.4: Coach sign-up, the second setting in the
   Public sign-up card, named by its own small heading. */
.admin-setting__name { margin: 0; font-size: 0.95rem; font-weight: 700; }
.admin-setting__name + .admin-setting__value { grid-row: auto; }

/* PERF-004: a page swapped in by nav.js that takes more than a moment shows a
   thin bar across the top, so a tap is always seen to have landed. */
html.is-navigating::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 1000;
  background: var(--orange);
  transform-origin: left;
  animation: afe-navigating 1.2s ease-out infinite;
}

@keyframes afe-navigating {
  from { transform: scaleX(0.1); }
  to { transform: scaleX(0.9); }
}

@media (prefers-reduced-motion: reduce) {
  html.is-navigating::before { animation: none; transform: none; }
}

/* AI-009 (docs/designs/ai-009-eve-history.md, section 8): Eve's history.
   The destructive style is the palette's `--danger` as a fill with white
   text: the one painted control on a confirm and in select mode, never
   beside another painted button. A confirm's actions sit on one row,
   Delete on the left and Cancel on the right, each as wide as its words. */
.button--danger { border-color: var(--danger); background: var(--danger); color: #fff; }
.button--danger:hover { background: #7a2921; }
.button--danger:focus-visible { outline: 4px solid rgba(141, 48, 40, 0.25); outline-offset: 2px; }
.confirm-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.confirm-actions .button { width: auto; min-height: 44px; padding: 8px 16px; }
.eve-delete { max-width: 480px; }
.eve-delete__goes { margin: 0; }
.eve-settings__count { margin: 0; }
.eve-settings > .eve-settings__delete { justify-self: start; margin-top: 8px; }
.eve-where__end { display: inline-flex; flex: none; align-items: center; min-height: 44px; margin-left: auto; padding: 0 4px; font-size: 0.9rem; }
.eve-earlier { margin: 0; font-size: 0.9rem; text-align: center; }
.eve-earlier .text-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px; }
.eve-earlier[aria-busy="true"] .text-link { color: var(--muted); text-decoration: none; }
/* AI-010 section 2.3: while the composer's field has focus on a phone the
   bottom bar steps out of the way and the composer sits on the keyboard's
   top edge; `--keyboard` is the gap between the layout and visual viewports,
   written by eve.js, and 0 where the browser resizes the page instead. */
@media (max-width: 879px) {
  html[data-keyboard="open"] .bottom-nav { display: none; }
  html[data-keyboard="open"] .eve-composer { bottom: var(--keyboard, 0px); }
  html[data-keyboard="open"] body[data-page="assistant"] .main-content { padding-bottom: 16px; }
}
.eve-day { display: grid; gap: 12px; scroll-margin-top: 16px; }
.eve-day__line { margin: 0; color: var(--muted); font-size: 0.82rem; font-weight: 650; text-align: center; }
/* Select mode: the form holds the days, so it takes the column's place and
   its own gap; the foot stays pinned where the composer was. The count in
   Delete selected (N) is a CSS counter of the checked boxes. */
.eve > .eve-select { display: flex; flex: 1 0 auto; flex-direction: column; gap: 12px; counter-reset: picked; }
.eve-pick { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 44px; height: 44px; margin-left: -12px; }
.eve-pick input { width: 22px; height: 22px; margin: 0; accent-color: var(--green); }
.eve-pick input:checked { counter-increment: picked; }
.eve-select__count::before { content: counter(picked); }
.eve-turn--pick { align-items: center; justify-self: stretch; max-width: none; }
.eve-turn--pick .eve-bubble { max-width: calc(100% - 88px); }
.eve-turn--pick.eve-turn--mine .eve-bubble { margin-left: auto; }
.eve-select__actions { position: sticky; z-index: 10; bottom: calc(86px + env(safe-area-inset-bottom)); display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); box-shadow: 0 6px 20px rgba(23, 34, 30, 0.08); }
.eve-select__actions .button { min-height: 44px; padding: 8px 16px; }
@media (min-width: 880px) {
  .eve-select__actions { bottom: 16px; }
}

/* STR-053 (D-162): Lighter today. The rules' sentence sits in the Adjusted
   for today summary on its own line; after the session it is said once. */
.today-adjustment-summary .lighter-today__line { color: var(--ink); }
.lighter-today__after { max-width: 480px; margin: 0 auto 16px; color: var(--muted); font-size: 0.86rem; text-align: center; }

.day-sheet__past-back { margin: 16px 0 0; }

/* A past day's list lines up with the link under it: no bullet, no indent,
   the name left and its state right, muted like the Plan's past rows. */
.day-sheet__items.day-sheet__past {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
  color: var(--muted);
}
.day-sheet__past li { align-items: baseline; font-weight: 600; }
.day-sheet__past .day-sheet__item-dose { color: var(--muted); }

/* CON-028 (D-130, D-188): a spacing rule is advice at Start. The sentence is
   said once above; the recommended choice, "Not today", is on the left and
   "Start anyway" is the quiet one on the right. Side by side at phone width,
   sized to the label from 600px up (no full-width buttons on a desktop). */
.advice-choice { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.advice-choice > .button { flex: 1 1 0; min-width: 0; }
@media (min-width: 600px) {
  .advice-choice > .button { flex: 0 0 auto; min-width: 140px; }
}

/* PLN-019 (D-189): a past day's question and its three answers. "Yes, log it"
   and "Yes, as planned" on the left, "No, skipped" at the right end, all
   quiet: the Plan has no primary. Under 600px the answers fill the row. */
.past-ask { margin: 16px 0 0; }
.past-ask__heading { margin: 0 0 8px; font-size: 1rem; }
.past-answers { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; max-width: 480px; }
.past-answers form { margin: 0; }
.past-answers .button { min-height: 44px; padding: 8px 16px; }
.past-answers .past-answers__no { margin-left: auto; }
/* PLN-019: past rows stay compact. The state and the quiet link share the
   row's own line (stacked 4px apart only where they cannot fit), and an empty
   past day is one line: the date, and "Log a session" at the right. The link
   is muted like the row and gets its 44px target from padding that a negative
   margin takes back, so the visible row does not grow. */
.week-row__state { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: baseline; gap: 4px 8px; }
.week-row__ask-link {
  display: inline-block;
  padding: 12px 0;
  margin: -12px 0;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 600;
  text-decoration: underline;
}
.week-row--bare .week-row__name { display: none; }
@media (max-width: 599px) {
  .week-row--bare .week-row__grid .week-row__when { grid-column: 1; }
}


/* CON-029 pass B (D-191): choose your cardio. Three steps and a summary, one
   question each, phone first. The form is capped at 480px and the painted
   primary is the only orange on a step. Spacing is 4, 8, 12 and 16 only.
   Under 600px the primary fills the row and the quiet ones share the row
   under it; from 600px up every button is as wide as its label. */
.cardio-flow { display: grid; gap: 16px; max-width: 480px; margin-bottom: 16px; padding: 16px; }
.cardio-flow fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.cardio-flow legend { margin: 0 0 8px; padding: 0; font-size: 1rem; font-weight: 680; }
[data-focus-heading]:focus { outline: none; }
.cardio-options { display: grid; gap: 8px; }
.cardio-option { position: relative; display: block; margin: 0; cursor: pointer; }
.cardio-option input { position: absolute; opacity: 0; pointer-events: none; }
.cardio-option__body { display: grid; gap: 4px; min-height: 44px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.cardio-option__body strong { font-size: 1rem; }
.cardio-option__body span { font-size: 0.88rem; }
.cardio-option__body small { color: var(--muted); font-size: 0.8rem; }
.cardio-option input:checked + .cardio-option__body { border-color: var(--green-2); background: var(--mint-2); box-shadow: inset 0 0 0 1px var(--green-2); }
.cardio-option input:focus-visible + .cardio-option__body { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.cardio-note { margin: 0; }
@supports selector(:has(*)) {
  .cardio-options:has(input[value="JOG"]:not(:checked)) .cardio-note { display: none; }
}
.cardio-flow .cardio-also > legend { color: var(--green); font-size: 0.88rem; font-weight: 700; }
.cardio-also__list { display: grid; gap: 4px; }
.cardio-also__row { display: flex; min-height: 44px; align-items: center; gap: 12px; margin: 0; cursor: pointer; font-size: 0.92rem; }
.cardio-also__row input { width: 20px; height: 20px; margin: 0; accent-color: var(--green-2); }
.cardio-also__row[hidden] { display: none; }
@supports selector(:has(*)) {
  .cardio-flow:has(input[name="main"][value="WALK"]:checked) .cardio-also__row[data-option="WALK"] { display: none; }
  .cardio-flow:has(input[name="main"][value="INCLINE_WALK"]:checked) .cardio-also__row[data-option="INCLINE_WALK"] { display: none; }
  .cardio-flow:has(input[name="main"][value="CYCLE"]:checked) .cardio-also__row[data-option="CYCLE"] { display: none; }
  .cardio-flow:has(input[name="main"][value="ROW"]:checked) .cardio-also__row[data-option="ROW"] { display: none; }
  .cardio-flow:has(input[name="main"][value="ELLIPTICAL"]:checked) .cardio-also__row[data-option="ELLIPTICAL"] { display: none; }
  .cardio-flow:has(input[name="main"][value="JOG"]:checked) .cardio-also__row[data-option="JOG"] { display: none; }
  .cardio-flow:has(input[name="main"][value="RUCK"]:checked) .cardio-also__row[data-option="RUCK"] { display: none; }
}
.cardio-error { max-width: 480px; margin: 0 0 16px; }
.cardio-choices { gap: 8px; }
.cardio-choices span { min-height: 44px; align-content: center; }
.cardio-followup { display: none; }
.cardio-followup--open { display: block; }
@supports selector(:has(*)) {
  .cardio-flow:has(input[name="minutes"][value="30"]:checked) .cardio-followup,
  .cardio-flow:has(input[name="minutes"][value="45"]:checked) .cardio-followup,
  .cardio-flow:has(input[name="minutes"][value="60"]:checked) .cardio-followup { display: block; }
  .cardio-flow:has(input[name="minutes"][value="0"]:checked) .cardio-followup,
  .cardio-flow:has(input[name="minutes"][value="10"]:checked) .cardio-followup,
  .cardio-flow:has(input[name="minutes"][value="20"]:checked) .cardio-followup { display: none; }
}
@supports not selector(:has(*)) {
  .cardio-followup { display: block; }
}
.cardio-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.cardio-actions .button--primary { flex: 1 1 100%; }
.cardio-actions .button--quiet { flex: 1 1 0; min-width: 0; padding: 12px; }
.cardio-summary__rows { display: grid; gap: 12px; margin: 0; }
.cardio-summary__rows > div { display: grid; gap: 4px; }
.cardio-summary__rows dt { color: var(--muted); font-size: 0.8rem; font-weight: 680; }
.cardio-summary__rows dd { margin: 0; font-size: 1.05rem; font-weight: 680; }
.cardio-summary__rows small { display: block; color: var(--muted); font-size: 0.8rem; font-weight: 500; }
.cardio-steady-ask { display: flex; align-items: flex-start; gap: 12px; min-height: 44px; margin: 0; cursor: pointer; }
.cardio-steady-ask input { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--green-2); }
.cardio-steady-ask span { display: grid; gap: 4px; font-size: 0.92rem; }
.cardio-steady-ask small { color: var(--muted); font-size: 0.8rem; }
.cardio-summary__time, .cardio-readonly__now { margin: 0; font-size: 0.92rem; }
@media (min-width: 600px) {
  .cardio-actions .button--primary { flex: 0 0 auto; min-width: 120px; }
  .cardio-actions .button--quiet { flex: 0 0 auto; padding: 12px 16px; }
  .cardio-followup .segmented { max-width: 240px; }
}
/* The Conditioning page's one line about the person's cardio, the steady
   offer under the suggested card, and the Plan's "Add a day?" card. The
   offer buttons are both quiet: the page's primary is Start. */
.cardio-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin: 0 0 16px; color: var(--muted); font-size: 0.86rem; }
.cardio-line strong { color: var(--ink); font-weight: 680; }
.cardio-line .text-link { margin: 0; }
.cardio-offer { display: grid; gap: 12px; }
.cardio-offer > * { margin: 0; }
.cardio-offer h2 { font-size: 1.05rem; }
@media (min-width: 600px) {
  .cardio-offer .past-answers__no { margin-left: 0; }
}
/* Under a session's name: how the effort feels, and a jog's steps. */
.week-row__effort, .today-effort { display: block; color: var(--muted); font-size: 0.78rem; }
/* The pace choice says what it costs in time. */
.pace-options .pace-cost { color: var(--muted); font-size: 0.76rem; font-weight: 500; }
/* Progress: the time comparison and the one line about eating. */
.aerobic-ledger-rows .cardio-comparison, .aerobic-ledger-rows .cardio-eating { margin: 0; color: var(--muted); font-size: 0.86rem; }
/* The day sheet's quiet offer of easy minutes after strength: one line under
   "Add another session", the select sized to its numbers, Add to its label. */
.after-strength { display: grid; gap: 4px; margin: 0; }
.after-strength label { margin: 0; font-size: 0.92rem; font-weight: 680; }
.after-strength__about { margin: 0; color: var(--muted); font-size: 0.82rem; }
.after-strength__pick { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
.after-strength select { width: auto; min-width: 0; min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); font-size: 0.86rem; }

/* Owner review, 2026-10-02: the Conditioning page does one job. The suggested
   session leads; the log form and the other sessions are folded cards (native
   details, so they work with no script); the brisk offer is one quiet line.
   Spacing is 4, 8, 12 or 16. */
.prescribed-card .today-adjust,
.prescribed-card .today-adjustment-summary { margin: 16px 0 0; }
.prescribed-card .conditioning-start-form, .prescribed-card > .button { margin-top: 16px; }
.prescribed-card .prescribed-line + p { margin-top: 4px; }
.fold { padding: 0; }
.fold > summary { display: flex; min-height: 56px; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; cursor: pointer; list-style: none; color: var(--ink); font-size: 1rem; font-weight: 680; }
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after { content: ""; flex: none; width: 8px; height: 8px; margin: 0 4px 4px 0; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); }
.fold[open] > summary::after { margin: 4px 4px 0 0; transform: rotate(-135deg); }
.fold > summary:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: -3px; border-radius: var(--radius); }
.fold__body { display: grid; gap: 12px; padding: 0 16px 16px; }
.fold__body > * { margin: 0; }
.fold__body h2 { font-size: 1.05rem; }
.hub-fold .fold__body { gap: 8px; }
/* Owner review, 2026-10-02: the brisk offer is one sentence with Add and
   Not now on one row beside it; under 480px the two buttons take their own
   row, still side by side and the same height. */
.cardio-steady-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--line); }
.cardio-steady-line p { flex: 1 1 240px; margin: 0; font-size: 0.9rem; }
.cardio-steady-line__actions { display: flex; flex: none; gap: 8px; }
.cardio-steady-line__actions .button { min-height: 44px; padding: 8px 16px; }
.cardio-steady-card { padding: 0 16px 16px; }

/* One row of quiet links with a bar between them, under a card's Start. */
.link-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 16px 0 0; }
.link-row .text-link { margin: 0; }
.link-row__bar { color: var(--line-strong, var(--muted)); }

/* The sessions, grouped by effort under a small heading. */
.hub-groups { display: grid; gap: 0; }
.hub-group__title { margin: 16px 0 8px; color: var(--muted); font-size: 0.86rem; font-weight: 640; }
.hub-group__title:first-child { margin-top: 0; }
.hub-group .hub-row:last-child { margin-bottom: 0; }

/* Owner review, 2026-10-02: the day sheet's quiet extras are one group under
   Save and Cancel, each under a hairline (the line used between the first and
   second session). The rest day reads like the others, from the left. */
.day-sheet__extras { display: grid; gap: 8px; }
.day-sheet__extra { padding-top: 8px; border-top: 1px solid var(--line); }
.day-sheet__extra.day-sheet__add { margin: 0; }
.day-sheet__extras .day-sheet__rest { flex: none; justify-content: flex-start; margin: 0; }
.day-sheet__added { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 8px; }
.day-sheet__added-min { color: var(--muted); font-size: 0.86rem; }

.prescribed-card > .text-link { margin-bottom: 0; }

.cardio-offer .past-answers .button { padding: 8px 12px; }
@supports selector(:has(*)) {
  /* Nothing to add to until a main option is picked: the list of others only
     follows a choice, so the same options are not listed twice. */
  .cardio-flow:not(:has(input[name="main"]:checked)) .cardio-also { display: none; }
}

/* Owner review, 2026-10-02 (second pass): the day sheet composes the day,
   then saves it. Movements are rows a person can scan and tap: name on the
   left, dose on the right, a hairline between, held to the form's width so
   the numbers stay beside the names on a wide screen. */
.day-sheet .day-sheet__items:not(.day-sheet__past) { max-width: 480px; margin: 12px 0 0; padding: 0; list-style: none; }
.day-sheet .day-sheet__items:not(.day-sheet__past) li { align-items: center; min-height: 44px; padding: 8px 0; border-top: 1px solid var(--line); }
.day-sheet .day-sheet__items:not(.day-sheet__past) li:last-child { border-bottom: 1px solid var(--line); }
.day-sheet .day-sheet__items:not(.day-sheet__past) .inline-link::after { content: " \203A"; color: var(--muted); }
.day-sheet__adds { display: grid; gap: 0; max-width: 480px; margin-top: 16px; }
.day-sheet__adds-title { margin: 0 0 8px; color: var(--muted); font-size: 0.86rem; font-weight: 640; }
.day-sheet__adds .day-sheet__extra { padding: 12px 0; border-top: 1px solid var(--line); }
.day-sheet__adds .day-sheet__extra:last-child { border-bottom: 1px solid var(--line); }
.day-sheet__adds .after-strength__pick { margin-top: 8px; }
.day-sheet__actions { margin-top: 16px; }
.day-sheet__under { margin: 16px 0 0; }
.day-sheet__under .day-sheet__rest { flex: none; margin: 0; justify-content: flex-start; }

/* Owner review, 2026-10-02 (third pass): the cardio summary reads as rows,
   label left and value right, then one choice of two. */
.cardio-summary__rows { gap: 0; }
.cardio-summary__rows > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 12px 0; border-top: 1px solid var(--line); }
.cardio-summary__rows > div:last-child { border-bottom: 1px solid var(--line); }
.cardio-summary__rows dt { flex: none; font-size: 0.86rem; font-weight: 540; }
.cardio-summary__rows dd { font-size: 0.95rem; font-weight: 640; text-align: right; }
.cardio-how { display: grid; gap: 8px; margin: 0; padding: 0; border: 0; }
.cardio-how legend { margin: 0 0 8px; padding: 0; color: var(--muted); font-size: 0.86rem; font-weight: 640; }
.cardio-how__option { display: flex; align-items: flex-start; gap: 12px; margin: 0; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; }
.cardio-how__option:has(input:checked) { border-color: var(--green-2); background: var(--mint-2); }
.cardio-how__option input { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--green-2); }
.cardio-how__option span { display: grid; gap: 4px; font-size: 0.92rem; }
.cardio-how__option small { color: var(--muted); font-size: 0.8rem; }

/* Third pass: a day row reads top down. The date is a small muted label,
   the session is the thing being read, and a rest day stays quiet. */
.week-row__grid .week-row__when strong { color: var(--muted); font-size: 0.78rem; font-weight: 600; }
.week-row__grid .week-row__name { font-size: 1rem; font-weight: 720; }
.week-row--rest .week-row__grid .week-row__name,
.week-row--past .week-row__grid .week-row__name { font-size: 0.92rem; font-weight: 500; }
.week-declaration__line + .week-cardio-note { margin: 4px 0 0; }

/* The added session after strength, drawn like the movement rows. */
.day-sheet__after { max-width: 480px; margin-top: 16px; }
.day-sheet__after-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--muted); font-size: 0.86rem; font-weight: 640; }
.day-sheet .day-sheet__after .day-sheet__items { margin-top: 4px; }

/* What leaves the day's form: one quiet card under it, a line between rows. */
.day-sheet__more { display: grid; gap: 0; margin-top: 16px; padding: 0 16px; }
.day-sheet__more-row { padding: 12px 0; }
.day-sheet__more-row + .day-sheet__more-row { border-top: 1px solid var(--line); }
.day-sheet__more .day-sheet__rest { flex: none; margin: 0; justify-content: flex-start; }
.day-sheet__more .day-sheet__save-workout { max-width: 480px; margin-top: 0; }

/* "Your weeks" is a label above its card; the template name has its button beside it. */
.week-tools__label-above { margin: 16px 0 8px; }
.week-tools > :first-child { border-top: 0; }
.week-tools__save-row { display: flex; gap: 8px; width: 100%; max-width: 480px; }
.week-tools__save-row input { flex: 1 1 auto; }
.week-tools__save-row .button { flex: 0 0 auto; width: auto; min-height: 44px; padding: 8px 16px; }
.cardio-summary__rows > div:first-child { padding-top: 0; border-top: 0; }
.week-declaration__line:has(+ .week-cardio-note) { margin-bottom: 0; }
.day-sheet .field + .day-sheet__after { margin-top: 0; }

/* Owner review, 2026-10-02 (fourth pass). */
/* The talk test beside the effort word it defines. */
.hub-group__hint { margin-left: 8px; color: var(--muted); font-size: 0.8rem; font-weight: 500; }
/* "After strength" is a heading for the row under it: small, muted, tight to
   its line, and closer to the field above. */
.day-sheet .field + .day-sheet__after { margin-top: -4px; }
.day-sheet__after-head { font-size: 0.78rem; font-weight: 640; }
.day-sheet__after-head .day-sheet__quiet { min-height: 32px; font-size: 0.86rem; }
.day-sheet .day-sheet__after .day-sheet__items { margin-top: 0; }
.after-strength__pick { flex-wrap: wrap; }
/* On a wide screen a card that holds a 480px form is as wide as the form
   plus its own padding, so the space left and right of the content is equal. */
@media (min-width: 720px) {
  .profile-form-card:has(> .day-sheet), .day-sheet__more, .week-declaration, .week-tools, .week-tools__label-above + .week-tools { max-width: 528px; }
  .week-declaration .week-list { max-width: none; }
}
.day-sheet .field + .day-sheet__after { margin-top: -16px; }
@media (min-width: 720px) { .day-sheet__more { padding: 0 24px; } }
.hub-group__title .hub-group__hint { font-weight: 400; }
/* The week's two actions: no visible label, and no more room than the rows need. */
.week-tools { margin-top: 16px; padding-top: 4px; padding-bottom: 12px; }
.week-tools__copy { padding: 4px 0; }
.week-tools__save { padding: 12px 0 0; }
/* The week's occasional actions, folded: the body carries the rows. */
.week-tools-fold { margin-top: 16px; }
.week-tools-fold .week-tools { display: grid; gap: 0; margin: 0; padding: 0 16px 12px; max-width: none; }
.week-tools-fold .week-tools > :first-child { border-top: 1px solid var(--line); }
@media (min-width: 720px) { .week-tools-fold { max-width: 528px; } }

/* Owner, 2026-10-02: a session row shows that it opens. The same small arrow
   the folded cards use, down when closed and up when open, after the minutes
   or the label. */
.hub-row > summary { list-style: none; }
.hub-row > summary::-webkit-details-marker { display: none; }
.hub-row > summary::after { content: ""; flex: none; width: 7px; height: 7px; margin: 0 4px 4px 4px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); }
.hub-row[open] > summary::after { margin: 4px 4px 0 4px; transform: rotate(-135deg); }
.advice-choice > .button:only-child { flex: 0 0 auto; }

/* Owner, 2026-10-03: End and Pause share the action spot under the clock,
   side by side; a paused clock is frozen and its digits blink. */
.timer-actions { display: flex; gap: 8px; justify-content: center; }
.timer-actions[hidden] { display: none; }
.timer-actions > .button { flex: 1 1 0; }
.timer-actions > .button[hidden] { display: none; }
@media (min-width: 600px) { .timer-actions > .button { flex: 0 0 auto; min-width: 160px; } }
@keyframes afe-paused-blink { 50% { opacity: 0.25; } }
.is-paused [data-stage-display] { animation: afe-paused-blink 1.2s steps(1, end) infinite; }
@media (prefers-reduced-motion: reduce) { .is-paused [data-stage-display] { animation: none; opacity: 0.6; } }

/* Owner, 2026-10-03: the time the clock recorded, shown and not editable. */
.finish-time { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0; padding: 12px 0; border-bottom: 1px solid var(--line); }
.finish-time > span { color: var(--muted); font-weight: 600; }
.finish-time > strong { font-size: 1.12rem; font-variant-numeric: tabular-nums; }

/* Owner, 2026-10-03: Maintain has no pace and no secondary goals. */
[data-maintain-only] { display: none; }
form:has(#plan-goal option[value="MAINTAIN"]:checked) [data-maintain-only] { display: block; }
form:has(#plan-goal option[value="MAINTAIN"]:checked) [data-growth-only] { display: none; }
.goal-growth-only { display: grid; gap: 16px; }

/* D-200: the one line about this week's cardio. */
.cardio-week-line { margin: 0; color: var(--muted); font-size: 0.92rem; }
.cardio-line + .cardio-week-line { margin: -4px 0 12px; }
.cardio-week-line strong { color: var(--ink, inherit); font-weight: 650; }
.cardio-week-line a { margin-left: 4px; font-weight: 650; }


/* PLN-024 (owner, 2026-10-05): the conditioning card reads name left and
   minutes right, Adjust today sits under Start and opens on "Do something
   else", and "Do something else" is a list of rows with one tag each. */
.today-adjust > summary { list-style: none; color: var(--ink); }
.today-adjust > summary::-webkit-details-marker { display: none; }
.today-adjust > summary::after { content: "\203A"; color: var(--soft); font-size: 1.3rem; line-height: 1; }
.today-adjust[open] > summary::after { content: "Close"; color: var(--muted); font-size: 0.78rem; font-weight: 600; }
/* PLN-025c (D-224): one swap screen. A card of radio rows under two quiet
   group headings, the Just today | From now on toggle, then Swap. Capped at
   480 px on a wide screen; full width on a phone. */
.swap-screen { display: grid; gap: 16px; max-width: 480px; }
.swap-list { margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.swap-list__group { margin: 0; padding: 14px 16px 6px; background: var(--paper); color: var(--muted); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.swap-list__row { display: flex; min-height: 48px; align-items: center; gap: 12px; margin: 0; padding: 10px 16px; border-top: 1px solid var(--line); cursor: pointer; font-size: 1rem; }
.swap-list__row input { width: 20px; height: 20px; margin: 0; flex: none; }
.swap-screen > .button { width: 100%; }
@media (min-width: 600px) { .swap-screen > .button { width: auto; min-width: 200px; justify-self: start; } }
/* PLN-025c (D-224): the done card. A hairline under "Next", the extra's
   name left and minutes right, its Start, then "Other workouts" drawn as the
   Adjust today row is, a whole tappable row with a chevron. */
.today-other { display: flex; min-height: 50px; align-items: center; justify-content: space-between; gap: 12px; margin-top: 6px; padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font-size: 0.86rem; font-weight: 720; text-decoration: none; }
.today-other::after { content: "\203A"; color: var(--soft); font-size: 1.3rem; line-height: 1; }
.today-adjust__row { display: flex; min-height: 56px; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 14px; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.today-adjust__row > span, .today-adjust__row > label { display: grid; gap: 2px; }
.today-adjust__row strong { font-size: 0.92rem; }
.today-adjust__row small { color: var(--muted); font-size: 0.76rem; }
.today-adjust__chevron { color: var(--soft); font-size: 1.3rem; }
.today-adjust__minutes .load-stepper { flex: 0 0 auto; }
.today-adjust__minutes small { white-space: nowrap; }
.today-adjust__minutes { flex-wrap: wrap; }
.today-adjust__minutes .load-stepper { gap: 6px; }
.today-adjust__minutes .load-stepper .input-suffix { flex: 0 0 auto; }
.today-adjust__minutes .input-suffix input { width: 3rem; min-width: 0; min-height: 42px; padding: 0 0 0 10px; border: 0 !important; border-radius: 0; box-shadow: none !important; }
.today-adjust__minutes .input-suffix > span { padding: 0 10px 0 4px; }
.today-adjust__minutes .load-stepper__button { width: 44px; min-width: 44px; }
.choice-list li:first-child .choice-row { border-top: 0; }
.choice-card h2 { margin: 0 0 4px; }
.choice-card__sub { margin: 0 0 6px; color: var(--muted); }
.choice-list { margin: 0; padding: 0; list-style: none; }
.choice-row { display: flex; min-height: 56px; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 2px; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.choice-row__name { font-weight: 720; }
.choice-row__tag { margin-left: 8px; padding: 2px 8px; border-radius: 999px; background: var(--orange-soft); color: var(--warning); font-size: 0.72rem; font-weight: 700; vertical-align: 2px; }
.choice-row__tag--next { background: var(--mint); color: var(--green); }
.choice-row__right { color: var(--muted); white-space: nowrap; }
.choice-row__chevron { margin-left: 8px; color: var(--soft); font-size: 1.3rem; vertical-align: -2px; }
.choice-list__divider { margin: 6px 0 12px; border: 0; border-top: 1px solid var(--line); }
.choice-list__quiet { color: var(--muted); font-size: 0.9rem; }
button.choice-list__quiet { padding: 0; border: 0; background: none; cursor: pointer; font: inherit; color: var(--muted); }
.day-sheet__label { margin: 0 0 6px; font-weight: 720; }
.day-sheet__chosen { display: flex; width: 100%; min-height: 64px; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.day-sheet__chosen-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 0; }
.day-sheet__chosen-name small { flex-basis: 100%; color: var(--muted); font-size: 0.82rem; }
.day-sheet__change { color: var(--green); font-weight: 720; white-space: nowrap; }
.choose-list { overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.choose-list__group { margin: 0; padding: 14px 16px 6px; background: var(--paper); color: var(--muted); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.choose-row { display: flex; width: 100%; min-height: 52px; align-items: center; gap: 12px; padding: 10px 16px; border: 0; border-top: 1px solid var(--line); background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.choose-row__radio { width: 20px; height: 20px; flex: 0 0 auto; border: 2px solid var(--soft); border-radius: 50%; }
.choose-row[aria-checked="true"] .choose-row__radio { border: 6px solid var(--green); }
.choose-row__name { flex: 1; }
.choose-row__minutes { color: var(--muted); }
.choose-session__cancel { margin: 16px 2px; }
.choice-row--add .choice-row__name { color: var(--green); }
.today-adjusted { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 14px 22px 0; padding: 11px 14px; border-radius: var(--radius-sm); background: var(--mint-2); }
.today-adjusted p { margin: 0; }
.today-adjusted__undo { color: var(--green); font-weight: 700; }
/* Owner, 2026-10-06: the line and Adjust today sit close under Start. */
.workout-cta + .today-adjusted, .workout-cta + .today-adjust { margin-top: -10px; }
.adjust-page { display: grid; gap: 14px; max-width: 480px; }
.option-list { margin: 0; padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.option-row { display: flex; min-height: 56px; align-items: center; gap: 14px; padding: 12px 16px; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none; cursor: pointer; }
.option-list > legend + .option-row { border-top: 0; }
.option-row input { width: 20px; height: 20px; flex: 0 0 auto; margin: 0; accent-color: var(--green); }
.option-row > span { display: grid; flex: 1; gap: 2px; }
.option-row small { color: var(--muted); font-size: 0.8rem; }
.option-row--link strong { color: var(--green); }
.option-row__chevron { flex: 0 0 auto !important; color: var(--soft); font-size: 1.3rem; }
.option-row__more { margin: 0 16px 12px 50px; }
.option-row__more.segmented { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
.adjust-page__keep.segmented { grid-template-columns: 1fr 1fr; }
.adjust-page__actions { display: flex; gap: 12px; }
.adjust-page__actions .button { flex: 1; }
.day-sheet__block { display: grid; gap: 10px; margin-bottom: 12px; padding: 4px 16px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.day-sheet__block .day-sheet__chosen { min-height: 56px; padding: 10px 0; border: 0; border-radius: 0; background: none; }
.day-sheet__chosen-name strong { font-size: 1.12rem; }
.day-sheet__chosen-end { display: flex; align-items: center; gap: 8px; color: var(--muted); white-space: nowrap; }
.day-sheet__chevron { color: var(--soft); font-size: 1.3rem; }
.day-sheet__block .day-sheet__items { margin: 0; }
.day-sheet__block-time { margin: 0; }
.day-sheet__add-row { display: flex; width: 100%; min-height: 52px; align-items: center; justify-content: space-between; margin: 0 0 12px; padding: 10px 16px; border: 1px dashed var(--line); border-radius: var(--radius-sm); background: none; color: var(--green); font: inherit; font-weight: 720; cursor: pointer; }

/* PLN-025a (owner, 2026-10-06): circuits. The setup card's line under a
   movement says what moved since last time; a harder (or easier) version is
   one soft box with "Use it"; what the circuit counts as sits just above
   Start. The finish card names each movement over what was done. */
.format-progress { display: block; margin-top: 6px; color: var(--green); font-size: 0.875rem; font-weight: 600; }
.format-harder { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; padding: 10px 12px; border-radius: 12px; background: var(--mint-2); font-size: 0.94rem; }
.format-harder a { white-space: nowrap; font-weight: 700; }
/* STR-061 (D-221, changed 2026-10-07): "Switch to kettlebell swings?" in
   bold, then I know it | Learn first | Not now on one row, in a soft box
   under the hinge, before Start. The links are underlined text; Not now is
   quieter. */
.swing-offer { margin: 2px 0 10px; padding: 10px 12px; border-radius: 12px; background: var(--mint-2); font-size: 0.94rem; line-height: 1.4; max-width: 480px; }
.swing-offer__text { margin: 0 0 6px; font-weight: 700; }
.swing-offer__links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; margin: 0; line-height: 1.4; }
.swing-offer__bar { color: var(--soft); }
/* A 44px tap target that gives its air back, so the box stays two lines tall. */
.swing-offer__link { display: inline-flex; align-items: center; min-height: 44px; margin: -11px 0; padding: 0; border: 0; background: none; color: var(--green); font: inherit; font-weight: 700; cursor: pointer; }
.swing-offer__quiet { color: var(--muted); font-weight: 600; }
.swing-offer__link:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.movement-list li:has(+ li.movement-list__swing) { border-bottom: 0; padding-bottom: 8px; }
.movement-list li.movement-list__swing { display: block; padding: 0 0 12px; border-bottom: 1px solid var(--line); }
.movement-list li.movement-list__swing .swing-offer { margin: 0; }
.movement-row .swing-offer { margin: 0; padding-top: 6px; }
/* STR-062: "Moving up to Push-Up" and a quiet Keep, before Start. The same
   box as the swing's choice, so the card reads one way. */
.moving-up { margin: 2px 0 10px; padding: 10px 12px; border-radius: 12px; background: var(--mint-2); font-size: 0.94rem; line-height: 1.4; max-width: 480px; }
.moving-up__text { margin: 0 0 6px; font-weight: 700; }
.moving-up__links { margin: 0; line-height: 1.4; }
.moving-up__keep { display: inline-flex; align-items: center; min-height: 44px; margin: -11px 0; padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-weight: 600; cursor: pointer; }
.moving-up__keep:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.movement-list li.movement-list__swing .moving-up,
.movement-row .moving-up { margin: 0; }
/* The lesson and the self-check: a page of their own before Start. */
.swing-lesson { max-width: 480px; }
.swing-lesson__demo { display: grid; place-items: center; height: 150px; margin: 0 0 14px; border-radius: 14px; background: var(--surface-2); color: var(--muted); font-size: 0.875rem; }
.swing-lesson__cues { margin: 0 0 14px; font-weight: 700; font-size: 1.06rem; }
.swing-lesson__steps { margin: 0 0 16px; padding: 0; list-style: none; }
.swing-lesson__steps li { display: flex; gap: 12px; align-items: baseline; margin: 10px 0; }
.swing-lesson__steps b { color: var(--green); }
.swing-lesson__back { margin: 14px 2px 0; }
.swing-lesson__tips { margin: -4px 0 16px; padding-left: 20px; }
.swing-lesson__tips li { margin: 6px 0; line-height: 1.45; }
.swing-lesson__skip { padding: 0; border: 0; background: none; color: var(--green); font: inherit; font-weight: 700; cursor: pointer; }
.swing-check__line { margin: 6px 0 16px; color: var(--muted); }
.swing-check__answers { display: flex; gap: 10px; max-width: 480px; }
.swing-check__answers .button { flex: 1; }
.swap-choices__heading { margin: 14px 0 8px; padding-top: 12px; border-top: 1px solid var(--line); color: var(--muted); font-size: 0.84rem; font-weight: 700; }
.movement-row--add.format-add-row { padding-top: 18px; padding-bottom: 18px; }
.movement-row--rounds .attestation { margin-top: 12px; }
.format-counts { margin: 0; color: var(--muted); font-size: 0.94rem; }
.format-compose-form:not(.format-compose-form--tabata) .format-counts { margin-top: -8px; }
.format-done-rows .movement-row { display: block; }
.format-done-rows__name { display: block; font-weight: 600; }
.format-done-rows__line { display: block; margin-top: 2px; color: var(--muted); font-size: 0.94rem; }
.format-rest-note { margin: 14px 0 6px; }
.format-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.format-chips label { display: inline-flex; min-height: 44px; align-items: center; padding: 0 14px; border: 1px solid var(--line); border-radius: 999px; background: #fff; font-weight: 600; cursor: pointer; }
.format-chips label:has(input:checked) { border-color: var(--green); background: var(--mint-2); color: var(--green); }
.format-chips label:has(input:focus-visible) { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.format-scores--stacked .format-score { flex-direction: column; flex-wrap: wrap; align-items: flex-start; }
.format-scores--stacked .format-score > .movement-row__label { font-size: 1.05rem; }
.format-scores--stacked .format-score .input-suffix { width: 5.5rem; }
.format-scores--stacked .format-score .input-suffix input { padding-left: 12px; }
.format-hardest { margin-top: 22px; }
.format-compose-form--tabata .movement-row--add.format-add-row { margin-top: 0; border-top: 1px solid var(--line); }
.circuit-easy { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 16px; padding: 14px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); text-decoration: none; }
.circuit-easy b { display: block; }
.circuit-easy small { display: block; margin-top: 2px; color: var(--muted); font-size: 0.86rem; }
.circuit-easy__chev { color: var(--soft); font-size: 1.4rem; }
.easy-after__kinds { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin: 0 0 14px; padding: 4px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.easy-after__kinds--2 { grid-template-columns: repeat(2, 1fr); }
.easy-after__kinds a { display: grid; min-height: 44px; place-items: center; border-radius: 8px; color: var(--muted); font-weight: 700; text-decoration: none; }
.easy-after__kinds a.is-chosen { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.easy-after__kinds a:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }

.plan-ask-eve { margin: 16px 0 0; }
.plan-ask-eve .text-link { margin: 0; gap: 8px; padding: 0; border: 0; background: none; font: inherit; font-weight: 650; cursor: pointer; }

/* BIL-012 v2 (D-231; `docs/designs/bil-012-admin-v2/`, owner 2026-10-08).
   The admin nav's Refunds badge in the bell badge's style, orange while
   something waits and red while a dispute is open; the queue, one aligned
   row per open request that opens its own page; Done's rows; and the
   narrow measure of one request. At phone width a queue row is two lines
   and a Done row is two. Above the underline rule so the rule stays last. */
.admin-nav__badge { display: inline-block; min-width: 18px; height: 18px; margin-left: 5px; padding: 0 5px; border-radius: 999px; background: var(--orange); color: white; font-size: 0.66rem; font-weight: 760; line-height: 18px; text-align: center; vertical-align: 1px; }
.admin-nav__badge--bad { background: var(--danger); }
.admin-queue, .admin-done { padding: 0; overflow: hidden; }
.admin-queue__row { display: grid; grid-template-columns: minmax(0, 1.4fr) 5.5rem 11rem 4.5rem minmax(0, 15rem); column-gap: 20px; align-items: center; min-height: 60px; padding: 10px 20px; border-top: 1px solid var(--line); color: var(--ink); font-size: 0.9rem; text-decoration: none; }
.admin-queue__row span { font-variant-numeric: tabular-nums; }
.admin-queue__head { min-height: 40px; border-top: 0; color: var(--muted); font-size: 0.78rem; font-weight: 700; }
a.admin-queue__row:hover { background: var(--surface-2); }
a.admin-queue__row:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: -3px; }
.admin-queue__name { min-width: 0; color: var(--green); font-weight: 700; overflow-wrap: anywhere; }
.admin-queue__line2 { display: none; }
.admin-queue__empty { margin: 0; padding: 20px 20px 6px; font-size: 0.95rem; }
.admin-queue__foot { padding: 6px 20px 8px; border-top: 1px solid var(--line); }
.admin-queue__empty + .admin-queue__foot { border-top: 0; padding-top: 0; }
.admin-done .admin-queue__empty { padding-bottom: 20px; }
.admin-queue__foot .text-link, .admin-narrow .text-link { margin: 0; }
.admin-narrow { max-width: 640px; }
.admin-actions--inline { margin-top: 0; }
.admin-done__row { display: grid; grid-template-columns: 4.5rem 12rem minmax(0, 1fr) 7rem; column-gap: 20px; align-items: baseline; padding: 12px 20px; border-top: 1px solid var(--line); font-size: 0.9rem; }
.admin-done__head { border-top: 0; padding-top: 14px; color: var(--muted); font-size: 0.78rem; font-weight: 700; }
.admin-done__when, .admin-done__charge { color: var(--muted); font-size: 0.84rem; font-variant-numeric: tabular-nums; }
.admin-done__row .inline-link { display: inline; min-height: 0; font-size: inherit; }
@media (max-width: 600px) {
  .admin-queue__head, .admin-done__head { display: none; }
  .admin-queue__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 4px; padding: 12px 16px; }
  .admin-queue__row .q-plan, .admin-queue__row .q-charged, .admin-queue__row .q-day { display: none; }
  .admin-queue__line2 { display: block; grid-column: 1 / -1; color: var(--muted); font-size: 0.82rem; }
  .admin-queue__foot { padding: 6px 16px 8px; }
  .admin-queue__empty { padding: 16px 16px 6px; }
  .admin-done__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; padding: 12px 16px; }
  .admin-done__when { grid-column: 2; grid-row: 1; text-align: right; }
  .admin-done__out { grid-column: 1; grid-row: 1; font-weight: 700; }
  .admin-done__who { grid-column: 1; grid-row: 2; }
  .admin-done__charge { grid-column: 2; grid-row: 2; text-align: right; }
}
@media (forced-colors: active) {
  .admin-nav__badge { border: 1px solid CanvasText; }
}

/* Coach stage 1 (owner, 2026-10-09; docs/designs/coach-screens-2026-10-09).
   The coaching mode's places and the client page. Rows are tight and even
   (screen rules: no header gap larger than the gap between rows); quiet
   buttons size to their label; a form keeps a form's width on a wide
   screen and is full width only at phone widths. */
/* Small buttons are round pills (screen rules, owner 2026-10-09): Select,
   Clear read, Mark read, + Add, + New. 40px tall, sized to the label. */
.button--small { min-height: 40px; padding: 6px 16px; border-radius: 999px; font-size: 0.95rem; }
/* The title and its small pill share a baseline (coach stage 1 review). */
.coach-title { align-items: baseline; }
.coach-title > div { min-width: 0; }
.coach-title__action { flex: none; }
/* The client list's two rows under the title: the label, then its number in
   a column of its own, never wrapping at 375; 16px before the list. */
/* D-250 (owner, 2026-10-09): the numbers sit at the right edge of the
   content column, the label at the left, one line each at 375. */
.coach-summary { display: grid; gap: 0; margin: -6px 0 16px; }
.coach-summary__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-items: center; min-height: 34px; margin: 0; color: var(--muted); font-size: 0.95rem; white-space: nowrap; }
.coach-summary__label { overflow: hidden; text-overflow: ellipsis; }
.coach-summary__value { justify-self: end; color: var(--ink); font-weight: 760; }
.coach-summary__row--link { color: var(--muted); text-decoration: none; }
.coach-summary__row--link .coach-summary__value { color: var(--green); }
.coach-summary__row--link:hover .coach-summary__value { text-decoration: underline; text-underline-offset: 4px; }
.coach-summary__row--link:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 6px; }
.coach-summary__chevron { margin-left: 6px; }
.account-menu__switch { margin: 0; padding: 4px 0; border-bottom: 1px solid var(--line); }
.account-menu__switch button { display: flex; width: 100%; min-height: 48px; align-items: center; padding: 0 16px; border: 0; background: none; color: var(--green); font: inherit; font-size: 0.92rem; font-weight: 700; text-align: left; cursor: pointer; }
.account-menu__switch button:hover { background: var(--surface-2); }
.account-menu__switch button:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: -3px; }
.action-card--button { width: 100%; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.action-symbol--face { overflow: hidden; padding: 0; border-radius: 50%; }
.action-symbol--face img { width: 100%; height: 100%; object-fit: cover; }
.coach-account__out { margin: 4px 0 0; }
.coach-account__out .text-link { margin: 0; }

/* Clients: a photo or initials, the name, one muted line. */
.client-rows { margin: 0; padding: 0; list-style: none; }
.client-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); }
.client-row:first-child { padding-top: 0; }
.client-row:last-child { padding-bottom: 0; border-bottom: 0; }
.client-row--link { position: relative; }
.client-face { display: grid; width: 44px; height: 44px; overflow: hidden; place-items: center; border-radius: 50%; background: var(--mint); color: var(--green); font-size: 0.92rem; font-weight: 760; }
.client-face img { width: 100%; height: 100%; object-fit: cover; }
.client-face--small { width: 26px; height: 26px; font-size: 0.72rem; }
.client-row__text { display: grid; min-width: 0; gap: 2px; }
.client-row__name { font-weight: 700; overflow-wrap: anywhere; }
.client-row__name .coach-row__link { margin: -10px 0; text-decoration: underline; }
/* The whole row opens the client; the name stays the link's text. */
.client-row--link .client-row__target::after { position: absolute; inset: 0; content: ""; }
.client-row__detail { color: var(--muted); font-size: 0.88rem; }
.client-row .coach-ready { position: relative; z-index: 1; margin: -10px 0; }
.client-row__actions { display: inline-flex; gap: 14px; }
.client-row__actions form { display: inline-flex; margin: 0; }
.client-row__actions .text-link { margin: 0; text-decoration: underline; }
.client-row__chevron, .place-row__chevron, .calendar-row__chevron { color: var(--soft); font-size: 1.4rem; line-height: 1; }

/* A list of rows that each open a page: name, one muted line, chevron. */
.place-rows { margin: 0; padding: 0; list-style: none; }
.place-rows > li { border-bottom: 1px solid var(--line); }
.place-rows > li:last-child { border-bottom: 0; }
.place-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 56px; padding: 10px 0; color: inherit; text-decoration: none; }
.place-rows > li:first-child .place-row { padding-top: 0; }
.place-rows > li:last-child .place-row { padding-bottom: 0; }
.place-row__text { display: grid; gap: 2px; min-width: 0; }
.place-row__name { font-weight: 700; }
.place-row__name--link, .place-row:hover .place-row__name { text-decoration: underline; text-underline-offset: 4px; }
.place-row__line { color: var(--muted); font-size: 0.88rem; }
.place-row:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 6px; }
.library-tabs { display: grid; width: 100%; margin: 0 0 10px; }
.library-card { margin-top: 0; }

/* The client page. */
.client-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: -6px 0 16px; }
.client-actions__button { gap: 8px; min-height: 44px; padding: 8px 16px; }
.calendar-card { padding: 16px 18px 12px; }
.calendar-card__switch { display: grid; grid-template-columns: 44px auto 44px; justify-content: center; align-items: center; gap: 8px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.calendar-card__week { margin: 0; font-size: 1.02rem; font-weight: 760; text-align: center; }
.calendar-card__step { display: grid; width: 44px; height: 44px; place-items: center; border-radius: 50%; color: var(--green); }
.calendar-card__step:hover { background: var(--surface-2); }
.calendar-card__step:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); }
.calendar-rows { margin: 0; padding: 0; list-style: none; }
.calendar-row { border-bottom: 1px solid var(--line); }
.calendar-row:last-child { border-bottom: 0; }
.calendar-row__link { display: grid; grid-template-columns: 4.6em minmax(0, 1fr) 4.4em 16px; gap: 10px; align-items: center; min-height: 48px; padding: 4px 8px; color: inherit; text-decoration: none; }
a.calendar-row__link:hover { background: var(--surface-2); border-radius: 12px; }
a.calendar-row__link:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); border-radius: 12px; }
.calendar-row--today .calendar-row__link { border-radius: 12px; background: var(--mint-2); }
.calendar-row--today .calendar-row__day { font-weight: 780; }
.calendar-row__name { min-width: 0; overflow-wrap: anywhere; }
.calendar-row__name--rest { color: var(--muted); }
.calendar-row__status { font-size: 0.86rem; }
.calendar-row__status--done { color: var(--green); font-weight: 760; }
.calendar-row__status--missed { color: var(--ink); }
.calendar-row__add { color: var(--green); font-weight: 760; text-decoration: underline; text-underline-offset: 4px; }
/* Owner, 2026-10-10: "Add" ends where the other rows' chevrons end, its
   cell spanning the status and chevron columns. */
.calendar-row__status--add { grid-column: 3 / 5; justify-self: end; }
.calendar-row__chevron { justify-self: end; }

/* The client's Settings. */
.client-back { display: inline-flex; min-height: 44px; align-items: center; gap: 8px; margin: -6px 0 2px; color: var(--green); font-weight: 700; text-decoration: none; }
.client-back:hover span:last-child { text-decoration: underline; }
.client-settings__header h1 { margin: 0; }
.client-settings__card { max-width: 560px; }
.client-settings__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.client-settings__text { display: grid; gap: 2px; }
.client-settings__text span { color: var(--muted); font-size: 0.9rem; }
.client-settings__since { margin: 0 0 12px; color: var(--muted); }
.client-settings__buttons { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.client-settings__buttons form { margin: 0; }
.you-can { margin: 0 0 8px; padding: 0; list-style: none; }
.you-can__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 48px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.you-can__row:last-child { border-bottom: 0; }
.you-can__state { flex: none; color: var(--muted); }

/* A short confirm over the page (screen rules, 2026-10-09). */
.small-confirm { width: min(360px, calc(100vw - 32px)); margin: auto; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); }
.small-confirm::backdrop { background: rgba(23, 34, 30, 0.32); }
.small-confirm p { margin: 0 0 14px; }
.small-confirm form { margin: 0 0 4px; }
.small-confirm .text-link { margin: 0; }
.confirm-card { max-width: 560px; }
.confirm-card__question { margin: 0 0 6px; font-size: 1.1rem; }
.confirm-card__line { margin: 0 0 14px; color: var(--muted); }
.confirm-card form { margin: 0 0 4px; }
.confirm-card .text-link { margin: 0; }

/* Weight increases and Add to a day: radio rows with one sentence. */
.weights-form { max-width: 520px; }
.weights-form__choices, .day-add__group { margin: 0; padding: 0; border: 0; }
.weights-choice { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 12px; align-items: start; padding: 8px 0; cursor: pointer; }
.weights-choice input { width: 22px; height: 22px; margin: 2px 0 0; accent-color: var(--green); }
.weights-choice__text { display: grid; gap: 2px; }
.weights-choice__text span { color: var(--muted); font-size: 0.9rem; }
.weights-form .field-help { margin: 4px 0 14px; }
.day-add { max-width: 560px; }
.day-add__card { padding-top: 16px; }
.day-add__group + .day-add__group { margin-top: 8px; }
.day-add__legend { padding: 0; margin: 0 0 2px; font-weight: 760; }
.day-add__choice { min-height: 44px; align-items: center; padding: 4px 0; }
.day-add__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.day-add__actions .text-link { margin: 0; }
.coach-day__session { margin: 0 0 12px; }

/* Add clients. */
.coach-add { max-width: 560px; }
.coach-add__heading { margin: 0 0 10px; font-size: 1.05rem; }
.coach-add__form .field { margin-bottom: 14px; }
.coach-add__summary { margin: 0 0 6px; }
.coach-add__lines { margin: 0 0 14px; padding: 0; list-style: none; }
.coach-add__line { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.coach-add__line:last-child { border-bottom: 0; }
.coach-add__who { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.coach-add__email { color: var(--muted); font-size: 0.9rem; }
.coach-add__skip { flex: none; max-width: 45%; color: var(--muted); font-size: 0.86rem; text-align: right; }
.coach-add__edit { margin: 6px 0 0; }

/* A day gone by and the check-ins. */
.day-done__moves { margin: 0; padding: 0; list-style: none; }
.day-done__move { padding: 12px 0; border-bottom: 1px solid var(--line); }
.day-done__move:first-child { padding-top: 0; }
.day-done__move:last-child { padding-bottom: 0; border-bottom: 0; }
.day-done__name { margin: 0 0 4px; font-size: 1rem; }
.day-done__set { margin: 0; }
.checkin-rows { margin: 0; }
.checkin-rows__row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.checkin-rows__row dt { color: var(--muted); }
.checkin-rows__row dd { margin: 0; font-weight: 700; }
.checkin-rows__note { margin: 8px 0 0; color: var(--muted); }

@media (min-width: 600px) {
  .coach-add .button--full, .weights-form .button--full, .day-add .button--full { width: auto; min-width: 200px; }
  .library-tabs { width: auto; min-width: 360px; }
}

/* Coach stage 1 (v2/23): the client's Plan says once that the coach set the
   week, and a rest day in it reads "Rest day" in normal text. */
.week-coach-line { margin: -4px 0 12px; color: var(--green); font-weight: 760; }
.week-row--rest-day .week-row__name, .week-row--rest.week-row--rest-day .week-row__grid .week-row__name { color: var(--ink); font-weight: 720; }
.coach-settings__can { margin: 4px 0 6px; padding: 0; font-weight: 760; }
.coach-title__action { gap: 4px; }
/* COA-016's ready card styles div.coach-move; a day sheet's movement row is a list item and stays a grid. */
li.coach-move { display: grid; justify-content: stretch; }
.coach-ready-card .coach-rows > .movement-row:last-child { padding-bottom: 0; border-bottom: 0; }
.coach-ready-card .coach-rows { padding-bottom: 0; border-bottom: 0; }

/* D-251 (owner, 2026-10-09; docs/designs/inbox-2026-10-09): one inbox
   behind the bell. The title with its small round pills, 16px clear before
   the tabs; the tabs Messages | Updates right under it; the list right
   under them, one conversation or Update per line. The bell is tinted on
   the inbox's own pages. */
.bell[aria-current="page"] { background: var(--mint-2); color: var(--green); }
.inbox { max-width: 640px; }
.inbox-head { align-items: center; margin-bottom: 16px; }
.inbox-head__pills { display: flex; flex: none; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.inbox-tabs { display: grid; width: 100%; margin: 0 0 10px; }
.inbox-tabs .week-tab > span { display: inline-flex; align-items: center; }
.inbox-count { display: inline-grid; min-width: 18px; height: 18px; margin-left: 6px; padding: 0 5px; place-items: center; border-radius: 999px; background: var(--orange); color: #fff; font-size: 0.66rem; font-weight: 760; line-height: 18px; }
.inbox-empty { margin: 4px 0 0; color: var(--muted); }
/* The card clips its rows to its own corners (owner, 2026-10-09): a hover or
   a checked row's tint never squares off a rounded corner or leaves a strip
   above the first row. The ⋯ menus are popovers in the top layer, so the
   clip never cuts one off. */
.inbox-list { padding: 0; overflow: hidden; }
.inbox-rows { margin: 0; padding: 0; list-style: none; }
.inbox-row { position: relative; display: flex; align-items: center; border-bottom: 1px solid var(--line); }
.inbox-rows > .inbox-row:last-child { border-bottom: 0; }
.inbox-row__link { display: flex; flex: 1; align-items: center; gap: 12px; min-width: 0; padding: 12px 16px; color: inherit; text-decoration: none; cursor: pointer; }
.inbox-row__link:hover { background: var(--surface-2); }
.inbox-row__link:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.18); outline-offset: -3px; }
.inbox-row__text { display: grid; flex: 1; gap: 2px; min-width: 0; }
.inbox-row__name { overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.inbox-row--unread .inbox-row__name { font-weight: 760; }
.inbox-row__line { overflow: hidden; color: var(--muted); font-size: 0.84rem; text-overflow: ellipsis; white-space: nowrap; }
.inbox-row--unread .inbox-row__line { color: var(--ink); }
.inbox-row__end { display: flex; flex: none; align-self: flex-start; align-items: center; gap: 6px; padding-top: 3px; color: var(--soft); font-size: 0.78rem; white-space: nowrap; }
.inbox-row__dot { width: 8px; height: 8px; border-radius: 50%; background: transparent; }
.inbox-row__muted { display: inline-grid; place-items: center; color: var(--soft); }
.inbox-row__muted svg { width: 14px; height: 14px; }
.inbox-row--unread .inbox-row__dot { background: var(--orange); }
.inbox-face { flex: none; width: 40px; height: 40px; }
.inbox-kind { display: grid; flex: none; width: 36px; height: 36px; place-items: center; border-radius: 50%; background: var(--surface-2); color: var(--green); }
.inbox-kind svg { width: 18px; height: 18px; }
.inbox-check { display: grid; flex: none; width: 40px; height: 40px; place-items: center; }
.inbox-check input { width: 20px; height: 20px; margin: 0; accent-color: var(--green); }
/* An Update's title and line wrap rather than lose their end; its ⋯ sits
   under the time so the words keep the row's width, and in select mode the
   row keeps its height (the ⋯ is gone, its space is not). */
.inbox-row--update .inbox-row__link { min-height: 72px; align-items: flex-start; }
.inbox-row--update .inbox-row__name { overflow: visible; font-size: 0.95rem; white-space: normal; }
.inbox-row--update .inbox-row__line { padding-right: 8px; }
.inbox-row--update .inbox-kind, .inbox-row--update .inbox-check { height: 36px; margin-top: 2px; }
.inbox-row--update .inbox-row__end { padding-bottom: 26px; }
.inbox-row__more { position: absolute; right: 4px; bottom: 6px; }
.inbox-more { display: grid; width: 44px; height: 36px; padding: 0; place-items: center; border: 0; border-radius: 12px; background: none; color: var(--muted); cursor: pointer; }
.inbox-more svg { width: 20px; height: 20px; }
.inbox-more:hover, .inbox-more:focus-visible { background: var(--surface-2); color: var(--ink); }
.inbox-more:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }
.button.inbox-delete { color: var(--danger); }
.inbox-actionbar .button--small, .inbox-head__pills .button--small { white-space: nowrap; }
.inbox-actionbar .button--small { padding: 6px 14px; }

/* The ⋯ action menu: the browser's own popover, placed under its button by
   app.js; a short list of actions on the row it belongs to. Without the
   script it opens in the middle of the screen, which still works. */
/* Owner, 2026-10-09: tight rows and as wide as the longest label plus its
   sides, never wider than 220px. Rows are 36px: still well over WCAG 2.2's
   24px target, with no gap between them but a hairline before Delete. */
.row-menu { width: max-content; min-width: 140px; max-width: min(220px, calc(100vw - 32px)); margin: auto; padding: 4px 0; overflow: hidden; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg); }
.row-menu.row-menu--placed { position: fixed; inset: auto; margin: 0; }
.row-menu form { margin: 0; }
.row-menu button { display: flex; width: 100%; min-height: 36px; align-items: center; padding: 0 14px; border: 0; background: none; color: var(--ink); font: inherit; font-size: 0.92rem; font-weight: 600; text-align: left; white-space: nowrap; cursor: pointer; }
.row-menu button:hover, .row-menu button:focus-visible { background: var(--surface-2); }
.row-menu .row-menu__sep { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--line); }
.row-menu .row-menu__danger { color: var(--danger); }

/* The short confirm: one line, Clear and Cancel side by side. */
.inbox-confirm p { font-weight: 650; }
.inbox-confirm__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.inbox-confirm__actions form { margin: 0; }

/* Select mode: while anything is checked, the action bar takes the bottom
   bar's place at its height, so nothing in the page moves. */
.inbox-actionbar { position: fixed; z-index: 31; right: 0; bottom: 0; left: 0; display: none; min-height: 70px; align-items: center; justify-content: center; gap: 8px; padding: 8px max(16px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); border-top: 1px solid var(--line); background: rgba(255, 255, 255, 0.97); box-shadow: 0 -10px 30px rgba(23, 34, 30, 0.06); }
body:has(.inbox-select input:checked) .inbox-actionbar { display: flex; }
body:has(.inbox-select input:checked) .bottom-nav { visibility: hidden; }
@media (min-width: 880px) {
  .inbox-actionbar { left: 220px; }
}

/* A conversation: who it is with and its ⋯, the lines, and the reply box at
   the foot with a round Send. */
.coach-thread { display: flex; max-width: 640px; min-height: calc(100vh - 68px - 118px); flex-direction: column; }
.coach-thread .eve-composer, .coach-thread > .error-summary, .coach-thread > .coach-thread__closed { margin-top: auto; }
.coach-thread > .error-summary + .eve-composer { margin-top: 0; }
@media (min-width: 880px) {
  .coach-thread { min-height: calc(100vh - 110px); }
}
.thread-head { align-items: center; margin-bottom: 8px; }
.thread-head__who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.thread-head__who h1 { overflow: hidden; font-size: 1.35rem; text-overflow: ellipsis; white-space: nowrap; }
.thread-head__more { flex: none; margin-right: -10px; }
.thread-turns { gap: 12px; }
.thread-turns .eve-turn { max-width: 86%; }
.thread-time { justify-self: center; margin: 4px 0 0; color: var(--soft); font-size: 0.74rem; }
.coach-thread .coach-thread__lines { margin-bottom: 16px; }
.coach-thread .eve-composer { padding: 6px 6px 6px 14px; }
.coach-thread .coach-thread__composer { max-width: none; }
.send-button { display: grid; flex: none; width: 44px; height: 44px; padding: 0; place-items: center; border: 0; border-radius: 50%; background: var(--green); color: #fff; cursor: pointer; }
.send-button svg { width: 20px; height: 20px; }
.send-button:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.3); outline-offset: 2px; }
@media (forced-colors: active) {
  .inbox-row--unread .inbox-row__dot, .inbox-count { border: 1px solid CanvasText; }
}

/* Coach stage 2 (D-253 to D-256; pictures v3, v4 and v5): the Library's
   workout editor, the movement picker, Request a movement and the program
   pages. Forms and their cards are 480px at most on a laptop, full width on
   a phone; small buttons are pills sized to their label. */
.lib-card, .lib-actions, .program-card, .program-runs, .lib-sent, .program-confirm__page-line { max-width: 480px; }
.lib-card { margin-bottom: 14px; padding: 20px; }
.lib-field { margin: 0 0 16px; padding: 0; border: 0; }
.lib-card > .lib-field:last-child, .lib-card > fieldset:last-child { margin-bottom: 0; }
.lib-field > legend { display: block; margin-bottom: 8px; padding: 0; color: var(--ink); font-size: 0.88rem; font-weight: 680; }
/* For time v3 (owner, 2026-10-10): the kinds lay out three to a row at
   every width. */
.lib-kinds__choices { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.lib-kind { min-height: 44px; padding: 7px 4px; border: 0; border-radius: 10px; background: none; color: var(--muted); font: inherit; font-size: 0.83rem; font-weight: 700; cursor: pointer; }
.lib-kind--current { background: var(--surface); color: var(--green); box-shadow: 0 2px 9px rgba(23, 34, 30, 0.1); }
.lib-kind:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 1px; }
.lib-steps { display: none; margin-top: 12px; }
.lib-steps label { display: block; margin-bottom: 8px; font-size: 0.88rem; font-weight: 680; }
.lib-warmup:has(select option[value="OWN"]:checked) .lib-steps { display: block; }
.lib-radios--timing { margin-bottom: 4px; }
.lib-inline { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.lib-inline label { margin: 0; }
.lib-number { width: 7.5rem; }
.field input.lib-minutes:not([type="radio"]):not([type="checkbox"]) { width: 7.5rem; }
.lib-radios { display: grid; gap: 6px; }
.lib-radio { display: flex; align-items: center; gap: 12px; min-height: 44px; margin: 0; font-weight: 650; cursor: pointer; }
.lib-radio input { width: 22px; height: 22px; margin: 0; accent-color: var(--green); }
.lib-total { margin: 4px 0 0; color: var(--muted); font-size: 0.88rem; }
.lib-rule { height: 0; margin: 18px 0 16px; border-top: 1px solid var(--line); }
.lib-heading { margin: 0 0 8px; font-size: 1rem; font-weight: 750; }
.lib-moves { margin: 0; padding: 0; list-style: none; }
.lib-move { padding: 14px 0; border-bottom: 1px solid var(--line); }
.lib-move:first-child { padding-top: 0; }
.lib-move__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lib-move__head .text-link { min-height: 36px; margin: 0; }
.lib-move__name { min-width: 0; font-weight: 700; overflow-wrap: anywhere; }
.lib-move__boxes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.lib-box { display: grid; gap: 4px; }
.lib-box > input, .lib-box .input-suffix { width: 4.5rem; min-height: 44px; }
.lib-box > input { padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); font-size: 1rem; }
.lib-box--rest .input-suffix { width: 7rem; }
.lib-box .input-suffix input { width: 100%; min-width: 0; min-height: 42px; padding: 8px 4px 8px 12px; border: 0; background: none; font-size: 1rem; }
.lib-box__caption { color: var(--muted); font-size: 0.8rem; }
.lib-rotate { margin: 12px 0 0; color: var(--muted); font-size: 0.9rem; }
.lib-add { padding-top: 14px; }
.lib-moves + .lib-add, .lib-rotate + .lib-add { margin-top: 14px; border-top: 1px solid var(--line); }
.lib-moves .lib-move:last-child { border-bottom: 0; padding-bottom: 0; }
.lib-add .field-help { margin: 0; }
/* For time v3 (owner, 2026-10-10): every add pill is a round, light green
   pill sized to its label, the bottom bar's selected tint with dark green
   words: Add a movement in the Library and on a For time, Add a week. */
.lib-add__button { display: inline-flex; align-items: center; justify-self: start; width: auto; min-height: 44px; padding: 8px 20px; border: 1px solid var(--mint-2); border-radius: 999px; background: var(--mint-2); color: var(--green); font-weight: 750; text-decoration: none; }
.lib-add__button:hover { border-color: #bed7ca; background: var(--mint-2); color: var(--green); }
.format-add-row.lib-add { padding: 8px 0; }
.lib-actions { margin-top: 4px; }
.lib-sent { margin: 0 0 14px; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--mint-2); }

.picker .lib-field { margin-bottom: 12px; }
.picker__list { margin: 0; }
.picker__label { margin: 4px 0 2px; color: var(--muted); font-size: 0.72rem; font-weight: 780; letter-spacing: 0.1em; text-transform: uppercase; }
.picker__rows { margin: 0; padding: 0; list-style: none; }
.picker__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; border-bottom: 1px solid var(--line); }
.picker__name { min-width: 0; font-weight: 650; overflow-wrap: anywhere; }
.picker__row .text-link { min-height: 40px; margin: 0; }
.picker__none { margin: 4px 0 0; padding-bottom: 10px; border-bottom: 1px solid var(--line); color: var(--muted); }
.picker__request { margin: 0; padding-top: 6px; color: var(--muted); font-size: 0.9rem; }
.picker__request .text-link { min-height: 36px; margin: 0; }

.program-runs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: -4px 0 12px; color: var(--muted); }
.program-runs .text-link { min-height: 36px; margin: 0; }
.program-runs--edit { gap: 8px; color: var(--ink); }
.program-runs--edit label { margin: 0; font-weight: 680; }
.program-runs--edit .lib-minutes { width: 3.75rem; min-height: 44px; padding: 8px 12px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); font-size: 1rem; }
.program-runs__unit { color: var(--muted); }
.program-card { padding: 12px 20px; }
.program-days, .program-weeks { margin: 0; padding: 0; list-style: none; }
.program-days > li, .program-weeks > li { border-bottom: 1px solid var(--line); }
.program-day { display: grid; grid-template-columns: 3.4em minmax(0, 1fr) 16px; gap: 12px; align-items: center; min-height: 48px; color: inherit; text-decoration: none; }
.program-day__day { font-weight: 750; }
.program-day__text { display: grid; gap: 2px; min-width: 0; padding: 8px 0; }
.program-day__line { color: var(--muted); font-size: 0.88rem; }
.program-day__name--rest { color: var(--muted); }
.program-day__chevron { color: var(--muted); }
.program-day:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 6px; }
.program-foot { padding: 6px 0 4px; }
.program-foot .text-link { margin: 0; }
.program-foot form { margin: 0; }
.program-foot .lib-add__button { margin-top: 8px; }
.program-week { position: relative; }
.program-week__head { display: flex; align-items: center; gap: 12px; min-height: 48px; padding-right: 52px; cursor: pointer; list-style: none; }
.program-week__head::-webkit-details-marker { display: none; }
.program-week__head:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 6px; }
.program-week__chevron { width: 9px; height: 9px; margin: 0 4px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(-45deg); transition: transform 160ms ease; }
.program-week__fold[open] .program-week__chevron { transform: rotate(45deg); }
.program-week__name { color: var(--muted); font-weight: 500; }
.program-week__more { position: absolute; top: 6px; right: -8px; }
.program-days--week { margin: 0 0 6px 30px; }
.program-days--week > li:last-child { border-bottom: 0; }
.program-choices > li { border-bottom: 1px solid var(--line); }
.program-choices > li:last-child { border-bottom: 0; }
.program-choice { display: grid; grid-template-columns: minmax(0, 1fr) 24px; gap: 12px; align-items: center; width: 100%; min-height: 56px; padding: 8px 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.program-choice:focus-visible { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; border-radius: 6px; }
.program-choice__tick { color: var(--green); font-size: 1.2rem; font-weight: 800; }
.row-menu .row-menu__item { display: flex; min-height: 36px; align-items: center; padding: 0 14px; color: var(--ink); font-size: 0.92rem; font-weight: 600; text-decoration: none; white-space: nowrap; }
.row-menu .row-menu__item:hover, .row-menu .row-menu__item:focus-visible { background: var(--surface-2); }
.program-confirm__title { margin: 0 0 8px; font-size: 1.15rem; }
.program-confirm .program-confirm__line { font-weight: 400; }
.program-confirm__page-line { margin: 0 0 16px; }
.no-popover-only { display: none; }
@supports not selector(:popover-open) {
  .needs-popover { display: none !important; }
  .no-popover-only { display: inline-flex; }
}


/* Owner, 2026-10-05: every text link is underlined, everywhere, one way.
   WCAG 1.4.1: a link set inside text may not be told apart by color alone,
   and the brand green sits too close to the ink for color to do it. Buttons,
   the navigation (bottom bar, side menu, tabs) and whole tappable rows with
   a chevron are not text links and are not underlined.
   `tests/test_link_underline.py` keeps every text-link class on this list. */
.inline-link,
.swing-offer__link,
.moving-up__keep,
.swing-lesson__skip,
.swing-offer__quiet,
.text-link,
.admin-queue__name,
.choice-list__quiet,
.today-adjusted__undo,
.workout-hero__link,
.week-row__ask-link,
.set-links__link,
.movement-title-row__link,
.movement-row__skip,
.movement-card__split,
.after-save-question__skip,
.advice-card__why,
.day-sheet__quiet,
.routine-new a.day-sheet__quiet,
.routine-card__edit,
.routine-editor__remove,
.coach-row__link,
.coach-ready,
.calendar-row__add,
.place-row__name--link,
.client-agreement__link,
.format-add-link,
.eve-where__end,
.home-banner__dismiss,
.back-link,
.admin-rowlink,
.standalone-foot a,
.announcement-body a,
.movement-aside > summary {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}


/* Owner, 2026-10-06 (D-217): every box and every control beside a box is 44px
   from the shared rules above, so the EMOM and Tabata setup needs no height
   of its own. It only closes the unit up against the number. */
.format-compose-form .input-suffix > span { padding: 0 8px; }

/* Owner, 2026-10-07: the typed weights list and its help hide once the chips work. */
[data-load-field][hidden],
[data-load-help][hidden] { display: none; }

/* TDY-002 (D-225): one Today card for every state, the workout card's shell
   (`_today_card.html`). The green header, a white body, then `.workout-cta`
   with the one orange Start and one row link under it: Adjust today, or
   Other workouts. The old looks' class names stay on the section for their
   behavior and tests; none of them lays anything out any more. */
.today-card__body { display: grid; gap: 8px; padding: 16px 22px 4px; }
.today-card__body p { margin: 0; }
.today-card__line { color: var(--muted); font-size: 0.9rem; line-height: 1.5; }
.today-card__body .choice-list { margin: 0; }
.today-extra { padding: 18px 22px 16px; }
.today-extra .eyebrow { margin: 0 0 6px; }
.today-extra__row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.today-extra__row h3 { margin: 0; font-size: 1.15rem; }
.today-extra__row span { flex: 0 0 auto; color: var(--muted); white-space: nowrap; }
.today-steps { margin: 0; padding: 8px 22px 6px; list-style: none; }
/* D-238: a timed format's rounds and timing, one line at the card's top. */
.today-timing { margin: 0; padding: 16px 22px 4px; font-size: 0.95rem; font-weight: 720; }
/* Owner, 2026-10-09: no wider from the setup line to the first movement
   than from one movement to the next. */
.today-timing + .movement-list { padding-top: 6px; }
.today-steps li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 0.9rem; }
.today-steps li:last-child { border-bottom: 0; }
.today-steps li span { flex: 0 0 auto; color: var(--muted); white-space: nowrap; }
.workout-cta form { margin: 0; }
.workout-cta > .today-adjust, .workout-cta > .today-other, .workout-cta > .today-adjusted { margin: 0; }
.workout-cta > .lighter-today__line { margin: 0; text-align: left; }
.today-adjust > summary, .today-other { color: var(--green); }
.today-later__row { padding: 0 2px; border-top: 1px solid var(--line); }
.today-later__row:first-child { border-top: 0; }
/* Other workouts: the "next up" tag stays on one line beside the name, and
   the minutes and chevron stay right however long the name is. */
.choice-row__name { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.choice-row__tag { margin-left: 0; white-space: nowrap; }
.choice-row__right { flex: 0 0 auto; }
.today-suggestion__reason { color: var(--muted); font-size: 0.86rem; line-height: 1.5; margin: 0; }
.workout-cta .today-adjusted p { color: inherit; text-align: left; }
/* PLN-024c: a planned Wall Sit's one recommendation and its Depth, the
   segmented control's four choices, above the card's Start. */
.workout-cta .today-wall-sit__advice { margin: 0 0 14px; color: var(--ink); font-size: 0.92rem; text-align: left; }
.today-depth { min-width: 0; margin: 0 0 14px; padding: 0; border: 0; }
.today-depth legend { margin: 0 0 8px; padding: 0; font-size: 0.86rem; font-weight: 720; }
.segmented--four { grid-template-columns: repeat(4, 1fr); }

/* REC-003: the one-tap check-in above Today's card. Two equal choices, then
   (Not so good) the questions in the app's green, the note and a quiet Save.
   After Good the card shows only the workout (D-238). */
.checkin-tap { display: grid; gap: 14px; }
.checkin-tap h2 { margin: 0; font-size: 1.25rem; }
.checkin-tap__line { margin: 0; color: var(--muted); line-height: 1.5; }
.checkin-tap__choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0; }
.checkin-tap__choices form { margin: 0; display: grid; }
.checkin-tap__choice { width: 100%; font-size: 1rem; }
.checkin-tap__choice--on { border-color: var(--green); background: var(--green); color: #fff; }
.checkin-tap__form { display: grid; gap: 14px; }
.checkin-tap__form .field { max-width: 480px; }
.checkin-tap .segmented { padding: 0; gap: 0; overflow: hidden; background: var(--surface); }
.checkin-tap .segmented label + label span { border-left: 1px solid var(--line); }
.checkin-tap .segmented span { border-radius: 0; color: var(--ink); }
.checkin-tap .segmented input:checked + span { background: var(--mint); color: var(--green); font-weight: 800; box-shadow: none; }
@media (min-width: 600px) {
  .checkin-tap__choices { grid-template-columns: repeat(2, auto); justify-content: start; }
  .checkin-tap__choice { width: auto; min-width: 160px; }
}

/* TDY-002 (owner, 2026-10-07): full width only at phone widths. From 600
   the card's primary sizes to its label and the controls under it keep a
   form's width, so a 900px card is not one long bar. */
@media (min-width: 600px) {
  .workout-cta { justify-items: start; }
  .workout-cta > .button--full,
  .workout-cta > form > .button--full,
  .workout-cta .today-pain-choices .button--full { width: auto; min-width: 200px; }
  .workout-cta > .mode-toggle,
  .workout-cta > .today-adjust,
  .workout-cta > form,
  .workout-cta > a.today-adjust__row { width: 100%; max-width: 360px; }
}

/* BIL-006b (D-230): the processor's figures on the choice page, pictures 1
   and 2. The amount reads under the plan's name; "Save" sits beside the
   yearly amount at full price; the founding line is muted under it. */
.billing-choose .option-card strong { font-size: 0.95rem; }
.billing-price { display: block; margin-top: 3px; color: var(--ink); font-size: 1.05rem; font-weight: 760; }
.billing-price small { display: block; margin: 2px 0 0; color: var(--muted); font-size: 0.8rem; font-weight: 600; }
.billing-price__save { margin-left: 6px; color: var(--green); }

/* BIL-012 (D-231): the refund request page's reason, and admin's two
   answers on a request's page. Refund and Decline are two toggles with a
   panel each; the shared rule opens every panel after an open toggle, so
   each panel here names the toggle it belongs to. */
.refund-request__reason { margin-top: 16px; }
.admin-actions--refund .admin-actions__toggle[open] ~ .admin-actions__panel { display: none; }
.admin-actions--refund .admin-actions__toggle--refund[open] ~ .admin-actions__panel--refund,
.admin-actions--refund .admin-actions__toggle--decline[open] ~ .admin-actions__panel--decline { display: grid; }

/* COA-016 (pictures 01 to 03): "Ready to move up" on the client list, a
   green link with an up arrow after the row's second line, and the Plan
   tab's card, each movement with its two loads under the name and a quiet
   Move up beside it. After a Move up the line under the name reads the new
   load and "Moved up" stands where the button was, and one quiet line says
   where the new load lands. */
.coach-ready { display: inline-flex; min-height: 44px; align-items: center; gap: 6px; margin: -12px 0; color: var(--green); font-size: 0.82rem; font-weight: 700; }
.coach-ready svg { width: 14px; height: 14px; flex: none; }
.coach-move { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.coach-move__name small { display: block; margin-top: 2px; color: var(--muted); font-size: 0.82rem; font-weight: 650; }
.coach-move__done { color: var(--green); font-size: 0.86rem; font-weight: 700; }
.coach-move form { margin: 0; }
.coach-move__notice { margin: 0 0 12px; padding: 12px 14px; border: 1px solid #bed7ca; border-radius: var(--radius-sm); background: var(--mint-2); color: var(--green); font-size: 0.9rem; font-weight: 590; }

/* BIL-007 (pictures 04 to 09b): Your plan. The rows keep label left and
   value right at every width (the account rows stack below 430px); one
   quiet line under them; the one orange Subscribe is full width at phone
   widths and sizes to its label from 600px. */
.coach-plan .account-row { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 16px; }
.coach-plan .account-row__value { text-align: right; }
@media (max-width: 430px) {
  .coach-plan .account-row { flex-direction: row; align-items: baseline; gap: 16px; padding: 10px 0; }
  .coach-plan .account-row__value { text-align: right; }
}
.coach-plan__help { margin: 12px 0 0; }
.coach-plan__actions { margin: 16px 0 0; }
.coach-plan__actions .text-link { margin: 0; }
@media (min-width: 600px) {
  .coach-plan__actions .button--full { width: auto; min-width: 200px; }
}
.coach-card__foot--plan { display: grid; justify-items: start; gap: 0; margin: 12px 0 0; }

/* COA-014 (pictures 11 to 14): Bring your clients. The paste box, the one
   quiet file line under it (the file input is the label's, visually
   hidden and still reached by keyboard), a skipped line's reason on the
   right, "Matched" in green, each working weight's label beside its box,
   and the one orange primary full width only at phone widths. */
.coach-import__box { width: 100%; min-height: 150px; padding: 10px 14px; border: 1px solid var(--line-strong, #cfd2ca); border-radius: var(--radius-sm); background: var(--surface); font: inherit; font-size: 0.9rem; }
.field .coach-import__file { position: relative; display: inline; margin: 0; color: var(--muted); font-size: inherit; font-weight: 400; cursor: pointer; }
.field .coach-import__file input[type="file"] { position: absolute; top: 0; left: 0; width: 1px; min-height: 0; height: 1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; opacity: 0; }
.coach-import__file:focus-within { outline: 3px solid rgba(35, 88, 73, 0.25); outline-offset: 2px; }
.coach-import__summary { margin: 12px 0 0; }
.coach-import__skip { color: var(--muted); font-size: 0.82rem; text-align: right; }
.coach-import__ok { color: var(--green); font-weight: 700; }
.coach-import__weight { display: grid; grid-template-columns: minmax(0, 1fr) minmax(96px, 45%); gap: 8px; align-items: center; margin: 0; }
.field.coach-import__weight label { margin: 0; }
.coach-import__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-top: 16px; }
.coach-import__actions .text-link { margin: 0; }
.coach-import__waiting { margin: 12px 0 0; }
@media (min-width: 600px) {
  .coach-import__actions .button--full { width: auto; min-width: 200px; }
}

/* COA-016: Your plan and the imports keep a form's width on a wide screen
   (owner: no full width on desktop). */
.coach-plan, .coach-import { max-width: 560px; }

/* Coach stage 1 review (owner, 2026-10-09). The day editor: the workout's
   name is the card's heading with a small round Change; a hairline and space
   between the last movement and the note with the save area. */
.coach-day__head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 12px; }
.coach-day__title { margin: 0; font-size: 1.3rem; font-weight: 760; letter-spacing: -0.01em; }
.coach-day__note { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--line); }
.coach-day__moves + .coach-day__note { margin-top: 20px; }
/* COA-010 moved: "Not cleared for hard intervals" where a hard interval
   session is chosen, never at the top of the client page. */
.coach-gate-note { margin: 0 0 12px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--surface-2); }
.coach-gate-note__title { margin: 0 0 4px; font-weight: 760; }
.coach-gate-note__line { margin: 0; color: var(--muted); }
.coach-gate-note .inline-link { display: inline; }
.day-add__gate { margin: 16px 0; max-width: 480px; }
.day-add__gate .coach-gate-note { margin: 0; }
@supports selector(:has(*)) {
  .day-add__gate { display: none; }
  .day-add:has(input[data-hard]:checked) .day-add__gate { display: block; }
}

/* Coach stage 1 review (owner, 2026-10-09): the bell at the top right of the
   page on a laptop, in coaching, where the topbar is hidden; the side menu
   carries no Messages row. */
.desk-bell { display: none; }
@media (min-width: 880px) {
  .desk-bell { display: flex; justify-content: flex-end; margin: -14px 0 6px; }
}
/* D-240 (pictures approved 2026-10-09): the AMRAP screen. While the rounds
   run, the page is one phone screen: the clock, "Round N" with one quiet
   line under it, the round's movements one per line, the reserved Undo
   line, the Round done circle in the lower part, then Pause and End. The
   line and the Undo line keep their space when empty and the circle keeps
   one size and place, so nothing moves on a tap; the tap's ring is drawn
   outside the circle with a shadow, which takes no room. */
.format-runner--amrap.is-running { display: flex; flex-direction: column; gap: 8px; min-height: calc(100svh - 76px); padding: 6px 0 4px; margin-bottom: 0; }
.format-runner--amrap.is-running .format-clock { padding: 10px 20px 12px; }
.format-runner--amrap.is-running .format-clock strong { font-size: 3.6rem; }
.format-runner--amrap.is-running .format-clock .timer-readout { margin-top: 2px; }
.format-runner--amrap.is-running .format-clock__cue,
.format-runner--amrap.is-running .format-clock__line { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.format-runner--amrap .format-runner__actions .sound-switch { justify-self: end; margin: -8px 0 0; }
.format-runner--amrap.is-running .format-runner__actions { display: none; }
.amrap-run { display: flex; flex: 1 0 auto; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.amrap-run[hidden] { display: none; }
.amrap-run__round { margin: 0; font-size: 2.4rem; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.05; letter-spacing: -0.02em; }
.amrap-run__line { min-height: 1.45em; margin: 0; color: var(--muted); font-size: 0.95rem; font-variant-numeric: tabular-nums; line-height: 1.45; }
.amrap-run__moves { display: grid; grid-template-columns: auto auto; justify-content: center; column-gap: 12px; row-gap: 6px; margin: 4px 0 0; padding: 0; list-style: none; font-size: 1.35rem; line-height: 1.25; text-align: left; }
.amrap-run__moves li { display: contents; }
.amrap-run__moves b { font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.amrap-run__moves span { font-weight: 550; }
.amrap-run__moves small { color: var(--muted); font-size: 1em; font-weight: 500; white-space: nowrap; }
.amrap-run__undo { display: flex; flex: 0 0 44px; align-items: center; justify-content: center; height: 44px; margin-top: 6px; }
.amrap-run__undo [hidden] { display: none; }
.amrap-run__undo .inline-link { padding: 0; border: 0; background: none; font-size: 1rem; cursor: pointer; }
.amrap-run__tap-form { display: flex; flex: 1 0 auto; align-items: center; justify-content: center; width: 100%; }
.amrap-run__tap { display: grid; flex: 0 0 auto; place-content: center; width: min(60vw, 288px); height: min(60vw, 288px); padding: 0; border: 0; border-radius: 50%; background: var(--orange); box-shadow: 0 10px 26px rgba(232, 111, 61, 0.28); color: #fff; font-size: 1.7rem; font-weight: 800; line-height: 1.1; letter-spacing: 0.01em; cursor: pointer; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.amrap-run__tap.is-flash { background: #ff8e5c; box-shadow: 0 0 0 10px rgba(232, 111, 61, 0.35), 0 10px 26px rgba(232, 111, 61, 0.28); }
/* Owner, 2026-10-09: green Start, then the lead-in's seconds in the same
   green circle (aria-disabled, so focus stays on it), then orange Round
   done. Only the color and the words change. */
.amrap-run__tap.is-start, .amrap-run__tap.is-lead-in { background: var(--timer-work); box-shadow: 0 10px 26px rgba(21, 128, 61, 0.26); }
.amrap-run__tap.is-lead-in { cursor: default; }
.amrap-run__tap.is-lead-in .amrap-run__tap-text { font-size: 4.6rem; line-height: 1; font-variant-numeric: tabular-nums; }
.amrap-run__tap:focus-visible { outline: 3px solid var(--green); outline-offset: 14px; }
.format-runner--amrap.is-running .stop-line { margin: 0; font-size: 0.8rem; }
/* Pictures 6 and 7: one question, then the result. */
.amrap-question, .amrap-result { display: grid; gap: 14px; }
.amrap-question[hidden], .amrap-result[hidden] { display: none; }
.amrap-question__ask { margin: 0; font-size: 1.05rem; font-weight: 700; }
.amrap-parts { display: grid; gap: 8px; }
.amrap-part { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 56px; padding: 12px 16px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); font-weight: 650; cursor: pointer; }
.amrap-part small { color: var(--muted); font-size: 1rem; font-weight: 500; }
.amrap-part.is-chosen, .amrap-part:has(input:checked) { border: 2px solid var(--green); background: var(--mint-2); }
.amrap-part:has(input:focus-visible) { outline: 3px solid rgba(35, 88, 73, 0.35); outline-offset: 2px; }
.amrap-partial { display: grid; gap: 8px; }
.amrap-partial[hidden] { display: none; }
.amrap-partial__label { font-weight: 700; }
.amrap-partial .input-suffix input { width: 100%; min-width: 0; min-height: 42px; padding: 0 12px; border: 0; background: transparent; font-size: 1.15rem; font-weight: 700; outline: 0; }
.amrap-partial .input-suffix > span { white-space: nowrap; }
.amrap-question__hint { margin: 0; }
.amrap-question > .button, .amrap-result > .button { justify-self: center; }
.amrap-result > h2 { margin: 0; }
.amrap-result > h2:focus { outline: none; }
.amrap-score { display: grid; justify-items: center; gap: 2px; padding: 6px 0 10px; text-align: center; }
.amrap-score strong { font-size: 1.85rem; font-weight: 800; line-height: 1.1; white-space: nowrap; }
.amrap-score small { color: var(--muted); font-size: 0.95rem; }
.amrap-score small[hidden] { display: none; }
.amrap-splits { margin: 0; padding: 0; list-style: none; }
.amrap-splits:empty { display: none; }
.amrap-splits li { display: flex; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
.amrap-splits li span { color: var(--muted); }

/* Coach stage 3 (D-258 to D-261): assign a program, the update question,
   the client page's program line, Start from a file, and the coach
   agreement's paragraphs and lists. */
.lib-from-file { margin: -6px 0 12px; }
.lib-from-file .text-link { margin: 0; }
.assign-form { max-width: 480px; }
.assign-card { margin-bottom: 16px; padding: 16px 18px; }
fieldset.assign-card { min-width: 0; }
.assign-card__title { display: block; float: left; width: 100%; margin: 0 0 6px; padding: 0; font-size: 1rem; font-weight: 760; }
.assign-card__title + * { clear: both; }
.assign-rows { margin: 0; padding: 0; list-style: none; }
.assign-row { display: flex; align-items: center; gap: 12px; min-height: 48px; margin: 0; cursor: pointer; }
.assign-row input { flex: none; width: 22px; height: 22px; margin: 0; accent-color: var(--green); }
.assign-row__name { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.assign-row__note { flex: none; color: var(--muted); font-size: 0.9rem; }
.assign-card__line { min-height: 1.4em; margin: 8px 0 0; color: var(--muted); font-size: 0.92rem; }
.assign-card__line:empty { display: none; }
.assign-skipped { max-width: 480px; margin: 0 0 12px; padding: 12px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--muted); font-size: 0.92rem; list-style: none; }
.update-question { max-width: 480px; padding: 18px; }
.update-question__title { margin: 0 0 8px; font-size: 1.05rem; line-height: 1.35; }
.update-question__clients { margin: 0; padding: 0; list-style: none; }
.update-question__client { min-height: 40px; gap: 12px; font-weight: 600; }
.update-question__client input { accent-color: var(--green); }
.update-question__name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.update-question__note { flex: none; color: var(--muted); font-size: 0.9rem; font-weight: 500; }
.update-question__line { margin: 8px 0 14px; color: var(--muted); font-size: 0.92rem; }
.update-question__actions { display: grid; gap: 10px; }
@media (min-width: 600px) {
  .update-question__actions { display: flex; align-items: center; gap: 12px; }
  .update-question__actions .button { width: auto; min-width: 140px; }
}
.program-assign { display: grid; gap: 8px; max-width: 480px; margin-top: 16px; }
.program-assign__line { margin: 0; color: var(--muted); font-size: 0.92rem; }
.program-assign__button { justify-self: start; width: auto; }
@media (max-width: 599px) { .program-assign__button { justify-self: stretch; width: 100%; } }
.calendar-card__assign { display: flex; justify-content: center; padding: 2px 0 12px; }
.calendar-card__assign-button { width: auto; min-height: 44px; padding: 8px 22px; }
.calendar-card__switch:has(+ .calendar-card__program) { padding-bottom: 2px; border-bottom: 0; }
.calendar-card__program { margin: 0; padding: 0 0 10px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 0.92rem; text-align: center; }
.calendar-card__program .text-link { margin: 0; font-weight: 700; }
.week-range__program { white-space: nowrap; }
.upload-form, .upload-review { max-width: 480px; }
.upload-card__columns { margin: 0 0 12px; color: var(--muted); }
.upload-card textarea { min-height: 150px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.95rem; line-height: 1.5; }
.upload-card__file { display: grid; gap: 6px; margin-top: 12px; }
.upload-card__file label { font-weight: 680; }
.upload-card__file input { max-width: 100%; font-size: 0.95rem; }
.upload-card__detail { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 6px 0 0; color: var(--muted); font-size: 0.92rem; }
.upload-card__detail .text-link { min-height: 0; margin: 0; padding: 0; line-height: inherit; }
.upload-group { padding: 16px 18px; }
.upload-group__heading { margin: 0 0 4px; font-size: 1rem; font-weight: 760; }
.upload-lines { margin: 0; padding: 0; list-style: none; }
.upload-line { padding: 10px 0; scroll-margin-top: 80px; }
.upload-line + .upload-line { border-top: 1px solid var(--line); }
.upload-line__name { margin: 0; font-weight: 700; overflow-wrap: anywhere; }
/* D-263: a matched line's quiet Change on the name's line, at the right. */
.upload-line__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.upload-line__head .text-link { min-height: 0; margin: -12px 0; padding: 12px 0; }
.upload-line__from { margin: 2px 0 0; color: var(--muted); font-size: 0.92rem; }
.upload-line__actions { display: flex; flex-wrap: wrap; gap: 4px 24px; margin-top: 4px; }
.upload-line__actions .text-link { min-height: 40px; margin: 0; }
.coach-agreement__preamble { margin: 0 0 14px; }
.coach-agreement__clauses ul { margin: 6px 0 10px; padding-left: 20px; }
.coach-agreement__clauses li li { margin: 4px 0; }
.assign-card .lib-field:last-of-type, .upload-review .upload-card .lib-field { margin-bottom: 0; }
/* D-258 amended (owner, 2026-10-10): a gear swap's line under its day on the
   client page and on its movement in the day editor, with the round Keep and
   Change pills under the words. The stage 3 review's spacing: the flag line
   keeps the card's own gap above the week card, and the program line sits as
   close under the dates as the rows sit to each other. */
/* D-263 (owner, 2026-10-10): a swap is ONE highlighted block. On the week
   card it is the whole row (the day, the words, the pills), square-edged and
   flush with the hairlines above and below, with room under the hairline so
   nothing touches; in the day editor it is the whole movement row the same
   way, and a session's or a left-out movement's block sits at the card's top.
   The pills are round, 16px clear of the words and of each other. The block
   is the light green of "That looked light" (STR-068), not the warning peach
   (owner, 2026-10-10): a suggestion, not a warning. */
.calendar-row--swap { padding-top: 6px; background: var(--mint-2); }
.calendar-row--swap .calendar-row__link,
.calendar-row--swap a.calendar-row__link:hover { border-radius: 0; background: transparent; }
.calendar-row--swap .swap-block__body { padding: 2px 8px 16px; }
.swap-block__body { display: grid; gap: 4px; margin: 0; }
.swap-block__text, .swap-block__ask { margin: 0; color: var(--ink); font-size: 0.92rem; line-height: 1.4; }
.swap-block__ask { font-weight: 700; }
.swap-block__pills { display: flex; flex-wrap: wrap; gap: 16px; margin: 12px 0 0; }
.swap-block__pills .button--small { width: auto; }
.coach-plan-form .coach-move--swap { margin-top: 8px; padding: 10px 12px 16px; background: var(--mint-2); }
.coach-move--swap .swap-block__body { padding: 4px 0 8px; }
.swap-block--day { margin: 0 0 12px; padding: 14px 12px 16px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--mint-2); }
.coach-flag { margin: 4px 0 14px; }
.calendar-card__switch:has(+ .calendar-card__program) { padding-bottom: 0; }
.calendar-card__program { margin-top: -6px; padding-bottom: 12px; }
/* STR-068 (D-257 amended): "That looked light" on the next set. The mint
   notice colours without the notice's floating position: part of the open
   row, under its line on the row's own 12px gap, the full width of the
   card's content. Two sentences on the left, one per line; the quiet small
   round "Yes" on the right, centred, so Save set stays the one primary. */
.too-light { display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 14px; border: 1px solid #bed7ca; border-radius: var(--radius-sm); background: var(--mint-2); color: var(--green); font-size: 0.95rem; font-weight: 590; line-height: 1.35; }
.too-light[hidden] { display: none; }
.too-light p { flex: 1 1 auto; margin: 0; }
.too-light p span { display: block; }
.too-light .button { flex: none; width: auto; }

/* STR-068: the set card's weight box holds five characters ("102.5") at
   every width, the number right-aligned next to "lb" in tabular figures.
   Chromium keeps the width of a number box's hidden spinner, which cut
   "40.0" to "40.(" and left a gap before "lb", so the spinner is off, as
   the coach's boxes already have it. "lb" and "reps" sit on the number's
   baseline rather than centred above it. */
.set-form .field--load .input-suffix { align-items: baseline; }
.set-form .field--load .input-suffix input[type="number"] { appearance: textfield; -moz-appearance: textfield; font-variant-numeric: tabular-nums; }
.set-form .field--load .input-suffix input[type="number"]::-webkit-inner-spin-button, .set-form .field--load .input-suffix input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.set-form .field--load .input-suffix input:not([type="radio"]):not([type="checkbox"]) { width: calc(5ch + 10px); padding: 0 2px 0 8px; text-align: right; }
.set-form .field--load .input-suffix > span { padding: 0 10px 0 4px; }
.set-form .movement-row__line .field--reps > input, .set-form .movement-row__line .field--reps > .field-unit { align-self: baseline; }

/* CON-040 (D-265, v3 pictures 2 to 5): For time runs on the AMRAP screen.
   The cap line sits under the digits in small type and stays while the
   clock runs (the AMRAP's line under the clock is for screen readers); the
   work is one movement per line with "Last time" under it; the result is
   "Your time" in a min:sec box, or "Reps done" with its stepper. */
.format-clock__cap { color: var(--timer-ink-soft); font-size: 0.85rem; font-weight: 600; text-align: center; }
.for-time-run .amrap-run__moves { margin-top: 10px; }
.for-time-run .amrap-run__line { margin-top: 10px; }
.for-time-finish > h2:focus { outline: none; }
.for-time-done { display: grid; justify-items: center; gap: 8px; }
.for-time-done[hidden], .for-time-reps[hidden] { display: none; }
.for-time-done__label { color: var(--muted); font-weight: 700; }
.for-time-done__time { width: min(100%, 200px); min-height: 60px; }
.for-time-done__time input { width: 100%; min-width: 0; min-height: 58px; padding: 0 8px 0 18px; border: 0; background: transparent; font-size: 1.85rem; font-weight: 800; font-variant-numeric: tabular-nums; outline: 0; }
.for-time-done__time > span { white-space: nowrap; }
.for-time-done__last { color: var(--muted); font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.for-time-reps { display: grid; gap: 8px; }
.for-time-reps .input-suffix input { width: 100%; min-width: 0; min-height: 42px; padding: 0 12px; border: 0; background: transparent; font-size: 1.15rem; font-weight: 700; outline: 0; }
.for-time-reps .input-suffix > span { white-space: nowrap; }

/* PRG-013 (D-266, v3 pictures 6 and 7): the Benchmarks card's rows, the
   name over the score, the chevron centred on the row; a benchmark's days,
   the date on the left and the score on the right. */
.benchmark-rows a { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: inherit; }
.benchmark-rows__text { display: grid; gap: 4px; min-width: 0; }
.benchmark-rows strong { font-size: 0.9rem; font-weight: 640; }
.benchmark-rows__text > span { color: var(--muted); font-size: 0.84rem; font-variant-numeric: tabular-nums; }
.benchmark-rows__chevron { flex: none; color: var(--soft); font-size: 1.2rem; line-height: 1; }
.benchmark-days-card { max-width: 480px; }
.benchmark-days > li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.benchmark-days b { font-weight: 750; font-variant-numeric: tabular-nums; }
.benchmark-again { margin-top: 16px; }
.workout-cta .today-benchmark-line { margin: 0 0 6px; font-size: 0.95rem; }


/* BIL-010 and BIL-011 on Account (pictures 6a to 6f, 7e): the Gift code
   field with Redeem as a pill, a coached client's status line (not red),
   the sale link's note, and 6e's small confirm pop-up drawn by the server. */
.gift-redeem { margin-top: 16px; }
.gift-redeem__label { display: block; margin-bottom: 8px; font-weight: 680; }
.gift-redeem__row { display: flex; align-items: center; gap: 16px; }
.gift-redeem__input { flex: 1; min-width: 0; max-width: 320px; min-height: 44px; padding: 9px 14px; border: 1px solid #cfd2ca; border-radius: var(--radius-sm); background: var(--surface); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.04em; }
.gift-redeem__row .button--small { width: auto; flex: 0 0 auto; }
.gift-redeem__status { margin: 8px 0 0; color: var(--ink); font-size: 0.9rem; }
.gift-account-note { margin: 16px 0 0; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--mint-2); color: var(--ink); }
.gift-confirm { position: fixed; z-index: 80; inset: 0; display: grid; place-items: center; padding: 16px; background: rgba(23, 33, 29, 0.42); }
.gift-confirm__box { width: 100%; max-width: 420px; padding: 24px; border-radius: 18px; background: var(--surface); box-shadow: var(--shadow-lg); }
.gift-confirm__box h2 { margin: 0 0 8px; font-size: 1.3rem; }
.gift-confirm__box p { margin: 0 0 20px; }
.gift-confirm__actions { display: flex; gap: 16px; }
.gift-confirm__actions .button { width: auto; border-radius: 999px; }
.billing-sale { margin: 0 0 16px; padding: 14px 16px; border-radius: var(--radius-sm); background: var(--mint-2); color: var(--green); font-weight: 700; }

/* BIL-010 picture 9: admin's Gifts list, and the gift and sale settings. */
.admin-gifts { padding: 0; overflow: hidden; }
.admin-gifts__row { display: grid; grid-template-columns: minmax(0, 1.6fr) 5.5rem 5.5rem 9.5rem minmax(0, 9rem); column-gap: 20px; align-items: center; min-height: 60px; padding: 12px 20px; border-top: 1px solid var(--line); font-size: 0.9rem; }
.admin-gifts__head { min-height: 40px; border-top: 0; color: var(--muted); font-size: 0.78rem; font-weight: 700; }
.admin-gifts__who { display: grid; min-width: 0; overflow-wrap: anywhere; }
.admin-gifts__code { color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.84rem; }
.admin-gifts__act { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 4px 16px; color: var(--muted); }
.admin-gifts__act form { margin: 0; display: flex; align-items: center; }
.admin-gifts__act .text-link, .admin-gifts__act .admin-gifts__side { margin: 0; min-height: 36px; display: inline-flex; align-items: center; line-height: 1.2; }
.admin-gifts__line2 { display: none; }
.admin-gift-form { display: grid; gap: 14px; max-width: 320px; margin-top: 14px; }
.admin-gift-form__buttons { display: flex; flex-wrap: wrap; gap: 16px; }
.admin-gift-form__buttons .button { width: auto; border-radius: 999px; }
@media (max-width: 640px) {
  .admin-gifts__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 8px; padding: 16px 20px; }
  .admin-gifts__head, .admin-gifts__bought, .admin-gifts__paid { display: none; }
  .admin-gifts__status { grid-column: 2; grid-row: 1; align-self: start; }
  .admin-gifts__act { grid-column: 1 / -1; justify-content: flex-start; }
  .admin-gifts__line2 { display: block; grid-column: 1 / -1; color: var(--muted); }
}

/* COA-046 (D-283): a coach's branding inside the app. The round coach photo
   at 32, 56 and 88px (initials in the mint circle without one), the Today
   row, the Plan line, the Updates icon, the Branding card, the landing page
   and Share your link with its QR code. */
.coach-face { display: grid; flex: none; place-items: center; overflow: hidden; border-radius: 50%; background: var(--mint); color: var(--green); font-weight: 760; }
.coach-face img { width: 100%; height: 100%; object-fit: cover; }
.coach-face--32 { width: 32px; height: 32px; font-size: 0.85rem; }
.coach-face--56 { width: 56px; height: 56px; font-size: 1.2rem; }
.coach-face--88 { width: 88px; height: 88px; font-size: 1.8rem; }
.coach-row { display: flex; align-items: center; gap: 12px; margin: 0 0 16px; }
.coach-row__text { display: grid; gap: 2px; min-width: 0; }
.coach-row__text strong { font-size: 0.95rem; }
.coach-row__text small { color: var(--muted); font-size: 0.85rem; line-height: 1.3; }
.week-coach-line.coach-line { display: flex; align-items: center; gap: 12px; margin: -4px 0 16px; }
.coach-line__text { display: grid; gap: 2px; min-width: 0; }
.coach-line__text small { color: var(--muted); font-size: 0.85rem; font-weight: 500; line-height: 1.3; }
.inbox-kind--photo { overflow: hidden; padding: 0; background: var(--mint); }
.inbox-kind--photo img { width: 100%; height: 100%; object-fit: cover; }
.coach-brand { max-width: 480px; }
.coach-brand h2 { margin: 0; }
.coach-brand__who { display: flex; align-items: center; gap: 16px; margin: 16px 0; }
.coach-brand__text { display: grid; justify-items: start; gap: 8px; }
.coach-brand__form { display: grid; gap: 16px; }
.coach-brand__form .field label { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.coach-brand__count { color: var(--muted); font-size: 0.85rem; font-weight: 520; }
.coach-brand__save { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.coach-brand__saved, .coach-share__saved { margin: 0; color: var(--green); font-size: 0.9rem; font-weight: 650; }
.coach-landing { display: grid; justify-items: center; gap: 8px; margin: 8px 0 0; text-align: center; }
.coach-landing h1 { margin: 8px 0 0; }
.coach-landing p { margin: 0; }
.coach-tag { color: var(--green); font-weight: 650; }
.coach-join-line { margin: 0; font-size: 1.05rem; font-weight: 650; }
.coach-preview { display: grid; justify-items: center; gap: 6px; max-width: 320px; margin: 16px 0; padding: 24px 16px; border: 1px solid var(--line); border-radius: 16px; background: var(--surface-2); text-align: center; }
.coach-preview strong { font-size: 1.1rem; }
.coach-preview p { margin: 0; }
.coach-preview__pill { margin-top: 8px; padding: 10px 24px; border: 1px solid var(--green); border-radius: 999px; color: var(--green); font-weight: 760; }
.coach-qr { display: grid; justify-items: start; margin: 0 0 16px; }
.coach-qr__image { display: block; width: 168px; height: 168px; padding: 8px; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.coach-share__field { max-width: 420px; margin: 0 0 16px; }
.coach-share__pills { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.coach-share__pills .button { width: auto; }
.coach-share__pills .button[hidden] { display: none; }
.coach-share__saved { margin-top: 16px; }
.coach-confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.coach-confirm .text-link { margin: 0; }

/* COA-046: Share your link, a page of its own with the QR code large. */
.coach-sharepage { display: grid; justify-items: center; gap: 16px; max-width: 420px; margin: 0 auto; padding: 8px 0 24px; }
.coach-sharepage .back-link { justify-self: start; }
.coach-sharepage__qr { display: block; width: 100%; max-width: 420px; aspect-ratio: 1; padding: 12px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.coach-sharepage__name { margin: 0; font-size: 1.25rem; font-weight: 760; text-align: center; }
.coach-sharepage__pills { justify-content: center; }
.coach-sharepage__pills .button { border-radius: 999px; }
.coach-qr__open { display: block; }
