/* EveryMile responsive shell and color themes.
   This layer intentionally loads after style.css: the original stylesheet
   owns component identity; this file owns theme tokens and phone layout. */

:root {
    --color-surface: #ffffff;
    --color-surface-raised: #ffffff;
    --color-brand-soft: #f6ded7;
    --color-positive: #267a55;
    --color-positive-soft: #dfeee6;
    --color-warning: #b86d16;
    --color-warning-soft: #f7e3c5;
    --color-danger: #a92f28;
    --color-danger-soft: #f5d8d4;
    --color-info: #276f89;
    --color-info-soft: #dbeaf0;
    --phase-base: #477b5b;
    --phase-base-soft: #eaf1ec;
    --phase-build: #92701e;
    --phase-build-soft: #f5efdf;
    --phase-peak: #a85732;
    --phase-peak-soft: #f5e8e1;
    --phase-cutback: #3d6f86;
    --phase-cutback-soft: #e7eff2;
    --phase-taper: #6b5686;
    --phase-taper-soft: #eeeaf3;
    --calendar-grid-line: #1d1d1b;
    --radius-card: 18px;
    --radius-control: 12px;
    --radius-pill: 999px;
    --app-shadow: 0 16px 40px rgba(29, 29, 27, 0.13);
    --app-shadow-small: 0 1px 2px rgba(25, 26, 28, 0.08), 0 6px 18px rgba(25, 26, 28, 0.05);
    --tap-size: 44px;
    --mobile-nav-height: 68px;
}

html[data-theme="dark"] {
    --color-bg: #121110;
    --color-bg-alt: #181715;
    --color-surface: #22211f;
    --color-surface-raised: #2a2825;
    --color-text: #f7f5f2;
    --color-text-muted: #bdb7af;
    --color-primary: #f08a70;
    --color-primary-dark: #d9694f;
    --color-on-primary: #1d1d1b;
    --color-accent: #f2b34a;
    --color-good: #59cf94;
    --color-good-dark: #319668;
    --color-series: #6cc3e0;
    --color-border: #48433e;
    --color-brand-soft: #39221d;
    --color-positive: #59cf94;
    --color-positive-soft: #183328;
    --color-warning: #f2b34a;
    --color-warning-soft: #382b18;
    --color-danger: #ff8e86;
    --color-danger-soft: #3b211f;
    --color-info: #6cc3e0;
    --color-info-soft: #192c44;
    --phase-base: #69b787;
    --phase-base-soft: #17261e;
    --phase-build: #e0b94f;
    --phase-build-soft: #2a2418;
    --phase-peak: #e58d68;
    --phase-peak-soft: #2c1e1a;
    --phase-cutback: #72bad4;
    --phase-cutback-soft: #17252c;
    --phase-taper: #b3a0d0;
    --phase-taper-soft: #241e2c;
    --calendar-grid-line: #000000;
    --app-shadow: 0 18px 42px rgba(0, 0, 0, 0.32);
    --app-shadow-small: 0 1px 2px rgba(0, 0, 0, 0.38), 0 8px 22px rgba(0, 0, 0, 0.2);
}

html {
    background: var(--color-bg);
}

body,
.site-header,
.site-nav,
.modal-dialog,
.calendar-day-drawer {
    transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}

body {
    min-width: 0;
    background: var(--color-bg);
}

button,
input,
select,
textarea {
    color: var(--color-text);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 20px;
    min-width: 0;
}

/* .theme-toggle's own pill styling is gone with the navbar button it was
   written for. The Settings control is a .button .button-secondary and
   never used it; .theme-toggle-icon/-label below are shared and stay. */

.site-nav a:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
    outline-offset: 2px;
}

.theme-toggle-icon {
    font-size: 1.05rem;
    line-height: 1;
}

.nav-link.is-active {
    color: var(--color-primary);
    font-weight: 700;
}

.settings-display-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 10px;
}

.theme-toggle-settings {
    gap: 7px;
}

/* Dark mode: replace the remaining fixed light surfaces with semantic
   surfaces while preserving workout/status accent colors. */
html[data-theme="dark"] .site-header {
    background: rgba(18, 17, 16, 0.88);
}

html[data-theme="dark"] :is(
    .form-field input,
    .form-field select,
    .form-field textarea,
    .status-field-table select,
    .refresh-option,
    .form-wizard-progress-button.is-current,
    .modal-dialog,
    .modal-tab-panel,
    .calendar-day-drawer,
    .calendar-cell-actions-menu,
    .day-drawer-workout,
    .community-tip,
    .recovery-card,
    .zones-primary-section,
    .zones-secondary-section,
    .zones-use-card,
    .zones-calibration-card,
    .zones-methods-card
) {
    background: var(--color-surface);
}

html[data-theme="dark"] :is(
    .calendar-day,
    .agenda-day,
    .plan-summary,
    .recovery-headline,
    .chart-range-option,
    .day-drawer-workout,
    .form-wizard-progress-button.is-current
) {
    background: var(--color-surface);
}

html[data-theme="dark"] :is(
    input[aria-invalid="true"],
    select[aria-invalid="true"],
    textarea[aria-invalid="true"]
) {
    background: var(--color-danger-soft);
}

html[data-theme="dark"] :is(
    .plan-card,
    .plan-header-card,
    .current-status-card,
    .auto-reg-card,
    .twin-card,
    .calibration-card,
    .plan-details-card-adjustment,
    .insights-link,
    .risk-factor,
    .recovery-confidence,
    .recovery-coverage,
    .recovery-load-pair div,
    .recovery-outlook-day,
    .zones-source-card,
    .suggestion-preamble,
    .suggestion-reasons,
    .post-race-card
) {
    background: var(--color-bg-alt);
}

html[data-theme="dark"] :is(.dashboard-section-recovery, .dashboard-section-community) {
    background: var(--color-bg);
}

html[data-theme="dark"] :is(.calendar-day-phase-base, .calendar-phase-column.calendar-day-phase-base) {
    background: #13251d;
}

html[data-theme="dark"] :is(.calendar-day-phase-build, .calendar-phase-column.calendar-day-phase-build) {
    background: #172539;
}

html[data-theme="dark"] :is(.calendar-day-phase-peak, .calendar-phase-column.calendar-day-phase-peak) {
    background: #30233d;
}

html[data-theme="dark"] :is(.calendar-day-phase-cutback, .calendar-phase-column.calendar-day-phase-cutback) {
    background: #33281a;
}

html[data-theme="dark"] :is(.calendar-day-phase-taper, .calendar-phase-column.calendar-day-phase-taper) {
    background: #173038;
}

html[data-theme="dark"] :is(.badge-easy, .badge-recovery, .badge-risk-low, .recovery-tag) {
    background: var(--color-positive-soft);
    color: #8ee3b6;
}

html[data-theme="dark"] :is(.zones-plan-badge, .refresh-protected-day) {
    background: var(--color-positive-soft);
    color: #8ee3b6;
}

html[data-theme="dark"] .zones-estimate-badge {
    background: var(--color-info-soft);
    color: #a8cbff;
    border-color: #35547a;
}

html[data-theme="dark"] :is(
    .badge-tempo,
    .badge-marathon_pace,
    .badge-interval,
    .badge-repetition,
    .badge-hill,
    .badge-risk-moderate,
    .auto-reg-override,
    .auto-reg-thin
) {
    background: var(--color-warning-soft);
    color: #f0bd72;
}

html[data-theme="dark"] :is(
    .badge-risk-elevated,
    .calendar-canceled-badge,
    .risk-factor-triggered,
    .form-error-summary,
    .recovery-alert,
    .recovery-flagged
) {
    background: var(--color-danger-soft);
    color: #ffaaa3;
}

html[data-theme="dark"] :is(.badge-long, .zones-source-estimate) {
    background: var(--color-info-soft);
    color: #a8cbff;
}

html[data-theme="dark"] :is(.physiology-domain-moderate, .day-drawer-workout-completed, .refresh-option.is-selected, .run-chart-controls button[aria-pressed="true"]) {
    background: var(--color-positive-soft);
}

html[data-theme="dark"] .physiology-domain-heavy {
    background: var(--color-warning-soft);
}

html[data-theme="dark"] .physiology-domain-severe {
    background: var(--color-danger-soft);
}

html[data-theme="dark"] .physiology-threshold {
    background: var(--color-surface-raised);
}

html[data-theme="dark"] :is(.badge-cross_train, .badge-strength) {
    background: #2a2340;
    color: #c8b4ff;
}

html[data-theme="dark"] .calendar-workout-card-rest {
    background: #202824;
}

html[data-theme="dark"] :is(.calendar-workout-card-easy, .calendar-workout-card-recovery) {
    background: #173126;
}

html[data-theme="dark"] :is(
    .calendar-workout-card-tempo,
    .calendar-workout-card-marathon_pace,
    .calendar-workout-card-interval,
    .calendar-workout-card-repetition,
    .calendar-workout-card-hill
) {
    background: #382a17;
}

html[data-theme="dark"] .calendar-workout-card-long {
    background: #182b43;
}

html[data-theme="dark"] :is(.calendar-workout-card-cross_train, .calendar-workout-card-strength) {
    background: #29223f;
}

html[data-theme="dark"] :is(.calendar-workout-card-race, .calendar-workout-card-time_trial) {
    background: #40261c;
}

html[data-theme="dark"] .calendar-tss-chip {
    background: rgba(0, 0, 0, 0.22);
}

html[data-theme="dark"] :is(.calendar-cell-actions summary:hover, .calendar-cell-actions summary:focus-visible, .calendar-cell-actions[open] summary) {
    background: rgba(0, 0, 0, 0.25);
}

html[data-theme="dark"] .calendar-bonus-workout-icon {
    color: var(--color-text);
}

html[data-theme="dark"] :is(.compliance-marker-under, .compliance-marker-too_hard, .workout-canceled-notice, .body-map-region-button.is-pain) {
    background: var(--color-danger-soft);
    color: #ffaaa3;
}

html[data-theme="dark"] :is(.compliance-marker-over, .compliance-marker-too_easy, .body-map-region-button.is-soreness) {
    background: var(--color-info-soft);
    color: #a8cbff;
}

html[data-theme="dark"] :is(.workout-strength-exercise-tag, .refresh-option-suggested) {
    background: var(--color-warning-soft);
    color: #f0bd72;
}

html[data-theme="dark"] .workout-strength-focus-tag {
    background: #2a2340;
    color: #c8b4ff;
}

html[data-theme="dark"] :is(.recovery-safety-card) {
    background: #241f17 !important;
    border-color: #63512c !important;
}

html[data-theme="dark"] :is(.suggestion, .post-race-card) {
    background-color: var(--color-surface);
}

html[data-theme="dark"] :is(.chat-message-error, .chat-message-system) {
    background: var(--color-danger-soft);
    color: #ffaaa3;
}

html[data-theme="dark"] :is(.chart-axis-label, .chart-label, .chart-zone-label) {
    fill: var(--color-text-muted);
}

html[data-theme="dark"] :is(.chart-gridline, .chart-axis) {
    stroke: var(--color-border);
}

html[data-theme="dark"] img,
html[data-theme="dark"] svg {
    color-scheme: dark;
}

/* Shared polish at every size. */
.plan-card,
.plan-header-card,
.current-status-card,
.auto-reg-card,
.twin-card,
.recovery-card,
.plan-details-card,
.integration-card,
.zones-source-card,
.zones-primary-section,
.zones-secondary-section,
.zones-use-card {
    box-shadow: var(--app-shadow-small);
}

.button,
.nav-link,
button.calendar-workout-card-main,
.calendar-day-drawer-trigger {
    -webkit-tap-highlight-color: transparent;
}

.button:active,
.nav-link:active {
    transform: translateY(1px);
}

/* Simulated phone mode in Settings. These mirror the real breakpoint so
   a desktop preview remains a faithful representation. */

/* Real phone/tablet viewport. Keep in lock-step with simulated mode. */
@media (max-width: 700px) {
    :root { --radius: 16px; }
    /* dvh, not vh: iOS Safari's collapsing URL bar makes 100vh ~60px
       taller than the visible viewport, so a 100vh page always starts
       scrolled-able by that much. */
    body { min-height: 100dvh; background: var(--color-bg-alt); }
    /* The floating nav pill sits above the home indicator, so the page
       has to clear the pill *and* the inset beneath it. */
    body.has-plan-nav main {
        padding-bottom: calc(var(--mobile-nav-height) + 22px + env(safe-area-inset-bottom));
    }
    .container {
        width: 100%;
        padding-inline: calc(14px + env(safe-area-inset-left)) calc(14px + env(safe-area-inset-right));
    }
    /* viewport-fit=cover paints under the status bar; pay it back here so
       the header never sits beneath the clock or the Dynamic Island. */
    .site-header {
        padding-top: env(safe-area-inset-top);
        /* The bottom nav pill is a descendant of this header, and any
           backdrop-filter makes an element a containing block for
           position:fixed descendants — which pinned the "fixed to the
           bottom of the screen" nav to the bottom of the *header*, i.e.
           the top of the screen. An opaque header on a phone frees it,
           and keeps small nav text off a blurred backdrop besides. */
        backdrop-filter: none;
        background: var(--color-surface);
    }
    .header-inner { height: 56px; }
    .brand-name { font-size: 1.05rem; }
    .header-actions { gap: 8px; }
    .site-nav-plan {
        position: fixed; z-index: 90; width: auto; height: var(--mobile-nav-height);
        inset: auto calc(8px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom))
               calc(8px + env(safe-area-inset-left));
        padding: 6px; gap: 2px; overflow-x: auto; border: 1px solid var(--color-border);
        border-radius: 20px; background: color-mix(in srgb, var(--color-surface) 92%, transparent);
        box-shadow: var(--app-shadow); backdrop-filter: blur(18px); transform: none;
        scrollbar-width: none; scroll-snap-type: x proximity;
    }
    .site-nav-plan::-webkit-scrollbar { display: none; }
    .nav-link {
        flex: 1 0 62px; min-height: 54px; flex-direction: column; justify-content: center; gap: 4px;
        padding: 5px 6px; border-radius: 14px; color: var(--color-text-muted); font-size: 0.62rem;
        line-height: 1; text-align: center; scroll-snap-align: center;
    }
    .nav-link:hover, .nav-link:focus-visible { background: var(--color-bg-alt); color: var(--color-primary); }
    .nav-link.is-active { background: color-mix(in srgb, var(--color-primary) 12%, var(--color-surface)); color: var(--color-primary); }
    .nav-icon, .nav-label { display: block; }
    .nav-icon { font-size: 1.12rem; }
    .nav-label { max-width: 68px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .site-nav-utility { position: static; width: auto; height: auto; padding: 0; gap: 5px; overflow: visible; border: 0; background: transparent; box-shadow: none; transform: none; }
    .site-nav-utility .nav-link { flex: 0 0 var(--tap-size); width: var(--tap-size); min-height: var(--tap-size); padding: 0; }
    .site-nav-utility .nav-label { display: none; }
    .site-footer { display: none; }
    .dashboard-section, .auth-section { padding: 20px 0 30px; }
    .dashboard-header { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; margin-bottom: 22px; }
    .dashboard-header h1, .form-container > h1, .auth-container > h1 { font-size: clamp(1.55rem, 7vw, 2rem); letter-spacing: -0.025em; }
    .form-subtitle { margin-top: -5px; font-size: 0.9rem; line-height: 1.45; }
    .plan-header-card, .current-status-card, .auto-reg-card, .plan-card, .recovery-card,
    .plan-details-card, .calibration-card, .zones-primary-section, .zones-secondary-section, .zones-use-card {
        padding: 16px; border-radius: 18px;
    }
    /* One row, however many actions there are. A two-column grid put three
       buttons on two rows with a gap where the fourth cell would be, which
       read as a mistake. .dashboard-inline-form is display:contents, so the
       Sync button is a flex item here like its siblings. */
    .dashboard-actions {
        display: flex;
        flex-wrap: nowrap;
        gap: 6px;
        width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .dashboard-actions::-webkit-scrollbar { display: none; }
    .dashboard-actions .button, .dashboard-actions button {
        flex: 1 1 0;
        /* Shrink to share the row; the row scrolls rather than wrapping if
           the labels genuinely cannot fit. */
        min-width: 0;
        min-height: var(--tap-size);
        padding-inline: 8px;
        font-size: 0.74rem;
        white-space: nowrap;
        justify-content: center;
        text-align: center;
    }
    :is(.button, button, input, select) { min-height: var(--tap-size); }
    .form-field input, .form-field select, .form-field textarea { width: 100%; min-height: 48px; padding: 12px 13px; border-radius: 12px; font-size: 16px; }
    :is(.goal-time-row, .zones-calibration-fields, .recovery-grid, .zones-source-grid, .zones-use-grid, .zones-cycling-grid, .insights-links, .plan-grid) { grid-template-columns: 1fr; }
    .goal-time-row { display: grid; }
    .calendar-nav { display: grid; gap: 12px; }
    .calendar-nav-months { display: grid; grid-template-columns: auto 1fr auto; width: 100%; gap: 8px; }
    .calendar-nav h2 { margin: 0; font-size: 1.05rem; text-align: center; }
    .calendar-density-control { width: 100%; }
    .calendar-density-control button { flex: 1; }
    .calendar-agenda-list { gap: 10px; }
    .agenda-day { padding: 13px; border: 1px solid var(--color-border); border-radius: 18px; box-shadow: var(--app-shadow-small); }
    .calendar-workout-card { border-radius: 14px; }
    .calendar-workout-card-main { min-height: 58px; padding: 10px 11px; }
    :is(.trend-chart, .workout-plot) { min-height: 220px; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-surface); }
    .chart-range-control { position: sticky; top: 64px; z-index: 4; width: 100%; padding: 6px; overflow-x: auto; border: 1px solid var(--color-border); border-radius: 14px; background: var(--color-surface); box-shadow: var(--app-shadow-small); }
    .chart-range-option { min-width: 54px; }
    :is(.table-scroll, .recovery-table-wrap, .zones-table-wrap, .chart-data-table) { margin-inline: -4px; overflow-x: auto; border-radius: 12px; scrollbar-width: thin; }
    :is(.data-table, .recovery-table, .plan-details-table) { min-width: 560px; }
    .zones-matrix { min-width: 0; }
    .zones-matrix thead { display: none; }
    .zones-matrix tbody, .zones-matrix tr, .zones-matrix th, .zones-matrix td { display: block; width: 100%; }
    .zones-matrix tr { margin-bottom: 10px; padding: 13px; border: 1px solid var(--color-border); border-radius: 14px; background: var(--color-bg-alt); }
    .zones-matrix th, .zones-matrix td { padding: 5px 0; border: 0; }
    .zones-matrix td::before { display: block; color: var(--color-text-muted); font-size: 0.66rem; font-weight: 750; letter-spacing: 0.04em; text-transform: uppercase; }
    .zones-matrix td:nth-child(2)::before { content: "Pace / power"; }
    .zones-matrix td:nth-child(3)::before { content: "Heart rate / purpose"; }
    .zones-matrix td:nth-child(4)::before { content: "RPE"; }
    .zones-matrix td:nth-child(5)::before { content: "Talk test"; }
    .zones-matrix td:nth-child(6)::before { content: "Purpose"; }
    .zones-cycling-table td:nth-child(2)::before { content: "Value"; }
    .zones-cycling-table td:nth-child(3)::before { content: "Purpose"; }
    .physiology-domains { grid-template-columns: 1fr; }
    .physiology-threshold { min-height: 30px; border-top: 1px dashed var(--color-border); border-bottom: 1px dashed var(--color-border); }
    .recovery-decision, .recovery-grid-two, .recovery-grid-three { grid-template-columns: 1fr; }
    .recovery-coverage { grid-template-columns: repeat(2, 1fr); border-radius: 18px; }
    .recovery-outlook { display: flex; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: 5px; }
    .recovery-outlook-day { flex: 0 0 128px; scroll-snap-align: start; }
    .twin-header { display: none; }
    .twin-summary { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); min-width: 0; gap: 10px; padding: 14px; }
    .twin-summary > span:not(.twin-summary-description)::before { content: attr(data-label); display: block; margin-bottom: 2px; color: var(--color-text-muted); font-size: 0.62rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
    .twin-summary-label, .twin-summary-description { grid-column: 1 / -1; }
    .twin-summary-description { color: var(--color-text-muted); font-size: 0.78rem; }
    .modal-overlay { align-items: flex-end; padding: 0; }
    .modal-dialog, .modal-dialog-workout, .modal-dialog-wide, .modal-dialog-settings, .modal-dialog-plan-details, .modal-dialog-chat {
        width: 100%; max-width: none; max-height: min(92dvh, 900px); margin: 0; border: 1px solid var(--color-border);
        border-bottom: 0; border-radius: 22px 22px 0 0; box-shadow: 0 -18px 48px rgba(0, 0, 0, 0.25);
    }
    .modal-header { min-height: 56px; padding: 10px 14px; }
    .modal-body { padding: 14px; overscroll-behavior: contain; }
    .modal-footer { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; padding: 10px 14px calc(10px + env(safe-area-inset-bottom)); }
    .modal-footer .button { width: 100%; }
    .calendar-day-drawer,
    .side-drawer {
        top: auto; bottom: 0; width: 100%; max-width: none;
        /* height:auto, not the desktop side-panel's 100%: a sheet should
           hug its content and stop, not stand full-height with the day's
           two activities stranded at the top of an empty column. */
        height: auto; max-height: 88dvh;
        padding-bottom: env(safe-area-inset-bottom);
        border-radius: 22px 22px 0 0;
    }
    .modal-detail-list { grid-template-columns: minmax(100px, 0.8fr) minmax(0, 1.2fr); gap: 8px 12px; }
    .plan-details-nav, .zones-tabs { position: sticky; top: 62px; z-index: 5; overflow-x: auto; flex-wrap: nowrap; padding: 6px; border: 1px solid var(--color-border); border-radius: 14px; background: color-mix(in srgb, var(--color-surface) 94%, transparent); box-shadow: var(--app-shadow-small); backdrop-filter: blur(14px); }
    .plan-details-nav a, .zones-tab { flex: 1 0 auto; min-height: 40px; white-space: nowrap; }
    .form-wizard-progress { position: sticky; top: 62px; z-index: 5; padding: 6px; border: 1px solid var(--color-border); border-radius: 16px; background: var(--color-surface); box-shadow: var(--app-shadow-small); }
    .body-map-layout { grid-template-columns: 1fr; }
    .page-message { margin: 10px 12px 0; padding: 11px 13px; }

    /* Ported from the old simulated-phone class path, which was the only
       place these lived — meaning a real iPhone never got them. The
       weekly-schedule grid becomes stacked label/value cards rather than
       a table that cannot fit seven columns. */
    .zones-sensor-grid { grid-template-columns: 1fr; }
    .recovery-coverage { grid-template-columns: repeat(2, 1fr); border-radius: 18px; }
    .daily-schedule-grid { display: block; }
    .daily-schedule-header { display: none; }
    .daily-schedule-day-label {
        margin: 12px 0 0; padding: 8px 10px 6px; border: 1px solid var(--color-border);
        border-bottom: 0; border-radius: 14px 14px 0 0; background: var(--color-bg-alt);
    }
    .daily-schedule-grid > div[data-label] {
        display: flex; align-items: center; justify-content: space-between; gap: 10px;
        padding: 6px 10px; border-inline: 1px solid var(--color-border);
    }
    .daily-schedule-grid > div[data-label]::before {
        content: attr(data-label); flex: 0 0 auto; color: var(--color-text-muted);
        font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
    }
    .daily-schedule-grid > div[data-label]:last-child {
        padding-bottom: 10px; border-bottom: 1px solid var(--color-border);
        border-radius: 0 0 14px 14px;
    }
    .daily-schedule-grid > div[data-label] :is(select, input) { width: 60%; min-width: 0; }
}

@media (max-width: 420px) {
    .dashboard-header { grid-template-columns: 1fr; }
    .dashboard-header > .button { width: 100%; }
    .recovery-coverage { grid-template-columns: 1fr 1fr; }
    .recovery-load-pair { grid-template-columns: 1fr; }
    .settings-display-actions { display: grid; grid-template-columns: 1fr; }
    .settings-display-actions .button { width: 100%; }
}

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

/* The enhanced chart shell owns its border and surface. Avoid nesting a
   second card outline around the SVG on phones and in dark mode. */
.chart-experience > :is(.trend-chart, .workout-pace-graph) {
    border: 0;
    border-radius: 0;
    background: transparent;
}

/* ==========================================================================
   Phone calendar: Day / Week / Month
   --------------------------------------------------------------------------
   The month grid is a desktop artifact. It needs 402px and gives each day
   ~35px — under the 44px tap minimum, and far too narrow for a card that
   carries a title, a Planned/Actual pair and a TSS chip. So the phone leads
   with today and a week agenda, and keeps the month as a density map.

   All three layouts read the same calendar_weeks the grid does, so they
   cannot disagree with each other about a date.
   ========================================================================== */

/* --- The layout switch ---------------------------------------------- */

.calendar-view-control {
    display: inline-flex;
    padding: 2px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.calendar-view-control button {
    min-height: 32px;
    padding: 5px 13px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 150ms ease, color 150ms ease;
}

.calendar-view-control button.is-selected {
    background: var(--color-surface);
    color: var(--color-primary);
    box-shadow: var(--app-shadow-small);
}

/* --- Week strip ------------------------------------------------------ */

.calendar-week-strip {
    margin-bottom: 14px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
}

.calendar-week-strip::-webkit-scrollbar { display: none; }

.week-strip-track {
    display: flex;
}

/* One week fills the strip exactly, so a swipe moves a week at a time
   rather than landing between two of them. */
.week-strip-week {
    display: grid;
    flex: 0 0 100%;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px;
    scroll-snap-align: start;
}

.week-strip-day {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    min-height: var(--tap-size);
    padding: 7px 2px 6px;
    border: 1px solid transparent;
    border-radius: 14px;
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    cursor: pointer;
    transition: transform 120ms ease, border-color 150ms ease;
}

.week-strip-day:active { transform: scale(0.94); }
.week-strip-day.is-outside { opacity: 0.38; }

.week-strip-day.is-today {
    border-color: var(--color-primary);
    background: var(--color-positive-soft);
}

.week-strip-dow {
    color: var(--color-text-muted);
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.week-strip-num {
    font-size: 0.95rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* The day's state as a single dot. This is the only per-day signal the
   strip carries — anything more does not survive a 50px column. */
.week-strip-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: transparent;
}

.week-strip-dot-done { background: var(--color-good); }
.week-strip-dot-missed { background: var(--color-accent); }
.week-strip-dot-upcoming { background: var(--color-text-muted); }

/* --- Day view -------------------------------------------------------- */

.today-card {
    padding: 18px;
    border: 1px solid var(--color-border);
    border-radius: 22px;
    background: var(--color-surface);
    box-shadow: var(--app-shadow);
}

.today-card-header {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.today-card-eyebrow {
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--color-positive-soft);
    color: var(--color-primary);
    font-size: 0.62rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.today-card-date {
    margin: 0;
    font-size: 1.15rem;
    letter-spacing: -0.02em;
}

.today-card-empty {
    margin: 0;
    padding: 18px 0;
    color: var(--color-text-muted);
    text-align: center;
}

.today-card-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin-top: 14px;
}

.today-card-actions .button { width: 100%; justify-content: center; }

/* .calendar-day-drawer-trigger strips border/padding/background so a bare
   date number can be a button. When that same trigger *is* a button, the
   reset wins on source order and leaves it looking like plain text — so
   put the box back. */
.button.calendar-day-drawer-trigger {
    padding: 9px 14px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
}

.button.calendar-day-drawer-trigger:hover,
.button.calendar-day-drawer-trigger:focus-visible {
    text-decoration: none;
}

/* The Day view enlarges the single card it is showing — this is the one
   place with room for the full prescription to be read at arm's length. */
.calendar-today-view .calendar-workout-card {
    padding: 14px;
    border-radius: 16px;
}

.calendar-today-view .calendar-workout-card-title { font-size: 1rem; }
.calendar-today-view .calendar-workout-summary { font-size: 0.85rem; }

/* --- Week totals strip ----------------------------------------------- */

/* Replaces the grid's 96px right-hand column, which costs 26% of a 393px
   screen — more than three day columns — to show six numbers that read
   perfectly well in a row. */
.week-totals-strip {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 14px;
    background: var(--color-bg-alt);
}

.week-totals-label {
    flex: 0 0 auto;
    color: var(--color-text-muted);
    font-size: 0.68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.week-totals-figures {
    display: flex;
    gap: 16px;
    flex: 1 1 auto;
    overflow-x: auto;
    scrollbar-width: none;
}

.week-totals-figures::-webkit-scrollbar { display: none; }

.week-total-figure {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    gap: 1px;
}

.week-total-value {
    font-size: 0.92rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    white-space: nowrap;
}

.week-total-unit {
    color: var(--color-text-muted);
    font-size: 0.78rem;
    font-weight: 500;
}

.week-total-name {
    color: var(--color-text-muted);
    font-size: 0.62rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* --- Week (agenda) view ---------------------------------------------- */

.agenda-week {
    margin-bottom: 22px;
}

.agenda-week-header {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 8px;
    padding: 7px 2px;
    background: var(--color-bg-alt);
}

.agenda-week-range {
    font-size: 0.8rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    text-transform: uppercase;
}

.agenda-week-phase {
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.agenda-week-current .agenda-week-range { color: var(--color-primary); }

.agenda-week .week-totals-strip { margin-bottom: 10px; }

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

/* --- Phone overrides for the three calendar layouts ------------------- */

@media (max-width: 700px) {
    /* Month becomes a density map. The grid cannot carry workout cards at
       ~35px per column, so it stops trying: each day keeps its number, its
       state dot and one colored bar per scheduled item. That is a month
       you can scan, which is the only thing a month view is good for on a
       phone — the Day and Week layouts carry the detail. */
    .calendar-grid-with-totals {
        grid-template-columns: repeat(7, minmax(0, 1fr));
    }

    /* Simple fits the whole month on screen because its cells hold bars.
       Standard and Technical hold real cards, which need room to be worth
       choosing — so the grid takes a readable column width and scrolls
       sideways instead of squeezing seven cards into 50px each. */
    html:not([data-calendar-density="simple"]) .calendar-grid-with-totals {
        grid-template-columns: repeat(7, minmax(118px, 1fr));
    }

    html:not([data-calendar-density="simple"]) .calendar-day { min-height: 92px; }

    .calendar-phase-header,
    .calendar-phase-column,
    .calendar-week-total,
    .calendar-week-total-header {
        display: none;
    }

    .calendar-day {
        min-height: 58px;
        padding: 5px 4px;
    }

    .calendar-day-planned {
        display: flex;
        flex-direction: column;
        gap: 2px;
        margin-top: 3px;
    }

    /* Simple, on a phone month grid, is a density map: each workout
       collapses to its own type-colored bar. The card keeps its background
       class, so a tempo day is the same color here as everywhere else, and
       the tints are saturated because as bare 6px bars they carry no text
       to be read against.

       Scoped to Simple deliberately. This used to apply at every density,
       which meant choosing Standard or Technical in month view changed
       nothing — the bars ignored it. */
    html[data-calendar-density="simple"] .calendar-day-planned .calendar-workout-card {
        min-height: 0;
        height: 6px;
        padding: 0;
        border-radius: 3px;
        overflow: hidden;
        filter: saturate(1.6) brightness(0.96);
    }

    html[data-calendar-density="simple"] .calendar-day-planned .calendar-workout-card > * {
        display: none;
    }

    /* Nothing to reveal when every item is already a bar. */
    html[data-calendar-density="simple"] .calendar-day-planned-overflow { display: none; }

    /* A border changes the cell's box inside a 1px-gap grid, so today's
       cell grew taller than the rest of its row. An inset ring marks it
       without touching layout — and in brand green rather than a
       hardcoded grey that vanishes against a dark cell. */
    .calendar-day-today {
        border: 0;
        box-shadow: inset 0 0 0 2px var(--color-primary);
    }

    .calendar-day-today .calendar-day-number { color: var(--color-primary); }

    .calendar-day-number { font-size: 0.72rem; }

    /* "done"/"missed"/"upcoming" does not fit as a word in a 50px column. */
    .calendar-day-state {
        width: 5px;
        height: 5px;
        padding: 0;
        border-radius: 50%;
        font-size: 0;
        overflow: hidden;
    }

    /* The nav row carries three controls on a phone; let them wrap into
       their own line rather than squeezing the month name. */
    .calendar-nav { display: grid; gap: 10px; }
    .calendar-nav-months { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
    .calendar-nav-months h2 { flex: 1 1 auto; font-size: 1.05rem; margin: 0; text-align: center; }
    /* Without this the arrows wrap onto two lines each and the month name
       is squeezed into a column. */
    .calendar-nav-months .button {
        flex: 0 0 auto;
        min-width: var(--tap-size);
        padding-inline: 12px;
        white-space: nowrap;
    }
    .calendar-view-control,
    .calendar-density-control { width: 100%; justify-content: space-between; }
    .calendar-view-control button,
    .calendar-density-control button { flex: 1 1 0; min-height: var(--tap-size); }

    /* Density applies to Week and Month alike. Only Day is exempt: it
       shows one card at full width, so there is nothing to dial. */
    html[data-calendar-view="day"] .calendar-density-control { display: none; }


    .today-card { padding: 16px; border-radius: 20px; }
    .today-card-date { font-size: 1.05rem; }

    .week-totals-strip {
        gap: 10px;
        padding: 9px 11px;
        /* Fades the last figure out instead of guillotining it, which is
           what tells you the row scrolls. */
        -webkit-mask-image: linear-gradient(to right, #000 88%, transparent);
        mask-image: linear-gradient(to right, #000 88%, transparent);
    }
    .week-totals-figures { gap: 14px; }

    .agenda-week-header {
        /* Clears the sticky site header so the week label doesn't scroll
           underneath it. */
        top: calc(56px + env(safe-area-inset-top));
    }
}

/* A phone in landscape is short, not wide: keep the compact chrome but let
   the agenda breathe into the extra width. */
@media (max-width: 926px) and (orientation: landscape) and (pointer: coarse) {
    .calendar-agenda-list { column-count: 2; column-gap: 14px; }
    .agenda-week { break-inside: avoid; }
}

/* --- Bottom sheets --------------------------------------------------- */

@media (max-width: 700px) {
    /* A grabber is the affordance that says "this drags". modal-shell.js
       inserts one into every dialog on a phone and handles the gesture. */
    .sheet-grabber {
        flex: none;
        width: 38px;
        height: 4px;
        margin: 8px auto 0;
        border-radius: 999px;
        background: var(--color-border);
    }

    .modal-dialog,
    .calendar-day-drawer,
    .side-drawer {
        /* Not `transform` alone: the drag sets an inline transform, and a
           transition on it is what makes the release spring back. */
        transition: transform 220ms cubic-bezier(0.32, 0.72, 0, 1);
        touch-action: pan-y;
    }

    .modal-overlay:not([hidden]) .modal-dialog,
    .calendar-day-drawer-overlay:not([hidden]) .calendar-day-drawer,
    .side-drawer-overlay:not([hidden]) .side-drawer {
        animation: sheet-rise 260ms cubic-bezier(0.32, 0.72, 0, 1);
    }

    @keyframes sheet-rise {
        from { transform: translateY(100%); }
        to { transform: translateY(0); }
    }

    /* Blur behind the sheet, so the page reads as parked rather than as a
       second competing surface. */
    .modal-overlay,
    .calendar-day-drawer-overlay,
    .side-drawer-overlay {
        background: color-mix(in srgb, #0a110e 42%, transparent);
        backdrop-filter: blur(6px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .modal-dialog,
    .calendar-day-drawer,
    .side-drawer {
        animation: none !important;
        transition: none !important;
    }
}

/* ==========================================================================
   Numerics and touch feedback
   ========================================================================== */

/* Tabular figures everywhere a number can change. Proportional digits are
   different widths, so a value that updates — a TSS chip, a compliance
   percentage, a week total — visibly jitters as it does. On a stats app
   that reads as cheap, and it is one declaration to fix.

   Scoped to the elements that hold numbers rather than set globally: prose
   genuinely reads better with proportional figures. */
.week-stat-value,
.week-total-value,
.load-stat-value,
.auto-reg-signal-value,
.calendar-tss-chip,
.calendar-day-number,
.badge-count,
.days-to-race-badge,
.modal-metric-value,
.metric-band-range,
.week-strip-num,
.agenda-day-date,
.calendar-workout-summary,
.workout-comparison-table td,
.modal-detail-list dd {
    font-variant-numeric: tabular-nums;
}

/* Touch feedback. A card that does not acknowledge the press reads as
   unresponsive on a touchscreen, where there is no hover state to have
   given the affordance away beforehand. */
@media (pointer: coarse) {
    .calendar-workout-card-main,
    .agenda-day-date,
    .week-strip-day,
    .today-card-actions .button,
    .calendar-view-control button,
    .calendar-density-control button {
        transition: transform 120ms ease;
    }

    .calendar-workout-card-main:active,
    .agenda-day-date:active,
    .today-card-actions .button:active,
    .calendar-view-control button:active,
    .calendar-density-control button:active {
        transform: scale(0.97);
    }
}

/* Phone type scale. One step down across the board, with the contrast
   carried by weight rather than size — at these sizes a heavier label
   separates from its value more legibly than a larger one does, and it
   costs no vertical space. Inputs stay at 16px (see the .form-field rule
   in the main phone block) because anything smaller makes iOS zoom the
   viewport on focus. */
@media (max-width: 700px) {
    .subsection-title { font-size: 1.02rem; }
    .calendar-workout-card-title { font-size: 0.78rem; font-weight: 700; }
    .calendar-workout-summary { font-size: 0.72rem; }
    .calendar-workout-summary-label {
        color: var(--color-text-muted);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.03em;
    }
    .agenda-day-date { font-size: 0.82rem; font-weight: 700; }
    .plan-meta { font-size: 0.78rem; }
    .week-stat-value, .load-stat-value { font-weight: 700; }
}

/* ==========================================================================
   Immediate-advice card: dismiss, inline preview dropdown, comparison cells
   ========================================================================== */

.urgent-advice-main {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

/* The card interrupts you because you reported an injury, so it has to be
   closable — but only for as long as the report that raised it stays
   recent (see web_views.URGENT_ADVICE_DISMISSAL_DAYS). */
.urgent-advice-dismiss {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #a33b32;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    transition: background 140ms ease;
}

.urgent-advice-dismiss:hover,
.urgent-advice-dismiss:focus-visible {
    background: color-mix(in srgb, #c45145 16%, transparent);
}

/* --- The dropdown --------------------------------------------------- */

.urgent-advice-preview {
    padding-top: 0.85rem;
    border-top: 1px solid color-mix(in srgb, #c45145 26%, transparent);
    animation: advice-preview-open 180ms cubic-bezier(0.32, 0.72, 0, 1);
}

.urgent-advice-preview[hidden] { display: none; }

@keyframes advice-preview-open {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}

.advice-preview-loading,
.advice-preview-empty {
    margin: 0;
    padding: 0.6rem 0;
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.advice-preview-summary {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.7rem;
}

.advice-preview-headline { font-weight: 750; font-size: 0.92rem; }

.advice-preview-meta {
    color: var(--color-text-muted);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

.advice-preview-delta { font-weight: 750; }
.advice-preview-delta-down { color: var(--color-good); }
.advice-preview-delta-up { color: var(--color-accent); }

.advice-preview-note,
.advice-preview-footnote {
    margin: 0.55rem 0 0;
    color: var(--color-text-muted);
    font-size: 0.74rem;
    line-height: 1.45;
}

/* --- The comparison cells -------------------------------------------- */

/* One cell per changed day, laid out across the week. Each stacks the day
   as it stands now above the day as proposed, so the change reads as a
   substitution rather than as two lists to reconcile. Scrolls sideways
   rather than wrapping: a week that reads as one row is the point. */
.advice-preview-cells {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
}

.advice-cell {
    display: flex;
    flex: 0 0 132px;
    flex-direction: column;
    gap: 3px;
    padding: 8px;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background: var(--color-surface);
    scroll-snap-align: start;
}

.advice-cell-date {
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.advice-cell-label {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.58rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.advice-cell-workout {
    display: block;
    margin-top: 2px;
    padding: 5px 7px;
    border-radius: 8px;
    font-size: 0.74rem;
    line-height: 1.3;
}

.advice-cell-figures {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.68rem;
    font-variant-numeric: tabular-nums;
}

/* The "now" side is deliberately muted and the proposal is not: the point
   of the cell is what it would become. */
.advice-cell-now { opacity: 0.66; }

.advice-cell-empty {
    display: block;
    margin-top: 2px;
    padding: 5px 7px;
    color: var(--color-text-muted);
    font-size: 0.72rem;
    font-style: italic;
}

.advice-cell-arrow {
    color: var(--color-text-muted);
    font-size: 0.8rem;
    text-align: center;
}

.advice-preview-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.85rem;
}

.advice-preview-actions .advice-preview-footnote { flex: 1 0 100%; }

/* The routine's own opener, now that the tile is a summary. */
.current-status-routine-open { margin-top: 0.6rem; }

@media (max-width: 700px) {
    .urgent-advice-main { flex-direction: column; align-items: stretch; }
    .urgent-advice-actions .button { flex: 1 1 0; justify-content: center; }
    .advice-cell { flex-basis: 124px; }
    /* Sharing one row clipped "Apply to my calendar" mid-label. The
       primary action gets its own line; "Not now" sits under it. */
    .advice-preview-actions { flex-direction: column; align-items: stretch; }
    .advice-preview-actions .button { width: 100%; justify-content: center; }
    .current-status-routine-open { width: 100%; justify-content: center; }
}

/* --- VDOT freshness ---------------------------------------------------- */

/* Every prescribed pace in a plan derives from one measured VDOT, and
   Daniels only lets that number come from a maximal effort — so it can sit
   unchanged for months while the runner it describes keeps training. */
.vdot-age-chip {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.6rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    vertical-align: middle;
}

.vdot-age-current { background: var(--color-positive-soft); color: var(--color-primary); }
.vdot-age-ageing { background: var(--color-warning-soft); color: #8a5a12; }
.vdot-age-stale { background: var(--color-danger-soft); color: #a33b32; }

.vdot-age-note {
    margin: 6px 0 0;
    color: var(--color-text-muted);
    font-size: 0.78rem;
    line-height: 1.45;
}

/* --- Today's session card, on a wide screen ---------------------------- */

/* The unified Today card stays one shell at every width. Its internal
   workout/context grid provides the desktop layout; this layer only keeps
   the workout compact and the action row horizontal on wider screens. */
@media (min-width: 701px) {
    #calendar-today-card {
        display: block;
        margin-bottom: 14px;
    }

    #calendar-today-card .calendar-workout-card {
        margin: 0;
        padding: 10px 12px;
        border-radius: 12px;
    }

    #calendar-today-card .calendar-workout-card-title { font-size: 0.95rem; }
    #calendar-today-card .calendar-workout-summary { font-size: 0.82rem; }

    #calendar-today-card .today-card-actions {
        display: flex;
        margin-top: 14px;
        white-space: nowrap;
    }

    #calendar-today-card .today-card-actions .button { width: auto; }

    #calendar-today-card .today-card-empty {
        padding: 0;
        text-align: left;
    }
}

/* --- Session plan ------------------------------------------------------ */

.session-plan-eyebrow {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.62rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.session-plan-summary {
    display: flex;
    gap: 22px;
    flex-wrap: wrap;
    margin-bottom: 18px;
    padding: 12px 14px;
    border: 1px solid var(--color-border);
    border-radius: 14px;
    background: var(--color-bg-alt);
}

.session-plan-figure { display: flex; flex-direction: column; gap: 2px; }

.session-plan-figure-name {
    color: var(--color-text-muted);
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.session-plan-figure-value {
    font-size: 1.05rem;
    font-weight: 750;
    font-variant-numeric: tabular-nums;
}

.session-plan-steps {
    margin: 0 0 16px;
    padding: 0;
    list-style: none;
    counter-reset: none;
}

.session-plan-step {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    border-left: 4px solid var(--color-border);
    background: var(--color-surface);
}

.session-plan-step + .session-plan-step { margin-top: 3px; }

/* The work steps are what the session is; the rest is scaffolding around
   them, so only they carry full weight. */
.session-plan-step-work {
    border-left-color: var(--color-accent);
    background: var(--color-warning-soft);
}

.session-plan-step-warmup,
.session-plan-step-cooldown { border-left-color: var(--color-primary); }
.session-plan-step-recovery { opacity: 0.75; }

.session-plan-step-index {
    flex: 0 0 auto;
    width: 22px;
    color: var(--color-text-muted);
    font-size: 0.7rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.session-plan-step-main {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex: 1 1 auto;
    flex-wrap: wrap;
}

.session-plan-step-label { font-weight: 650; }

.session-plan-step-target {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.session-plan-note,
.session-plan-why {
    color: var(--color-text-muted);
    font-size: 0.85rem;
    line-height: 1.55;
}

@media (max-width: 700px) {
    .session-plan-summary { gap: 14px; padding: 10px 12px; }
    .session-plan-figure-value { font-size: 0.95rem; }
    .session-plan-step { padding: 10px; }
}

/* --- Undo banner ------------------------------------------------------- */

.undo-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 1rem;
    padding: 12px 16px;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: var(--radius);
    background: var(--color-positive-soft);
    font-size: 0.86rem;
}

.undo-banner-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.undo-banner-status {
    color: var(--color-text-muted);
    font-size: 0.78rem;
}

@media (max-width: 700px) {
    .undo-banner { flex-direction: column; align-items: stretch; }
    .undo-banner-actions .button { width: 100%; justify-content: center; }
}

/* --- Today's tile, collapsed ------------------------------------------- */

/* It is a <details> now (see _today_dashboard.html). The header is the
   summary, so the tile reads the same minimised as it did expanded — just
   without the session grid, evidence and actions under it. */
#calendar-today-card > summary {
    cursor: pointer;
    list-style: none;
}

#calendar-today-card > summary::-webkit-details-marker { display: none; }

/* The default triangle sits outside the header's flex layout, so the
   affordance is drawn here instead and rotates on open. */
.today-dashboard-toggle-hint {
    display: block;
    width: 9px;
    height: 9px;
    margin-top: 4px;
    margin-left: auto;
    border-right: 2px solid var(--color-text-muted);
    border-bottom: 2px solid var(--color-text-muted);
    transform: rotate(45deg);
    transition: transform 160ms ease;
}

#calendar-today-card[open] .today-dashboard-toggle-hint {
    transform: rotate(-135deg);
}

/* Collapsed, the tile is a summary line — the generous card padding it
   carries when open is too much for that. */
#calendar-today-card:not([open]) {
    padding-block: clamp(14px, 2vw, 18px);
}

#calendar-today-card:not([open]) > summary { margin-bottom: 0; }

#calendar-today-card > summary:hover .today-dashboard-toggle-hint {
    border-color: var(--color-primary);
}

#calendar-today-card > summary:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
    outline-offset: 3px;
    border-radius: 12px;
}

/* --- Week pager -------------------------------------------------------- */

.week-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
    padding: 8px 10px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg-alt);
}

.week-pager-label {
    color: var(--color-text);
    font-size: 1rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.calendar-agenda-list .agenda-week[hidden] { display: none; }

@media (max-width: 700px) {
    .week-pager {
        gap: 8px;
        padding: 6px;
        border-radius: 16px;
    }
    .week-pager .button {
        min-height: var(--tap-size);
        padding-inline: 10px;
        font-size: 0.74rem;
    }
    .week-pager-label { flex: 1 1 auto; font-size: 0.9rem; }
}

/* ==========================================================================
   Training load: summary bar + side panel
   ========================================================================== */

/* --- The panel --------------------------------------------------------- */

.side-drawer-overlay {
    position: fixed;
    inset: 0;
    z-index: 120;
    background: rgba(22, 33, 29, 0.5);
}

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

.side-drawer {
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    width: min(460px, 100%);
    height: 100%;
    background: var(--color-bg);
    box-shadow: -12px 0 35px rgba(22, 33, 29, 0.2);
}

.side-drawer-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    flex: none;
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--color-border);
}

.side-drawer-header h2 { margin: 3px 0 0; font-size: 1.15rem; letter-spacing: -0.02em; }

.side-drawer-eyebrow {
    color: var(--color-text-muted);
    font-size: 0.62rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.side-drawer-body {
    flex: 1 1 auto;
    padding: 16px 20px 24px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.side-drawer-intro {
    margin: 0 0 16px;
    color: var(--color-text-muted);
    font-size: 0.84rem;
    line-height: 1.55;
}

@media (max-width: 700px) {
    .side-drawer-body { padding: 14px; }
}

/* --- Training load explainer ------------------------------------------ */

.load-explainer-section + .load-explainer-section {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.load-explainer-section h3 {
    margin: 0 0 6px;
    font-size: 0.86rem;
    font-weight: 750;
    letter-spacing: -0.01em;
}

.load-explainer-section p {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.85rem;
    line-height: 1.6;
}

/* ==========================================================================
   VDOT trend (Fitness zones)
   ========================================================================== */

.vdot-trend {
    margin-bottom: 24px;
    padding: 18px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}

.vdot-trend-heads {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.vdot-head { display: flex; flex-direction: column; gap: 2px; }

.vdot-head-label {
    color: var(--color-text-muted);
    font-size: 0.64rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.vdot-head-value {
    font-size: 1.6rem;
    font-weight: 750;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

/* Behind the goal is the ordinary state mid-block, not a failure — amber,
   not red. Ahead of it is worth saying plainly. */
.vdot-head-gap-behind { color: #8a5a12; }
.vdot-head-gap-ahead { color: var(--color-primary); }

.vdot-head-tag { color: var(--color-text-muted); font-size: 0.7rem; }

.vdot-head-tag-measured { color: var(--color-primary); font-weight: 700; }
.vdot-head-tag-estimate { color: #8a5a12; font-weight: 700; }

.vdot-head-detail {
    margin: 0 0 12px;
    color: var(--color-text-muted);
    font-size: 0.78rem;
    line-height: 1.5;
}

.vdot-goal-line {
    stroke: var(--color-accent);
    stroke-width: 1.5;
    stroke-dasharray: 5 4;
}

.vdot-goal-label {
    fill: var(--color-accent);
    font-size: 0.62rem;
    font-weight: 800;
    text-anchor: end;
    dominant-baseline: text-after-edge;
}

/* A line drawn from discounted sensor readings is not a measured trend,
   and should not look like one. */
.chart-line-estimated { stroke-dasharray: 6 4; opacity: 0.85; }
.chart-dot-estimated { fill: var(--color-text-muted); }

@media (max-width: 700px) {
    .vdot-trend { padding: 14px; }
    .vdot-trend-heads { gap: 18px; }
    .vdot-head-value { font-size: 1.3rem; }
}

/* The info panel's body: a paragraph, not a hint. */
.info-tooltip-text[hidden] { display: none; }

.info-drawer-text {
    margin: 0;
    color: var(--color-text);
    font-size: 0.9rem;
    line-height: 1.65;
}

/* --- Day and Week navigate by their own chunk -------------------------- */

/* The month stepper moves by a chunk neither view deals in, and each has
   its own pager that names the dates it is showing. Every width, not just
   phones: the duplication is the problem, not the space it takes. */
html:is([data-calendar-view="day"], [data-calendar-view="week"]) .calendar-nav-months {
    display: none;
}



.day-panel {
    padding: 16px;
    border: 1px solid var(--color-border);
    border-radius: 18px;
    background: var(--color-surface);
}

.day-panel[hidden] { display: none; }

.day-panel-today { border-color: var(--color-primary); }

.day-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}

.day-panel-header h3 {
    margin: 0;
    font-size: 1.05rem;
    letter-spacing: -0.02em;
}

.day-panel-empty {
    margin: 0;
    padding: 18px 0;
    color: var(--color-text-muted);
    text-align: center;
}

.day-panel-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 14px;
}

.calendar-today-view .week-totals-strip { margin-top: 14px; }

@media (max-width: 700px) {
    .day-panel { padding: 13px; border-radius: 16px; }
    .day-panel-actions .button { flex: 1 1 0; justify-content: center; }
}

/* The strip marks today; in Day view it also marks the day being shown,
   which is not always the same one. */
.week-strip-day.is-selected {
    border-color: var(--color-primary);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}

/* Training Load: where the numbers come from, and whether they've settled. */
.load-source-note {
    margin: -4px 0 12px;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--color-text-muted, #6b7280);
}

/* Checkbox fields: box beside its label, not a lone box in a full-width row. */
.form-field-checkbox label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}
.form-field-checkbox input[type="checkbox"] {
    width: 18px;
    height: 18px;
    flex: none;
    margin: 0;
}

/* Evening recovery: a <details> so it can sit as one line until it's
   the thing to do now. */
.evening-recovery > summary.evening-recovery-header { cursor: pointer; list-style: none; }
.evening-recovery > summary.evening-recovery-header::-webkit-details-marker { display: none; }
.evening-recovery > summary.evening-recovery-header::after {
    content: "▾";
    flex: none;
    margin-left: 4px;
    color: var(--color-text-muted);
    transition: transform 0.15s ease;
}
.evening-recovery:not([open]) > summary.evening-recovery-header::after { transform: rotate(-90deg); }
.evening-recovery-race_eve { border-left-color: #1f6fb3; }
.evening-recovery-last-night { margin-top: 4px !important; color: var(--color-text) !important; font-weight: 600; }
.evening-recovery-exercises { margin: 6px 0 0; padding-left: 16px; }
.evening-recovery-exercises li { margin: 3px 0; font-size: 0.72rem; color: var(--color-text-muted); }
.evening-recovery-exercises li strong { display: inline !important; font-size: 0.72rem; color: var(--color-text); }
.evening-recovery-exercises li small { display: block; margin: 0; color: var(--color-text-muted); font-weight: 600; }
.evening-recovery-remaining { margin: 8px 0 0; color: var(--color-text-muted); font-size: 0.74rem; }
.evening-recovery-actions button:disabled { opacity: 0.5; cursor: not-allowed; }


/* ==========================================================================
   Status board: Today / Tomorrow / Tonight as one-line cards, the detail
   in the status side panel (_status_drawer.html, status-board.js)
   ========================================================================== */

.status-board {
    display: grid;
    gap: 10px;
    margin: 14px 0 12px;
}

.status-board-cards {
    display: flex;
    flex-direction: column;
    gap: 8px;
}


.status-board .status-card {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-primary);
    border-radius: 14px;
    background: var(--color-surface);
    box-shadow: none;
}

.status-board .status-card::before { display: none; }

/* Buttons that read as text: a card title, a row, a badge. */
.status-card-title,
.status-row,
.status-today-session,
.status-link,
.status-inputs-chip {
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.status-card-title {
    padding: 0;
    border: 0;
    background: none;
    font-weight: inherit;
    letter-spacing: inherit;
}

.status-card-title:hover,
.status-card-title:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

button.status-badge { border: 0; font-family: inherit; cursor: pointer; }

/* Beats the generic .current-status-card padding/margin. */
.status-board #calendar-today-card { margin: 0; padding: 12px 14px; }

.status-board .evening-recovery-header > div { flex: 1 1 auto; min-width: 0; }
.status-board .evening-recovery-header > .badge { flex: none; align-self: flex-start; }

.status-link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--color-primary);
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
}

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

/* --- Today ----------------------------------------------------------- */

.status-board .status-today .current-status-overview {
    padding: 0;
    border: 0;
    background: none;
    flex-direction: row;
    align-items: flex-start;
}

.status-board .status-today.current-status-card { margin: 0; }
.status-today:has(.current-status-overview-elevated) { border-left-color: #b3521f; }
.status-today:has(.current-status-overview-moderate) { border-left-color: #b3941f; }
.status-today:has(.current-status-overview-neutral) { border-left-color: var(--color-text-muted); }

.status-today .today-card-eyebrow { display: inline-block; margin-bottom: 4px; }

.status-today h2 {
    margin: 0;
    font-size: 1.05rem;
    line-height: 1.3;
    letter-spacing: -0.015em;
}

.status-today-session {
    display: flex;
    align-items: baseline;
    gap: 8px;
    width: 100%;
    margin: 8px 0 0;
    padding: 6px 8px;
    border: 0;
    border-radius: 9px;
    background: var(--color-bg-alt);
    font-size: 0.86rem;
}

button.status-today-session:hover { background: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg-alt)); }

.status-row-label {
    flex: none;
    color: var(--color-text-muted);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.status-done { margin-left: auto; color: var(--color-primary); font-size: 0.76rem; font-weight: 700; }

.status-board .status-today .today-card-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
}

.status-board .status-today .today-card-actions .button { width: auto; }

.today-card-primary-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.status-inputs-chip {
    padding: 4px 9px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: none;
    color: var(--color-text-muted);
    font-size: 0.72rem;
    font-weight: 700;
}

.status-inputs-chip:hover { color: var(--color-text); border-color: var(--color-text-muted); }

/* --- Tomorrow -------------------------------------------------------- */

.status-tomorrow { padding: 0 !important; }
.status-tomorrow.auto-reg-card-decrease { border-left-color: #b3521f; }
.status-tomorrow.auto-reg-card-increase { border-left-color: var(--color-good); }

.status-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "label badge"
        "main badge"
        "sentence badge";
    column-gap: 12px;
    row-gap: 2px;
    align-items: center;
    width: 100%;
    padding: 11px 14px;
    border: 0;
    border-radius: 12px;
    background: none;
}

.status-row:hover { background: color-mix(in srgb, var(--color-primary) 4%, transparent); }
.status-row .status-row-label { grid-area: label; }
.status-row-main { grid-area: main; font-size: 0.92rem; }
.status-row-sentence { grid-area: sentence; color: var(--color-text-muted); font-size: 0.78rem; line-height: 1.4; }
.status-row .badge { grid-area: badge; }

/* --- Tonight --------------------------------------------------------- */

.status-board .evening-recovery.status-card { padding: 12px 14px; }
.status-board .evening-recovery-protect.status-card { border-left-color: #b3521f; }
.evening-recovery-actions > div { align-items: center; }

/* --- The one alert line --------------------------------------------- */

.status-board .status-alert {
    position: relative;
    margin: 0;
    padding: 10px 40px 10px 14px;
    border: 1px solid var(--color-border);
    border-left: 4px solid #b3941f;
    border-radius: 14px;
    background: var(--color-surface);
    gap: 0;
}

.status-board .urgent-advice-card.status-alert {
    border-color: color-mix(in srgb, #c45145 40%, var(--color-border));
    border-left-color: #c45145;
    background: color-mix(in srgb, #c45145 5%, var(--color-surface));
}

.status-alert-line {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.status-alert-text { flex: 1 1 260px; margin: 0; font-size: 0.86rem; line-height: 1.45; }
.status-alert .urgent-advice-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.status-board .urgent-advice-preview:not([hidden]) { margin-top: 10px; }

/* --- Phone chips (hidden until the phone layout below) -------------- */

.status-chips { display: none; }

.status-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: none;
    padding: 7px 10px 7px 12px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 700;
    scroll-snap-align: start;
    cursor: pointer;
}

.status-chip .badge { font-size: 0.64rem; }

/* --- The panel -------------------------------------------------------- */

.status-drawer-tabs {
    display: flex;
    gap: 6px;
    flex: none;
    padding: 10px 20px;
    border-bottom: 1px solid var(--color-border);
    overflow-x: auto;
}

.status-drawer-tabs button {
    padding: 5px 12px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: none;
    color: var(--color-text-muted);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
}

.status-drawer-tabs button.is-active {
    border-color: var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 10%, transparent);
    color: var(--color-primary);
}

.status-drawer-slot:empty { display: none; }
.status-drawer-slot { margin-bottom: 16px; }
.status-drawer-slot > * { margin: 0 !important; }

.status-drawer-section h3 { margin: 0 0 8px; font-size: 1rem; }
.status-drawer-section h4 { margin: 18px 0 8px; font-size: 0.78rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.status-drawer-section p { font-size: 0.86rem; line-height: 1.5; }
.status-drawer-lead { margin-top: 0; }
.status-drawer-eyebrow-text { color: var(--color-text-muted); font-size: 0.72rem !important; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; }

.status-drawer-readings {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin: 12px 0 0;
}

.status-drawer-readings div { padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 10px; }
.status-drawer-readings dt { color: var(--color-text-muted); font-size: 0.68rem; font-weight: 700; }
.status-drawer-readings dd { margin: 2px 0 0; font-size: 0.84rem; font-weight: 700; }
.status-drawer-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.status-drawer-recommendation { margin-top: 10px; }

/* Card titles that open a panel read as headings, not as (i) icons. */
.info-icon.status-card-title {
    width: auto;
    height: auto;
    border: 0;
    border-radius: 0;
    background: none;
    font-size: inherit;
    line-height: inherit;
}

/* --- Phones: one row of chips instead of stacked cards --------------- */

@media (max-width: 700px) {
    .status-chips {
        display: flex;
        gap: 8px;
        margin: 0 -16px;
        padding: 2px 16px 4px;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
    }

    .status-chips::-webkit-scrollbar { display: none; }

    [data-status-card]:not(.status-drawer-slot > *) { display: none !important; }

    .status-drawer-tabs { padding: 8px 14px; }

    .status-row { grid-template-columns: minmax(0, 1fr); grid-template-areas: "label" "main" "sentence" "badge"; }
    .status-row .badge { justify-self: start; margin-top: 4px; }
}

/* The alert stays a row that wraps, whatever older phone rules say about
   .urgent-advice-main — a column made the text's flex-basis a height. */
.status-board .status-alert-line { flex-direction: row !important; align-items: center !important; }
.status-board .status-alert-line > .status-alert-text { flex: 1 1 0; min-width: min(240px, 100%); }

/* The panel is narrow; the freshness readings get two columns there. */
.status-drawer .current-status-freshness { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.status-drawer .current-status-freshness-item { min-width: 0; white-space: normal; }
.status-drawer .current-status-freshness-item small,
.status-drawer .current-status-freshness-item strong { overflow: visible; text-overflow: clip; white-space: normal; }

@media (max-width: 700px) {
    .status-board .status-alert .urgent-advice-actions { width: 100%; }
    .status-board .status-alert .urgent-advice-actions .button { flex: 1 1 0; }
}

/* Three readings of the same four weeks: heart rate, pace, plan. */
@media (min-width: 701px) {
    .zones-use-card .zones-use-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* Tomorrow + next seven days in rows (plan_calendar.html). */
.calendar-outlook-summary { display: block; }
.calendar-outlook-tomorrow {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 320px;
    min-width: 0;
    padding: 0 12px 0 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.calendar-outlook-tomorrow:hover .calendar-outlook-advice { color: var(--color-text); }
/* No outline when clicked (the panel also hands focus back here when it
   closes); keyboard focus still gets a visible, on-brand ring. */
.calendar-outlook-tomorrow:focus { outline: none; }
.calendar-outlook-tomorrow:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--color-primary) 55%, transparent);
    outline-offset: 3px;
    border-radius: 6px;
}
.calendar-outlook-advice { color: var(--color-text-muted); }
.calendar-outlook-tomorrow .badge { margin-left: auto; flex: none; }
.calendar-outlook-week {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 320px;
    color: inherit;
    text-decoration: none;
}
.status-drawer-verdict { margin-bottom: 12px; }
.status-drawer-verdict h3 { margin: 4px 0 6px; }
.status-drawer-session { margin: 0; font-size: 0.84rem !important; }
.status-drawer-primary { margin-bottom: 8px; }

@media (max-width: 700px) {
    /* The strip stacks on phones (style.css), and a flex-basis in a column
       is a height — so the two halves size to their content instead. */
    .calendar-outlook-tomorrow,
    .calendar-outlook-week { flex: none; width: 100%; }
    .calendar-outlook-tomorrow { flex-wrap: wrap; padding: 0 0 10px; border-right: 0; border-bottom: 1px solid var(--color-border); }
    .calendar-outlook-week { flex-wrap: wrap; }
    .calendar-outlook-tomorrow .badge { margin-left: 0; }
}


/* ==========================================================================
   Status board in the outlook strip's concise style: light grey strip,
   thin border, small type, one line per item (.calendar-outlook-summary).
   ========================================================================== */

.status-board { gap: 8px; margin: 10px 0 8px; }

.status-board .status-alert,
.status-board .urgent-advice-card.status-alert,
.status-board .evening-recovery.status-card {
    padding: 9px 13px;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background: var(--color-bg-alt);
    box-shadow: none;
    font-size: 0.8rem;
    line-height: 1.4;
}

/* The one colour cue each keeps: a thin left rule for its level. */
.status-board .status-alert { border-left: 4px solid #b3941f; }
.status-board .urgent-advice-card.status-alert { border-left-color: #c45145; }
.status-board .evening-recovery.status-card { border-left: 1px solid var(--color-border); }
.status-board .evening-recovery-protect.status-card { border-left: 4px solid #b3521f; }

.status-board .status-alert-line { gap: 8px; }
.status-board .status-alert-text { font-size: 0.8rem; }
.status-board .status-alert .urgent-advice-actions { gap: 6px; }
.status-board .status-alert .button-compact { padding: 4px 10px; font-size: 0.74rem; min-height: 0; }
.status-board .status-link { font-size: 0.76rem; }
.status-board .urgent-advice-dismiss { top: 50%; transform: translateY(-50%); width: 24px; height: 24px; font-size: 1rem; }
.status-board .urgent-advice-card.status-alert { padding-right: 36px; }

/* Tonight's summary as one strip row: label, title, detail, badge, caret. */
.status-strip-row {
    display: flex !important;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.status-strip-label { flex: none; }
.status-strip-main { flex: none; font-weight: 600; }
.status-strip-detail {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--color-text-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
}
.status-board .evening-recovery > summary.evening-recovery-header::after { margin-left: 0; }
.status-board .evening-recovery[open] .status-strip-detail { white-space: normal; }
.status-board .evening-recovery[open] > summary { padding-bottom: 8px; border-bottom: 1px solid var(--color-border); }
.status-board .evening-recovery-grid { margin-top: 10px; }

@media (max-width: 700px) {
    .status-strip-row { flex-wrap: wrap; }
    .status-strip-detail { flex-basis: 100%; white-space: normal; order: 5; }
    .status-board .urgent-advice-dismiss { top: 8px; transform: none; }
}

/* Plan header actions: small pills. They're occasional tools (details,
   adjust, sync), not the page's main content, so they shouldn't carry the
   visual weight of the calendar's own calls to action. */
.plan-header-card .dashboard-actions { gap: 6px; align-items: center; }
.plan-header-card .dashboard-actions .button {
    min-height: 0;
    padding: 5px 12px;
    border-width: 1px;
    border-radius: 999px;
    box-shadow: none;
    font-size: 0.78rem;
    font-weight: 650;
    line-height: 1.2;
}
.plan-header-card .dashboard-actions .button:hover { transform: none; }
.plan-header-card .dashboard-actions .badge-count { font-size: 0.66rem; }

.plan-header-card .dashboard-actions .button-primary { border-color: var(--color-primary); }

@media (max-width: 700px) {
    /* Wrap rather than scroll: a clipped "Sync Da…" reads as broken. */
    .plan-header-card .dashboard-actions { flex-wrap: wrap; gap: 6px; overflow: visible; }
    .plan-header-card .dashboard-actions .button,
    .plan-header-card .dashboard-actions button {
        flex: 0 0 auto;
        min-height: 34px;
        padding: 5px 11px;
        font-size: 0.74rem;
    }
}


/* Recovery tab count: tonight's routine is ready and not yet recorded. */
.nav-link { position: relative; }
.nav-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    margin-left: 5px;
    padding: 0 5px;
    border-radius: 999px;
    background: #c45145;
    color: #fff;
    font-size: 0.66rem;
    font-weight: 800;
    line-height: 1;
    vertical-align: 2px;
}
@media (max-width: 700px) {
    /* Icon-only nav: the count sits on the icon's corner. */
    .nav-count { position: absolute; top: 2px; right: 50%; margin: 0 -22px 0 0; }
}

/* Outlook strip: Today/Tonight · Tomorrow · Next 7 days. */
.calendar-outlook-segment {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 260px;
    min-width: 0;
    padding: 0 12px 0 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.calendar-outlook-segment:last-child { border-right: 0; padding-right: 0; }
.calendar-outlook-segment .badge { margin-left: auto; flex: none; }
.calendar-outlook-segment:focus { outline: none; }
.calendar-outlook-segment:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--color-primary) 55%, transparent);
    outline-offset: 3px;
    border-radius: 6px;
}
.status-board-tonight { margin: 0 0 16px; }
.evening-recovery-why { margin-top: 10px; font-size: 0.78rem; color: var(--color-text-muted); }
.evening-recovery-why summary { cursor: pointer; color: var(--color-primary); font-weight: 700; }
.evening-recovery-why p { margin: 6px 0 0; line-height: 1.45; }

@media (max-width: 700px) {
    .calendar-outlook-segment { flex: none; width: 100%; flex-wrap: wrap; padding: 0 0 10px; border-right: 0; border-bottom: 1px solid var(--color-border); }
    .calendar-outlook-segment:last-child { border-bottom: 0; padding-bottom: 0; }
    .calendar-outlook-segment .badge { margin-left: 0; }
}

/* Visually hidden, still read by screen readers. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Segments size to their content; only the advice text wraps. */
.calendar-outlook-segment { flex: 1 1 auto; }
.calendar-outlook-segment > strong,
.calendar-outlook-main { flex: none; white-space: nowrap; }
.calendar-outlook-advice { min-width: 0; }

/* --- Run context features (feature_views.py) ---------------------------- */

.feature-modal .modal-dialog { max-width: 640px; }
.feature-page { max-width: 720px; }

.run-extras-slot:empty { display: none; }
.run-extras { margin-top: 8px; }
.run-shoe-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.run-shoe-form select { padding: 6px 8px; border-radius: 8px; border: 1px solid var(--color-border); background: var(--color-bg); color: var(--color-text); font: inherit; }
.run-extras-link { font-size: 0.85rem; }
.autosave-note { margin: 0; font-size: 0.8rem; }
.route-history-table,
.health-preview-table,
.race-card-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin: 8px 0; }
.route-history-table th, .route-history-table td,
.health-preview-table th, .health-preview-table td,
.race-card-table th, .race-card-table td { padding: 6px 8px; border-bottom: 1px solid var(--color-border); text-align: left; }
.route-history-table tr.is-current td { font-weight: 600; }
.workout-watch-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.workout-watch-actions .modal-meta { flex-basis: 100%; margin: 0; }

.shoe-list { list-style: none; padding: 0; margin: 0 0 20px; display: grid; gap: 12px; }
.shoe-row { border: 1px solid var(--color-border); border-radius: var(--radius); padding: 12px 14px; }
.shoe-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.shoe-meter { height: 8px; border-radius: 999px; background: var(--color-bg-alt); margin: 10px 0 6px; overflow: hidden; }
.shoe-meter span { display: block; height: 100%; background: var(--color-primary); border-radius: inherit; }
.shoe-soon .shoe-meter span { background: #d99a1e; }
.shoe-replace .shoe-meter span { background: #c8553d; }
.shoe-retired { opacity: 0.65; }
.shoe-actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; }
.shoe-add-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.checkbox-label { display: inline-flex; align-items: center; gap: 8px; font-size: 0.9rem; }

.health-banner {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
    margin: 12px 0; padding: 10px 14px; border-radius: var(--radius);
    background: var(--color-warning-soft, #fff4e0); border: 1px solid var(--color-border);
}
.health-banner-actions { display: flex; gap: 8px; align-items: center; }
.health-kinds { border: 0; padding: 0; margin: 0; display: grid; gap: 8px; }
.health-kinds legend { font-weight: 600; margin-bottom: 8px; }
.health-kind { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 10px; cursor: pointer; }
.health-kind.is-selected, .health-kind:has(input:checked) { border-color: var(--color-primary); }
.health-active, .health-preview { padding: 12px 14px; border-radius: var(--radius); background: var(--color-bg-alt); margin-bottom: 12px; }
.health-preview-table tr.is-paused td { color: var(--color-text-muted); }

.race-section { margin-bottom: 20px; }
.race-forecast { padding: 10px 14px; border-radius: var(--radius); background: var(--color-bg-alt); }
.race-forecast.is-warm { background: var(--color-warning-soft, #fff4e0); }
.race-forecast.is-danger { background: var(--color-danger-soft, #fde8e4); }
.race-timeline { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.race-timeline li {
    display: grid; grid-template-columns: 5.5em 1fr auto; gap: 2px 10px;
    padding: 8px 10px; border-radius: 10px; border: 1px solid var(--color-border);
}
.race-timeline li.is-next { border-color: var(--color-primary); background: var(--color-positive-soft, #eef7f1); }
.race-timeline li.is-past { opacity: 0.55; }
.race-timeline-time { font-variant-numeric: tabular-nums; font-weight: 600; }
.race-timeline-label { font-weight: 600; }
.race-timeline-countdown { color: var(--color-text-muted); font-size: 0.85rem; text-align: right; }
.race-timeline-detail { grid-column: 2 / -1; color: var(--color-text-muted); font-size: 0.88rem; }
.race-warmup-steps { margin: 0 0 10px; padding-left: 18px; }
.race-timer { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.race-timer-display { font-size: 2rem; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 4ch; }
.race-card-table td:nth-child(2), .race-card-table td:nth-child(3) { font-variant-numeric: tabular-nums; }
.race-card-table td.is-slow { color: #c8553d; }
.race-card-table td.is-fast { color: var(--color-primary); }
.race-card-note { color: var(--color-text-muted); font-size: 0.85rem; }
.race-location-search { display: flex; gap: 8px; }
.race-location-search input { flex: 1; min-width: 0; }
.race-places { border: 0; padding: 0; display: grid; gap: 6px; }

.scenario-slider { width: 100%; accent-color: var(--color-primary); }
.scenario-slider-value { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 5.5em; text-align: right; }

@media (max-width: 700px) {
    .shoe-add-grid { grid-template-columns: 1fr; }
    .race-timeline li { grid-template-columns: 4.8em 1fr; }
    .race-timeline-countdown { grid-column: 2; text-align: left; }
}
#scenario-result { transition: opacity 0.15s ease; }
#scenario-result.is-updating { opacity: 0.55; }
.scenario-input-group:has(.scenario-slider) { display: flex; align-items: center; gap: 10px; width: 100%; }
.scenario-input-group .scenario-slider { flex: 1; min-width: 0; width: auto; }
@media (max-width: 700px) {
    /* Title above the actions on phones and small tablets: with four or
       five actions a side-by-side row squeezed the title to one word per line. */
    .plan-header-card .dashboard-header { grid-template-columns: 1fr; gap: 12px; }
}
.plan-header-card .dashboard-actions a.button { display: inline-flex; align-items: center; }

/* --- Brand E type: Archivo throughout ------------------------------------ */
button, input, select, textarea { font-family: inherit; }
h1, h2, h3 { font-family: var(--font-body); letter-spacing: -0.015em; }
h1 { font-weight: 800; }
h2, h3 { font-weight: 700; }

/* Re-pace offer after a race or tune-up (plan_suggestions.repace_offer). */
.repace-banner {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
    margin: 12px 0; padding: 10px 14px; border-radius: var(--radius);
    background: var(--color-info-soft); border: 1px solid var(--color-border);
}

/* --- Login + sample mode (training/sample_mode.py) ---------------------- */
.login-layout { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 560px); gap: 48px; justify-content: center; align-items: start; }
.login-panel h2 { margin: 0 0 8px; }
.sample-panel { padding: 24px 26px; border: 1px solid var(--color-border); border-radius: calc(var(--radius) + 4px); background: var(--color-bg-alt); }
.sample-form { display: flex; flex-direction: column; gap: 18px; margin-top: 18px; }
.sample-choice { border: 0; padding: 0; margin: 0; }
.sample-choice legend { font-weight: 700; font-size: 0.92rem; margin-bottom: 8px; }
/* One row per question: every answer the same width, evenly spaced. */
.sample-options { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; }
.sample-option { position: relative; min-width: 0; }
.sample-option input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.sample-option > span {
    display: flex; align-items: center; justify-content: center; box-sizing: border-box; width: 100%; height: 44px;
    padding: 0 4px; border-radius: 999px; border: 1px solid var(--color-border); background: var(--color-surface);
    font-size: 0.88rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-variant-numeric: tabular-nums; cursor: pointer;
}
.sample-hint { margin: -4px 0 8px; font-size: 0.8rem; color: var(--color-text-muted); }
.sample-scale { display: flex; justify-content: space-between; margin-top: 6px; font-size: 0.75rem; color: var(--color-text-muted); }
.sample-option input:checked + span { border-color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface)); color: var(--color-primary); }
.sample-option input:focus-visible + span { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.sample-banner {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
    max-width: var(--max-width); margin: 12px auto 0; padding: 10px 16px; border-radius: var(--radius);
    background: var(--color-warning-soft); border: 1px solid var(--color-border); box-sizing: border-box;
}
.sample-banner-actions { display: flex; align-items: center; gap: 14px; }
@media (max-width: 860px) {
    .login-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
    .sample-banner { margin: 10px 16px 0; }
}
/* A run's plain-language read-out is information, not a brand moment or
   a warning: neutral, whichever way the run went. */
.workout-interpretation {
    border-left-color: var(--color-text-muted);
    background: var(--color-bg-alt);
}
.sample-banner { max-width: calc(var(--max-width) - 48px); }
.sample-preview { margin: 0; padding: 10px 12px; border-radius: 10px; background: var(--color-surface); border: 1px solid var(--color-border); font-size: 0.9rem; }

/* Sample-mode guided tour (training/js/sample-tour.js). */
.tour-target {
    position: relative;
    z-index: 60;
    border-radius: 10px;
    outline: 3px solid var(--color-primary);
    outline-offset: 3px;
    box-shadow: 0 0 0 9999px rgba(17, 17, 16, 0.35);
}
.tour-card {
    position: fixed; z-index: 70; box-sizing: border-box; padding: 16px 18px 14px;
    border-radius: 16px; background: var(--color-surface); color: var(--color-text);
    border: 1px solid var(--color-border); box-shadow: var(--app-shadow);
}
.tour-count { margin: 0; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-primary); }
.tour-title { margin: 4px 0 6px; font-size: 1.1rem; }
.tour-body { margin: 0 0 14px; font-size: 0.92rem; line-height: 1.45; }
.tour-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tour-nav { display: flex; gap: 8px; }
.tour-skip { border: 0; background: none; padding: 8px 0; font: inherit; font-size: 0.85rem; color: var(--color-text-muted); cursor: pointer; text-decoration: underline; }
@media (max-width: 420px) {
    /* Five answers still fit one row on the narrowest phones. */
    .sample-panel { padding: 18px 14px; }
    .sample-options { gap: 6px; }
    .sample-option > span { font-size: 0.8rem; }
}

/* ==========================================================================
   Calendar page: one gap between every card. The cards each brought their
   own margins (12, 22, 18, 16, 8px...), so the spacing depended on which
   banners happened to be showing. The stack owns the gap now; a card's own
   margins are zeroed so they can't add to it.
   ========================================================================== */

.container.calendar-stack {
    display: flex;
    flex-direction: column;
    gap: var(--calendar-card-gap, 16px);
}
.container.calendar-stack > * { margin-top: 0; margin-bottom: 0; min-width: 0; }
/* The status board is only phone chips on wider screens, where the chips
   are hidden — an empty board would otherwise count as a card and double
   the gap around it. */
.container.calendar-stack > .status-board:not(:has(> :not(.status-chips))) { display: none; }
@media (max-width: 700px) {
    .container.calendar-stack { --calendar-card-gap: 12px; }
    .container.calendar-stack > .status-board:not(:has(> :not(.status-chips))) { display: grid; }
}

/* ==========================================================================
   Status popups (toasts.js): lower left, above the phone nav pill, gone
   after five seconds with a bar showing the time left.
   ========================================================================== */

.toast-region {
    position: fixed;
    z-index: 2900;
    left: calc(16px + env(safe-area-inset-left));
    bottom: calc(16px + env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: min(380px, calc(100vw - 32px));
    pointer-events: none;
}
.toast-region:empty { display: none; }
.toast {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    overflow: hidden;
    padding: 12px 12px 14px 16px;
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-good);
    border-radius: var(--radius);
    background: var(--color-surface-raised);
    color: var(--color-text);
    box-shadow: var(--app-shadow);
    font-size: 0.9rem;
    line-height: 1.4;
    pointer-events: auto;
    animation: toast-in 180ms ease-out;
    transition: opacity 200ms ease, transform 200ms ease;
}
.toast-error { border-left-color: #c45145; }
.toast-warning { border-left-color: var(--color-accent); }
.toast-info { border-left-color: var(--color-series); }
.toast-text { flex: 1 1 auto; min-width: 0; }
.toast-close {
    flex: none;
    width: 24px;
    height: 24px;
    margin: -2px -2px 0 0;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--color-text-muted);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}
.toast-close:hover, .toast-close:focus-visible { background: var(--color-bg-alt); color: var(--color-text); }
.toast::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    height: 3px;
    width: 100%;
    background: currentColor;
    opacity: 0.18;
    transform-origin: left;
    animation: toast-countdown var(--toast-duration, 5000ms) linear forwards;
}
.toast:hover::after, .toast:focus-within::after { animation-play-state: paused; }
.toast.is-leaving { opacity: 0; transform: translateY(8px); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-countdown { to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; transition: none; }
    .toast::after { display: none; }
}
@media (max-width: 700px) {
    /* Above the floating nav pill. */
    .toast-region { bottom: calc(var(--mobile-nav-height) + 24px + env(safe-area-inset-bottom)); }
}

/* ==========================================================================
   Track Editorial theme
   --------------------------------------------------------------------------
   The EveryMile mark supplies the visual grammar: warm paper, ink, track
   red, rounded lanes, and small finish-line details. Semantic states keep
   their own colors so the brand never reads as an injury or warning.
   ========================================================================== */

body {
    background: var(--color-bg);
}

h1,
h2,
h3 {
    color: var(--color-text);
    font-family: var(--font-body);
    font-weight: 800;
    letter-spacing: -0.025em;
}

h1 {
    letter-spacing: -0.04em;
}

.brand-name {
    font-family: var(--font-display);
    letter-spacing: -0.055em;
}

.site-header {
    background: color-mix(in srgb, var(--color-bg) 88%, transparent);
    border-color: var(--color-border);
    backdrop-filter: blur(16px) saturate(115%);
}

.site-nav-plan .nav-link {
    position: relative;
}

@media (min-width: 701px) {
    .site-nav-plan .nav-link {
        padding: 12px 2px;
    }

    .site-nav-plan .nav-link::after {
        content: "";
        position: absolute;
        right: 2px;
        bottom: 3px;
        left: 2px;
        height: 3px;
        border-radius: var(--radius-pill);
        background: var(--color-primary);
        opacity: 0;
        transition: opacity 120ms ease;
    }

    .site-nav-plan .nav-link.is-active::after {
        opacity: 1;
    }

    .site-nav-plan .nav-link:not(.is-active):is(:hover, :focus-visible)::after {
        opacity: 0.35;
    }
}

:is(
    .plan-card,
    .plan-header-card,
    .current-status-card,
    .auto-reg-card,
    .twin-card,
    .recovery-card,
    .plan-details-card,
    .integration-card,
    .zones-source-card,
    .zones-primary-section,
    .zones-secondary-section,
    .zones-use-card,
    .calibration-card
) {
    border-color: var(--color-border);
    border-radius: var(--radius-card);
    background: var(--color-surface);
    box-shadow: var(--app-shadow-small);
}

html[data-theme="dark"] :is(
    .plan-card,
    .plan-header-card,
    .current-status-card,
    .auto-reg-card,
    .twin-card,
    .recovery-card,
    .plan-details-card,
    .integration-card,
    .zones-source-card,
    .zones-primary-section,
    .zones-secondary-section,
    .zones-use-card,
    .calibration-card
) {
    background: var(--color-surface);
}

/* The calendar heading is a standard card, not an extension of the page
   canvas. Keep this explicit so older .plan-header-card background rules
   cannot give this one a secondary/tinted surface. */
.calendar-title-card.plan-header-card,
html[data-theme="dark"] .calendar-title-card.plan-header-card {
    background: var(--color-bg-alt);
    border-color: var(--color-border);
    box-shadow: var(--app-shadow-small);
}

.button {
    border-radius: var(--radius-pill);
    font-weight: 700;
}

.button-primary {
    border: 1px solid var(--color-primary);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--color-text) 12%, transparent);
}

.button-secondary {
    border-color: color-mix(in srgb, var(--color-text) 30%, var(--color-border));
    background: color-mix(in srgb, var(--color-surface) 78%, transparent);
}

.button-secondary:is(:hover, :focus-visible) {
    background: var(--color-brand-soft);
}

:is(a, button, input, select, textarea, summary):focus-visible {
    outline: 3px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
    outline-offset: 3px;
}

:is(
    .today-card-eyebrow,
    .today-dashboard-section-label,
    .recovery-eyebrow,
    .recovery-card-kicker,
    .zones-eyebrow
) {
    color: var(--color-primary);
}

.today-card-eyebrow {
    background: var(--color-brand-soft);
}

.today-dashboard.today-card {
    overflow: hidden;
    border-radius: calc(var(--radius-card) + 2px);
    background: var(--color-surface-raised);
    box-shadow: var(--app-shadow-small);
}

.today-dashboard::before {
    width: 5px;
    border-radius: var(--radius-pill);
    background: var(--color-primary);
}

.today-dashboard-context,
.today-dashboard-session .calendar-workout-card,
.evening-recovery,
.evening-recovery-step,
.evening-recovery-tomorrow {
    border-color: var(--color-border);
}

.evening-recovery {
    border-left-color: var(--color-primary);
    background: color-mix(in srgb, var(--color-bg-alt) 78%, var(--color-surface));
}

.evening-recovery-full {
    border-left-color: var(--color-warning);
}

.evening-recovery-protect {
    border-left-color: var(--color-danger);
}

/* Calendar cells remain quiet paper surfaces. Phase is a lane stripe rather
   than a full-cell wash, leaving workout type and completion easy to scan. */
.calendar-grid {
    gap: 1px;
    border-color: var(--calendar-grid-line);
    border-radius: var(--radius-card);
    background: var(--calendar-grid-line);
}

.calendar-day {
    background: var(--color-surface);
}

.calendar-day.calendar-day-phase-base {
    background: linear-gradient(var(--phase-base) 0 3px, transparent 3px), var(--color-surface);
}

.calendar-day.calendar-day-phase-build {
    background: linear-gradient(var(--phase-build) 0 3px, transparent 3px), var(--color-surface);
}

.calendar-day.calendar-day-phase-peak {
    background: linear-gradient(var(--phase-peak) 0 3px, transparent 3px), var(--color-surface);
}

.calendar-day.calendar-day-phase-cutback {
    background: linear-gradient(var(--phase-cutback) 0 3px, transparent 3px), var(--color-surface);
}

.calendar-day.calendar-day-phase-taper {
    background: linear-gradient(var(--phase-taper) 0 3px, transparent 3px), var(--color-surface);
}

.calendar-day-outside,
.calendar-day-outside.calendar-day-phase-base,
.calendar-day-outside.calendar-day-phase-build,
.calendar-day-outside.calendar-day-phase-peak,
.calendar-day-outside.calendar-day-phase-cutback,
.calendar-day-outside.calendar-day-phase-taper {
    background: var(--color-surface);
}

.calendar-phase-column.calendar-day-phase-base { background: var(--phase-base); }
.calendar-phase-column.calendar-day-phase-build { background: var(--phase-build); }
.calendar-phase-column.calendar-day-phase-peak { background: var(--phase-peak); }
.calendar-phase-column.calendar-day-phase-cutback { background: var(--phase-cutback); }
.calendar-phase-column.calendar-day-phase-taper { background: var(--phase-taper); }

.calendar-phase-column-label {
    color: #ffffff;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

html[data-theme="dark"] .calendar-phase-column-label {
    color: #121110;
}

.calendar-day-today {
    border-color: var(--color-primary);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}

.calendar-day-today .calendar-day-number {
    color: var(--color-primary);
}

.calendar-weekday-header,
.calendar-week-total {
    background: var(--color-bg-alt);
}

.week-strip-day.is-today {
    border-color: var(--color-primary);
    background: var(--color-brand-soft);
}

.week-strip-dot-done { background: var(--color-positive); }
.week-strip-dot-missed { background: var(--color-danger); }

/* Data has a stable language: blue is measured, red is the selected moment
   or goal, and muted dashed marks are projections. */
.chart-bar-planned-easy,
.chart-legend-swatch-planned-easy,
.chart-swatch-planned {
    fill: var(--color-positive-soft);
    background: var(--color-positive-soft);
}

.chart-bar-planned-hard,
.chart-legend-swatch-planned-hard {
    fill: var(--color-warning-soft);
    stroke: var(--color-warning);
    background: var(--color-warning-soft);
    border-color: var(--color-warning);
}

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

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

.chart-trend-line,
.chart-marker-median {
    stroke: var(--color-series);
}

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

.chart-today-marker,
.chart-marker-goal {
    stroke: var(--color-primary);
}

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

.chart-bar-planned-easy-future,
.chart-bar-planned-hard-future {
    fill: color-mix(in srgb, var(--color-text-muted) 13%, var(--color-surface));
    stroke: var(--color-text-muted);
    stroke-dasharray: 3 3;
    opacity: 0.78;
}

.chart-legend-swatch-planned-future {
    background: var(--color-text-muted);
    opacity: 0.55;
}

.chart-experience {
    border-radius: var(--radius-card);
    box-shadow: none;
}

.chart-selection {
    border-left: 3px solid var(--color-primary);
    background: var(--color-brand-soft);
}

/* Plan details use rules and spacing for hierarchy; contained sub-sections
   no longer compete with the outer editorial card. */
.plan-details-card {
    padding: clamp(20px, 3vw, 30px);
}

.plan-details-card-adjustment {
    border-left: 4px solid var(--color-primary);
    background: color-mix(in srgb, var(--color-brand-soft) 46%, var(--color-surface));
}

html[data-theme="dark"] .plan-details-card-adjustment {
    background: color-mix(in srgb, var(--color-brand-soft) 46%, var(--color-surface));
}

.plan-details-card :is(.plan-summary, .risk-factor, .insights-link) {
    box-shadow: none;
}

.plan-details-nav,
.zones-tabs,
.form-wizard-progress {
    border-radius: var(--radius-pill);
    box-shadow: none;
}

.plan-details-nav a,
.zones-tab,
.form-wizard-progress-button {
    border-radius: var(--radius-pill);
}

/* Recovery is calm and informational. Green remains an outcome, amber a
   caution, and red a problem state—the brand rail is reserved for focus. */
.recovery-page .recovery-card {
    background: var(--color-surface);
    box-shadow: none;
}

.recovery-decision {
    border-color: color-mix(in srgb, var(--color-positive) 28%, var(--color-border));
    border-left-color: var(--color-positive);
    border-radius: var(--radius-card);
    background: linear-gradient(120deg, var(--color-positive-soft), var(--color-surface));
}

.recovery-decision-decrease {
    border-color: color-mix(in srgb, var(--color-danger) 30%, var(--color-border));
    border-left-color: var(--color-danger);
    background: linear-gradient(120deg, var(--color-danger-soft), var(--color-surface));
}

.recovery-confidence {
    background: color-mix(in srgb, var(--color-surface-raised) 84%, transparent);
}

.recovery-coverage {
    border-radius: var(--radius-card);
    background: var(--color-bg-alt);
}

.toast-error { border-left-color: var(--color-danger); }
.toast-warning { border-left-color: var(--color-warning); }
.toast-info { border-left-color: var(--color-info); }

@media (max-width: 700px) {
    body {
        background: var(--color-bg);
    }

    .site-header {
        background: var(--color-bg);
    }

    .site-nav-plan {
        padding: 5px;
        border-radius: var(--radius-pill);
        background: color-mix(in srgb, var(--color-surface-raised) 94%, transparent);
        box-shadow: 0 12px 30px color-mix(in srgb, var(--color-text) 15%, transparent);
    }

    .site-nav-plan .nav-link {
        border-radius: var(--radius-pill);
    }

    .site-nav-plan .nav-link.is-active {
        background: transparent;
        color: var(--color-primary);
    }

    .site-nav-plan .nav-link::after {
        content: "";
        position: absolute;
        left: 50%;
        bottom: 3px;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--color-primary);
        opacity: 0;
        transform: translateX(-50%) scale(0.5);
        transition: opacity 150ms ease, transform 150ms ease;
    }

    .site-nav-plan .nav-link.is-active::after {
        opacity: 1;
        transform: translateX(-50%) scale(1);
    }

    .agenda-day {
        box-shadow: none;
    }
}
