/* EveryMile — brand E, "Track": track red on lane white, infield ink.
   --color-primary is the brand (buttons, links, selection, active nav);
   --color-good keeps green for anything that *means* good (on target,
   low risk, completed, easy); --color-series draws chart data so a pace
   line never reads as a warning next to the heart-rate line. */
:root {
    --color-bg: #faf9f7;
    --color-bg-alt: #f4f3f0;
    --color-text: #1d1d1b;
    --color-text-muted: #665f57;
    --color-primary: #b5462f;
    --color-primary-dark: #8f3522;
    --color-on-primary: #ffffff;
    --color-accent: #b86d16;
    --color-good: #267a55;
    --color-good-dark: #145a38;
    --color-series: #276f89;
    --color-border: #cbd1d7;
    --font-body: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    --font-display: "Archivo Black", "Archivo", -apple-system, BlinkMacSystemFont, sans-serif;
    --max-width: 1240px;
    --radius: 14px;
    font-size: 16px;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--font-body);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.5;
}

.container {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 24px;
}

h1, h2, h3 {
    line-height: 1.2;
    margin: 0 0 16px;
}

p {
    margin: 0 0 16px;
    color: var(--color-text-muted);
}

a {
    color: inherit;
    text-decoration: none;
}

/* Header */

.site-header {
    position: sticky;
    top: 0;
    z-index: 10;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--color-border);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 72px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 1.25rem;
}

.brand-mark {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
}

.brand-mark-track,
.brand-mark-lane { stroke: var(--color-primary); }
.brand-mark-lane { opacity: 0.55; }
.brand-mark-finish { stroke: var(--color-text); }
.brand-mark-dot { fill: var(--color-text); }

.brand-name {
    font-family: var(--font-display);
    font-weight: 400;
    letter-spacing: -0.01em;
    color: var(--color-text);
}

.brand-name-accent { color: var(--color-primary); }

.site-nav {
    display: flex;
    align-items: center;
    gap: 28px;
    font-weight: 500;
}

.site-nav a:hover {
    color: var(--color-primary);
}

.nav-cta {
    padding: 8px 18px;
    background: var(--color-primary);
    color: var(--color-on-primary) !important;
    border-radius: 999px;
    font-weight: 600;
}

.nav-cta:hover {
    background: var(--color-primary-dark);
}

.nav-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.nav-icon {
    display: none;
    line-height: 1;
}

/* Line icons drawn in the link's own colour, so the active tab turns
   brand red and dark mode needs nothing extra. */
.nav-icon svg {
    display: block;
    width: 22px;
    height: 22px;
    margin: 0 auto;
}

/* Mobile view toggle — previews the phone layout at any window size.
   It renders the current page inside a device-sized <iframe> (see
   mobile-view-toggle.js), which has a real viewport of its own, so the
   @media blocks below fire inside it exactly as they do on a phone.
   This replaced a class (html.mobile-view-active) that duplicated every
   mobile declaration: the two copies drifted, and 93 selectors ended up
   styled on a real iPhone but not in the preview meant to represent it. */

.mobile-view-toggle {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* The preview chrome itself. Drawn at the device's true CSS pixel size and
   then scaled to fit the window, so the page inside always measures a real
   393px (or 375/440) viewport regardless of how large the browser is. */

.phone-preview-overlay {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    padding: 18px;
    background: color-mix(in srgb, #070d0b 78%, transparent);
    backdrop-filter: blur(10px);
}

.phone-preview-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
    padding: 8px 10px 8px 16px;
    border: 1px solid color-mix(in srgb, #ffffff 16%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, #0e1714 88%, transparent);
    color: #f4f1ec;
}

.phone-preview-title {
    font-weight: 700;
    font-size: 0.85rem;
    letter-spacing: -0.01em;
}

.phone-preview-devices {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    border-radius: 999px;
    background: color-mix(in srgb, #ffffff 10%, transparent);
}

.phone-preview-chip {
    padding: 5px 11px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: color-mix(in srgb, #f4f1ec 72%, transparent);
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.phone-preview-chip.is-selected {
    background: var(--color-primary);
    color: #06120c;
    font-weight: 700;
}

.phone-preview-size {
    color: color-mix(in srgb, #f4f1ec 58%, transparent);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}

.phone-preview-close {
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 50%;
    background: color-mix(in srgb, #ffffff 12%, transparent);
    color: #f4f1ec;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

.phone-preview-stage {
    transform-origin: top center;
}

.phone-preview-device {
    position: relative;
    box-sizing: content-box;
    padding: 11px;
    border-radius: 47px;
    background: linear-gradient(160deg, #2b3a34, #0d1512);
    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

/* The Dynamic Island / notch cut-out, drawn over the page so the preview
   shows how much vertical room the real status bar actually takes. */
.phone-preview-device.has-notch::after {
    content: "";
    position: absolute;
    top: 21px;
    left: 50%;
    width: 104px;
    height: 27px;
    border-radius: 999px;
    background: #050b09;
    transform: translateX(-50%);
    pointer-events: none;
}

.phone-preview-frame {
    display: block;
    border: 0;
    border-radius: 38px;
    background: var(--color-bg);
}

/* The week-total sidebar's fixed 152px eats a third of a ~480px-wide
   mobile frame, leaving too little for the 7 real day columns to shrink
   into even with min-width: 0 above — so it shrinks too on mobile. */

/* Page messages */

.page-message {
    max-width: var(--max-width);
    margin: 16px auto 0;
    padding: 12px 24px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
}

/* Auth pages */

.auth-section {
    padding: 64px 0;
}

.auth-container {
    max-width: 420px;
}

/* Sign-in codes (landing/two_factor.py) */
.auth-secondary {
    margin-top: 8px;
}

.two-factor-steps {
    padding-left: 20px;
    line-height: 1.6;
}

.two-factor-steps li + li {
    margin-top: 12px;
}

/* The QR stays black on white in dark mode — scanners need the contrast. */
.two-factor-qr {
    display: block;
    width: fit-content;
    margin: 12px 0;
    padding: 8px;
    background: #fff;
    border-radius: 8px;
    line-height: 0;
}

.two-factor-qr svg {
    max-width: 100%;
    height: auto;
}

.two-factor-key {
    display: inline-block;
    margin-top: 4px;
    font-size: 0.95rem;
    letter-spacing: 0.04em;
}

.two-factor-codes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 16px;
    padding: 16px;
    margin: 16px 0 24px;
    list-style: none;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 1.05rem;
}

.auth-form,
.dashboard-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 24px 0;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.form-field label {
    font-weight: 600;
    font-size: 0.9rem;
}

.form-field input,
.form-field select,
.form-field textarea {
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font: inherit;
    background: #fff;
    color: var(--color-text);
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* Invalid input, marked on the box that's actually wrong rather than only
   in a sentence at the top of the form. Keyed off aria-invalid, which
   Django sets on any widget whose field has errors — so the visual cue and
   the screen-reader cue can't drift apart, and no template has to
   remember to add a class. */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
    border-color: #b3261e !important;
    border-width: 2px;
    background: #fff6f5;
}

input[aria-invalid="true"]:focus,
select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus {
    outline-color: #b3261e;
}

/* Field errors inside the weekly-schedule grid: the grid cells are plain
   divs, so the message needs its own styling there rather than inheriting
   .form-field ul. */
.daily-schedule-grid .errorlist,
.status-field-table .errorlist {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    color: #b3261e;
    font-size: 0.75rem;
    line-height: 1.35;
}

/* The daily check-in's five 1-5 ratings (see
   _daily_status_form_fields.html) — a label/value table instead of five
   stacked label-over-select blocks. */
.status-field-table {
    width: 100%;
    border-collapse: collapse;
    margin: 4px 0 16px;
}

.status-field-table th,
.status-field-table td {
    text-align: left;
    padding: 8px 0;
    border-bottom: 1px solid var(--color-border);
}

.status-field-table th {
    font-weight: 600;
    font-size: 0.9rem;
    padding-right: 12px;
    white-space: nowrap;
}

.status-field-table td {
    width: 100%;
}

.status-field-table select {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font: inherit;
    background: #fff;
    color: var(--color-text);
}

.status-field-table select:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.status-field-table tr:last-child th,
.status-field-table tr:last-child td {
    border-bottom: none;
}

/* An empty errorlist is used to mark a field as invalid without repeating
   a message that's already stated once for the whole group. */
.errorlist:empty {
    display: none;
}

.form-help {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin: 0;
}

/* Perceived-effort (RPE) radio scale — 10 options in a row instead of a
   dropdown or number stepper, since it's one point on a fixed 1-10 scale
   a runner picks, not a value worth typing. */
.effort-scale-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.effort-scale {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.effort-scale > div {
    display: flex;
}

.effort-scale label {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    padding: 6px 4px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.8rem;
    cursor: pointer;
}

.effort-scale input[type="radio"] {
    /* The label text is the whole visible control — the input itself
       just needs to stay clickable/focusable, not visually doubled up
       next to its own number. */
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.effort-scale label:has(input:checked) {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-on-primary);
    font-weight: 600;
}

.effort-scale label:has(input:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.effort-scale-caption {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.form-field ul {
    color: #b3261e;
    font-size: 0.85rem;
    margin: 0;
    padding-left: 18px;
}

.auth-switch {
    font-size: 0.9rem;
}

.form-container {
    max-width: 520px;
}

.form-subtitle {
    margin-top: -8px;
    color: var(--color-text-muted);
}

/* Dashboard */

.dashboard-section {
    padding: 15px 0 30px;
}

.dashboard-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

/* The calendar page's plan name/dates, action buttons, and plan-status
   line combined into one card — .dashboard-header keeps its full
   margin-bottom everywhere else it's used (plan details/trends/recovery/
   twins), so the tighter spacing here is scoped to this one nesting. */
.plan-header-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px;
}

.plan-header-card .dashboard-header {
    margin-bottom: 0;
}

.plan-header-status {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    font-weight: 600;
    font-size: 0.85rem;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--color-border);
}

.dashboard-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

/* A <form> among .dashboard-actions' <a class="button"> children (e.g.
   the "Sync Strava" POST button) shouldn't introduce its own box in the
   flex row — display: contents promotes its <button> to be the actual
   flex item, sized/spaced exactly like its sibling links. */
.dashboard-inline-form {
    display: contents;
}

.subsection-title {
    font-size: 1.25rem;
    margin: 40px 0 16px;
}

.empty-state {
    color: var(--color-text-muted);
    font-style: italic;
}

.plan-status-line {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    font-weight: 600;
    margin: 12px 0;
}

.plan-status-reasons {
    font-weight: 400;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.calendar-feedback-icon {
    display: inline-block;
    margin-left: 4px;
    font-size: 0.8rem;
    text-decoration: none;
    line-height: 1;
    filter: grayscale(1) opacity(0.6);
}

.calendar-feedback-icon:hover,
.calendar-feedback-icon:focus-visible {
    filter: none;
}

/* Only shown when a day has exactly one logged activity — Intervals.icu's
   per-day TSS is a daily total, not broken out per activity, so it isn't
   attributed to any one of several same-day activities (see
   web_views.py's daily_metric_by_date note). */
.calendar-tss-badge {
    display: inline-block;
    margin-left: 4px;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    font-size: 0.65rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

/* A canceled workout (web_views.py::cancel_workout) keeps its original
   badge/distance/TSS — it's still the plan's own prescribed day, just
   flagged as not happening — dimmed with a small "Canceled" tag rather
   than replaced, so what was originally there is still legible. */
.calendar-workout-row-canceled {
    opacity: 0.55;
}

.calendar-canceled-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 999px;
    background: #fde3e3;
    border: 1px solid var(--color-border);
    font-size: 0.65rem;
    font-weight: 600;
    color: #b3261e;
}

.plan-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
}

.plan-card {
    display: block;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
    transition: border-color 0.15s ease;
}

.plan-card:hover {
    border-color: var(--color-primary);
}

.plan-card h2 {
    font-size: 1.1rem;
    margin-bottom: 8px;
}

.plan-meta {
    font-size: 0.85rem;
    margin: 0;
    color: var(--color-text-muted);
}

.days-to-race-badge {
    display: inline-block;
    padding: 0.05rem 0.5rem;
    margin-left: 0.4rem;
    border-radius: 999px;
    background: var(--color-accent);
    color: #fff;
    font-size: 0.75em;
    font-weight: 600;
}

.days-to-race-badge-today {
    background: #b3721f;
}

.table-scroll {
    overflow-x: auto;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.data-table th,
.data-table td {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.data-table th {
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
}

.badge-rest {
    background: #eef0ef;
    color: var(--color-text-muted);
}

.badge-easy,
.badge-recovery {
    background: #e4f5ea;
    color: var(--color-good-dark);
}

/* Every hard-effort type (tempo/marathon_pace/interval/repetition/hill)
   shares one "hard effort" color, recovery shares easy's color (it's an
   Easy-pace variant, not a new effort category), and cross-training/
   strength share one "supplemental" color — a workout's own label text
   still says which is which, but the calendar grid still reads as the
   same simple rest/easy/hard/long/supplemental/race shape at a glance,
   even with 12 workout types now, instead of a distinct hue per type. */
.badge-tempo,
.badge-marathon_pace,
.badge-interval,
.badge-repetition,
.badge-hill {
    background: #fdf1e3;
    color: #b3721f;
}

.badge-long {
    background: #e3edfd;
    color: #1f4fb3;
}

.badge-cross_train,
.badge-strength {
    background: #e6e3fd;
    color: #5a3fb3;
}

/* A tune-up race is a real race effort, just not the goal one — it shares
   the race colour so the calendar reads "this is a race day" at a glance,
   with the lighter treatment marking it as the rehearsal rather than the
   event itself. */
.badge-race {
    background: var(--color-accent);
    color: #fff;
}

.badge-time_trial {
    background: #ffe4d6;
    color: #a8420f;
}

.badge-risk-low {
    background: #e4f5ea;
    color: var(--color-good-dark);
}

.badge-risk-moderate {
    background: #fdf1e3;
    color: #b3721f;
}

.badge-risk-elevated {
    background: #fdece3;
    color: #b3521f;
}

/* "Not enough data" — deliberately grey rather than green, so an
   unmeasured plan doesn't look like a healthy one (see
   status_signals._STATUS_BADGE_CLASSES). */
.badge-risk-neutral {
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
}

/* Plan builder form */

.form-fieldset {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px;
    margin: 0;
}

.form-fieldset legend {
    padding: 0 8px;
    font-weight: 600;
    font-size: 0.9rem;
}

.goal-time-row {
    display: flex;
    gap: 16px;
}

.goal-time-row .form-field {
    flex: 1;
}

/* Five columns: day, time available, priority, activity, add-on. This
   said repeat(3, ...) after the Add-on column was added, so every row's
   fifth cell wrapped onto a phantom second line. */
.daily-schedule-grid {
    display: grid;
    grid-template-columns: 80px repeat(4, minmax(104px, 1fr));
    gap: 8px 10px;
    align-items: center;
}

.daily-schedule-header {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.daily-schedule-day-label {
    font-weight: 600;
}

.daily-schedule-grid select {
    width: 100%;
}

@media (max-width: 640px) {
    .daily-schedule-grid {
        grid-template-columns: 1fr;
    }

    .daily-schedule-header {
        display: none;
    }

    .daily-schedule-day-label {
        margin-top: 8px;
    }
}

/* Calendar */

/* Month navigation only — the page-level buttons that used to sit on
   the right of this row are in the header card's action cluster now, so
   there is nothing to space apart. Tighter margins than the old row
   carried, since this and the legend below it are the last things
   between the reader and the grid. */
.calendar-nav {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 12px 0 8px;
}

.calendar-density-control {
    display: inline-flex;
    margin-left: auto;
    padding: 2px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg-alt);
}

.calendar-density-control button {
    padding: 5px 9px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
}

.calendar-density-control button.is-selected {
    background: var(--color-bg);
    color: var(--color-text);
    box-shadow: 0 1px 4px rgba(22, 33, 29, 0.14);
    font-weight: 700;
}

.calendar-nav-months {
    display: flex;
    align-items: center;
    gap: 12px;
    justify-content: space-between;
    width: 100%;
}

.calendar-nav h2 {
    margin: 0;
    font-size: 1.25rem;
}

/* Recovery status card — HRV/resting HR/sleep/stress as loader-style
   bars, each relative to the runner's own recent baseline (see
   recovery.py::wellness_status_summary) rather than a universal target. */
.wellness-status-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-top: 16px;
    padding: 10px 13px;
}
.quick-outlook-title,
.wellness-status-title,
.load-status-title {
    margin: 0 0 12px;
}

/* Training-load card — Intervals.icu's own CTL/ATL/ramp-rate numbers
   (recovery.py::load_status), a second/cross-check training-load model
   alongside this app's own ACWR. Not a percentage bar like the wellness
   card above — CTL/ATL are absolute, unbounded units. */
.load-status-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-top: 16px;
    padding: 10px 13px;
}

.load-status-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    column-gap: 16px;
    row-gap: 16px;
}

.load-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: center;
}

/* Every bar in a row of the Training Load card sits on exactly the same
   line, whatever the stat is called.
   A stat is four stacked rows — label, value, bar, range — and the label
   is the one that varies: "Long Term Fitness (CTL)" wraps where "ACWR"
   never does, so the bars landed at two or three different heights.
   Subgrid makes those four rows *shared across the whole card* rather
   than sized per stat, so the label row is as tall as the tallest label
   and every bar starts where every other bar starts. The min-heights
   below are the fallback for browsers without subgrid: they reserve two
   lines for a label and one for a value, which gets the common cases
   aligned without guaranteeing it. */
@supports (grid-template-rows: subgrid) {
    .load-stat {
        display: grid;
        grid-row: span 4;
        grid-template-rows: subgrid;
        row-gap: 2px;
    }

    /* Sized by the shared row instead, so the fallback's reserved space
       doesn't add to a row that's already the right height. */
    .load-stat-label,
    .load-stat-value {
        min-height: 0;
    }
}

/* Every load-stat is a <button> (click for its trend + description — see
   load-detail-modal.js) — reset to look like the plain div it used to be,
   same treatment as .wellness-bar. */
.load-stat-clickable {
    width: 100%;
    text-align: center;
    background: none;
    border: none;
    padding: 6px;
    margin: -6px;
    font: inherit;
    color: inherit;
    cursor: pointer;
    border-radius: var(--radius);
    transition: background 0.15s ease;
}

.load-stat-clickable:hover,
.load-stat-clickable:focus-visible {
    background: var(--color-bg-alt);
}

/* Every bar in the Training Load grid sits on the same line.
   A bar's vertical position is set entirely by what stacks above it — its
   label and its value — and those vary: "Long Term Fitness (CTL)" wraps
   to two lines at most widths while "ACWR" never does, so the bars across
   the card landed at two or three different heights. Reserving two lines
   for the label and one for the value makes the offset identical for
   every stat, whatever its name. Bottom-aligned within that reserved
   space, so a one-line label sits against its value rather than floating
   above a gap. */
.load-stat-label {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    min-height: 2.2em;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.load-stat-value {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 1.5em;
    font-size: 1.1rem;
    font-weight: 600;
}

/* Sliding-scale loader bars under each training-load field — good/
   elevated color a field with an established guardrail (target CTL,
   weekly TSS, TSB: see recovery.py's RACE_TYPE_LOAD_GUARDRAILS/
   TSB_GUARDRAIL_LOW/HIGH); "low"/"moderate"/"elevated" color ramp rate's
   existing sustainable/aggressive risk levels; "neutral" (ATL, same-day
   TSS) is a plain positional read with no good/bad judgment attached. */
.load-bar-track {
    position: relative;
    margin-top: 4px;
    height: 8px;
    border-radius: 999px;
    background: var(--color-border);
    overflow: hidden;
}

.load-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 999px;
    transition: left 0.2s ease, width 0.2s ease;
}

/* TSB's bar fills from the scale's center (0) outward — see
   recovery.py::load_status's tsb_bar_left/tsb_bar_width — so its track
   gets a visible tick at that center point the fill grows from. */
.load-bar-track-centered {
    overflow: visible;
}

.load-bar-center-mark {
    position: absolute;
    top: -2px;
    left: 50%;
    width: 2px;
    height: calc(100% + 4px);
    margin-left: -1px;
    border-radius: 1px;
    background: var(--color-text-muted);
    z-index: 1;
}

.load-bar-fill-good,
.load-bar-fill-low {
    background: var(--color-good);
}

.load-bar-fill-moderate {
    background: #b3941f;
}

.load-bar-fill-elevated {
    background: #b3261e;
}

.load-bar-fill-neutral {
    background: var(--color-text-muted);
}

.load-bar-range {
    display: flex;
    justify-content: space-between;
    margin-top: 3px;
    font-size: 0.65rem;
    color: var(--color-text-muted);
}

.load-stat-note {
    margin-top: 3px;
    font-size: 0.65rem;
    color: var(--color-text-muted);
}

.validation-page {
    display: grid;
    gap: 24px;
}

.validation-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

.validation-card {
    padding: 22px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    box-shadow: var(--app-shadow-small, 0 4px 16px rgba(29, 29, 27, 0.07));
}

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

.validation-card-heading h2,
.operations-card h3 {
    margin: 0;
}

.validation-checklist {
    display: grid;
    gap: 8px;
    padding: 0;
    list-style: none;
}

.validation-checklist li {
    display: flex;
    gap: 8px;
    color: var(--color-text-muted);
}

.validation-checklist li.is-complete {
    color: var(--color-text);
}

.validation-stats,
.operations-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}

.validation-stats div,
.operations-grid > div {
    display: grid;
    gap: 3px;
    padding: 12px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
}

.validation-stats dt,
.operations-grid span {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.validation-stats dd {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 700;
}

.operations-grid {
    margin-bottom: 22px;
}

.operations-grid small {
    color: var(--color-text-muted);
}

.ops-status {
    display: inline-flex;
    width: fit-content;
    font-weight: 700;
}

.ops-status-ok { color: var(--color-primary); }
.ops-status-warning,
.ops-status-stale,
.ops-status-missing { color: #9a6d00; }
.ops-status-error { color: #b3261e; }

@media (max-width: 760px) {
    .validation-grid,
    .validation-stats,
    .operations-grid {
        grid-template-columns: 1fr 1fr;
    }
}

.load-status-risk {
    margin: 12px 0 0;
}

.wellness-status-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 16px;
}

/* Each bar is a <button> (see plan_calendar.html) so its exact numbers and
   physiological rationale are a click away — reset to look like the plain
   container it used to be, with just a hover/focus affordance added. */
.wellness-bar {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 6px;
    margin: -6px;
    font: inherit;
    color: inherit;
    cursor: pointer;
    border-radius: var(--radius);
    transition: background 0.15s ease;
}

.wellness-bar:hover,
.wellness-bar:focus-visible {
    background: var(--color-bg-alt);
}

.wellness-bar-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 6px;
    margin-bottom: 4px;
}

.wellness-bar-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.wellness-bar-value {
    font-size: 0.95rem;
    font-weight: 600;
}

.wellness-bar-track {
    height: 10px;
    border-radius: 999px;
    background: var(--color-border);
    overflow: hidden;
}

.wellness-bar-fill {
    height: 100%;
    min-width: 5px;
    border-radius: 999px;
    transition: width 0.2s ease;
}

.wellness-bar-fill-good {
    background: var(--color-good);
}

.wellness-bar-fill-neutral {
    background: #b3941f;
}

.wellness-bar-fill-low {
    background: #b3261e;
}

.wellness-bar-range {
    display: flex;
    justify-content: space-between;
    margin-top: 3px;
    font-size: 0.65rem;
    color: var(--color-text-muted);
}

.wellness-bar-baseline {
    display: block;
    margin-top: 4px;
    font-size: 0.7rem;
    color: var(--color-text-muted);
}

/* VO2max-calibrated pace zones and heart-rate zones, split out of the
   This Week card into their own card — same look, its own title. */
.this-week-card-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

/* VO2max-calibrated pace zones / heart-rate zones — a secondary reference
   inside the This Week card (see hr_zones.py, web_views.py's
   _pace_zones_from_vo2max), not a replacement for the plan's own
   schedule. */
.this-week-zones {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 16px;
}

.zone-table-title {
    font-size: 0.9rem;
    margin: 0 0 8px;
}

.zone-table-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 12px;
    margin: 0;
    font-size: 0.85rem;
}

.zone-table-list dt {
    color: var(--color-text-muted);
}

.zone-table-list dd {
    margin: 0;
    font-weight: 600;
    text-align: right;
}

.zone-table-method {
    margin: 8px 0 0;
    font-size: 0.7rem;
    color: var(--color-text-muted);
}

.this-week-card-title {
    margin: 0 0 12px;
}

.this-week-jump-link {
    font-size: 0.85rem;
    white-space: nowrap;
}

.this-week-card-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
    gap: 12px;
}

/* VO2max/Max HR reuse the This Week card's own stat-grid look at the top
   of the Fitness Zone card, above the pace/HR zone tables below them. */
.fitness-zone-stats {
    margin-bottom: 16px;
}

/* Fitness Zones dashboard ------------------------------------------------ */
.fitness-zones-page {
    max-width: 1180px;
}

.fitness-zones-header {
    align-items: flex-start;
    gap: 24px;
}

.zones-eyebrow {
    margin: 0 0 5px;
    color: var(--color-primary-dark);
    font-size: 0.7rem;
    font-weight: 750;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.zones-tabs {
    display: inline-flex;
    gap: 4px;
    margin: 18px 0 22px;
    padding: 4px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.zones-tab {
    padding: 8px 22px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.86rem;
    font-weight: 700;
    cursor: pointer;
}

.zones-tab.is-active {
    background: var(--color-bg);
    color: var(--color-primary-dark);
    box-shadow: 0 2px 8px rgba(29, 29, 27, 0.1);
}

.zones-tab:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.zones-source-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.zones-source-grid-two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.zones-source-card,
.zones-primary-section,
.zones-secondary-section,
.zones-use-card,
.zones-calibration-card,
.zones-methods-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    box-shadow: 0 3px 14px rgba(29, 29, 27, 0.04);
}

.zones-source-card {
    min-width: 0;
    padding: 17px 18px;
}

.zones-source-primary {
    border-top: 3px solid var(--color-primary);
}

.zones-source-estimate {
    border-top: 3px dashed #708f9f;
}

.zones-source-label {
    display: block;
    margin-bottom: 4px;
    color: var(--color-text-muted);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.zones-source-card > strong {
    display: block;
    font-size: 1.2rem;
}

.zones-source-card p {
    margin: 6px 0;
    font-size: 0.8rem;
}

.zones-source-method {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.7rem;
    line-height: 1.4;
}

.zones-estimate-badge,
.zones-plan-badge {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    padding: 3px 8px;
    border: 1px solid #bed0d9;
    border-radius: 999px;
    background: #edf5f8;
    color: #355b6d;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.zones-source-card strong .zones-estimate-badge {
    margin-left: 4px;
    vertical-align: middle;
}

.zones-plan-badge {
    border-color: #b9d8c7;
    background: #edf8f1;
    color: var(--color-primary-dark);
}

.zones-primary-section,
.zones-secondary-section,
.zones-use-card {
    margin-top: 18px;
    padding: 22px;
}

.zones-section-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: 15px;
}

.zones-section-heading h2 {
    margin: 0;
    font-size: 1.2rem;
}

.physiology-domains {
    display: grid;
    grid-template-columns: 1fr auto 0.72fr auto 0.58fr;
    align-items: stretch;
    min-height: 54px;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.physiology-domain {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 9px 14px;
}

.physiology-domain strong {
    font-size: 0.8rem;
}

.physiology-domain span,
.physiology-threshold span {
    font-size: 0.64rem;
}

.physiology-domain-moderate {
    background: #e7f4ea;
}

.physiology-domain-heavy {
    background: #fff3cf;
}

.physiology-domain-severe {
    background: #fde6e3;
}

.physiology-threshold {
    display: flex;
    align-items: center;
    padding: 5px 7px;
    background: #fff;
    color: var(--color-text-muted);
    writing-mode: vertical-rl;
    transform: rotate(180deg);
}

.zones-domain-note {
    margin: 7px 0 18px;
    color: var(--color-text-muted);
    font-size: 0.72rem;
}

.zones-table-wrap {
    overflow-x: auto;
}

.zones-matrix {
    width: 100%;
    min-width: 820px;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.zones-matrix th,
.zones-matrix td {
    padding: 11px 10px;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}

.zones-matrix thead th {
    color: var(--color-text-muted);
    font-size: 0.67rem;
    letter-spacing: 0.045em;
    text-transform: uppercase;
}

.zones-matrix tbody th {
    white-space: nowrap;
}

.zones-matrix small {
    display: block;
    margin-top: 3px;
    color: var(--color-text-muted);
    font-size: 0.67rem;
    font-weight: 400;
    line-height: 1.35;
    white-space: normal;
}

.zones-pace-cell {
    min-width: 170px;
    font-weight: 650;
}

.zones-zone-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 7px;
    border-radius: 50%;
    background: var(--color-series);
}

.zones-zone-marathon,
.zones-zone-threshold {
    background: #c58a20;
}

.zones-zone-interval,
.zones-zone-repetition {
    background: #ba443b;
}

.zones-sensor-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(120px, 1fr));
    gap: 8px;
    margin-top: 14px;
}

.zones-sensor-row {
    padding: 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-alt);
}

.zones-sensor-row strong,
.zones-sensor-row span,
.zones-sensor-row small {
    display: block;
}

.zones-sensor-row strong {
    font-size: 0.75rem;
}

.zones-sensor-row span {
    margin: 5px 0;
    font-size: 0.9rem;
    font-weight: 700;
}

.zones-sensor-row small {
    color: var(--color-text-muted);
    font-size: 0.65rem;
    line-height: 1.35;
}

.zones-use-grid,
.zones-cycling-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.zones-use-grid h3 {
    margin: 0 0 8px;
    font-size: 0.82rem;
}

.zones-stack {
    display: flex;
    width: 100%;
    height: 15px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.zones-stack-low {
    background: #65aa7d;
}

.zones-stack-moderate {
    background: #d5a13a;
}

.zones-stack-high {
    background: #c65a52;
}

.zones-stack-key {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    margin: 7px 0 0;
    color: var(--color-text-muted);
    font-size: 0.7rem;
}

.zones-disagreement {
    margin: 16px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.76rem;
}

.zones-disagreement.has-disagreement {
    color: #875d12;
}

.zones-cycling-grid > .zones-primary-section {
    min-width: 0;
}

.zones-cycling-table {
    min-width: 480px;
}

.zones-calibration-card,
.zones-methods-card {
    margin-top: 18px;
}

.zones-calibration-card > summary,
.zones-methods-card > summary {
    padding: 15px 18px;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 700;
}

.zones-calibration-card[open] > summary,
.zones-methods-card[open] > summary {
    border-bottom: 1px solid var(--color-border);
}

.zones-calibration-form,
.zones-methods-content {
    padding: 18px;
}

.zones-calibration-fields {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin: 14px 0;
}

.zones-calibration-fields .form-field {
    margin: 0;
}

.zones-calibration-fields input {
    width: 100%;
}

.zones-calibration-fields small {
    display: block;
    margin-top: 4px;
    color: var(--color-text-muted);
    font-size: 0.68rem;
}

.zones-methods-content {
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.zones-methods-content ul {
    margin-bottom: 0;
}

@media (max-width: 850px) {
    .zones-source-grid,
    .zones-source-grid-two,
    .zones-cycling-grid {
        grid-template-columns: 1fr;
    }

    .zones-sensor-grid {
        grid-template-columns: repeat(2, minmax(120px, 1fr));
    }

    .zones-calibration-fields {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 620px) {
    .zones-use-grid {
        grid-template-columns: 1fr;
    }

    .zones-section-heading {
        display: block;
    }

    .zones-section-heading > span {
        margin-top: 7px;
    }

    .physiology-domain {
        padding: 8px;
    }

    .physiology-domain span {
        display: none;
    }

    .zones-sensor-grid {
        grid-template-columns: 1fr;
    }
}

.this-week-card-stats .week-stat {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
}

.this-week-card-stats .week-stat-value {
    font-size: 1.1rem;
    text-align: left;
}

/* Compliance marker — an at-a-glance symbol next to a day's date, on top
   of (not instead of) the "✓ X km logged" line, since that line only
   appears once you've scrolled to read it while the marker is visible
   immediately. */
.compliance-marker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    margin-left: 4px;
    border-radius: 50%;
    font-size: 0.6rem;
    line-height: 1;
    vertical-align: middle;
}

.compliance-marker-on_target {
    background: #1f7a4d;
    color: #fff;
}

.compliance-marker-under {
    background: #fdeee3;
    color: #b3521f;
    border: 1px solid #b3521f;
}

.compliance-marker-over {
    background: #e8f0fb;
    color: #1f4fb3;
    border: 1px solid #1f4fb3;
}

.compliance-marker-missed {
    background: #b3261e;
    color: #fff;
}

/* Right volume, wrong intensity. Distinct from under/over, which are
   about distance — these two say the session happened but wasn't the
   session that was prescribed. Filled rather than outlined, because
   unlike a distance drift this is a substantive miss. */
.compliance-marker-too_easy {
    background: #e8f0fb;
    color: #1f4fb3;
    border: 1px solid #1f4fb3;
}

.compliance-marker-too_hard {
    background: #fdeee3;
    color: #b3521f;
    border: 1px solid #b3521f;
}

.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background: var(--color-border);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    /* Horizontal-only: a narrow viewport can still need more room than it
       has (see the min-width: 0 note below) — scrolling to see a clipped
       column beats losing it silently, which `overflow: hidden` here
       used to do. Vertical rows never overflow, so that axis stays clipped
       for the rounded corners. */
    overflow-x: auto;
    overflow-y: hidden;
}

.calendar-grid-with-totals {
    grid-template-columns: 24px repeat(7, 1fr) 160px;
}

/* The skinny leading phase-swatch column — one cell per calendar row,
   colored and labeled with that row's dominant training phase (see
   web_views.py's week_phase), replacing the old standalone phase-key
   legend above the grid so the phase reads directly off each row instead
   of requiring a lookup. Reuses the same .calendar-day-phase-* background
   classes the day cells already use, so a phase is always the same color
   everywhere it appears. */
.calendar-phase-header {
    padding: 0;
}

.calendar-phase-column {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    background: var(--color-bg-alt);
}

.calendar-phase-column-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.calendar-week-total {
    background: var(--color-bg-alt);
    padding: 8px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    font-size: 0.75rem;
}

.week-stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px;
    min-width: 0;
}

.week-stat-label {
    font-weight: 400;
    font-size: 0.65rem;
    color: var(--color-text-muted);
    text-transform: uppercase;
    white-space: nowrap;
}

.week-stat-value {
    font-weight: 600;
    text-align: right;
}

.week-stat-primary .week-stat-value {
    display: inline-flex;
    align-items: baseline;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 4px;
}

.calendar-week-pct-change {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.calendar-week-pct-up {
    color: var(--color-primary-dark);
}

.calendar-week-pct-down {
    color: #1f4fb3;
}

/* A jump of more than 10% from the prior week — the classic "10% rule"
   threshold community advice warns against — is flagged distinctly. */
.calendar-week-pct-high {
    color: #b3521f;
}

.calendar-weekday-header {
    background: var(--color-bg-alt);
    padding: 8px;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    /* A grid item's default min-width is auto (its content's own minimum,
       e.g. an unbreakable badge label) — not 0 — so a 1fr track normally
       refuses to shrink past that, growing the whole grid wider than its
       container on a narrow screen instead. Same on .calendar-day and
       .calendar-week-total below. */
    min-width: 0;
}

.calendar-day {
    /* Not !important: that unconditionally beat every
       .calendar-day-phase-* rule below regardless of specificity, so phase
       tinting never rendered at all. Phase is useful at-a-glance context
       ("am I in base or peak?") and is already computed per day. */
    background: #fff;
    min-height: 96px;
    min-width: 0;
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.8rem;
}

.calendar-day-outside {
    background: var(--color-bg-alt);
    opacity: 0.8;
}

.calendar-phase-column.calendar-day-phase-base {
    background-color: #4d9f6b;
}

.calendar-phase-column.calendar-day-phase-build {
    background-color: #d9a520;
}

.calendar-phase-column.calendar-day-phase-peak {
    background-color: #e0722c;
}

.calendar-phase-column.calendar-day-phase-cutback {
    background-color: #5b8fd4;
}

.calendar-phase-column.calendar-day-phase-taper {
    background-color: #9166c9;
}

/* Today is a border, not a fill — a fill would fight with the phase
   shading above (today is always in exactly one phase already); the
   border reads as "today" regardless of which phase color is underneath. */
.calendar-day-today {
    border: 2px solid #3c3c3c;
    /* Keeps the phase stripe visible on today's cell too, rather than
       today's border replacing it. */
    box-shadow: inset 0 0 0 1px #383839;
}

.calendar-day-today .calendar-day-number {
    color: #6a3fb3;
}

.calendar-day-number {
    font-weight: 600;
    font-size: 0.85rem;
}

/* Planned workouts on the grid calendar render as small "mini status"
   cards stacked at the top of the day cell: a type line, then a stats
   line (mileage when the type has distance, TSS when expected). Scoped
   under .calendar-day-planned so the agenda view (which still uses the
   flat .calendar-workout-row layout below) is unaffected. */
.calendar-day-planned {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.calendar-workout-card {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 3px 4px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-bg-alt);
}

/* The whole card takes on its workout type's key color (the same six-
   bucket scheme the .badge-* rules use below) rather than just the pill
   inside it — the type badge's background then blends into the card,
   leaving just its bold colored text as the accent. */
.calendar-workout-card-rest {
    background: #eef0ef;
}

.calendar-workout-card-easy,
.calendar-workout-card-recovery {
    background: #e4f5ea;
}

.calendar-workout-card-tempo,
.calendar-workout-card-marathon_pace,
.calendar-workout-card-interval,
.calendar-workout-card-repetition,
.calendar-workout-card-hill {
    background: #fdf1e3;
}

.calendar-workout-card-long {
    background: #e3edfd;
}

.calendar-workout-card-cross_train,
.calendar-workout-card-strength {
    background: #e6e3fd;
}

.calendar-workout-card-race {
    background: #ffe4d6;
}

.calendar-workout-card-time_trial {
    background: #fff1e8;
}

/* The type badge's pill shape reads as a circular border sitting inside
   an already-colored card — flattened here so the card's own color does
   the work instead. */
.calendar-workout-card-effort .badge {
    border-radius: 0;
    padding: 0;
}

.calendar-workout-card-canceled {
    opacity: 0.55;
}

.calendar-workout-card-effort {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}

.calendar-workout-card-effort::-webkit-scrollbar {
    display: none;
}

.calendar-workout-card-type-line {
    color: var(--color-text-muted);
    font-size: 0.62rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.calendar-workout-card-tss-line {
    color: var(--color-text-muted);
    font-size: 0.62rem;
}

/* Separates the planned cards above from the completed/logged runs below
   — only rendered when a day has both, so a day with just one section
   never shows an orphan rule. */
.calendar-day-divider {
    width: 100%;
    margin: 0;
    border: none;
    border-top: 1px solid var(--color-border);
}

.calendar-day-completed {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.calendar-workout-row {
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
    padding: 3px 2px;
    border-radius: 2px;
}

.calendar-workout-row::-webkit-scrollbar {
    display: none;
}

.calendar-workout-row .badge,
.calendar-workout-row .calendar-detail,
.calendar-workout-row .calendar-tss-badge,
.calendar-workout-row .calendar-canceled-badge {
    flex-shrink: 0;
}

.calendar-detail {
    color: var(--color-text-muted);
    font-size: 0.75rem;
}

.calendar-logged {
    color: var(--color-primary-dark);
    font-size: 0.75rem;
    font-weight: 600;
}

/* A logged-run row is independently selectable (see calendar.js's
   renderLoggedRunDetails) — a faint tint and left accent distinguish it
   at a glance from a *planned* workout row above it in the same cell. */
.calendar-logged-row {
    background: rgba(31, 122, 77, 0.06);
    border-left: 2px solid var(--color-primary);
}

/* A logged cross-training or strength session (see web_views.py's
   LOGGED_CROSS_TRAINING_ACTIVITY_TYPES) gets the same purple a *planned*
   cross-training day already uses (.badge-cross_train /
   .calendar-workout-card-cross_train) instead of the green above, which
   otherwise made a logged bike ride indistinguishable from a logged run. */
.calendar-logged-row-cross_train {
    background: rgba(90, 63, 179, 0.08);
    border-left: 2px solid #5a3fb3;
}

.calendar-logged-row-cross_train .calendar-logged {
    color: #5a3fb3;
}

/* Agenda view — a compact one-row-per-day list, toggled in place of the
   grid (see calendar-agenda-toggle.js) rather than a whole separate page,
   for a narrow viewport where 7 shrunken grid columns get cramped. */
.calendar-agenda-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* The [hidden] attribute is how calendar-agenda-toggle.js shows/hides
   these two — without this pair of rules, the unconditional `display`
   above/on .calendar-grid would override the browser's default
   [hidden]{display:none} (an author stylesheet rule always beats the
   user-agent default, regardless of selector specificity), and clicking
   the toggle would set the attribute correctly while both views stayed
   visible — the same class of bug .modal-overlay[hidden] guards against
   above. */
#calendar-grid-view[hidden],
#calendar-agenda-view[hidden] {
    display: none;
}

.agenda-day {
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 10px;
}

.agenda-day-today {
    border: 2px solid #6a3fb3;
}

.agenda-day-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.agenda-day-date {
    font-weight: 600;
    font-size: 0.9rem;
}

.agenda-workout-row {
    padding: 4px 6px;
}

.agenda-day-empty {
    color: var(--color-text-muted);
    font-size: 0.8rem;
    margin: 0;
}

/* "Move to another day" — the swap action inside the workout-details
   popup (calendar.js::buildSwapSection). */
.workout-swap-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.workout-swap-section .modal-subheading {
    width: 100%;
    margin: 0 0 4px;
}

.workout-swap-select {
    flex: 1;
    min-width: 160px;
}

.workout-swap-status {
    margin: 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    width: 100%;
}

.workout-absorb-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.workout-absorb-section .modal-subheading {
    margin: 0 0 4px;
}

.workout-absorb-status {
    margin: 8px 0 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.workout-cancel-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px;
}

.workout-cancel-section .modal-subheading {
    width: 100%;
    margin: 0 0 4px;
}

.workout-cancel-reason-select {
    flex: 1;
    min-width: 160px;
}

.workout-cancel-notes {
    flex-basis: 100%;
    resize: vertical;
    font: inherit;
    padding: 6px 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.workout-cancel-status {
    margin: 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    width: 100%;
}

.workout-adjustment-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.workout-adjustment-section .modal-subheading {
    margin: 0 0 4px;
}

.workout-adjustment-option {
    padding: 8px 10px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    margin-bottom: 8px;
}

.workout-adjustment-option-current {
    border-color: var(--color-primary);
}

.workout-adjustment-option-label {
    margin: 0;
    font-weight: 600;
    font-size: 0.85rem;
}

.workout-adjustment-option-stats {
    margin: 2px 0 0;
    font-size: 0.8rem;
    color: var(--color-primary-dark);
}

.workout-adjustment-option-description {
    margin: 4px 0 0;
}

.workout-adjustment-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-top: 12px;
}

.workout-adjustment-column-title {
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin: 0 0 8px;
}

@media (max-width: 640px) {
    .workout-adjustment-columns {
        grid-template-columns: 1fr;
    }
}

.workout-strength-routine {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.workout-strength-routine .modal-subheading {
    margin: 0 0 4px;
}

.workout-strength-exercise-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.workout-strength-exercise {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 10px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    font-size: 0.85rem;
}

.workout-strength-exercise-name {
    font-weight: 600;
}

.workout-strength-exercise-prescription {
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* An explosive/plyometric movement is a different kind of stimulus from the
   rest of a routine (and carries a foot-contact budget — see
   strength_programs.py), so it's marked rather than blending in. */
.workout-strength-exercise-dynamic {
    border-left: 3px solid var(--color-accent);
}

.workout-strength-exercise-tag {
    padding: 1px 8px;
    border-radius: 999px;
    background: #ffe4d6;
    color: #a8420f;
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.workout-strength-focus {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 8px;
}

.workout-strength-focus-label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.workout-strength-focus-tag {
    padding: 2px 10px;
    border-radius: 999px;
    background: #e6e3fd;
    color: #5a3fb3;
    font-size: 0.7rem;
    font-weight: 600;
}

.workout-strength-contacts {
    margin: 10px 0 0;
    font-size: 0.8rem;
}

.workout-strength-contacts-value {
    font-weight: 600;
}

.workout-strength-note,
.workout-structure-note-text {
    margin: 8px 0 0;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

/* Why a session is the size it is (the published ceiling that bounded it),
   as opposed to what the workout type trains — see .workout-why. */
.workout-structure-note {
    margin-top: 16px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
    border-left: 3px solid var(--color-primary);
}

.workout-structure-note .modal-subheading {
    margin: 0;
}

.workout-structure-note .workout-structure-note-text {
    margin-top: 6px;
}

.plan-details-strength-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.plan-details-strength-list li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 10px;
    border-radius: var(--radius);
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    font-size: 0.85rem;
}

.plan-details-strength-name {
    font-weight: 600;
}

.plan-details-strength-prescription {
    color: var(--color-text-muted);
    white-space: nowrap;
}

@media (max-width: 640px) {
    .calendar-day {
        min-height: 64px;
        font-size: 0.7rem;
    }

    .calendar-grid-with-totals {
        grid-template-columns: 16px repeat(7, minmax(36px, 1fr)) 96px;
    }

    .calendar-phase-column-label {
        font-size: 0.55rem;
    }

    .week-stat-label {
        font-size: 0.6rem;
    }

    .modal-dialog-workout {
        max-width: 90%;
    }
}

.integration-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.integration-card p {
    margin: 0;
}

.integration-card form {
    margin: 0;
}

.integration-card + .integration-card {
    margin-top: 16px;
}

/* Full-width within the card's flex row (flex-basis: 100%), so it reads
   as a banner above the connect/disconnect line rather than squeezing
   into the row as a competing flex item. */
.integration-paused-note {
    flex-basis: 100%;
    font-size: 0.85rem;
    color: var(--color-text-muted);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 8px 12px;
}

.button {
    display: inline-block;
    padding: 14px 28px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 1rem;
    transition: transform 0.15s ease, background 0.15s ease;
}

.button-skinny {
    display: inline-block;
    padding: 3px 28px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 1rem;
    transition: transform 0.15s ease, background 0.15s ease;
}

/* Same class of bug as .modal-overlay[hidden] elsewhere in this file: a
   plain `display: inline-block` above would override the browser's
   default [hidden]{display:none} (author CSS beats the user-agent
   default regardless of specificity) — needed since calendar.js hides
   the "Log this run" footer button via the hidden attribute for an
   already-logged run's details popup. */
.button[hidden] {
    display: none;
}

.button:hover {
    transform: translateY(-1px);
}

.button-primary {
    background: var(--color-primary);
    color: var(--color-on-primary);
}

.button-primary:hover {
    background: var(--color-primary-dark);
}

.button-secondary {
    background: transparent;
    color: var(--color-text);
    border: 1px solid var(--color-border);
}

.button-secondary:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* Footer */

.site-footer {
    border-top: 1px solid var(--color-border);
    padding: 32px 0;
}

.footer-inner {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

@media (max-width: 640px) {
    .site-nav {
        gap: 16px;
        font-size: 0.9rem;
    }

    .nav-icon {
        display: inline;
    }

    .nav-label {
        display: none;
    }
}

/* Calendar workout row interactivity */

.calendar-workout-row-clickable {
    cursor: pointer;
    transition: box-shadow 0.1s ease, background 0.1s ease;
}

.calendar-workout-row-clickable:hover,
.calendar-workout-row-clickable:focus-visible {
    box-shadow: inset 0 0 0 2px var(--color-primary);
    outline: none;
}

/* Applied only via JS to the specific row whose modal is open — never
   present on page load, and removed again whenever the modal is dismissed. */
.calendar-workout-row-selected {
    box-shadow: inset 0 0 0 2px var(--color-primary);
    background: var(--color-bg-alt);
}

/* Workout details modal */

.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(22, 33, 29, 0.5);
    align-items: center;
    justify-content: center;
    padding: 24px;
    z-index: 100;
}

/* The [hidden] attribute is how JS shows/hides this — without this rule,
   the unconditional `display` above (needed once shown) would override the
   browser's default [hidden]{display:none} and the modal would render open
   on every page load. */
.modal-overlay[hidden] {
    display: none;
}

.modal-overlay:not([hidden]) {
    display: flex;
}

.modal-dialog {
    background: var(--color-bg);
    border-radius: var(--radius);
    max-width: 480px;
    width: 100%;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}

/* A modal's <form> (when one wraps .modal-body + .modal-footer, e.g. so a
   single submit button in the footer submits the fields in the body) would
   otherwise sit between .modal-dialog and its header/body/footer children
   as an extra, non-flex box. display: contents removes it from layout —
   its children become flex items of .modal-dialog directly — while it
   keeps working as a real <form> for submission and the footer's
   type="submit" button. */
.modal-dialog > form {
    display: contents;
}

.modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 24px 32px 16px;
    flex: none;
}

.modal-header h2 {
    margin: 0;
}

/* Header and footer stay fixed within the dialog — only .modal-body
   scrolls, so the close/primary/secondary buttons are always reachable
   without hunting through scrolled-away content. */
.modal-body {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0;
    padding: 0 32px 24px;
}

.modal-close {
    position: static;
    background: none;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    color: #c0392b;
    padding: 4px;
    flex: none;
}

.modal-close:hover {
    color: #8e2a1f;
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    padding: 16px 32px 24px;
    border-top: 1px solid var(--color-border);
    flex: none;
}

/* Settings modal (Preferences + Connected devices + Display, combined) */

.modal-dialog-settings {
    max-width: 560px;
}

.settings-section {
    margin-top: 24px;
    padding-top: 24px;
    border-top: 1px solid var(--color-border);
}

.settings-section:first-of-type {
    margin-top: 20px;
    padding-top: 0;
    border-top: none;
}

.settings-section-title {
    font-size: 1rem;
    margin: 0 0 12px;
}

/* Plan details modal — several cards of prose/tables plus the 4-column
   weekly-schedule grid (now merged in from the old, separate Edit Plan
   modal), needs real room. */

.modal-dialog-plan-details {
    max-width: 720px;
}

/* Workout-details modal — a percentage of the viewport rather than a fixed
   cap, and wider still on a phone since there's no room to spare there.
   The narrow-viewport override lives in the @media block below, which is
   now the only place phone layout is defined. */

.modal-dialog-workout {
    max-width: 50%;
}

#workout-modal .modal-header {
    padding: 14px 32px 10px;
}

#workout-modal .modal-header h2 {
    font-size: 1.15rem;
}

#workout-modal .modal-close {
    padding: 2px;
    font-size: 1.25rem;
}

#workout-modal .modal-footer {
    gap: 8px;
    padding: 10px 32px 12px;
}

#workout-modal .modal-footer .button {
    padding: 7px 14px;
    font-size: 0.82rem;
}

/* Info icons next to scientific/technical terms. Clicking one opens the
   shared side panel (info-drawer.js); the text itself is kept in the
   document beside the icon, hidden, so it survives without JavaScript.

   The old floating bubble is gone along with the JS that had to position
   it: fixed-positioned, measured from the icon's coordinates, clamped to
   the viewport and flipped above the icon when there was no room below —
   all of it to stop the bubble overflowing a scrolling ancestor like the
   calendar grid. A panel anchored to the viewport edge cannot have that
   problem. */

.info-tooltip {
    position: relative;
    display: inline-block;
    margin-left: 4px;
}

.info-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.7rem;
    line-height: 1;
    cursor: pointer;
    vertical-align: middle;
    padding: 0;
}

.info-icon:hover,
.info-icon[aria-expanded="true"] {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.modal-meta {
    color: var(--color-text-muted);
    margin-bottom: 12px;
}

.modal-subheading {
    font-size: 1rem;
    margin: 24px 0 8px;
}

.modal-detail-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 16px;
    margin: 16px 0 0;
}

.modal-detail-list dt {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.modal-detail-list dd {
    margin: 0;
    font-weight: 600;
}

/* Workout-details popup: physiological rationale */

.workout-canceled-notice {
    margin: 8px 0 0;
    padding: 6px 10px;
    border-radius: var(--radius);
    background: #fde3e3;
    color: #b3261e;
    font-size: 0.85rem;
    font-weight: 600;
}

.workout-why {
    background: var(--color-bg-alt);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-top: 16px;
}

.workout-why .modal-subheading {
    margin: 0 0 6px;
}

.workout-why-explanation {
    margin: 0;
    font-size: 0.9rem;
}

.workout-pace-section {
    margin-top: 16px;
}

.workout-pace-graph {
    width: 100%;
    height: auto;
    margin: 8px 0;
}

.workout-pace-graph-axis {
    stroke: var(--color-border);
    stroke-width: 1;
}

.workout-pace-graph-bar {
    fill: var(--color-series);
}

.workout-pace-graph-tick {
    stroke: var(--color-border);
    stroke-width: 1;
}

.workout-pace-graph-label {
    font-size: 7px;
    fill: var(--color-text-muted);
}

.workout-pace-graph-ytick-label {
    font-size: 7px;
    fill: var(--color-text-muted);
}

.workout-pace-graph-axis-title {
    font-size: 7px;
    font-weight: 600;
    fill: var(--color-text-muted);
}

/* Logged-run pace/heart-rate line chart (calendar.js::buildPaceHeartRateChart) */

.workout-pace-graph-line-pace {
    stroke: var(--color-series);
    stroke-width: 2;
}

.workout-pace-graph-line-hr {
    stroke: #b3521f;
    stroke-width: 2;
    stroke-dasharray: 3 2;
}

.workout-pace-graph-dot-pace {
    fill: var(--color-series);
}

.workout-pace-graph-dot-hr {
    fill: #b3521f;
}

.workout-pace-graph-line-planned {
    stroke: var(--color-text-muted);
    stroke-width: 2;
    stroke-dasharray: 6 3;
}

.workout-pace-target-band {
    fill: rgba(90, 63, 179, 0.12);
    pointer-events: none;
}

.run-chart-shell {
    margin-top: 8px;
}

.run-chart-controls {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
    margin-bottom: 7px;
}

.run-chart-controls button[aria-pressed="true"] {
    border-color: var(--color-primary);
    background: #e4f5ea;
}

.run-chart-hint {
    color: var(--color-text-muted);
    font-size: 0.72rem;
}

.run-chart-host svg {
    cursor: crosshair;
    touch-action: pan-y;
    user-select: none;
}

.run-chart-hit-point {
    fill: transparent;
    stroke: transparent;
}

.run-chart-event-marker,
.run-chart-segment-marker {
    stroke-width: 1;
    stroke-dasharray: 3 3;
}

.run-chart-event-marker {
    stroke: #b3521f;
}

.run-chart-segment-marker {
    stroke: #6a3fb3;
}

.run-chart-x-title {
    fill: var(--color-text-muted);
}

.workout-pace-graph-ytick-label-pace,
.workout-pace-graph-axis-title-pace {
    fill: var(--color-series);
}

.workout-pace-graph-ytick-label-hr,
.workout-pace-graph-axis-title-hr {
    fill: #b3521f;
}

.workout-chart-wrapper {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.workout-chart-legend {
    display: flex;
    gap: 14px;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.workout-chart-legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.workout-chart-legend-item::before {
    content: "";
    display: inline-block;
    width: 14px;
    height: 2px;
}

.workout-chart-legend-pace::before {
    background: var(--color-series);
}

.workout-chart-legend-hr::before {
    background: #b3521f;
    background-image: linear-gradient(to right, #b3521f 60%, transparent 60%);
    background-size: 5px 2px;
}

.workout-chart-legend-planned::before {
    background: var(--color-text-muted);
    background-image: linear-gradient(to right, var(--color-text-muted) 60%, transparent 60%);
    background-size: 7px 2px;
}

.workout-splits-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 8px;
    font-size: 0.85rem;
}

.workout-splits-table th,
.workout-splits-table td {
    text-align: left;
    padding: 4px 8px;
    border-bottom: 1px solid var(--color-border);
}

.workout-splits-table th {
    color: var(--color-text-muted);
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
}

/* "Ask Claude" chat modal */

.modal-dialog-chat {
    max-width: 560px;
    display: flex;
    flex-direction: column;
}

.chat-token-meter {
    margin: 16px 0;
}

.chat-token-bar-track {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    height: 8px;
    overflow: hidden;
}

.chat-token-bar-fill {
    background: var(--color-primary);
    height: 100%;
    width: 0%;
    transition: width 0.2s ease;
}

.chat-token-bar-fill-limit {
    background: var(--color-accent);
}

.chat-token-label {
    display: block;
    margin-top: 6px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.chat-messages {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 320px;
    overflow-y: auto;
    padding: 4px 2px;
    margin-bottom: 16px;
}

.chat-message {
    padding: 10px 14px;
    border-radius: var(--radius);
    max-width: 85%;
    line-height: 1.4;
    white-space: pre-wrap;
}

.chat-message-assistant {
    background: var(--color-bg-alt);
    align-self: flex-start;
}

.chat-message-user {
    background: var(--color-primary);
    color: var(--color-on-primary);
    align-self: flex-end;
}

.chat-message-error,
.chat-message-system {
    background: #fdecea;
    color: #8e2a1f;
    align-self: center;
    font-size: 0.85rem;
    text-align: center;
}

.chat-form {
    display: flex;
    gap: 8px;
}

.chat-input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 1rem;
}

.chat-input:disabled {
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
}

/* Training trend charts (server-rendered inline SVG, no chart library) */

.chart-caption {
    font-size: 0.9rem;
    color: var(--color-text-muted);
    margin: 24px 0 8px;
}

.trend-chart {
    width: 100%;
    height: auto;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.chart-axis {
    stroke: var(--color-border);
    stroke-width: 1;
}

.chart-gridline {
    stroke: var(--color-border);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.chart-axis-label {
    font-size: 9px;
    fill: var(--color-text-muted);
}

.chart-y-axis-label {
    text-anchor: end;
    dominant-baseline: middle;
}

.chart-y-axis-label-right {
    text-anchor: start;
    dominant-baseline: middle;
    fill: var(--color-accent);
}

/* The planned bar stacks easy/long (bottom) under hard (top) — see
   weekly_mileage_series' planned_hard_km — reusing the same "hard effort"
   orange the calendar's own tempo/interval/hill/etc. badges already use,
   so a runner sees the same color mean the same thing everywhere. */
.chart-bar-planned-easy {
    fill: #cfe8db;
}

.chart-bar-planned-hard {
    fill: #fdf1e3;
    stroke: #b3721f;
    stroke-width: 1;
}

.chart-bar-actual {
    fill: var(--color-series);
}

.chart-legend {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin: 0 0 8px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.chart-legend-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 3px;
    border: 1px solid var(--color-border);
}

.chart-legend-swatch-planned-easy {
    background: #cfe8db;
}

.chart-legend-swatch-planned-hard {
    background: #fdf1e3;
    border-color: #b3721f;
}

.chart-legend-swatch-actual {
    background: var(--color-series);
}

.chart-line {
    fill: none;
    stroke: var(--color-series);
    stroke-width: 2;
}

.chart-dot {
    fill: var(--color-primary-dark);
}

/* Every chart's clickable data points/bars (see chart-tooltip.js) — a
   visible affordance that they're interactive, plus a focus ring for
   keyboard users tabbing through an SVG chart. */
[data-tip] {
    cursor: pointer;
}

[data-tip]:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* Fixed (viewport-relative), not absolute, and a very high z-index — same
   reasoning the old info bubble used: most charts live inside a
   modal (z-index 100), and a body-appended absolutely-positioned element
   doesn't inherit that stacking context, so it needs to out-rank modals
   and everything else on its own to ever be visible over one. */
.chart-tooltip {
    position: fixed;
    z-index: 9999;
    background: var(--color-text);
    color: var(--color-bg);
    font-size: 0.75rem;
    font-weight: 600;
    padding: 4px 8px;
    border-radius: 4px;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.chart-label {
    font-size: 9px;
    fill: var(--color-text-muted);
    text-anchor: middle;
}

.chart-legend {
    display: flex;
    gap: 16px;
    margin: 8px 0 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.chart-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.chart-swatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 2px;
}

.chart-swatch-planned {
    background: #cfe8db;
}

.chart-swatch-actual {
    background: var(--color-series);
}

.chart-swatch-hr {
    background: var(--color-accent);
}

/* Heart-rate overlay on the fitness trend chart — an opt-in extra series,
   hidden until its toggle checkbox is checked. The checkbox, its label, the
   chart, and the legend are all siblings inside .chart-with-toggle so a
   plain CSS sibling selector can drive the show/hide without any JS. */

.chart-with-toggle {
    position: relative;
    display: flex;
    flex-direction: column;
}

.chart-toggle {
    order: -1;
    align-self: flex-start;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-bottom: 6px;
    cursor: pointer;
}

.chart-toggle-input {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

/* The efficiency overlay (metres per heartbeat) replaced the raw
   heart-rate second axis — two independently autoscaled axes invited
   reading a correlation that may not be there. Opt-in, same as before. */
.chart-efficiency-overlay {
    display: none;
}

.chart-toggle-input:checked ~ .trend-chart .chart-efficiency-overlay {
    display: inline;
}

.chart-line-efficiency {
    stroke: var(--color-accent);
    stroke-dasharray: 4 3;
}

.chart-dot-efficiency {
    fill: var(--color-accent);
}

/* The fitted trend line through weekly pace — the direction is genuinely
   hard to see through week-to-week noise without it. */
.chart-trend-line {
    stroke: #6a3fb3;
    stroke-width: 2;
    stroke-dasharray: 6 4;
    opacity: 0.85;
}

.chart-trend-summary {
    margin: 0 0 8px;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* The plan's own prescribed pace zones, as reference lines — an absolute
   pace value isn't interpretable without them. */
.chart-zone-band {
    stroke: var(--color-border);
    stroke-width: 1;
    stroke-dasharray: 2 4;
}

.chart-zone-label {
    font-size: 9px;
    fill: var(--color-text-muted);
}

/* "Today" on the mileage chart, so planned-but-not-yet-due is visually
   distinct from planned-and-missed. */
.chart-today-marker {
    stroke: #6a3fb3;
    stroke-width: 1.5;
    stroke-dasharray: 3 3;
}

/* A future week's planned bar: muted and dashed, because it's a plan and
   not an unmet target.
   These must restate their own fill. Setting opacity alone left the bars
   with SVG's default fill — black — so every future week drew the same
   flat grey block regardless of series, and the legend's easy/hard
   swatches matched nothing on the chart. On a plan that runs eight months
   out, almost every week is a future week, so that was most of the graph. */
.chart-bar-planned-easy-future {
    fill: #cfe8db;
    stroke: #6bab88;
    stroke-width: 1;
    stroke-dasharray: 2 2;
    opacity: 0.75;
}

.chart-bar-planned-hard-future {
    fill: #fdf1e3;
    stroke: #b3721f;
    stroke-width: 1;
    stroke-dasharray: 2 2;
    opacity: 0.75;
}

.chart-bar-actual-partial {
    opacity: 0.7;
}

.chart-legend-swatch-planned-future {
    background: var(--color-series);
    opacity: 0.4;
}

/* Digital-twin projection distribution */

.chart-bar-distribution {
    fill: var(--color-series);
    opacity: 0.75;
}

.chart-interval-band {
    fill: var(--color-series);
    opacity: 0.12;
}

.chart-marker-median {
    stroke: #6a3fb3;
    stroke-width: 2;
}

.chart-marker-goal {
    stroke: var(--color-accent);
    stroke-width: 2;
    stroke-dasharray: 4 3;
}

.chart-swatch-median {
    background: #6a3fb3;
}

.chart-swatch-goal {
    background: var(--color-accent);
}

.chart-swatch-trend {
    background: #6a3fb3;
}

.chart-swatch-efficiency {
    background: var(--color-accent);
}

.twin-goal-outside {
    margin-top: 8px;
    padding: 10px 12px;
    border-left: 3px solid var(--color-accent);
    background: var(--color-bg-alt);
}

/* Every chart's numbers, available as a table — the chart's entire meaning
   used to live in one aria-label string, and colour alone distinguished
   the series. */
.chart-data-table {
    margin-top: 10px;
    font-size: 0.85rem;
}

.chart-data-table summary {
    cursor: pointer;
    color: var(--color-text-muted);
}

.chart-data-table .data-table {
    width: 100%;
    margin-top: 8px;
    border-collapse: collapse;
}

.chart-data-table .data-table th,
.chart-data-table .data-table td {
    padding: 4px 8px;
    text-align: left;
    border-bottom: 1px solid var(--color-border);
}

.chart-data-table .data-table th {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
}

/* Adjustable "what-if" scenario twin */

.scenario-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
    padding: 16px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-bottom: 16px;
}

.scenario-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.8rem;
}

.scenario-field label {
    font-weight: 600;
    color: var(--color-text-muted);
}

.scenario-input-group {
    display: flex;
    align-items: center;
    gap: 6px;
}

.scenario-input-group input {
    width: 72px;
    padding: 6px 8px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 0.9rem;
}

.scenario-unit {
    color: var(--color-text-muted);
    white-space: nowrap;
}

.scenario-result {
    padding: 16px;
}

.twin-risk-reason {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 12px 0;
}

.risk-factor-list {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.risk-factor {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    padding: 6px 10px;
    border-radius: 6px;
    background: var(--color-bg-alt);
    font-size: 0.8rem;
}

.risk-factor-triggered {
    background: #fdece3;
}

.risk-factor-name {
    font-weight: 600;
}

.risk-factor-value {
    color: var(--color-text-muted);
}

.risk-factor-description {
    flex-basis: 100%;
    margin: 0;
}

/* Recovery & training load */

.dashboard-section-recovery {
    background: var(--color-bg-alt);
}

/* Digital twins: each is an expandable <details> card rather than a plain
   table row, so it can hold a full technical breakdown without cluttering
   the default view. */

.twin-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow-x: auto;
}

.twin-header,
.twin-summary {
    display: grid;
    grid-template-columns: 90px 1fr 1fr 1fr 1fr 110px;
    gap: 12px;
    align-items: center;
    min-width: 640px;
}

.twin-header {
    padding: 0 16px 4px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.twin-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.twin-summary {
    padding: 12px 16px;
    cursor: pointer;
    font-size: 0.9rem;
    list-style: none;
}

.twin-summary::-webkit-details-marker {
    display: none;
}

.twin-summary-label {
    font-weight: 600;
}

.twin-card[open] .twin-summary {
    border-bottom: 1px solid var(--color-border);
}

.twin-details-body {
    padding: 16px;
}

.twin-technical-description {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin: 0 0 16px;
}

.recovery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
}

.recovery-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
}

.recovery-card h3 {
    font-size: 1rem;
    margin-bottom: 12px;
}

.recovery-value {
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0 0 8px;
}

.calibration-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px 20px;
    margin: 16px 0;
}

.calibration-card h3 {
    font-size: 1rem;
    margin: 0 0 8px;
}

/* Interval coverage sits inside the calibration card as a second,
   separately-gradeable claim — a rule rather than another nested box, so
   the card doesn't read as two cards. */
.calibration-coverage {
    border-top: 1px solid var(--color-border);
    margin-top: 16px;
    padding-top: 12px;
}

.calibration-coverage h4 {
    font-size: 0.875rem;
    margin: 0 0 6px;
}

/* Verdict badges reuse the risk palette's semantics: well calibrated is
   the good outcome, too narrow (overconfident) the concerning one. */
.badge-coverage-well-calibrated {
    background: #e4f5ea;
    color: var(--color-primary-dark);
}

.badge-coverage-too-narrow {
    background: #fdece3;
    color: #b3521f;
}

.badge-coverage-too-wide {
    background: #fdf1e3;
    color: #b3721f;
}

.badge-coverage-unknown {
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
}

.metric-caveat {
    font-size: 0.75rem;
    font-style: italic;
    color: var(--color-text-muted);
    margin: 12px 0 4px;
}

.acwr-validity-check {
    margin-top: 4px;
}

/* Plan details page */

.plan-details-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 24px;
    margin-bottom: 20px;
}

.plan-details-card-adjustment {
    background: var(--color-bg-alt);
}

.plan-details-value {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0 0 8px;
}

.plan-details-table {
    width: 100%;
    border-collapse: collapse;
    margin: 16px 0;
    font-size: 0.9rem;
}

.plan-details-table th,
.plan-details-table td {
    text-align: left;
    padding: 8px 12px;
    border-bottom: 1px solid var(--color-border);
}

.plan-details-phase-name {
    text-transform: capitalize;
    font-weight: 600;
}

.plan-details-phase-cutback .plan-details-phase-name {
    color: #b3521f;
}

.plan-details-phase-taper .plan-details-phase-name {
    color: #1f4fb3;
}

.plan-details-bar {
    display: flex;
    height: 32px;
    border-radius: 999px;
    overflow: hidden;
    font-size: 0.75rem;
    font-weight: 600;
    color: #fff;
}

.plan-details-bar-easy,
.plan-details-bar-hard {
    display: flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
}

.plan-details-bar-easy {
    background: var(--color-good);
}

.plan-details-bar-hard {
    background: var(--color-accent);
}

/* Links from the calendar page out to the digital-twins/trends/recovery
   pages that used to be sections on this same page. */

.insights-links {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin: 40px 0 8px;
}

.insights-link {
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 20px;
    color: var(--color-text);
    transition: border-color 0.15s ease;
}

.insights-link:hover {
    border-color: var(--color-primary);
}

.insights-link-title {
    font-weight: 600;
    font-size: 1.05rem;
}

.insights-link-hint {
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* Community suggestions — deliberately distinct visual treatment from the
   data-driven sections above, since this is curated general guidance, not
   personalized analysis. */

.dashboard-section-community {
    background: #fdf8ee;
}

.community-tip-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.community-tip {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 16px 20px;
    font-size: 0.95rem;
}

/* "Why this plan is shaped the way it is" — the cited principles behind the
   generator's structural limits (see _plan_details_content.html). */
.plan-details-principles {
    margin: 12px 0 0;
}

.plan-details-principles dt {
    margin-top: 14px;
    font-weight: 600;
    font-size: 0.9rem;
}

.plan-details-principles dt:first-child {
    margin-top: 0;
}

.plan-details-principles dd {
    margin: 4px 0 0;
    padding-left: 12px;
    border-left: 2px solid var(--color-border);
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--color-text-muted);
}

/* The twin's one-line finish-time derivation, in place of the paragraph
   that used to restate the table beneath it. */
.twin-derivation {
    margin: 0 0 10px;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.button-compact {
    padding: 6px 14px;
    font-size: 0.85rem;
}

/* --- Tabbed modal (workout details) -----------------------------------
   The workout dialog used to append every section into one flat scroll —
   rationale, charts, splits, metrics, swap/absorb/cancel, adjustment
   options and the strength routine — so the actions sat several screens
   below the physiology. Three tabs keep the actions reachable. */
/* The value-band table in a metric-detail modal (see modal-shell.js's
   buildBandsTable and recovery.py's _load_field_bands). A table because
   the content is a lookup — find the row your own number falls in —
   which is what it was already doing in prose, badly. */
.metric-bands {
    margin-top: 14px;
}

.metric-bands-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
}

.metric-bands-table th {
    padding: 4px 8px 6px 0;
    text-align: left;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
}

.metric-bands-table td {
    padding: 6px 8px 6px 0;
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
}

.metric-bands-table tr:last-child td {
    border-bottom: none;
}

.metric-band-range {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* The band's own verdict, colored with the same vocabulary the bars use
   so a row reads the same way its bar does. */
.metric-band-label {
    white-space: nowrap;
    font-weight: 600;
}

.metric-band-good .metric-band-label {
    color: var(--color-good-dark);
}

.metric-band-moderate .metric-band-label {
    color: #b3721f;
}

.metric-band-elevated .metric-band-label {
    color: #b3521f;
}

.metric-band-meaning {
    color: var(--color-text-muted);
}

.modal-tablist {
    display: flex;
    gap: 2px;
    margin: 0 0 14px;
    border-bottom: 1px solid var(--color-border);
}

.modal-tab {
    padding: 8px 16px;
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    font: inherit;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--color-text-muted);
    cursor: pointer;
}

.modal-tab:hover {
    color: var(--color-text);
}

.modal-tab[aria-selected="true"] {
    color: var(--color-primary-dark);
    border-bottom-color: var(--color-primary);
}

.modal-tab:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.workout-comparison-table {
    width: 100%;
    margin: 4px 0 14px;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin-top: 25px;
}

.workout-comparison-table th,
.workout-comparison-table td {
    padding: 7px 9px;
    border-bottom: 1px solid var(--color-border);
    text-align: right;
}

.workout-comparison-table thead th {
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.workout-comparison-table th:first-child {
    text-align: left;
}

.workout-comparison-table tbody th {
    color: var(--color-text-muted);
    font-weight: 600;
}

.workout-comparison-table tbody tr:last-child th,
.workout-comparison-table tbody tr:last-child td {
    border-bottom: 0;
}

/* A dialog caps its height and scrolls its *body*, so the title and the
   close control stay put instead of scrolling away. */
.modal-dialog {
    max-height: 88vh;
    display: flex;
    flex-direction: column;
}

.modal-body {
    overflow-y: auto;
    min-height: 0;
}

/* While a modal is open the page behind it must not scroll. */
body.modal-open {
    overflow: hidden;
}

/* --- Plan Details: at-a-glance summary header -------------------------
   The page opened with a form and a 296-character paragraph; none of
   "where am I in this plan / how much is left / what does it peak at" was
   stated anywhere, despite all of it already being computed. */
.plan-summary {
    margin-bottom: 20px;
    padding: 18px 20px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: #fff;
}

.plan-summary-numbers {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin-bottom: 16px;
}

.plan-summary-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.plan-summary-value {
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.plan-summary-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

/* Proportional phase timeline — a phase twice as long is twice as wide,
   rather than five equal blocks. */
.plan-phase-timeline {
    display: flex;
    gap: 2px;
    height: 30px;
    border-radius: 6px;
    overflow: hidden;
}

.plan-phase-segment {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    cursor: pointer;
    overflow: hidden;
}

.plan-phase-segment-label {
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0 6px;
}

.plan-phase-segment-current {
    outline: 2px solid #6a3fb3;
    outline-offset: -2px;
}

.plan-summary-caption {
    margin: 14px 0 0;
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

/* --- Chart interaction ------------------------------------------------
   Every chart used to be read-only: the sole interaction was clicking
   exactly on a 2.5px dot to reveal its value. */

/* Nearest-point crosshair (chart-crosshair.js). */
.chart-crosshair-line {
    stroke: var(--color-text-muted);
    stroke-width: 1;
    stroke-dasharray: 3 3;
    opacity: 0.5;
    pointer-events: none;
}

.chart-point-active {
    stroke: var(--color-text);
    stroke-width: 2;
    paint-order: stroke;
}

circle.chart-point-active {
    r: 5;
}

/* Time-range filter. */
.chart-range-control {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 12px;
}

.chart-range-label {
    margin-right: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.chart-range-option {
    padding: 4px 12px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: #fff;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
}

.chart-range-option:hover {
    border-color: var(--color-primary);
}

.chart-range-option-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-on-primary);
}

/* Clickable legend entries that hide their own series. */
.chart-legend-toggle {
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 3px 10px;
    background: none;
    font: inherit;
    font-size: 0.8rem;
    color: inherit;
    cursor: pointer;
}

.chart-legend-toggle:hover {
    border-color: var(--color-border);
}

.chart-legend-toggle-off {
    opacity: 0.4;
    text-decoration: line-through;
}

/* Week annotations — a dip is otherwise indistinguishable from a miss. */
.chart-week-marker {
    stroke: #fff;
    stroke-width: 1.5;
}

.chart-week-marker-cutback {
    fill: #5b8fd4;
}

.chart-week-marker-tune_up {
    fill: #9166c9;
}

.chart-week-marker-race {
    fill: var(--color-accent);
}

/* --- Day-cell legibility ----------------------------------------------
   2.1: effort was communicated by background tint and badge colour only.
   Roughly 1 in 12 men has some colour vision deficiency, and the
   hard-effort orange sits next to the race orange. A left-edge weight
   gives the same three-way distinction without relying on hue. */
.calendar-workout-card {
    border-left-width: 3px;
    border-left-style: solid;
    border-left-color: var(--color-border);
}

.calendar-workout-card-rest,
.calendar-workout-card-recovery {
    border-left-style: dotted;
}

.calendar-workout-card-easy,
.calendar-workout-card-long {
    border-left-color: var(--color-good);
}

.calendar-workout-card-tempo,
.calendar-workout-card-marathon_pace,
.calendar-workout-card-interval,
.calendar-workout-card-repetition,
.calendar-workout-card-hill {
    border-left-width: 5px;
    border-left-color: #b3721f;
}

.calendar-workout-card-race,
.calendar-workout-card-time_trial {
    border-left-width: 5px;
    border-left-style: double;
    border-left-color: #a8420f;
}

/* 2.2: one unambiguous state per day. "Did I do it" is the question a
   runner scanning a month actually has, and it was carried by a small
   marker next to the date number. */
.calendar-day-state {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-left: auto;
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.calendar-day-state-missed {
    background: #fde3e3;
    color: #b3261e;
}

.calendar-day-state-upcoming {
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
}

.calendar-day-number {
    display: flex;
    align-items: center;
    gap: 4px;
}

.calendar-day-drawer-trigger {
    border: 0;
    padding: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.calendar-day-drawer-trigger:hover,
.calendar-day-drawer-trigger:focus-visible {
    color: var(--color-primary-dark);
    text-decoration: underline;
    outline: none;
}

/* 2.3: CSS Grid gives every cell in a week the height of the tallest, so
   one two-entry day inflated the whole row. Cap the visible cards and
   summarise the rest. */
.calendar-day-planned-overflow {
    align-self: flex-start;
    padding: 2px 7px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg);
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

/* Compact workout-card hierarchy: title, planned/completed comparison,
   then a small stress chip. The card remains colored by workout type;
   completion changes its state rather than adding a second row below it. */
.calendar-workout-card {
    position: relative;
    display: flex;
    min-width: 0;
    padding: 0;
    overflow: visible;
    transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease;
}

.calendar-workout-card-main {
    display: block;
    width: 100%;
    min-width: 0;
    padding: 5px 25px 5px 6px;
    border: 0;
    border-radius: inherit;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
}

button.calendar-workout-card-main {
    cursor: pointer;
}

.calendar-workout-card:has(button.calendar-workout-card-main:hover),
.calendar-workout-card:has(button.calendar-workout-card-main:focus-visible) {
    z-index: 3;
    border-color: var(--color-primary);
    box-shadow: 0 5px 14px rgba(22, 33, 29, 0.16);
    transform: translateY(-1px);
}

.calendar-workout-card:has(button.calendar-workout-card-main:active) {
    box-shadow: 0 2px 5px rgba(22, 33, 29, 0.14);
    transform: translateY(0);
}

button.calendar-workout-card-main:focus-visible {
    box-shadow: none;
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.calendar-workout-card-main.calendar-workout-row-clickable:hover,
.calendar-workout-card-main.calendar-workout-row-clickable:focus-visible {
    background: rgba(255, 255, 255, 0.2);
    box-shadow: none;
}

.calendar-workout-card-title,
.calendar-workout-card-secondary,
.calendar-workout-card-tertiary {
    display: block;
}

html[data-calendar-density="simple"] .calendar-workout-card-secondary,
html[data-calendar-density="simple"] .calendar-workout-card-tertiary,
html[data-calendar-density="simple"] .calendar-cell-actions,
html[data-calendar-density="simple"] .calendar-day-state {
    display: none;
}

html[data-calendar-density="technical"] .calendar-workout-card-secondary {
    white-space: normal;
}

/* Technical adds a line of figures the other densities drop. Without it
   this density differed from Standard by the single white-space rule
   above, so choosing it appeared to do nothing. */
.calendar-workout-card-technical {
    display: none;
}

html[data-calendar-density="technical"] .calendar-workout-card-technical {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-top: 2px;
}

.calendar-technical-figure {
    padding: 0 4px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--color-text-muted) 12%, transparent);
    color: var(--color-text-muted);
    font-size: 0.58rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.5;
    white-space: nowrap;
}

.calendar-technical-phase {
    text-transform: capitalize;
}

/* Simple hides it too — it is the opposite end of the same dial. */
html[data-calendar-density="simple"] .calendar-workout-card-technical {
    display: none;
}

.calendar-workout-card-title {
    overflow: hidden;
    color: var(--color-text);
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.calendar-workout-card-secondary {
    margin-top: 3px;
    overflow: hidden;
    color: var(--color-text-muted);
    font-size: 0.66rem;
    line-height: 1.25;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.calendar-workout-summary-line {
    display: grid;
    overflow: hidden;
    text-overflow: ellipsis;
}

.calendar-workout-summary-line + .calendar-workout-summary-line {
    margin-top: 8px;
}

.calendar-workout-summary-label {
    font-weight: 700;
}

.calendar-workout-card-tertiary {
    margin-top: 4px;
}

.calendar-tss-chip {
    display: inline-flex;
    padding: 1px 5px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.7);
    color: var(--color-text-muted);
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.calendar-completed-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    margin-right: 3px;
    border-radius: 50%;
    background: var(--color-good);
    color: #fff;
    font-size: 0.66rem;
    line-height: 1;
}

.calendar-bonus-workout-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    margin-right: 3px;
    color: #484848;
    font-size: 0.7rem;
    line-height: 1;
    vertical-align: middle;
}

.calendar-completion-accurate {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 1px;
    min-width: 1.05rem;
    height: 1.05rem;
    margin-right: 3px;
    color: var(--color-primary-dark);
    font-size: 0.48rem;
    line-height: 1;
    vertical-align: middle;
}

.calendar-workout-missed-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    margin-right: 3px;
    border-radius: 50%;
    color: #b3261e;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
    vertical-align: middle;
}

.calendar-completion-signal {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    min-width: 1.05rem;
    height: 1.05rem;
    margin-right: 3px;
    vertical-align: middle;
}

.calendar-completion-triangles {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 0.42rem;
    line-height: 0.34rem;
}

.calendar-completion-triangles-up {
    color: var(--color-primary-dark);
}

.calendar-completion-triangles-down {
    color: #b3521f;
}

.calendar-cell-actions {
    position: absolute;
    top: 2px;
    right: 2px;
    z-index: 5;
}

.calendar-cell-actions summary {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 5px;
    color: var(--color-text-muted);
    cursor: pointer;
    font-size: 1rem;
    font-weight: 700;
    list-style: none;
}

.calendar-cell-actions summary::-webkit-details-marker {
    display: none;
}

.calendar-cell-actions summary:hover,
.calendar-cell-actions summary:focus-visible,
.calendar-cell-actions[open] summary {
    background: rgba(255, 255, 255, 0.85);
    color: var(--color-text);
    outline: none;
}

.calendar-cell-actions-menu {
    position: absolute;
    top: 25px;
    right: 0;
    width: max-content;
    min-width: 130px;
    padding: 4px;
    border: 1px solid var(--color-border);
    border-radius: 7px;
    background: var(--color-bg);
    box-shadow: 0 8px 24px rgba(22, 33, 29, 0.18);
}

.calendar-cell-actions-menu button {
    display: block;
    width: 100%;
    padding: 7px 9px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    font-size: 0.76rem;
    text-align: left;
    cursor: pointer;
}

.calendar-cell-actions-menu button:hover,
.calendar-cell-actions-menu button:focus-visible {
    background: var(--color-bg-alt);
    outline: none;
}

/* Day drawer: complete day context without expanding every month cell. */
.calendar-day-drawer-overlay {
    position: fixed;
    inset: 0;
    z-index: 110;
    background: rgba(22, 33, 29, 0.42);
}

.calendar-day-drawer-overlay[hidden] {
    display: none;
}

.calendar-day-drawer {
    position: absolute;
    top: 0;
    right: 0;
    width: min(430px, 100%);
    height: 100%;
    overflow-y: auto;
    background: var(--color-bg);
    box-shadow: -12px 0 35px rgba(22, 33, 29, 0.2);
}

.calendar-day-drawer-header {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 22px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
}

.calendar-day-drawer-header h2 {
    margin: 2px 0 0;
    font-size: 1.3rem;
}

.calendar-day-drawer-eyebrow {
    color: var(--color-text-muted);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.calendar-day-drawer-body {
    padding: 20px 22px 32px;
}

.day-drawer-section + .day-drawer-section {
    margin-top: 24px;
}

.day-drawer-section h3 {
    margin: 0 0 10px;
    font-size: 0.82rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.day-drawer-workout {
    padding: 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg-alt);
}

.day-drawer-workout + .day-drawer-workout {
    margin-top: 9px;
}

.day-drawer-workout-completed {
    border-color: #8ab79d;
    background: #f0f8f3;
}

.day-drawer-workout-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.day-drawer-workout p,
.day-drawer-empty {
    margin: 5px 0 0;
    color: var(--color-text-muted);
    font-size: 0.84rem;
}

.day-drawer-segments {
    margin-top: 8px;
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.day-drawer-segments summary {
    cursor: pointer;
}

.day-drawer-segments ul {
    margin: 6px 0 0;
    padding-left: 18px;
}

.day-drawer-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

.agenda-day-date {
    border: 0;
    padding: 0;
    background: transparent;
    color: inherit;
    cursor: pointer;
}

.plan-header-notice {
    margin: 8px 0 0;
    padding: 6px 12px;
    border-left: 3px solid #d9a520;
    background: var(--color-bg-alt);
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* --- Plan Details structure -------------------------------------------
   11 sibling h2 sections of equal visual weight read as one wall with
   nothing findable. Three tiers plus anchors give it a shape. */
.plan-details-nav {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 18px;
    padding: 10px 0;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.plan-details-nav a {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-decoration: none;
}

.plan-details-nav a:hover {
    color: var(--color-primary-dark);
}

.plan-details-tier {
    margin: 32px 0 12px;
    padding-bottom: 6px;
    border-bottom: 2px solid var(--color-primary);
    font-size: 1.1rem;
    scroll-margin-top: 64px;
}

.plan-details-tier:first-of-type {
    margin-top: 8px;
}

/* The cited-principles list: heading (with its figure) visible, the
   justification behind a click. It's the right content in the wrong
   default state — it was the first thing between a runner and their plan. */
.plan-details-principles-collapsible dt {
    cursor: default;
}

.plan-details-principles-collapsible dd {
    max-height: 3.2em;
    overflow: hidden;
    position: relative;
    transition: max-height 0.2s ease;
}

.plan-details-principles-collapsible dd::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 1.4em;
    background: linear-gradient(transparent, var(--color-bg-alt));
    pointer-events: none;
}

.plan-details-principles-collapsible:hover dd,
.plan-details-principles-collapsible:focus-within dd {
    max-height: 22em;
}

.plan-details-principles-collapsible:hover dd::after,
.plan-details-principles-collapsible:focus-within dd::after {
    display: none;
}

/* --- Plan Details: read-first evidence dashboard --------------------- */
.plan-details-dashboard,
.plan-details-edit-panel {
    margin: 0 0 22px;
    padding: 20px;
    border: 1px solid var(--color-border);
    border-radius: 18px;
    background: var(--color-bg);
    box-shadow: var(--app-shadow-small, 0 8px 24px rgba(20, 35, 30, 0.06));
}

.plan-details-dashboard-heading,
.plan-details-editor-heading,
.plan-details-card-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.plan-details-dashboard-heading h2,
.plan-details-editor-heading h2 {
    margin: 2px 0 0;
    font-size: 1.12rem;
}

.plan-details-dashboard-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin-top: 16px;
}

.plan-details-dashboard-tile {
    min-width: 0;
    padding: 14px;
    border: 1px solid color-mix(in srgb, var(--color-border) 78%, transparent);
    border-radius: 13px;
    background: var(--color-bg-alt);
}

.plan-details-dashboard-tile > span,
.plan-details-dashboard-tile small,
.plan-details-evidence-list small,
.long-run-stress-grid span,
.long-run-stress-grid small,
.intensity-comparison span,
.intensity-comparison small {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.72rem;
}

.plan-details-dashboard-tile > span {
    margin-bottom: 5px;
    font-weight: 750;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.plan-details-dashboard-tile strong {
    display: block;
    margin-bottom: 4px;
    overflow-wrap: anywhere;
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
}

.plan-details-dashboard-tile.is-caution,
.intensity-comparison .is-caution {
    border-color: color-mix(in srgb, #d3902f 42%, var(--color-border));
    background: color-mix(in srgb, #f3b85b 8%, var(--color-bg-alt));
}

.plan-details-evidence-summary {
    padding: 18px;
}

.plan-details-evidence-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 20px;
    margin-top: 12px;
}

.plan-details-evidence-list article {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 0;
    border-top: 1px solid var(--color-border);
}

.plan-details-evidence-list article > div > span,
.plan-details-evidence-list article strong,
.plan-details-evidence-list article small {
    display: block;
}

.plan-details-evidence-list article > div > span {
    margin-bottom: 3px;
    color: var(--color-text-muted);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
}

.plan-details-evidence-list article small {
    margin-top: 3px;
}

.evidence-grade {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    min-height: 24px;
    padding: 3px 8px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.66rem;
    font-weight: 750;
    white-space: nowrap;
}

.evidence-grade-direct,
.evidence-grade-consensus {
    border-color: color-mix(in srgb, var(--color-primary) 38%, var(--color-border));
    color: var(--color-primary-dark);
}

.evidence-grade-missing,
.evidence-grade-heuristic,
.evidence-grade-coaching,
.evidence-grade-mixed {
    border-color: color-mix(in srgb, #d3902f 45%, var(--color-border));
    color: color-mix(in srgb, #9a5e0a 88%, var(--color-text));
}

.plan-details-edit-panel {
    border-color: color-mix(in srgb, var(--color-primary) 36%, var(--color-border));
    background: color-mix(in srgb, var(--color-primary) 3%, var(--color-bg));
    scroll-margin-top: 76px;
}

.plan-details-edit-panel[hidden] {
    display: none;
}

.plan-details-edit-panel > .plan-details-card:last-child {
    margin-bottom: 0;
}

.plan-details-settings-grid,
.plan-edit-impact-grid,
.long-run-stress-grid,
.intensity-comparison {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}

.plan-edit-preview {
    margin: 18px 0;
    padding: 18px;
    border: 1px solid color-mix(in srgb, #d3902f 45%, var(--color-border));
    border-radius: 14px;
    background: color-mix(in srgb, #f3b85b 7%, var(--color-bg));
}

.plan-edit-preview h3 {
    margin: 4px 0 6px;
}

.plan-edit-impact-grid article,
.long-run-stress-grid > div,
.intensity-comparison article {
    padding: 11px 12px;
    border: 1px solid var(--color-border);
    border-radius: 11px;
    background: var(--color-bg);
}

.plan-edit-impact-grid span,
.plan-edit-impact-grid strong {
    display: block;
}

.plan-edit-impact-grid span {
    margin-bottom: 4px;
    color: var(--color-text-muted);
    font-size: 0.7rem;
}

.plan-edit-impact-grid strong {
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
}

.plan-edit-days-wrap,
.quality-budget-table-wrap {
    overflow-x: auto;
    margin-top: 12px;
}

.button-danger-confirm {
    background: #a94332;
    border-color: #a94332;
}

.taper-preview {
    display: grid;
    gap: 8px;
    margin: 16px 0 10px;
}

.taper-preview-row {
    display: grid;
    grid-template-columns: 58px minmax(100px, 1fr) 40px minmax(120px, auto);
    align-items: center;
    gap: 9px;
    font-size: 0.75rem;
}

.taper-preview-track {
    height: 10px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.taper-preview-track span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--color-good), var(--color-accent));
}

.taper-preview-row small {
    color: var(--color-text-muted);
}

.quality-budget-table small {
    display: block;
    color: var(--color-text-muted);
}

.quality-budget-meter {
    display: block;
    width: 100%;
    min-width: 90px;
    height: 5px;
    margin-top: 6px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.quality-budget-meter i {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--color-accent);
}

.long-run-stress-grid {
    margin-top: 12px;
}

.long-run-stress-grid strong,
.intensity-comparison strong {
    display: block;
    margin: 4px 0;
    font-size: 0.9rem;
}

.long-run-status {
    margin-top: 10px;
    padding-left: 10px;
    border-left: 3px solid var(--color-good);
}

.long-run-status.is-caution {
    border-color: #d3902f;
}

.intensity-domain-bar {
    display: flex;
    height: 28px;
    margin: 14px 0 10px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.intensity-domain-bar span {
    display: grid;
    min-width: 2px;
    place-items: center;
    overflow: hidden;
    color: #fff;
    font-size: 0.68rem;
}

.intensity-domain-moderate { background: #3e8c73; }
.intensity-domain-heavy { background: #d39535; }
.intensity-domain-severe { background: #b64f45; }

.intensity-domain-legend {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 14px;
}

.intensity-domain-legend > span {
    display: grid;
    grid-template-columns: 9px 1fr;
    gap: 2px 7px;
    align-items: center;
}

.intensity-domain-legend i {
    grid-row: 1 / span 2;
    width: 9px;
    height: 24px;
    border-radius: 999px;
}

.intensity-domain-legend small {
    color: var(--color-text-muted);
    font-size: 0.68rem;
}

.plan-details-principles-disclosure {
    display: grid;
    gap: 8px;
}

.plan-details-principles-disclosure details {
    border: 1px solid var(--color-border);
    border-radius: 11px;
    background: var(--color-bg-alt);
}

.plan-details-principles-disclosure summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 12px;
    cursor: pointer;
    font-size: 0.86rem;
    font-weight: 700;
}

.plan-details-principles-disclosure p {
    margin: 0;
    padding: 0 12px 12px;
    color: var(--color-text-muted);
    font-size: 0.82rem;
    line-height: 1.55;
}

@media (max-width: 760px) {
    .plan-details-dashboard,
    .plan-details-edit-panel {
        padding: 14px;
        border-radius: 15px;
    }

    .plan-details-dashboard-heading,
    .plan-details-editor-heading,
    .plan-details-card-heading {
        align-items: stretch;
        flex-direction: column;
    }

    .plan-details-dashboard-grid,
    .plan-details-evidence-list,
    .plan-details-settings-grid,
    .plan-edit-impact-grid,
    .long-run-stress-grid,
    .intensity-comparison {
        grid-template-columns: 1fr;
    }

    .plan-details-evidence-list article:nth-child(2) {
        border-top: 1px solid var(--color-border);
    }

    .taper-preview-row {
        grid-template-columns: 48px minmax(80px, 1fr) 36px;
    }

    .taper-preview-row small {
        grid-column: 2 / -1;
    }

    .intensity-domain-legend {
        grid-template-columns: 1fr;
    }
}

.twin-summary-description {
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

/* One-line verdict per chart, so the trends page is skimmable rather than
   three plots with no stated conclusion. */
.chart-verdict {
    margin: 0 0 6px;
    font-size: 0.92rem;
    font-weight: 600;
}

/* Recovery page: the answer first, then the cards. */
.recovery-headline {
    margin-bottom: 16px;
    padding: 14px 18px;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: var(--radius);
    background: #fff;
}

.recovery-headline-attention {
    border-left-color: #b3261e;
}

.recovery-headline-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
}

.recovery-headline-detail {
    margin: 4px 0 0;
    font-size: 0.88rem;
    color: var(--color-text-muted);
}

/* Recovery dashboard ----------------------------------------------------- */
.recovery-page {
    max-width: 1180px;
}

.recovery-page-header {
    align-items: flex-start;
    gap: 24px;
}

.recovery-eyebrow,
.recovery-card-kicker {
    margin: 0 0 5px;
    color: var(--color-primary-dark);
    font-size: 0.72rem;
    font-weight: 750;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.recovery-decision {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 190px;
    gap: 20px 36px;
    margin: 18px 0 12px;
    padding: 24px 26px 18px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--color-good) 30%, var(--color-border));
    border-left: 5px solid var(--color-good);
    border-radius: calc(var(--radius) + 2px);
    /* Theme tokens, not fixed light tints: a hard-coded near-white start
       washed the text out in dark mode. */
    background: linear-gradient(120deg, var(--color-positive-soft), var(--color-bg));
}

.recovery-decision-decrease {
    border-color: color-mix(in srgb, #b3261e 30%, var(--color-border));
    border-left-color: #b3261e;
    background: linear-gradient(120deg, var(--color-danger-soft), var(--color-bg));
}

.recovery-decision h2 {
    margin: 0 0 8px;
    font-size: clamp(1.25rem, 2.4vw, 1.75rem);
}

.recovery-reason-list,
.recovery-check-list {
    margin: 8px 0 0;
    padding-left: 20px;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.recovery-reason-list li + li,
.recovery-check-list li + li {
    margin-top: 6px;
}

.recovery-confidence {
    display: flex;
    flex-direction: column;
    align-self: center;
    gap: 3px;
    padding: 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: rgba(255, 255, 255, 0.78);
}

.recovery-confidence strong {
    font-size: 1.2rem;
}

.recovery-confidence span:last-child,
.recovery-confidence-label {
    color: var(--color-text-muted);
    font-size: 0.72rem;
}

.recovery-confidence-label {
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.recovery-advisory-note {
    grid-column: 1 / -1;
    margin: 0;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.78rem;
}

.recovery-coverage {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    margin-bottom: 34px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-alt);
}

.recovery-coverage div {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 7px;
    padding: 10px 14px;
    border-right: 1px solid var(--color-border);
}

.recovery-coverage div:last-child {
    border-right: 0;
}

.recovery-coverage span {
    color: var(--color-text-muted);
    font-size: 0.78rem;
}

.recovery-section-title {
    margin: 34px 0 14px;
    font-size: 1.15rem;
}

.recovery-grid-two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-top: 20px;
}

.recovery-grid-three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.recovery-page .recovery-card {
    min-width: 0;
    padding: 20px;
    box-shadow: 0 3px 14px rgba(29, 29, 27, 0.045);
}

.recovery-page .recovery-card h2,
.recovery-page .recovery-card h3 {
    margin-top: 0;
}

.recovery-value small {
    color: var(--color-text-muted);
    font-size: 0.82rem;
    font-weight: 500;
}

.recovery-status-line,
.recovery-summary-line {
    margin: 4px 0 8px;
    font-size: 0.86rem;
    font-weight: 650;
}

.recovery-summary-line {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}

.recovery-mini-stats,
.recovery-load-pair {
    display: grid;
    gap: 7px;
    margin: 12px 0 0;
}

.recovery-mini-stats div,
.recovery-load-pair div {
    display: flex;
    justify-content: space-between;
    gap: 18px;
    padding: 7px 0;
    border-bottom: 1px solid var(--color-border);
}

.recovery-mini-stats dt,
.recovery-load-pair dt {
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.recovery-mini-stats dd,
.recovery-load-pair dd {
    margin: 0;
    font-size: 0.82rem;
    font-weight: 700;
    text-align: right;
}

.recovery-load-pair {
    grid-template-columns: repeat(2, 1fr);
}

.recovery-load-pair div {
    display: block;
    padding: 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-alt);
}

.recovery-load-pair dd {
    margin-top: 5px;
    font-size: 1.1rem;
    text-align: left;
}

.recovery-table-wrap {
    overflow-x: auto;
}

.recovery-table {
    width: 100%;
    margin-top: 12px;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.recovery-table th,
.recovery-table td {
    padding: 8px 9px;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    white-space: nowrap;
}

.recovery-table thead th {
    color: var(--color-text-muted);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.recovery-text-alert {
    color: #a32b24;
    font-weight: 700;
}

.recovery-compact-list {
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
}

.recovery-compact-list li {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    padding: 7px 0;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.recovery-compact-list strong {
    color: var(--color-text);
}

.recovery-details {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
    font-size: 0.82rem;
}

.recovery-details summary {
    cursor: pointer;
    font-weight: 700;
}

.recovery-card-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.recovery-card-heading h2,
.recovery-card-heading h3,
.recovery-card-heading p {
    margin-bottom: 4px;
}

.recovery-safety-card {
    border-color: #e6c98e !important;
    background: #fffdf7 !important;
}

.recovery-alert {
    padding: 10px 12px;
    border-left: 3px solid #b3261e;
    background: #fff2f0;
    color: #8f211b;
    font-size: 0.85rem;
}

.recovery-outlook-card {
    margin-top: 20px;
}

.recovery-outlook {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 8px;
    margin-top: 14px;
}

.recovery-outlook-day {
    min-width: 0;
    padding: 11px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-alt);
}

.recovery-outlook-day.is-demanding {
    border-top: 3px solid #b36b18;
}

.recovery-outlook-day time,
.recovery-outlook-day span,
.recovery-outlook-day small {
    display: block;
}

.recovery-outlook-day time {
    color: var(--color-text-muted);
    font-size: 0.67rem;
    text-transform: uppercase;
}

.recovery-outlook-day time strong {
    display: block;
    color: var(--color-text);
    font-size: 1.15rem;
}

.recovery-outlook-day span {
    margin: 8px 0 4px;
    overflow: hidden;
    font-size: 0.78rem;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.recovery-outlook-day small {
    color: var(--color-text-muted);
    font-size: 0.68rem;
    line-height: 1.35;
}

@media (max-width: 850px) {
    .recovery-grid-three {
        grid-template-columns: 1fr;
    }

    .recovery-outlook {
        grid-template-columns: repeat(4, minmax(110px, 1fr));
        overflow-x: auto;
    }
}

@media (max-width: 700px) {
    .recovery-decision,
    .recovery-grid-two {
        grid-template-columns: 1fr;
    }

    .recovery-coverage {
        grid-template-columns: repeat(2, 1fr);
    }

    .recovery-coverage div:nth-child(2) {
        border-right: 0;
    }

    .recovery-coverage div:nth-child(-n + 2) {
        border-bottom: 1px solid var(--color-border);
    }

    .recovery-card-heading {
        display: block;
    }

    .recovery-card-heading .button {
        margin-top: 8px;
    }
}

/* --- Evidence-led coaching flow ------------------------------------ */
.today-dashboard.today-card {
    position: relative;
    margin: 18px 0;
    padding: clamp(18px, 3vw, 28px);
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--color-primary) 18%, var(--color-border));
    border-radius: 24px;
    background: linear-gradient(140deg, color-mix(in srgb, var(--color-primary) 7%, var(--color-surface)) 0%, var(--color-surface) 48%);
    box-shadow: 0 16px 45px color-mix(in srgb, var(--color-text) 9%, transparent);
}
.today-dashboard::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--color-primary); }
.today-dashboard-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 18px; }
.today-dashboard-header h2 { margin: 5px 0 4px; max-width: 760px; font-size: clamp(1.35rem, 2.4vw, 2rem); letter-spacing: -0.035em; line-height: 1.12; }
.today-dashboard-header p { max-width: 720px; margin: 0; color: var(--color-text-muted); }
.today-dashboard-trust { display: flex; align-items: flex-end; flex-direction: column; gap: 7px; flex: 0 0 auto; }
.fitness-anchor-chip { display: inline-flex; align-items: center; min-height: 27px; padding: 4px 10px; border: 1px solid var(--color-border); border-radius: 999px; background: var(--color-bg-alt); color: var(--color-text-muted); font-size: 0.72rem; font-weight: 750; white-space: nowrap; }
.fitness-anchor-chip-high { border-color: color-mix(in srgb, var(--color-primary) 32%, var(--color-border)); color: var(--color-primary); }
.fitness-anchor-chip-low { border-color: color-mix(in srgb, #c48724 38%, var(--color-border)); color: #936313; }
.today-dashboard-layout { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(230px, 0.7fr); gap: 14px; }
.today-dashboard-session { display: grid; gap: 8px; }
.today-dashboard-session .calendar-workout-card { margin: 0; min-height: 86px; border-radius: 16px; }
.today-dashboard-context { display: grid; gap: 1px; overflow: hidden; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-border); }
.today-dashboard-context div { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; background: var(--color-surface); }
.today-dashboard-context span { color: var(--color-text-muted); font-size: 0.73rem; }
.today-dashboard-context strong { font-size: 0.8rem; text-align: right; }
.today-dashboard-rest { display: flex; flex-direction: column; justify-content: center; min-height: 86px; padding: 15px; border: 1px dashed var(--color-border); border-radius: 16px; }
.today-dashboard-rest span { margin-top: 3px; color: var(--color-text-muted); font-size: 0.8rem; }
.today-dashboard .today-card-actions { display: flex; justify-content: flex-start; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.today-dashboard .today-card-actions .button { width: auto; }

.goal-feasibility-card { margin-top: 18px; padding: 16px; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-bg-alt); }
.goal-feasibility-card-warning { border-color: color-mix(in srgb, #c44b3f 42%, var(--color-border)); background: color-mix(in srgb, #c44b3f 7%, var(--color-surface)); }
.goal-feasibility-card-caution { border-color: color-mix(in srgb, #c48724 42%, var(--color-border)); background: color-mix(in srgb, #c48724 7%, var(--color-surface)); }
.goal-feasibility-heading { display: flex; align-items: center; gap: 11px; }
.goal-feasibility-heading h3 { margin: 2px 0 0; }
.goal-feasibility-icon { display: grid; width: 34px; height: 34px; place-items: center; border-radius: 10px; background: var(--color-surface); color: var(--color-primary); font-weight: 850; }
.goal-feasibility-anchor { display: flex; justify-content: space-between; gap: 12px; margin: 13px 0; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 11px; background: var(--color-surface); }
.goal-feasibility-anchor span { color: var(--color-text-muted); font-size: 0.75rem; }
.goal-strategy-options { margin-top: 14px; }
.goal-strategy-options > div { display: grid; gap: 7px; margin-top: 8px; }
.goal-strategy-options label { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 11px; background: var(--color-surface); cursor: pointer; }

.weekly-review-flow { display: grid; gap: 13px; }
.weekly-review-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 0; padding: 0; list-style: none; }
.weekly-review-steps li { display: flex; align-items: center; gap: 7px; min-width: 0; padding: 8px 10px; border-radius: 10px; background: var(--color-bg-alt); color: var(--color-text-muted); font-size: 0.7rem; font-weight: 750; }
.weekly-review-steps li > span, .weekly-review-panel-heading > span { display: grid; flex: 0 0 auto; width: 23px; height: 23px; place-items: center; border-radius: 50%; background: var(--color-surface); color: var(--color-primary); font-size: 0.7rem; box-shadow: inset 0 0 0 1px var(--color-border); }
.weekly-review-steps .is-current { background: color-mix(in srgb, var(--color-primary) 12%, var(--color-surface)); color: var(--color-primary); }
.weekly-review-panel { padding: 15px; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-surface); }
.weekly-review-panel-heading { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.weekly-review-panel-heading p { margin: 0; color: var(--color-text-muted); font-size: 0.62rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
.weekly-review-panel-heading h2 { margin: 1px 0 0; font-size: 1rem; }
.weekly-review-metrics, .weekly-review-learning-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.weekly-review-metrics article, .learning-card { min-width: 0; padding: 11px 12px; border-radius: 12px; background: var(--color-bg-alt); }
.weekly-review-metrics span, .learning-card > span { display: block; margin-bottom: 4px; color: var(--color-text-muted); font-size: 0.67rem; font-weight: 700; }
.weekly-review-metrics strong, .learning-card strong { display: block; font-size: 0.9rem; }
.weekly-review-learning-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.learning-card p { margin: 5px 0 0; color: var(--color-text-muted); font-size: 0.72rem; line-height: 1.4; }
.learning-card-high, .learning-card-positive { box-shadow: inset 3px 0 0 var(--color-good); }
.learning-card-warning { box-shadow: inset 3px 0 0 #c44b3f; }
.learning-card-caution { box-shadow: inset 3px 0 0 #c48724; }
.weekly-review-tune-up, .weekly-review-window { margin: 10px 0 0; color: var(--color-text-muted); font-size: 0.76rem; }
.weekly-review-clear { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; padding: 12px; border-radius: 12px; background: color-mix(in srgb, var(--color-good) 8%, var(--color-surface)); }
.weekly-review-clear > span { display: grid; width: 30px; height: 30px; place-items: center; border-radius: 50%; background: var(--color-good); color: #fff; }
.weekly-review-clear p { margin: 2px 0 0; color: var(--color-text-muted); font-size: 0.75rem; }
.weekly-review-keep-status { display: inline; margin-left: 8px; color: var(--color-text-muted); font-size: 0.75rem; }
.tune-up-result-card { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; margin: 10px 0; }
.tune-up-result-card div { padding: 9px 10px; border-radius: 10px; background: var(--color-bg-alt); }
.tune-up-result-card span { display: block; color: var(--color-text-muted); font-size: 0.65rem; }
.tune-up-result-card strong { display: block; margin-top: 3px; font-size: 0.82rem; }
.tune-up-goal-outlook { padding: 9px 11px; border-left: 3px solid var(--color-primary); background: var(--color-bg-alt); font-size: 0.78rem; }

.workout-coaching-brief { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 12px; }
.workout-coaching-brief-item { padding: 12px; border: 1px solid var(--color-border); border-radius: 13px; background: var(--color-bg-alt); }
.workout-coaching-brief-item span { display: block; margin-bottom: 5px; color: var(--color-primary); font-size: 0.63rem; font-weight: 850; letter-spacing: 0.08em; text-transform: uppercase; }
.workout-coaching-brief-item strong { display: block; font-size: 0.79rem; line-height: 1.4; }
.workout-progressive-details { margin: 8px 0; border: 1px solid var(--color-border); border-radius: 12px; background: var(--color-surface); }
.workout-progressive-details > summary { padding: 11px 13px; cursor: pointer; color: var(--color-text); font-size: 0.78rem; font-weight: 750; }
.workout-progressive-details[open] > summary { border-bottom: 1px solid var(--color-border); }
.workout-progressive-details > :not(summary) { margin: 12px; }
.workout-strength-adapted { margin-top: 10px; padding: 10px 12px; border: 1px solid color-mix(in srgb, #c48724 38%, var(--color-border)); border-radius: 11px; background: color-mix(in srgb, #c48724 7%, var(--color-surface)); font-size: 0.76rem; }
.workout-strength-adapted ul { margin: 6px 0 0; padding-left: 18px; }

.plan-evidence-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.plan-evidence-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.plan-evidence-grid > div { padding: 11px 12px; border-radius: 11px; background: var(--color-bg-alt); }
.plan-evidence-grid span, .plan-evidence-grid small { display: block; color: var(--color-text-muted); font-size: 0.7rem; }
.plan-evidence-grid strong { display: block; margin: 4px 0; font-size: 0.88rem; }

@media (max-width: 760px) {
    .today-dashboard.today-card { margin-inline: -4px; padding: 16px; border-radius: 20px; }
    .today-dashboard-header, .plan-evidence-card-header { flex-direction: column; }
    .today-dashboard-trust { align-items: flex-start; flex-direction: row; flex-wrap: wrap; }
    .today-dashboard-layout { grid-template-columns: 1fr; }
    .today-dashboard-context { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .today-dashboard-context div { align-items: flex-start; flex-direction: column; }
    .today-dashboard-context strong { text-align: left; }
    .today-dashboard .today-card-actions { display: grid; grid-template-columns: 1fr 1fr; }
    .today-dashboard .today-card-actions .button { width: 100%; }
    .today-dashboard .today-card-actions .button:first-child { grid-column: 1 / -1; }
    .weekly-review-steps { grid-template-columns: 1fr 1fr; }
    .weekly-review-metrics { grid-template-columns: 1fr 1fr; }
    .weekly-review-learning-grid, .plan-evidence-grid { grid-template-columns: 1fr; }
    .workout-coaching-brief { grid-template-columns: 1fr; }
}

@media (max-width: 440px) {
    .today-dashboard-context { grid-template-columns: 1fr; }
    .weekly-review-steps li { padding: 7px; font-size: 0.64rem; }
    .tune-up-result-card { grid-template-columns: 1fr; }
}

/* --- Product-completion surfaces ------------------------------------- */
.calendar-outlook-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0 18px;
    padding: 10px 13px;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background: var(--color-bg-alt);
    color: var(--color-text);
    font-size: 0.8rem;
    line-height: 1.4;
    text-decoration: none;
}
.calendar-outlook-summary.is-caution { border-left: 4px solid #b3721f; }
.calendar-outlook-link { margin-left: auto; color: var(--color-primary); font-weight: 750; white-space: nowrap; }

.plan-history-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.plan-history-card { padding: 18px; border: 1px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); box-shadow: var(--app-shadow-small); }
.plan-history-card h2 { margin: 8px 0 14px; }
.plan-history-card dl { display: grid; gap: 7px; margin: 0; }
.plan-history-card dl div { display: flex; justify-content: space-between; gap: 16px; }
.plan-history-card dt { color: var(--color-text-muted); }
.plan-history-card dd { margin: 0; font-weight: 700; }
.plan-history-card p { color: var(--color-text-muted); line-height: 1.55; }
.plan-history-actions, .lifecycle-actions { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 18px; }

/* The summary is shared by a full page and a narrower dialog. A real grid
   keeps all four figures aligned and prevents Week/phase labels from
   collapsing into uneven flex rows in the modal. */
.plan-summary-numbers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.modal-dialog-plan-details .plan-summary { padding: 14px; }
.modal-dialog-plan-details .plan-summary-value { font-size: 1.15rem; }

/* Expanded Today uses the width before adding height: workout and context
   remain side by side until a genuinely narrow screen. */
.today-dashboard-layout { grid-template-columns: minmax(0, 1.6fr) minmax(250px, 0.75fr); gap: 14px; }
.today-dashboard .today-dashboard-context { align-content: start; }

@media (max-width: 700px) {
    .calendar-outlook-summary { align-items: flex-start; flex-direction: column; }
    .calendar-outlook-link { margin-left: 0; }
    .plan-summary-numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .plan-phase-segment-label { font-size: 0.62rem; padding-inline: 3px; }
    .today-dashboard-layout { grid-template-columns: 1fr; }
    .lifecycle-actions .button { flex: 1 1 100%; justify-content: center; }
}

@media (max-width: 390px) {
    .plan-summary-numbers { grid-template-columns: 1fr 1fr; gap: 10px; }
    .plan-summary-value { font-size: 1.05rem; }
    .plan-summary-label { font-size: 0.62rem; }
}

/* --- Mobile: the agenda view is the mobile-appropriate layout ----------
   It existed but required finding and pressing a toggle. Seven shrunken
   grid columns are unreadable on a phone, so below this width the agenda
   is the default and the toggle flips back to the grid. */
@media (max-width: 700px) {
    /* Five columns is unreadable on a phone, so each day becomes its own
       card: the header row is dropped and every cell states its own
       label from the data-label the template puts on it. Without that
       the stacked version was four unlabelled selects in a column. */
    .daily-schedule-grid {
        display: block;
    }

    .daily-schedule-header {
        display: none;
    }

    .daily-schedule-day-label {
        margin: 12px 0 0;
        padding: 8px 10px 6px;
        font-weight: 700;
        background: var(--color-bg-alt);
        border: 1px solid var(--color-border);
        border-bottom: none;
        border-radius: var(--radius) var(--radius) 0 0;
    }

    .daily-schedule-grid > div[data-label] {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 6px 10px;
        border-left: 1px solid var(--color-border);
        border-right: 1px solid var(--color-border);
    }

    .daily-schedule-grid > div[data-label]:last-child {
        border-bottom: 1px solid var(--color-border);
        border-radius: 0 0 var(--radius) var(--radius);
        padding-bottom: 10px;
    }

    .daily-schedule-grid > div[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 0.75rem;
        font-weight: 600;
        color: var(--color-text-muted);
        text-transform: uppercase;
    }

    .daily-schedule-grid > div[data-label] select,
    .daily-schedule-grid > div[data-label] input {
        flex: 1 1 auto;
        min-width: 0;
        max-width: 60%;
    }
}

/* --- Workout modal: outcome-first, activity-aware flow ---------------- */
.modal-dialog-workout {
    width: min(760px, calc(100vw - 28px));
}

#workout-modal .workout-modal-header {
    position: sticky;
    top: 0;
    z-index: 4;
    align-items: flex-start;
    gap: 18px;
    background: color-mix(in srgb, var(--color-surface) 94%, transparent);
    backdrop-filter: blur(14px);
}

.workout-footer-menu {
    position: relative;
}

.workout-footer-menu > summary {
    cursor: pointer;
    list-style: none;
}

.workout-footer-menu > summary::-webkit-details-marker { display: none; }

.workout-footer-menu > div {
    position: absolute;
    right: 0;
    bottom: calc(100% + 7px);
    min-width: 190px;
    padding: 5px;
    border: 1px solid var(--color-border);
    border-radius: 11px;
    background: var(--color-surface);
    box-shadow: 0 12px 28px color-mix(in srgb, var(--color-text) 14%, transparent);
}

.workout-footer-menu button {
    width: 100%;
    padding: 9px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 680;
    text-align: left;
}

.workout-footer-menu button:hover,
.workout-footer-menu button:focus-visible {
    background: var(--color-bg-alt);
    color: var(--color-primary);
}

.workout-modal-heading {
    min-width: 0;
}

.workout-modal-eyebrow {
    display: block;
    margin-bottom: 3px;
    color: var(--color-text-muted);
    font-size: 0.66rem;
    font-weight: 780;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

#workout-modal .workout-modal-heading h2 {
    margin: 0;
    font-size: clamp(1.05rem, 2.3vw, 1.35rem);
    letter-spacing: -0.02em;
}

#workout-modal-summary {
    margin: 4px 0 0;
    color: var(--color-text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

.workout-modal-navigation {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
}

.modal-nav-button {
    display: grid;
    width: 34px;
    height: 34px;
    place-items: center;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
}

.modal-nav-button:hover:not(:disabled),
.modal-nav-button:focus-visible {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.modal-nav-button:disabled {
    cursor: default;
    opacity: 0.35;
}

#workout-modal .modal-footer {
    position: sticky;
    bottom: 0;
    z-index: 4;
    background: color-mix(in srgb, var(--color-surface) 94%, transparent);
    backdrop-filter: blur(14px);
}

.workout-interpretation {
    margin: 2px 0 12px;
    padding: 11px 13px;
    border-left: 3px solid var(--color-primary);
    border-radius: 0 11px 11px 0;
    background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
    font-size: 0.84rem;
    font-weight: 650;
    line-height: 1.45;
}

.workout-comparison-delta {
    font-weight: 720;
    white-space: nowrap;
}

.workout-comparison-delta.is-higher,
.workout-comparison-delta.is-lower { color: #a65b24; }
.workout-comparison-delta.is-matched { color: var(--color-primary-dark); }

.workout-segment-timeline {
    margin-bottom: 12px;
}

.workout-segment-track {
    display: flex;
    min-height: 58px;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: 13px;
    background: var(--color-bg-alt);
}

.workout-segment-block {
    display: flex;
    min-width: 58px;
    justify-content: center;
    flex-direction: column;
    gap: 2px;
    padding: 8px;
    border-right: 1px solid color-mix(in srgb, var(--color-surface) 65%, transparent);
    color: var(--color-text);
    text-align: center;
}

.workout-segment-block:last-child { border-right: 0; }
.workout-segment-block strong { overflow: hidden; font-size: 0.72rem; text-overflow: ellipsis; white-space: nowrap; }
.workout-segment-block span { color: var(--color-text-muted); font-size: 0.64rem; }
.workout-segment-block-0 { background: color-mix(in srgb, var(--color-series) 11%, var(--color-surface)); }
.workout-segment-block-1 { background: color-mix(in srgb, #6a3fb3 10%, var(--color-surface)); }
.workout-segment-block-2 { background: color-mix(in srgb, var(--color-accent) 11%, var(--color-surface)); }
.workout-segment-block-3 { background: color-mix(in srgb, #4382bb 10%, var(--color-surface)); }

.workout-segment-completion {
    position: relative;
    margin: 7px 0 0;
    padding-top: 7px;
    color: var(--color-text-muted);
    font-size: 0.7rem;
}

.workout-segment-completion::before {
    content: "";
    position: absolute;
    inset: 0 auto auto 0;
    width: var(--completion);
    height: 3px;
    border-radius: 999px;
    background: var(--color-primary);
}

.workout-swap-button.is-confirming,
.workout-absorb-button.is-confirming,
.workout-cancel-button.is-confirming {
    border-color: #a65b24;
    background: color-mix(in srgb, #d49a25 12%, var(--color-surface));
    color: #8a5715;
}

/* --- Shared chart experience ----------------------------------------- */
.chart-experience {
    margin: 12px 0 8px;
    padding: 14px;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: 16px;
    background: var(--color-surface);
    box-shadow: 0 8px 24px color-mix(in srgb, var(--color-text) 6%, transparent);
}

.chart-insight-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 10px;
}

.chart-insight-header h3 {
    margin: 0;
    font-size: 0.95rem;
}

.chart-insight-header p {
    max-width: 680px;
    margin: 3px 0 0;
    color: var(--color-text-muted);
    font-size: 0.76rem;
    line-height: 1.4;
}

.chart-source {
    display: block;
    margin-top: 4px;
    color: var(--color-text-muted);
    font-size: 0.65rem;
    font-weight: 650;
}

.chart-evidence-chip {
    display: inline-flex;
    flex: 0 0 auto;
    padding: 4px 8px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.66rem;
    font-weight: 760;
    white-space: nowrap;
}

.chart-evidence-high { border-color: color-mix(in srgb, var(--color-good) 35%, var(--color-border)); color: var(--color-good-dark); }
.chart-evidence-low { border-color: color-mix(in srgb, #d49a25 38%, var(--color-border)); color: #8a6418; }

.chart-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}

.chart-tool {
    min-height: 32px;
    padding: 5px 10px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text-muted);
    cursor: pointer;
    font: inherit;
    font-size: 0.7rem;
    font-weight: 700;
}

.chart-tool:hover,
.chart-tool:focus-visible,
.chart-tool[aria-pressed="true"] {
    border-color: var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
    color: var(--color-primary-dark);
}

.chart-experience > .trend-chart,
.chart-experience > .workout-pace-graph {
    width: 100%;
    min-height: 220px;
}

.chart-selection {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 35px;
    margin-top: 7px;
    padding: 8px 10px;
    border-radius: 10px;
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
}

.chart-drilldown {
    flex: 0 0 auto;
    color: var(--color-primary);
    font-weight: 740;
    text-decoration: none;
}

.chart-focus-mode,
.chart-experience:fullscreen {
    display: flex;
    width: min(1200px, 100vw);
    height: 100vh;
    justify-content: center;
    flex-direction: column;
    margin: 0 auto;
    padding: clamp(16px, 4vw, 42px);
    border: 0;
    border-radius: 0;
    background: var(--color-bg);
}

.chart-focus-mode > .trend-chart,
.chart-focus-mode > .workout-pace-graph {
    min-height: min(62vh, 620px);
}

.chart-subplot-label {
    margin: 18px 0 0;
    color: var(--color-text-muted);
    font-size: 0.72rem;
    font-weight: 760;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.trend-chart-secondary {
    min-height: 175px;
}

.chart-confidence-band {
    fill: color-mix(in srgb, var(--color-series) 13%, transparent);
    stroke: none;
}

.chart-week-marker-adjustment { fill: #6a3fb3; }
.chart-week-marker-injury { fill: #b3261e; }
.chart-week-marker-interruption { fill: #b3721f; }

/* Non-colour encoding: planned/estimated marks remain distinguishable in
   monochrome and for common colour-vision deficiencies. */
.chart-bar-planned-easy,
.chart-bar-planned-hard {
    stroke: var(--color-text-muted);
    stroke-width: 0.45;
    stroke-dasharray: 2 1;
}

@media (max-width: 700px) {
    #workout-modal {
        align-items: flex-end;
        padding: 0;
    }

    #workout-modal .modal-dialog-workout {
        width: 100%;
        max-height: calc(100dvh - env(safe-area-inset-top));
        margin: 0;
        border-radius: 22px 22px 0 0;
    }

    #workout-modal .modal-body {
        padding-inline: 14px;
    }

    #workout-modal .modal-footer {
        padding-bottom: calc(12px + env(safe-area-inset-bottom));
    }

    #workout-modal .modal-tablist {
        position: sticky;
        top: 0;
        z-index: 3;
        overflow-x: auto;
        background: var(--color-surface);
        scrollbar-width: none;
    }

    #workout-modal .modal-tab {
        min-width: max-content;
    }

    .workout-comparison-table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
    }

    .workout-segment-track {
        overflow-x: auto;
    }

    .chart-experience {
        margin-inline: -4px;
        padding: 11px;
        border-radius: 14px;
    }

    .chart-insight-header {
        flex-direction: column;
        gap: 8px;
    }

    .chart-toolbar {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 2px;
        scrollbar-width: none;
    }

    .chart-tool {
        flex: 0 0 auto;
        min-height: 38px;
    }

    .chart-selection {
        align-items: flex-start;
        flex-direction: column;
    }
}

/* --- Print: a month view worth putting on the fridge ------------------- */
@media print {
    .site-header,
    .site-footer,
    /* .dashboard-actions covers the agenda toggle and "Log today's
       status" too — both moved into that cluster. */
    .dashboard-actions,
    /* Training Load and Recovery Status used to live in their own
       .dashboard-section-diagnostics wrapper, which this rule hid as one
       unit. They're inline cards now (see plan_calendar.html) — hidden
       individually here so a print of "a month view worth putting on the
       fridge" doesn't also print two dozen progress bars. */
    .load-status-card,
    .wellness-status-card,
    .dashboard-section-community,
    .chart-range-control,
    .modal-overlay {
        display: none !important;
    }

    .calendar-day {
        min-height: 78px;
        break-inside: avoid;
    }

    .calendar-grid {
        break-inside: avoid;
    }

    a[href]::after {
        content: "";
    }
}

/* --- Form wizard (form-wizard.js) -------------------------------------- */

/* A progress strip over the plan builder's three steps. Every step is a
   real button — this is one form, not a gated funnel, so someone who
   only wants to change their race date can jump straight there. */
.form-wizard-progress {
    display: flex;
    gap: 8px;
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    counter-reset: none;
}

.form-wizard-progress-item {
    flex: 1 1 0;
    min-width: 0;
}

.form-wizard-progress-button {
    display: flex;
    align-items: baseline;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    /* The active step is marked by a top rule rather than a fill, so the
       three steps stay equally legible. */
    border-top-width: 3px;
    border-top-style: solid;
    border-top-color: var(--color-border);
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.8rem;
    text-align: left;
    cursor: pointer;
}

.form-wizard-progress-button:hover {
    border-color: var(--color-primary-dark);
    border-top-color: var(--color-primary-dark);
}

.form-wizard-progress-button.is-current {
    background: #fff;
    border-top-color: var(--color-primary-dark);
    color: var(--color-text);
    font-weight: 600;
}

.form-wizard-progress-button.is-complete .form-wizard-progress-number {
    background: var(--color-primary-dark);
    color: var(--color-on-primary);
}

.form-wizard-progress-number {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--color-border);
    color: var(--color-text);
    font-size: 0.7rem;
    font-weight: 700;
}

.form-wizard-progress-label {
    flex: 1 1 auto;
    min-width: 0;
}

.form-wizard-progress-optional {
    flex: 0 0 auto;
    font-size: 0.65rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--color-text-muted);
}

.form-wizard-nav {
    display: flex;
    gap: 10px;
    margin: 20px 0 12px;
}

@media (max-width: 640px) {
    /* Numbers only below this width — three text labels side by side
       wrap into three illegible stacks. */
    .form-wizard-progress-label,
    .form-wizard-progress-optional {
        display: none;
    }

    .form-wizard-progress-button {
        justify-content: center;
    }
}

/* An invalid field can be far off-screen on a form this long, so the
   errors are also listed at the top with links into them. */
.form-error-summary {
    margin: 0 0 20px;
    padding: 12px 16px;
    background: #fdece3;
    border: 1px solid #b3261e;
    border-radius: var(--radius);
}

.form-error-summary-heading {
    margin: 0 0 6px;
    font-size: 0.85rem;
    font-weight: 600;
    color: #b3261e;
}

.form-error-summary ul {
    margin: 0;
    padding-left: 20px;
    font-size: 0.85rem;
}

.form-error-summary a {
    color: #b3261e;
}

/* --- Unified metric-detail modal (modalShell.buildMetricDetail) -------- */

/* The wellness, load and fitness-zone modals all present "a metric, its
   value, its history and an explanation". This is the one headline row
   they share, so they read as one family. */
.modal-metric-headline {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 4px;
}

.modal-metric-value {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

/* --- Auto-regulation cards (auto_regulation.py) ------------------------ */

/* Direction is carried by a left rule rather than a fill: these sit above
   the Day Summary, and three filled cards stacked would shout. */
.auto-reg-card {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-border);
    border-radius: var(--radius);
    padding: 14px 18px;
    margin: 0 0 16px;
    margin-top: 16px;
}

.auto-reg-card-decrease {
    border-left-color: #b3521f;
}

.auto-reg-card-increase {
    border-left-color: var(--color-good-dark);
}

/* A recovery-routine badge_class
   ("elevated"/"moderate"/"low", see body_map.OUTCOME_BADGE_CLASSES) is a
   different vocabulary from a recommendation's "decrease"/"increase"
   direction, so it gets its own left-rule colors rather than being forced
   into that pair. */
.auto-reg-card-elevated {
    border-left-color: #b3261e;
}

.auto-reg-card-moderate {
    border-left-color: #b3941f;
}

.auto-reg-card-low {
    border-left-color: var(--color-good);
}

/* "Current Status": tomorrow's intensity guidance and today's body-map
   check-in, merged into one card (see plan_calendar.html). The outer
   card is a plain shell; each .current-status-block inside it carries
   its own left-rule accent — same convention as .auto-reg-card, just
   nested, since the two blocks can each be in a different state
   (decrease/increase for the daily recommendation, elevated/moderate/low
   for the recovery routine) at the same time. */
.current-status-card {
    background: var(--color-surface, var(--color-bg-alt));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg, 16px);
    padding: 18px;
    margin-top: 16px;
    box-shadow: 0 12px 32px color-mix(in srgb, #14251d 7%, transparent);
}

.current-status-overview {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.95rem 1rem;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: 12px;
    background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 7%, var(--color-surface, #fff)), var(--color-surface, #fff) 62%);
}

.current-status-overview-elevated { border-left-color: #b3521f; background: linear-gradient(135deg, color-mix(in srgb, #b3521f 8%, var(--color-surface, #fff)), var(--color-surface, #fff) 62%); }
.current-status-overview-moderate { border-left-color: #b3721f; background: linear-gradient(135deg, color-mix(in srgb, #b3721f 8%, var(--color-surface, #fff)), var(--color-surface, #fff) 62%); }
.current-status-overview-neutral { border-left-color: var(--color-text-muted); background: var(--color-bg-alt); }
.current-status-verdict { min-width: 0; }
.current-status-eyebrow { display: block; margin-bottom: 0.25rem; color: var(--color-text-muted); font-size: 0.68rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; }
.current-status-verdict-line { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.current-status-verdict-line h2 { margin: 0; font-size: clamp(1.1rem, 2vw, 1.4rem); line-height: 1.2; }
.current-status-verdict p { max-width: 62rem; margin: 0.35rem 0 0; color: var(--color-text-muted); font-size: 0.88rem; line-height: 1.45; }
.current-status-primary-action { flex: none; }
.current-status-primary-action .button { white-space: nowrap; }

.current-status-freshness {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.45rem;
    margin: 0.65rem 0 0.8rem;
}

.current-status-freshness-item {
    min-width: 0;
    padding: 0.45rem 0.55rem;
    border-radius: 9px;
    background: var(--color-bg-alt);
}

.current-status-freshness-item small,
.current-status-freshness-item strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.current-status-freshness-item small { color: var(--color-text-muted); font-size: 0.64rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; }
.current-status-freshness-item strong { margin-top: 0.08rem; font-size: 0.75rem; font-weight: 700; }
.current-status-freshness-item.is-missing strong { color: var(--color-text-muted); font-weight: 600; }

.current-status-conflict {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.2rem 0.6rem;
    margin-bottom: 0.8rem;
    padding: 0.65rem 0.75rem;
    border-radius: 9px;
    background: color-mix(in srgb, #d49a25 10%, var(--color-surface, #fff));
    color: var(--color-text);
    font-size: 0.8rem;
}
.current-status-conflict::before { content: "↔"; grid-row: 1 / span 2; color: #9a6a13; font-weight: 900; }
.current-status-conflict span { color: var(--color-text-muted); }
.current-status-post-race { margin: 0 0 0.8rem; padding: 0.65rem 0.75rem; border: 1px solid var(--color-border); border-radius: 9px; }
.current-status-post-race summary, .current-status-details summary { cursor: pointer; font-size: 0.8rem; font-weight: 750; }
.current-status-post-race p { margin: 0.55rem 0 0; font-size: 0.82rem; }

/* Two readings of the same moment, side by side: the body-map check-in
   and the intensity recommendation are drawn from different data and
   neither follows from the other, so stacking them with a divider
   implied a sequence that isn't there.

   Equal columns rather than auto-sized, so the pair doesn't reflow every
   time one side gains a flagged region or an override note. Collapses to
   a single column below the breakpoint, where side-by-side would leave
   each column too narrow to read. */
.current-status-columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.7rem;
}

.current-status-column > div {
    height: 100%;
    padding: 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 11px;
    background: var(--color-bg-alt);
}

.current-status-column .auto-reg-card-decrease { border-left: 3px solid #b3521f; }
.current-status-column .auto-reg-card-increase,
.current-status-column .auto-reg-card-hold,
.current-status-column .auto-reg-card-low { border-left: 3px solid var(--color-good); }
.current-status-column .auto-reg-card-moderate { border-left: 3px solid #b3941f; }
.current-status-column .auto-reg-card-elevated { border-left: 3px solid #b3261e; }
.current-status-summary-tile .auto-reg-headline { min-height: 2.7em; }
.current-status-tile-meta { display: inline-flex; align-items: center; gap: 0.45rem; }
.current-status-inline-action { color: var(--color-primary); font-size: 0.72rem; font-weight: 750; text-decoration: none; }
.current-status-inline-action:hover, .current-status-inline-action:focus-visible { text-decoration: underline; }
.current-status-details { margin-top: 0.65rem; padding-top: 0.55rem; border-top: 1px solid var(--color-border); }
.current-status-details[open] > summary { margin-bottom: 0.7rem; }
.current-status-routine-content { display: grid; gap: 0.7rem; }

@media (max-width: 860px) {
    .current-status-overview { align-items: stretch; flex-direction: column; }
    .current-status-primary-action .button { width: 100%; }
    .current-status-freshness { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .current-status-freshness-item:last-child { grid-column: 1 / -1; }
    .current-status-columns {
        grid-template-columns: 1fr;
        gap: 0.6rem;
    }
}

@media (max-width: 480px) {
    .current-status-card { padding: 0.7rem; }
    .current-status-overview { padding: 0.75rem; }
    .current-status-freshness { grid-template-columns: 1fr 1fr; gap: 0.35rem; }
    .current-status-conflict { grid-template-columns: auto minmax(0, 1fr); }
}

.current-status-subtitle {
    margin: 0;
    font-size: 1rem;
}

.auto-reg-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.auto-reg-header .subsection-title {
    margin: 0;
}

.auto-reg-headline {
    margin: 6px 0 0;
    font-size: 0.95rem;
}

.auto-reg-advice {
    margin: 8px 0 0;
    font-size: 0.875rem;
}

/* When the plan's own periodization overrules the signals, or a reported
   injury floors the recommendation — the runner should see that a
   judgement was applied on top of the arithmetic. */
.auto-reg-override {
    margin: 8px 0 0;
    padding: 8px 10px;
    background: #fdf1e3;
    border-radius: var(--radius);
    font-size: 0.8rem;
    color: #7a4d12;
}

.auto-reg-signals {
    margin-top: 10px;
    font-size: 0.8rem;
}

.auto-reg-signals summary {
    cursor: pointer;
    color: var(--color-text-muted);
}

.auto-reg-thin {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #fdf1e3;
    color: #b3721f;
    font-size: 0.7rem;
    text-transform: uppercase;
}

.auto-reg-signal-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
}

.auto-reg-signal {
    display: grid;
    grid-template-columns: minmax(120px, auto) minmax(60px, auto) 1fr;
    gap: 4px 12px;
    align-items: baseline;
    padding: 6px 0;
    border-top: 1px solid var(--color-border);
}

.auto-reg-signal-name {
    font-weight: 600;
}

.auto-reg-signal-value {
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.auto-reg-signal-reading {
    color: var(--color-text-muted);
}

.auto-reg-signal-decrease .auto-reg-signal-value {
    color: #b3521f;
}

.auto-reg-signal-increase .auto-reg-signal-value {
    color: var(--color-good-dark);
}

/* A reading that was noticed and deliberately not counted — struck
   through rather than hidden, so the recommendation stays auditable. */
.auto-reg-signal-suppressed .auto-reg-signal-value {
    text-decoration: line-through;
    color: var(--color-text-muted);
}

@media (max-width: 640px) {
    .auto-reg-signal {
        grid-template-columns: 1fr auto;
    }

    .auto-reg-signal-reading {
        grid-column: 1 / -1;
    }
}

/* --- Refresh preview modal -------------------------------------------- */

/* The adjustment options. A vertical list rather than a segmented row:
   each one carries a sentence explaining what it does, and the runner is
   choosing between substantively different actions, not toggling a
   setting. Nothing here applies on selection — picking an option only
   previews it. */
.refresh-options {
    margin: 0 0 14px;
    padding: 0;
    border: none;
}

.refresh-options-legend {
    padding: 0;
    margin: 0 0 8px;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.refresh-option {
    display: block;
    width: 100%;
    margin: 0 0 6px;
    padding: 10px 12px;
    text-align: left;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.refresh-option:hover {
    background: var(--color-bg-alt);
}

.refresh-option.is-selected {
    border-color: var(--color-primary);
    background: #e4f5ea;
}

.refresh-option-label {
    display: block;
    font-size: 0.9rem;
    font-weight: 600;
}

.refresh-option-suggested {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #fdf1e3;
    color: #b3721f;
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.refresh-option-description {
    display: block;
    margin-top: 2px;
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

/* Scope picker: this week only, or the whole remainder. A segmented pair
   rather than a <select>, because there are exactly two options and the
   choice changes the numbers directly below it — it should read as part of
   the preview, not as a form control detached from it. */
.refresh-scope {
    display: flex;
    gap: 0;
    margin: 0 0 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.refresh-scope-option {
    flex: 1 1 0;
    padding: 8px 12px;
    background: var(--color-bg);
    border: none;
    font: inherit;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.refresh-scope-option + .refresh-scope-option {
    border-left: 1px solid var(--color-border);
}

.refresh-scope-option:hover {
    background: var(--color-bg-alt);
}

.refresh-scope-option.is-selected {
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-weight: 600;
}

.refresh-verdict {
    margin: 0 0 14px;
    font-size: 0.9rem;
}

.refresh-verdict-noop {
    color: var(--color-text-muted);
}

.refresh-protected-day {
    margin: 0 0 14px;
    padding: 10px 12px;
    border-left: 3px solid var(--color-primary);
    border-radius: 4px;
    background: #e4f5ea;
    font-size: 0.88rem;
}

.refresh-day-changes {
    margin: 0 0 16px;
    overflow-x: auto;
}

.refresh-day-changes h4 {
    margin: 0 0 8px;
    font-size: 0.9rem;
}

.refresh-day-change-table {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.refresh-day-change-table th,
.refresh-day-change-table td {
    padding: 9px 10px;
    border: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}

.refresh-day-change-table thead th {
    background: var(--color-bg-alt);
    color: var(--color-text-muted);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.refresh-day-change-table tbody th {
    width: 105px;
    white-space: nowrap;
}

.refresh-change-date {
    display: block;
    margin-top: 2px;
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 400;
}

.refresh-change-entry + .refresh-change-entry {
    margin-top: 7px;
    padding-top: 7px;
    border-top: 1px solid var(--color-border);
}

.refresh-change-segments {
    margin-top: 4px;
    color: var(--color-text-muted);
}

.refresh-change-segments summary {
    cursor: pointer;
}

.refresh-change-segments ul {
    margin: 4px 0 0;
    padding-left: 18px;
}

.refresh-change-empty,
.refresh-day-changes-empty {
    color: var(--color-text-muted);
}

.refresh-day-changes-empty {
    margin: 0 0 14px;
    font-size: 0.88rem;
}

.refresh-diff {
    margin: 0 0 14px;
}

.refresh-diff-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 0;
    border-top: 1px solid var(--color-border);
}

.refresh-diff dt {
    font-size: 0.85rem;
    font-weight: 600;
}

.refresh-diff dd {
    margin: 0;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.refresh-from {
    color: var(--color-text-muted);
}

.refresh-arrow {
    margin: 0 4px;
    color: var(--color-text-muted);
}

.refresh-to {
    font-weight: 700;
}

.refresh-delta {
    margin-left: 4px;
    color: var(--color-text-muted);
}

@media (max-width: 480px) {
    .refresh-diff-row {
        flex-direction: column;
        gap: 2px;
    }

    .refresh-diff dd {
        text-align: left;
    }
}

/* --- Race execution plan + fuelling (race_execution.py, fueling.py) --- */

.workout-race-plan,
.workout-fueling-section {
    margin-top: 16px;
}

/* Each part of the race plan as its own block: warm-up, splits,
   contingencies, fuelling. Separated by rules rather than boxed, so the
   modal doesn't become a stack of cards. */
.race-plan-block {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}

.race-plan-heading {
    font-size: 0.875rem;
    margin: 0 0 6px;
}

.race-plan-list {
    margin: 0 0 6px;
    padding-left: 20px;
    font-size: 0.85rem;
}

.race-plan-splits {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.race-plan-splits th,
.race-plan-splits td {
    padding: 4px 8px;
    text-align: right;
    border-bottom: 1px solid var(--color-border);
}

.race-plan-splits th:first-child,
.race-plan-splits td:first-child {
    text-align: left;
}

.race-plan-splits th {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

/* The finish row is the number the whole table exists to reach. */
.race-plan-finish td {
    font-weight: 700;
    border-bottom: none;
}

/* Whether the app's own advice has been worth taking. */
.recommendation-check {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--color-border);
}

/* --- Body map (body_map.py, body-map.js) ------------------------------- */

.body-map-views {
    display: flex;
    gap: 20px;
    justify-content: center;
    flex-wrap: wrap;
    margin: 12px 0;
}

.body-map-view {
    margin: 0;
    text-align: center;
}

.body-map-view figcaption {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    margin-bottom: 4px;
}

.body-map-svg {
    width: 150px;
    max-width: 40vw;
    height: auto;
}

/* The figure exists to orient the hit areas, not to be a medical
   illustration — a single supplied standing-figure outline, drawn as an
   outline rather than the source asset's solid black fill so it reads as
   a diagram backdrop, not a silhouette competing with the hit-area
   highlighting on top of it. Theme-aware via the same custom properties
   as the rest of the app. */
.body-map-segments path {
    fill: none;
    stroke: var(--color-text-muted);
    stroke-width: 1.5;
    stroke-linejoin: round;
}

.body-map-hit {
    fill: transparent;
    stroke: transparent;
    cursor: pointer;
}

.body-map-hit:hover,
.body-map-hit:focus-visible {
    fill: rgba(31, 122, 77, 0.18);
    stroke: var(--color-primary-dark);
    stroke-width: 1;
    outline: none;
}

/* Marked regions are colour-coded by kind, which is the distinction
   everything downstream turns on. */
.body-map-hit.is-soreness {
    fill: rgba(31, 79, 179, 0.3);
    stroke: #1f4fb3;
    stroke-width: 1;
}

.body-map-hit.is-pain {
    fill: rgba(179, 82, 31, 0.35);
    stroke: #b3521f;
    stroke-width: 1.5;
}

/* The list equivalent: shown instead of the diagram on narrow screens,
   where tapping a 25px SVG rect is miserable, and always available to a
   keyboard. */
.body-map-region-list {
    margin-top: 12px;
}

.body-map-region-group {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 8px 10px;
    margin: 0 0 8px;
}

.body-map-region-group legend {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.body-map-region-button {
    display: inline-block;
    margin: 2px;
    padding: 4px 10px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.body-map-region-button.is-soreness {
    background: #e8f0fb;
    border-color: #1f4fb3;
    color: #1f4fb3;
}

.body-map-region-button.is-pain {
    background: #fdeee3;
    border-color: #b3521f;
    color: #b3521f;
}

@media (min-width: 701px) {
    /* The diagram is the primary interaction on a pointer device; the
       list stays in the DOM for keyboards and is collapsed to a
       secondary affordance rather than removed. */
    .body-map-region-list {
        font-size: 0.75rem;
    }
}

@media (max-width: 700px) {
    .body-map-views {
        display: none;
    }
}

/* --- The marked-region cards ------------------------------------------- */

.body-map-marks {
    margin: 14px 0;
}

.body-map-mark {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 10px 12px;
    margin-bottom: 10px;
}

.body-map-mark-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.body-map-mark-label {
    font-weight: 600;
    font-size: 0.9rem;
}

.body-map-mark-remove {
    background: none;
    border: none;
    color: var(--color-text-muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.body-map-kind-row,
.body-map-severity-row,
.body-map-answer-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    flex-wrap: wrap;
}

.body-map-kind-button,
.body-map-severity-button,
.body-map-answer-button {
    padding: 4px 12px;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

.body-map-severity-button {
    min-width: 32px;
    font-variant-numeric: tabular-nums;
}

.body-map-kind-button[aria-pressed="true"],
.body-map-severity-button[aria-pressed="true"],
.body-map-answer-button[aria-pressed="true"] {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
    color: var(--color-on-primary);
    font-weight: 600;
}

/* Painful is the consequential choice; it reads differently when made. */
.body-map-kind-button[data-kind="pain"][aria-pressed="true"] {
    background: #b3521f;
    border-color: #b3521f;
}

.body-map-severity-label {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

/* The screening questions. Set apart, because answering them honestly
   is the point and they shouldn't read as more optional chrome. */
.body-map-screen {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--color-border);
}

.body-map-screen-intro {
    margin: 0 0 8px;
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

.body-map-question {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
}

.body-map-question-prompt {
    font-size: 0.8rem;
}

.body-map-question .body-map-answer-row {
    margin-top: 0;
    flex: 0 0 auto;
}

@media (max-width: 480px) {
    .body-map-question {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
    }
}

/* --- The generated routine --------------------------------------------- */

.recovery-routine-card .recovery-flagged {
    margin-top: 12px;
    padding: 12px 14px;
    background: #fdece3;
    border: 1px solid #b3521f;
    border-radius: var(--radius);
}

.recovery-flagged-label {
    margin: 0 0 6px;
    font-size: 0.9rem;
    color: #8f3f18;
}

.recovery-flagged-reasons {
    margin: 0;
    padding-left: 18px;
    font-size: 0.8rem;
}

.recovery-section {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}

.recovery-section-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 6px;
    font-size: 0.9rem;
}

.recovery-heading {
    margin: 10px 0 4px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    text-transform: uppercase;
}

.recovery-meta,
.recovery-note,
.recovery-modality {
    display: block;
    font-size: 0.72rem;
    color: var(--color-text-muted);
}

.recovery-modality {
    display: inline;
    margin-left: 6px;
    font-weight: 400;
}

/* The prompt shown inside the "How you're feeling" block of
   .current-status-card when nothing has been reported today. */
.body-map-prompt-text {
    margin: 8px 0 0;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.body-map-prompt-text strong {
    color: var(--color-text);
}

.body-map-prompt-action {
    margin: 12px 0 0;
}

/* The check-in needs more width than a standard dialog: two body
   diagrams side by side plus the marked-region cards. */
.modal-dialog-wide {
    max-width: 680px;
}

/* Marks an exercise as training something running specifically depends
   on, rather than general gym work. The flag drives selection too (see
   recovery_routines._sorted_by_load), so showing it explains why these
   came first. */
.recovery-tag {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #e4f5ea;
    color: var(--color-primary-dark);
    font-size: 0.62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    vertical-align: middle;
}

/* --- Plan suggestions -----------------------------------------------
   Proposals the runner can accept or decline. Nothing here is a change
   that has happened — the visual weight is deliberately closer to a
   notice than to an alert, because an app that shouts every time it has
   an idea trains people to stop reading it. See plan_suggestions.py. */

.badge-count {
    display: inline-block;
    min-width: 1.35rem;
    padding: 0 0.35rem;
    margin-left: 0.4rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.35);
    font-size: 0.8em;
    font-weight: 600;
    text-align: center;
}

.suggestion-preamble {
    margin: 0 0 1rem;
    padding: 0.6rem 0.8rem;
    border-radius: 6px;
    background: #f4f7fa;
    color: var(--color-text-muted, #5a6672);
    font-size: 0.9rem;
}

.suggestion-category + .suggestion-category {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-border);
}

.suggestion-category-title {
    margin: 0;
    font-size: 1.1rem;
}

.suggestion-category-description {
    margin: 0.25rem 0 0.75rem;
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.suggestion-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.suggestion {
    border: 1px solid var(--color-border, #dfe4e8);
    border-left-width: 4px;
    border-radius: 8px;
    padding: 0.9rem 1rem;
}

.suggestion-attention {
    border-left-color: #b3721f;
}

.suggestion-info {
    border-left-color: #8a97a3;
}

.suggestion-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.suggestion-title {
    margin: 0;
    font-size: 1.02rem;
}

.suggestion-summary {
    margin: 0.5rem 0 0.75rem;
}

.suggestion-reasons {
    margin: 0 0 0.75rem;
    padding: 0.6rem 0.8rem;
    border-radius: 6px;
    background: #fafbfc;
    font-size: 0.9rem;
}

.suggestion-reasons dt {
    font-weight: 600;
}

.suggestion-reasons dd {
    margin: 0 0 0.5rem;
    color: var(--color-text-muted, #5a6672);
}

.suggestion-reasons dd:last-child {
    margin-bottom: 0;
}

.suggestion-diff {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
}

.suggestion-diff caption {
    text-align: left;
    padding-bottom: 0.35rem;
    color: var(--color-text-muted, #5a6672);
    font-size: 0.85rem;
}

.suggestion-diff th,
.suggestion-diff td {
    text-align: left;
    padding: 0.3rem 0.5rem 0.3rem 0;
    border-bottom: 1px solid var(--color-border, #eef1f4);
}

.suggestion-delta {
    font-size: 0.8em;
    color: var(--color-text-muted, #5a6672);
}

.suggestion-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.suggestion-footnote {
    margin: 0.5rem 0 0;
    color: var(--color-text-muted, #5a6672);
    font-size: 0.82rem;
}

/* --- Post-race recovery ---------------------------------------------
   Shown once the race has been run, when the plan itself has nothing
   left to say. See post_race.py. */

.post-race-card {
    margin-bottom: 1.25rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--color-border, #dfe4e8);
    border-left: 4px solid var(--color-primary, #2f7d55);
    border-radius: 8px;
    background: #f7fbf8;
}

.post-race-phase {
    margin: 0.35rem 0;
}

.post-race-window {
    margin-left: 0.5rem;
    color: var(--color-text-muted, #5a6672);
    font-size: 0.9rem;
}

.post-race-guidance {
    margin: 0 0 0.6rem;
}

.post-race-next-plan,
.post-race-caveat {
    margin: 0 0 0.4rem;
    color: var(--color-text-muted, #5a6672);
    font-size: 0.88rem;
}

/* --- Plan adjustment review ----------------------------------------- */
.weekly-review-cadence {
    margin: 0.55rem 0 0;
    color: var(--text-muted, var(--color-text-muted, #5a6672));
    font-size: 0.84rem;
}

.urgent-advice-card {
    /* Was a flex row; now a column, because the inline preview dropdown
       opens underneath the headline + actions rather than beside them. */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin-bottom: 1rem;
    padding: 1rem 2.4rem 1rem 1rem;
    border: 1px solid color-mix(in srgb, #c45145 48%, var(--border, #dfe4e8));
    border-left: 4px solid #c45145;
    border-radius: var(--radius-lg, 14px);
    background: color-mix(in srgb, #c45145 7%, var(--surface, #fff));
    margin-top: 16px;
}

.urgent-advice-card h2,
.urgent-advice-card p { margin: 0.2rem 0; }
.urgent-advice-label { color: #a33b32; font-size: 0.76rem; font-weight: 750; letter-spacing: 0.06em; text-transform: uppercase; }
.urgent-advice-actions { display: flex; flex-wrap: wrap; gap: 0.45rem; }

.adjustment-workflow {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.45rem;
    margin: 0 0 1rem;
    padding: 0;
    list-style: none;
}

.adjustment-workflow li {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0.7rem;
    border-radius: 999px;
    background: var(--surface-subtle, #f3f6f5);
    color: var(--text-muted, #5a6672);
    font-size: 0.82rem;
    font-weight: 700;
}

.adjustment-workflow li span {
    display: grid;
    width: 1.45rem;
    height: 1.45rem;
    place-items: center;
    border-radius: 50%;
    background: var(--surface, #fff);
}

.adjustment-workflow li.is-active { background: color-mix(in srgb, var(--accent, #2f7d55) 14%, var(--surface, #fff)); color: var(--accent, #2f7d55); }
.adjustment-step { margin: 0 0 1rem; padding: 1rem; border: 1px solid var(--border, #dfe4e8); border-radius: var(--radius-lg, 14px); background: var(--surface, #fff); }
.adjustment-step h3 { margin: 0.1rem 0 0.55rem; }
.adjustment-impact-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.55rem; }
.adjustment-impact-grid article { padding: 0.7rem; border: 1px solid var(--border, #dfe4e8); border-radius: 10px; background: var(--surface-subtle, #f7f9f8); }
.adjustment-impact-grid article > span { display: block; color: var(--text-muted, #5a6672); font-size: 0.76rem; }
.adjustment-confidence { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.7rem; color: var(--text-muted, #5a6672); font-size: 0.82rem; }
.adjustment-confidence-value { padding: 0.18rem 0.5rem; border-radius: 999px; background: color-mix(in srgb, var(--accent, #2f7d55) 12%, var(--surface, #fff)); color: var(--accent, #2f7d55); font-size: 0.73rem; }
.adjustment-confidence-low { background: color-mix(in srgb, #d49a25 12%, var(--surface, #fff)); color: #8a6418; }
.adjustment-confidence small { margin-left: auto; font-size: 0.74rem; }
.adjustment-evidence-table-wrap { overflow: hidden; border: 1px solid var(--border, #dfe4e8); border-radius: 10px; }
.adjustment-evidence-table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 0.8rem; }
.adjustment-evidence-table caption { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.adjustment-evidence-table th, .adjustment-evidence-table td { padding: 0.55rem 0.65rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border, #dfe4e8); }
.adjustment-evidence-table thead th { background: var(--surface-subtle, #f7f9f8); color: var(--text-muted, #5a6672); font-size: 0.68rem; letter-spacing: 0.04em; text-transform: uppercase; }
.adjustment-evidence-table thead th:nth-child(1) { width: 22%; }
.adjustment-evidence-table thead th:nth-child(2) { width: 38%; }
.adjustment-evidence-table thead th:nth-child(3) { width: 24%; }
.adjustment-evidence-table thead th:nth-child(4) { width: 16%; }
.adjustment-evidence-table tbody tr:last-child > * { border-bottom: 0; }
.adjustment-evidence-table tbody tr.is-direct th:first-child { box-shadow: inset 3px 0 0 var(--accent, #2f7d55); }
.adjustment-evidence-note, .adjustment-source { display: block; margin-top: 0.14rem; color: var(--text-muted, #5a6672); font-size: 0.72rem; line-height: 1.35; }
.adjustment-source.is-direct { color: var(--accent, #2f7d55); font-weight: 700; }
.adjustment-influence { display: inline-flex; padding: 0.17rem 0.45rem; border-radius: 999px; background: var(--surface-subtle, #f7f9f8); color: var(--text-muted, #5a6672); font-size: 0.68rem; font-weight: 750; }
.adjustment-influence-high { background: color-mix(in srgb, #c45145 10%, var(--surface, #fff)); color: #a33b32; }
.adjustment-influence-medium { background: color-mix(in srgb, #d49a25 11%, var(--surface, #fff)); color: #7d5b17; }
.adjustment-conflicts, .adjustment-escalation { margin-top: 0.65rem; padding: 0.7rem; border-radius: 10px; background: color-mix(in srgb, #d49a25 10%, var(--surface, #fff)); }
.adjustment-conflicts ul, .adjustment-escalation ul, .adjustment-missing ul { margin: 0.35rem 0 0; padding-left: 1.1rem; }
.adjustment-missing { margin-top: 0.55rem; }
.refresh-scope-option.is-major::after { content: "Extra confirmation"; display: block; font-size: 0.65rem; font-weight: 500; opacity: 0.72; }
.counterproposal-editor { margin-top: 0.8rem; padding: 0.7rem; border: 1px solid var(--border, #dfe4e8); border-radius: 10px; }
.counterproposal-editor summary { cursor: pointer; font-weight: 700; }
.counterproposal-fields { display: grid; gap: 0.6rem; margin-top: 0.75rem; }
.counterproposal-fields input[type="number"] { width: 5rem; margin: 0 0.3rem; }
.adjustment-impact-grid { margin: 0.7rem 0; }
.adjustment-impact-grid article strong { display: block; margin-top: 0.2rem; font-size: 0.9rem; }
.adjustment-impact-intensity { grid-column: 1 / -1; }
.adjustment-lock-date { display: flex; align-items: center; gap: 0.25rem; margin-top: 0.4rem; color: var(--text-muted, #5a6672); font-size: 0.7rem; font-weight: 600; }
.adjustment-confirm-check { display: flex; align-items: start; gap: 0.5rem; margin: 0.55rem 0; font-weight: 650; }
.adjustment-confirm-major { padding: 0.6rem; border-radius: 8px; background: color-mix(in srgb, #d49a25 10%, var(--surface, #fff)); }
.adjustment-history { margin: 0.75rem 0; }
.adjustment-history > summary { cursor: pointer; font-weight: 700; }
.adjustment-history ul { padding: 0; list-style: none; }
.adjustment-history li { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.6rem 0; border-bottom: 1px solid var(--border, #dfe4e8); }
.adjustment-history li span, .suggestion-evidence-summary span { display: block; color: var(--text-muted, #5a6672); font-size: 0.78rem; }
.suggestion-evidence-summary { margin: 0.65rem 0; padding: 0.65rem; border-radius: 9px; background: var(--surface-subtle, #f7f9f8); }
.suggestion-impact-grid { margin-bottom: 0.8rem; }

@media (max-width: 700px) {
    .urgent-advice-card { align-items: stretch; flex-direction: column; }
    .urgent-advice-actions .button { flex: 1 1 100%; }
    .adjustment-workflow li { justify-content: center; padding-inline: 0.35rem; font-size: 0.73rem; }
    .adjustment-impact-grid { grid-template-columns: 1fr; }
    .adjustment-confidence { align-items: flex-start; flex-wrap: wrap; }
    .adjustment-confidence small { flex-basis: 100%; margin-left: 0; }
    .adjustment-evidence-table-wrap { border: 0; overflow: visible; }
    .adjustment-evidence-table, .adjustment-evidence-table tbody, .adjustment-evidence-table tr { display: block; }
    .adjustment-evidence-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
    .adjustment-evidence-table tr { margin-bottom: 0.5rem; padding: 0.6rem 0.7rem; border: 1px solid var(--border, #dfe4e8); border-radius: 10px; background: var(--surface-subtle, #f7f9f8); }
    .adjustment-evidence-table tbody tr.is-direct { border-left: 3px solid var(--accent, #2f7d55); }
    .adjustment-evidence-table tbody tr.is-direct th:first-child { box-shadow: none; }
    .adjustment-evidence-table th, .adjustment-evidence-table td { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 0.45rem; padding: 0.25rem 0; border: 0; }
    .adjustment-evidence-table th::before, .adjustment-evidence-table td::before { content: attr(data-label); color: var(--text-muted, #5a6672); font-size: 0.67rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; }
    .adjustment-impact-intensity { grid-column: auto; }
    .adjustment-step { padding: 0.75rem; }
    .adjustment-history li { align-items: stretch; flex-direction: column; }
}

/* --- Unified Today + Current Status card ------------------------------ */
.today-dashboard.current-status-card {
    margin-top: 18px;
}

.today-dashboard .current-status-overview {
    align-items: flex-start;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.today-dashboard .current-status-verdict-line {
    margin-top: 4px;
}

.today-dashboard .current-status-verdict p {
    max-width: 760px;
}

.today-dashboard-section-label {
    color: var(--color-text-muted);
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.evening-recovery {
    margin-top: 14px;
    padding: 14px;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: 16px;
    background: var(--color-bg-alt);
}

.evening-recovery-full { border-left-color: #b3941f; }
.evening-recovery-protect { border-left-color: #b3521f; }
.evening-recovery-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.evening-recovery-header h3 { margin: 4px 0 3px; font-size: 1rem; }
.evening-recovery-header p, .evening-recovery-reason { margin: 0; color: var(--color-text-muted); font-size: 0.78rem; line-height: 1.45; }
.evening-recovery-reason { margin-top: 7px; }
.evening-recovery-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; margin-top: 11px; }
.evening-recovery-step { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; padding: 10px; border: 1px solid var(--color-border); border-radius: 11px; background: var(--color-surface); cursor: pointer; }
.evening-recovery-step input { margin-top: 3px; }
.evening-recovery-step strong, .evening-recovery-step small, .evening-recovery-step span span { display: block; }
.evening-recovery-step strong { font-size: 0.8rem; }
.evening-recovery-step small { margin: 1px 0 3px; color: var(--color-primary); font-size: 0.68rem; font-weight: 750; }
.evening-recovery-step span span { color: var(--color-text-muted); font-size: 0.72rem; line-height: 1.4; }
.evening-recovery-tomorrow { display: grid; grid-template-columns: minmax(150px, 0.35fr) minmax(0, 1fr); gap: 12px; margin-top: 10px; padding: 10px; border-radius: 11px; background: color-mix(in srgb, var(--color-primary) 7%, var(--color-surface)); }
.evening-recovery-tomorrow span, .evening-recovery-tomorrow strong { display: block; }
.evening-recovery-tomorrow span { color: var(--color-text-muted); font-size: 0.66rem; font-weight: 750; text-transform: uppercase; }
.evening-recovery-tomorrow strong { margin-top: 2px; font-size: 0.8rem; }
.evening-recovery-tomorrow p { margin: 0; color: var(--color-text-muted); font-size: 0.76rem; line-height: 1.45; }
.evening-recovery-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; }
.evening-recovery-actions label { color: var(--color-text-muted); font-size: 0.74rem; font-weight: 700; }
.evening-recovery-actions select { margin-left: 5px; padding: 6px; }
.evening-recovery-actions > div { display: flex; gap: 7px; }
.evening-recovery-learning { margin: 10px 0 0; color: var(--color-text-muted); font-size: 0.72rem; }
.evening-recovery-learning.is-ready { color: var(--color-text); }

.today-status-details {
    margin-top: 14px;
    border-top: 1px solid var(--color-border);
}

.today-status-details > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 43px;
    cursor: pointer;
    list-style: none;
    color: var(--color-text);
    font-size: 0.8rem;
    font-weight: 780;
}

.today-status-details > summary::-webkit-details-marker,
.today-action-menu > summary::-webkit-details-marker {
    display: none;
}

.today-status-details > summary small {
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 550;
}

.today-status-details > summary::after {
    content: "⌄";
    margin-left: auto;
    color: var(--color-text-muted);
    font-size: 1rem;
    transition: transform 150ms ease;
}

.today-status-details[open] > summary::after {
    transform: rotate(180deg);
}

.today-status-details-body {
    padding: 2px 0 4px;
}

.today-plan-status {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0 0 10px;
    font-size: 0.78rem;
}

.today-status-details .current-status-freshness {
    margin-top: 0;
}

.today-dashboard .today-card-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 12px;
}

.today-card-primary-actions {
    display: flex;
    min-width: 0;
}

.today-action-menu {
    position: relative;
    flex: 0 0 auto;
}

.today-action-menu > summary {
    display: grid;
    width: 38px;
    height: 38px;
    place-items: center;
    border: 1px solid var(--color-border);
    border-radius: 11px;
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 850;
    letter-spacing: 0.08em;
}

.today-action-menu > summary:hover,
.today-action-menu > summary:focus-visible {
    border-color: var(--color-primary);
    box-shadow: 0 5px 14px color-mix(in srgb, var(--color-text) 9%, transparent);
}

.today-action-menu-popover {
    position: absolute;
    right: 0;
    bottom: calc(100% + 7px);
    z-index: 12;
    display: grid;
    min-width: 165px;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background: var(--color-surface);
    box-shadow: 0 14px 32px color-mix(in srgb, var(--color-text) 16%, transparent);
}

.today-action-menu-popover button {
    padding: 10px 13px;
    border: 0;
    border-bottom: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 680;
    text-align: left;
}

.today-action-menu-popover button:last-child {
    border-bottom: 0;
}

.today-action-menu-popover button:hover,
.today-action-menu-popover button:focus-visible {
    background: var(--color-bg-alt);
    color: var(--color-primary);
}

@media (max-width: 760px) {
    .today-dashboard .current-status-overview {
        gap: 10px;
    }

    .today-dashboard .today-dashboard-context {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .today-dashboard .today-card-actions {
        display: flex;
    }

    .evening-recovery-grid { grid-template-columns: 1fr; }
    .evening-recovery-tomorrow { grid-template-columns: 1fr; }
    .evening-recovery-actions { align-items: stretch; flex-direction: column; }
    .evening-recovery-actions > div { display: grid; grid-template-columns: 1fr 1fr; }

    .today-card-primary-actions {
        flex: 1 1 auto;
    }

    .today-dashboard .today-card-primary-actions .button {
        width: 100%;
    }
}

@media (max-width: 440px) {
    .today-status-details > summary small {
        display: none;
    }

    .today-dashboard .today-dashboard-context {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
