/* Colors/type below are aliases onto brand/tokens/tokens.css's --th-*
   custom properties (loaded via brand-tokens.css) — that file is the
   single source of truth for the palette; keep these in sync with it
   rather than hardcoding hex here. */
:root {
    --bg: var(--th-bg);
    --card: var(--th-surface);
    --text: var(--th-text);
    --muted: var(--th-text-muted);
    --accent: var(--th-accent);
    --on-accent: var(--th-on-accent);
    --border: var(--th-line);
    --surface-2: var(--th-surface-2);
    --positive: var(--th-positive);
    --negative: var(--th-negative);
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.12);
    /* The left nav rail always renders in the brand's dark "ink" surface,
       a fixed chrome element (like the app
       icon's own background) rather than page content. */
    --sidebar-width: 220px;
    --sidebar-bg: var(--th-ink);
    --sidebar-border: var(--th-line);
    --sidebar-text: var(--th-text-muted);
    --sidebar-text-active: var(--th-chalk);
    --sidebar-hover-bg: rgba(255, 255, 255, 0.06);
    --sidebar-active-bg: rgba(255, 255, 255, 0.1);
    color-scheme: dark;
}

.lucide {
    width: 16px;
    height: 16px;
    stroke-width: 2;
    flex-shrink: 0;
    vertical-align: -3px;
}
.icon-sm { width: 13px; height: 13px; }
.icon-lg { width: 22px; height: 22px; vertical-align: -5px; }
.icon-xl { width: 40px; height: 40px; vertical-align: -10px; }
h1 .lucide { width: 22px; height: 22px; vertical-align: -3px; }
.logo .lucide { width: 20px; height: 20px; color: var(--accent); }
.disc-icon .lucide, .tile-icon .lucide { width: 20px; height: 20px; }

* { box-sizing: border-box; }

body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--th-font-ui);
    margin: 0;
    padding: 24px 16px 40px calc(var(--sidebar-width) + 16px);
    -webkit-font-smoothing: antialiased;
}
/* The pre-login connect screen has no sidebar to make room for. */
body.no-sidebar { padding-left: 16px; }

/* The left nav rail — fixed for the life of the scroll, its own deep-purple
   brand color (see --sidebar-* in :root). Everything
   that used to live in a horizontal sticky <header> above the content now
   lives here instead, freeing the full page width — including the sticky
   filter bar — for content. */
header {
    position: fixed;
    overflow-x: hidden;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-width);
    background: var(--sidebar-bg);
    border-right: 1px solid var(--sidebar-border);
    overflow-y: auto;
    z-index: 300;
}

.sidebar-inner { display: flex; flex-direction: column; height: 100%; padding: 20px 14px; gap: 4px; }

.logo { display: flex; align-items: center; text-decoration: none; padding: 4px 10px 22px; }
.logo-full { width: 100%; max-width: 188px; height: auto; display: block; }
.logo-compact { height: 28px; width: auto; display: none; }

/* overflow-y:auto + min-height:0 — without this, once the nav list's
   items outgrow the space flex left for them above the theme
   toggle/Settings footer, they don't push those footer items down (a
   shrunk flex item's overflowing content doesn't affect sibling layout);
   it just visually spills over them. Scrolling internally instead keeps
   the footer always clear, regardless of how many nav items there are. */
.sidenav { display: flex; flex-direction: column; gap: 2px; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }
.sidenav a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 8px;
    color: var(--sidebar-text);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    transition: background 0.12s, color 0.12s;
}
.sidenav a .lucide { width: 18px; height: 18px; }
.sidenav a:hover { color: var(--sidebar-text-active); background: var(--sidebar-hover-bg); }
.sidenav a.active { color: var(--sidebar-text-active); background: var(--sidebar-active-bg); box-shadow: inset 3px 0 0 var(--accent); }
.sidenav-divider { height: 1px; background: var(--sidebar-border); margin: 8px 10px; }

/* Collapsible nav groups — see _nav.html's collapse/expand script. */
.nav-group { display: flex; flex-direction: column; }
.nav-group-header {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 10px 4px; margin-top: 4px;
    background: none; border: none; width: 100%; text-align: left; cursor: pointer;
    font: 600 11px/1 var(--th-font-ui); letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--sidebar-text); opacity: 0.6;
}
.nav-group-header:hover { opacity: 1; }
.nav-group-chevron { width: 13px !important; height: 13px !important; transition: transform 0.15s; }
.nav-group.is-collapsed .nav-group-chevron { transform: rotate(-90deg); }
.nav-group-items { display: flex; flex-direction: column; gap: 2px; }
.nav-group.is-collapsed .nav-group-items { display: none; }

.sidenav-settings, .sidenav-bottom-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    color: var(--sidebar-text);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    transition: background 0.12s, color 0.12s;
    background: none;
    border: none;
    width: 100%;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}
.sidenav-settings {
    margin-top: 8px;
    padding: 15px 10px 9px;
    border-top: 1px solid var(--sidebar-border);
}
.sidenav-settings .lucide, .sidenav-bottom-item .lucide { width: 18px; height: 18px; flex-shrink: 0; }
.sidenav-settings:hover, .sidenav-settings.active, .sidenav-bottom-item:hover, .sidenav-bottom-item.active { color: var(--sidebar-text-active); }
.sidenav-settings:disabled { opacity: 0.6; cursor: default; }

/* Below ~760px the rail collapses to icons only, reclaiming horizontal
   space for content rather than a hamburger menu — this app is mostly
   used at desktop widths, so a full mobile nav pattern isn't worth it. */
@media (max-width: 760px) {
    :root { --sidebar-width: 60px; }
    .sidebar-inner { padding: 16px 8px; align-items: center; }
    .logo { padding: 4px 0 18px; justify-content: center; }
    .logo-full { display: none; }
    .logo-compact { display: block; }
    .sidenav a, .sidenav-settings, .sidenav-bottom-item { justify-content: center; padding: 10px; width: 100%; }
    .sidenav a span, .sidenav-settings span, .sidenav-bottom-item span { display: none; }
    /* Icon-only rail has no room for a text group label, and nothing to
       collapse toward — every group always shows, in full, with no header. */
    .nav-group-header { display: none; }
    .nav-group.is-collapsed .nav-group-items { display: flex; }
}

.filter-bar-title {
    font-family: var(--th-font-display);
    font-weight: 800;
    font-stretch: 125%;
    letter-spacing: -0.02em;
}

.settings-layout { display: flex; flex-direction: column; gap: 16px; margin-top: -8px; }
.settings-panels { display: flex; flex-direction: column; gap: 20px; min-width: 0; flex: 1; }

.settings-tabs {
    display: flex;
    gap: 4px;
    overflow-x: auto;
    border-bottom: 1px solid var(--border);
    margin: 0 0 4px;
}
.settings-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 14px;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.settings-tab:hover { color: var(--text); }
.settings-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.settings-panel { display: none; flex-direction: column; gap: 20px; }
.settings-panel.active { display: flex; }

/* On wide screens the tab bar becomes a left sidebar instead — on narrow
   screens it stays a horizontally-scrollable strip (never wraps mid-word
   or clips off-screen, which a plain flex-wrap row used to do once there
   were enough tabs to not fit one line). */
@media (min-width: 860px) {
    .settings-layout { flex-direction: row; align-items: flex-start; gap: 24px; }
    .settings-tabs {
        flex-direction: column;
        overflow-x: visible;
        border-bottom: none;
        border-right: 1px solid var(--border);
        padding-right: 14px;
        width: 190px;
        flex-shrink: 0;
        gap: 2px;
    }
    .settings-tab {
        justify-content: flex-start;
        white-space: normal;
        border-bottom: none;
        border-left: 2px solid transparent;
        border-radius: 6px;
        margin-bottom: 0;
        padding: 9px 12px;
    }
    .settings-tab:hover { background: var(--surface-2); }
    .settings-tab.active { background: var(--surface-2); border-left-color: var(--accent); }
}

.theme-picker { display: inline-flex; gap: 4px; background: var(--surface-2); border-radius: 10px; padding: 4px; }
.theme-option {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 16px;
    background: none;
    border: none;
    border-radius: 8px;
    color: var(--muted);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.theme-option:hover { color: var(--text); }
.theme-option.active { background: var(--card); color: var(--text); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); }

.ask-card { display: flex; flex-direction: column; gap: 14px; }
.ask-messages { display: flex; flex-direction: column; gap: 14px; min-height: 320px; max-height: 60vh; overflow-y: auto; padding: 4px; }

/* Empty-state hero — this tool can see the same data every other page
   renders, so the blank state should sell that rather than read as a
   placeholder. */
.ask-hero { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 10px; padding: 32px 16px; }
.ask-hero-icon {
    display: flex; align-items: center; justify-content: center;
    width: 52px; height: 52px; border-radius: 50%;
    background: color-mix(in srgb, var(--accent) 14%, transparent);
    color: var(--accent);
    margin-bottom: 4px;
}
.ask-hero-icon .lucide { width: 24px; height: 24px; }
.ask-hero-title { margin: 0; font-family: var(--th-font-display); font-weight: 800; font-stretch: 125%; font-size: 22px; letter-spacing: -0.01em; }
.ask-hero-sub { margin: 0; max-width: 40ch; color: var(--muted); font-size: 14px; line-height: 1.5; }
.ask-chip-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 6px; max-width: 480px; }
.ask-chip {
    padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border);
    background: var(--card); color: var(--text); font-size: 13px; font-weight: 500;
    cursor: pointer; transition: background 0.12s, border-color 0.12s;
}
.ask-chip:hover { background: var(--surface-2); border-color: var(--muted); }

.ask-msg { display: flex; gap: 8px; align-items: flex-end; }
.ask-msg-user { justify-content: flex-end; }
.ask-msg-assistant { justify-content: flex-start; }
.ask-msg-avatar {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 26px; height: 26px; border-radius: 50%; margin-bottom: 2px;
    background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.ask-msg-avatar .lucide { width: 14px; height: 14px; }
.ask-msg-bubble {
    max-width: 75%;
    padding: 11px 15px;
    border-radius: 16px;
    font-size: 14px;
    line-height: 1.5;
}
.ask-msg-user .ask-msg-bubble { background: var(--th-surface-3); color: var(--th-text); border-bottom-right-radius: 4px; }
.ask-msg-assistant .ask-msg-bubble { background: var(--card); border: 1px solid var(--border); border-bottom-left-radius: 4px; box-shadow: var(--shadow-card); }
.ask-msg-pending { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.ask-msg-bubble p { margin: 0 0 8px; }
.ask-msg-bubble p:last-child { margin-bottom: 0; }
.ask-msg-bubble ul, .ask-msg-bubble ol { margin: 0 0 8px; padding-left: 20px; }
.ask-msg-bubble ul:last-child, .ask-msg-bubble ol:last-child { margin-bottom: 0; }
.ask-msg-bubble li { margin-bottom: 2px; }
.ask-msg-bubble strong { font-weight: 700; }
.ask-msg-bubble code { background: rgba(128,128,128,0.15); padding: 1px 5px; border-radius: 4px; font-size: 0.9em; }

.ask-composer {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 6px 6px 18px; border-radius: 999px;
    background: var(--card); border: 1px solid var(--border);
    transition: border-color 0.12s;
}
.ask-composer:focus-within { border-color: var(--accent); }
.ask-composer input {
    flex: 1; border: none; background: none; outline: none;
    font: 400 14px/1.4 var(--th-font-ui); color: var(--text); padding: 8px 0;
}
.ask-composer input::placeholder { color: var(--muted); }
.ask-send-btn {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 34px; height: 34px; border-radius: 50%; border: none;
    background: var(--accent); color: var(--on-accent); cursor: pointer;
    transition: filter 0.12s;
}
.ask-send-btn:hover { filter: brightness(1.08); }
.ask-send-btn:disabled { opacity: 0.5; cursor: default; filter: none; }
h2 {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 12px;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
    letter-spacing: -0.005em;
}
h3 { display: flex; align-items: center; gap: 8px; }

.hint { color: var(--muted); font-size: 13px; margin: -8px 0 12px; line-height: 1.5; }

/* One consistent legend style for every chart in the app — dataset legends
   (rendered by renderChartLegend()) and the static phase-color legend alike. */
.chart-legend {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    justify-content: flex-end;
    margin: -6px 0 14px;
    font-size: 12px;
    color: var(--muted);
}
.chart-legend-item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.chart-legend-item.clickable { cursor: pointer; user-select: none; }
.chart-legend-item.clickable:hover { color: var(--text); }
.chart-legend-item.legend-hidden { opacity: 0.35; text-decoration: line-through; }
.legend-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }

/* Pairs a chart's own dataset legend (left) with the static phase-color
   legend (right) on one line, when a chart has both. */
.chart-legend-row { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; margin: -6px 0 14px; }
.chart-legend-row .chart-legend { margin: 0; }
.chart-legend-row .chart-legend:first-child { justify-content: flex-start; }

.race-flag { display: inline-flex; color: var(--th-text-2); margin-left: 6px; vertical-align: -2px; }

main {
    max-width: 900px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

main.wide { max-width: 1400px; }

/* Every Chart.js canvas here declares a small `height` attribute (a legacy
   aspect-ratio hint Chart.js reads before it takes over sizing) — until its
   JS actually runs, the browser lays it out at that raw ~90px, then Chart.js
   resizes it to its real responsive height (~200-350px) once a chart is
   created. That growth-on-load is what reads as the page "bouncing" on
   first load — reserving realistic space up front avoids it.
   This floor belongs on the *wrapper* Chart.js measures (.th-canvas-wrap,
   from loaders.js withCanvasChartLoading), not on the canvas element
   itself: Chart.js sets the canvas's own `height` via inline style once it
   initializes, and CSS min-height on that same element only ever acts as
   an extra floor on top of it (min-height wins over a smaller inline
   height — they aren't the same property, so specificity doesn't apply) —
   forcing the canvas's CSS box taller than the bitmap Chart.js actually
   drew at, which stretches and blurs it. Constraining the wrapper instead
   lets Chart.js measure and draw at the reserved size correctly the first
   time, with nothing left to conflict with afterwards.

   A flat min-height wasn't enough on its own, though: none of these
   charts set an explicit aspectRatio, so with maintainAspectRatio (the
   default) Chart.js locks onto the ratio implied by the bare <canvas>
   element's own width/height *HTML attributes* at creation — default
   width 300 over whatever `height="N"` the template gave it (90 for most
   charts here) — and keeps that ratio through every later resize,
   regardless of the container's own size. A flat 220px (or a generic
   2:1) floor doesn't match that per-chart ratio, so the wrapper still
   grew or shrank out from under the loader once the real chart replaced
   it — read as the whole page "bouncing". withCanvasChartLoading (in
   loaders.js) sets this wrapper's aspect-ratio inline from that same
   canvas attribute before anything ever draws into it, so the two always
   agree; the aspect-ratio below is only a fallback for the instant before
   that JS runs. */
.th-canvas-wrap { aspect-ratio: 300 / 90; min-height: 160px; }

/* Reserve roughly the same space these JS-populated containers end up
   with, matching the height their loading skeleton uses (see loaders.js
   withChartLoading calls) — so the very first paint doesn't start at 0
   and then jump once data arrives. */
#lifetime-stats, #personal-bests-groups { min-height: 130px; }
#heatmap { min-height: 140px; }
#power-curve { min-height: 100px; }
#hr-zones { min-height: 90px; }
#overall-summary { min-height: 240px; }

/* JS-populated placeholder containers (forms, banners, review queues) still
   count as flex children — and so still eat a `gap` — even with zero height
   while empty, which reads as unexplained blank space above the next card. */
main > div:empty { display: none; }

.goal-card { border: 1px solid var(--th-line-strong); }
.goal-card-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 12px; }
.goal-card-header h2 { margin: 0; }

.tile-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }

.tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 20px;
    cursor: pointer;
    color: var(--text);
    font-size: 13px;
    min-width: 84px;
    transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.tile:hover { border-color: var(--th-line-strong); transform: translateY(-1px); }
.tile-selected { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--card)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent); }
.tile-icon { font-size: 24px; }
.tile-label { font-weight: 500; }
.tile-small { padding: 8px 14px; min-width: unset; }
.tile-small .tile-label { font-weight: 400; }

.goal-description { margin: 8px 0 0; }

.badge {
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    margin-left: auto;
}
.badge-key { background: color-mix(in srgb, var(--positive) 15%, transparent); color: var(--positive); }
.badge-secondary { background: rgba(144, 153, 168, 0.15); color: var(--muted); }

.disc-card-secondary { opacity: 0.6; }

.global-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 16px;
}
.global-field {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px;
}
.global-field.field-modified { border-color: var(--accent); }
.global-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.global-field input { width: 100%; margin-bottom: 6px; }
.field-desc { margin: 4px 0; }
.field-default { margin: 0; font-style: italic; }

.goal-time-inputs { display: flex; align-items: center; gap: 6px; }
/* Split calculator's Delta column — predicted vs. goal-time split. */
.split-delta-behind { color: var(--negative); font-weight: 600; }
.split-delta-ahead { color: var(--positive); font-weight: 600; }
.goal-time-inputs input { width: 56px; flex: none; text-align: center; margin-bottom: 0; -moz-appearance: textfield; }
.goal-time-inputs input::-webkit-outer-spin-button, .goal-time-inputs input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.goal-time-inputs span { color: var(--muted); font-size: 13px; margin-right: 4px; }

.logic-actions { display: flex; align-items: center; gap: 12px; margin-top: 12px; }

.mix-type-heading { font-size: 15px; margin: 20px 0 8px; color: var(--muted); }
.mix-type-heading:first-child { margin-top: 0; }

.mix-config-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 8px; }
.mix-config-table th { text-align: left; color: var(--muted); font-weight: 500; padding: 6px 8px; border-bottom: 1px solid var(--border); }
.mix-config-table td { padding: 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }

.mix-cell-inner { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.mix-cell-icon { font-size: 14px; }
.mix-input {
    width: 46px;
    background: var(--card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 4px;
    font-size: 12px;
}
.mix-weight { margin-left: 6px; font-weight: 600; color: var(--th-text-2); font-size: 12px; }
.mix-row-actions { display: flex; gap: 6px; white-space: nowrap; }

.health-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    background: color-mix(in srgb, var(--th-warning) 9%, var(--th-surface));
    border: 1px solid color-mix(in srgb, var(--th-warning) 45%, var(--th-line));
    border-radius: 10px;
    padding: 14px 18px;
    margin-bottom: 20px;
}
.health-banner-text { font-size: 14px; }
.health-banner-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.health-form-card { margin-bottom: 20px; }
.health-form-card label { display: block; font-size: 12px; color: var(--muted); margin: 8px 0 4px; }
.health-form-card input, .health-form-card textarea, .health-form-card select { width: 100%; }
/* flex, not grid — a form row shouldn't stretch its fields to fill the
   card the way a card grid does; with only 2 fields (e.g. Type/Distance)
   in a wide card, grid's auto-fit 1fr pushed them to opposite edges with
   a huge gap between. Fields now sit compactly, left-aligned. */
.health-form-row { display: flex; flex-wrap: wrap; gap: 12px; }
.health-form-row > * { flex: 0 1 220px; min-width: 160px; }

.health-events-list { display: flex; flex-direction: column; gap: 10px; }
.health-event-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--bg);
    border-left: 4px solid;
}
.health-event-row.illness { border-color: var(--th-negative); }
.health-event-row.injury { border-color: var(--th-warning); }
.health-event-row.taper { border-color: var(--th-text-muted); }
.health-event-row.recovery { border-color: var(--th-text-muted); }
.health-event-main { font-size: 14px; }
.health-event-meta { color: var(--muted); font-size: 12px; }

/* Section label above each of the Races page's two stacked lists
   (upcoming, then past — both always visible, no tab to switch). */
.race-list-heading {
    display: flex; align-items: center; gap: 8px;
    margin: 20px 0 10px; font-size: 14px; font-weight: 600; color: var(--muted);
}
.race-list-heading:first-of-type { margin-top: 16px; }

.race-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    border-radius: 8px;
    background: var(--bg);
    border: 1px solid var(--border);
    margin-bottom: 10px;
}
.race-card-main { cursor: pointer; flex: 1; min-width: 0; }
.race-card-main:hover .race-name { color: var(--accent); text-decoration: underline; }

/* The Goal page's "which upcoming race is this actually for" link — a
   compact one-line card in the same family as .race-card, styled as a
   link (the whole thing navigates to the Races page). */
.linked-race-card {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
    padding: 10px 14px;
    border-radius: 8px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
}
.linked-race-card:hover { border-color: var(--accent); }
.linked-race-card:hover strong { color: var(--accent); }
.race-countdown { font-size: 28px; font-weight: 700; color: var(--th-chalk); }
.race-name { font-weight: 600; }
.race-meta { color: var(--muted); font-size: 13px; }
/* A quick glance at what's been backfilled for a past race yet — see
   raceDataSummaryHTML() in races.js. */
.race-data-summary { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
.race-data-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }
.race-data-chip .lucide { width: 13px; height: 13px; }
.race-data-chip.is-filled { color: var(--positive); }

.race-legs { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.race-leg-row {
    display: grid;
    grid-template-columns: 24px 1fr 90px 70px 90px 90px;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13px;
    text-decoration: none;
    color: var(--text);
}
.race-leg-row:hover { border-color: var(--accent); }
.race-leg-icon { display: flex; color: var(--th-text-2); }
.race-leg-name { font-weight: 500; }

/* T1/T2 logging in the race-detail popup — legs alone always undercount
   a multi-leg race's real result, so this fills the gap manually. */
.race-transitions { margin-top: 0; }
.race-transitions-row { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.race-transitions-row label { flex: 1; min-width: 0; margin: 0; font-size: 13px; color: var(--muted); }
.race-transitions-total { font-size: 14px; margin-top: 4px; }
#rr-overall-fields:disabled, #rr-ag-fields:disabled { opacity: 0.4; }

/* The race-detail popup accumulated a lot of features (distance/category,
   legs, transitions, results-finder, manual results) all in one flat
   stack — grouped into clearly titled sections instead, each with its
   own top border, so it reads as a sequence of small forms rather than
   one long one. */
.race-detail-section { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }
.race-detail-section:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.race-detail-section-title {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 600; margin: 0 0 12px;
}
.race-detail-section-title .lucide { width: 16px; height: 16px; color: var(--muted); }
.race-results-import-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.race-results-manual-title { font-size: 13px; font-weight: 600; color: var(--muted); margin: 14px 0 10px; }

.gap-context-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin: 12px 0;
}
.gap-context-label { font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.02em; }
.gap-activity-row {
    display: grid;
    grid-template-columns: 76px 1fr 104px 52px 64px;
    gap: 8px;
    font-size: 12px;
    padding: 4px 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}
.gap-activity-row span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hr-flag {
    background: rgba(244, 162, 97, 0.12);
    border: 1px solid rgba(244, 162, 97, 0.4);
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 13px;
    margin: 10px 0;
}
.gap-data-note { font-style: italic; margin-top: 8px; }
/* The sticky title bar under the banner pulls itself up 24px (it is normally flush with the top of the page),
   which covered the bottom of the gap panel. Give the banner that room back. */
#health-banner-container:not(:empty) { padding-bottom: 28px; }
.closest-race-note {
    background: rgba(244, 197, 0, 0.1);
    border: 1px solid rgba(244, 197, 0, 0.35);
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 13px;
    margin-bottom: 10px;
}

/* Metrics are the loudest thing on most screens (brand type scale): every
   prominent number reads in tabular IBM Plex Mono, not the UI face. */
.stat-card-value, .disc-pct, .gauge-pct, .race-countdown, .mix-weight {
    font-family: var(--th-font-data);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

/* Top-lit gradient surface + a corner spotlight tinted by the card's own
   "glow" color. Only cards that opt in via --card-glow (the :has()
   selectors below, one per chart) get a visible spotlight — a card with
   no chart identity has nothing meaningful to tint it, and defaulting
   the glow to the plain --accent painted every card (stat tiles, text
   panels) with the same generic accent wash, which reads as a stain
   rather than a chart-specific highlight. */
.card {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: linear-gradient(180deg, color-mix(in srgb, var(--text) 5%, var(--card)) 0%, var(--card) 55%);
    border: 1px solid color-mix(in srgb, var(--text) 9%, transparent);
    border-radius: 20px;
    padding: 22px 22px 18px;
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 9%, transparent), var(--shadow-card);
}
.card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 240px;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(72% 100% at 88% -10%, color-mix(in srgb, var(--card-glow, transparent) 15%, transparent), transparent 72%);
}

/* Tints each chart card's corner spotlight (--card-glow, used by .card::
   before above) to that chart's own series color — "a corner spotlight
   tinted by the chart's own colour" — without needing to touch the JS
   that renders into each canvas. */
.card:has(#fitness-chart), .card:has(#hr-zone-series-chart), .card:has(#hrv-chart), .card:has(#weight-chart), .card:has(#resting-hr-chart) { --card-glow: var(--th-text-muted); }
.card:has(#vo2max-chart) { --card-glow: var(--th-run); }
.card:has(#readiness-series-chart) { --card-glow: var(--accent); }
.card:has(#tc-chart) { --card-glow: var(--accent); }

.btn {
    display: inline-block;
    background: var(--accent);
    color: var(--on-accent);
    padding: 8px 16px;
    border-radius: 6px;
    text-decoration: none;
    border: none;
    cursor: pointer;
    font-weight: 500;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: filter 0.12s, transform 0.06s;
    font-size: 14px;
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: scale(0.98); }

.btn-secondary {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
    box-shadow: none;
}
.btn-secondary:hover { filter: none; border-color: var(--muted); }

.select {
    background: var(--card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 13px;
}

/* The page's title + its sticky filter/range controls share one purple
   bar in the sidebar's own color, flush against the top of the viewport
   (canceling body's top padding) so it reads as the sidebar's rail
   continuing across the top — an "L" of matching chrome around the
   content rather than a separate bordered header. */
.filter-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin: -24px -16px 24px -16px;
    padding: 12px 20px;
    position: sticky;
    top: 0;
    z-index: 150;
    background: var(--sidebar-bg);
}
/* A second filter bar further down a page (e.g. Readiness's chart-scoped
   Day/Week/Month/Year controls) isn't page chrome — reusing the dark,
   sticky, sidebar-colored bar there reads as a second, disconnected nav
   rail stranded mid-page. Giving this variant its own card-like box (an
   earlier attempt: background/border/radius) just traded one detached
   floating element for another. This one isn't boxed at all — a plain
   control row sitting directly in the page flow, the same way a .hint
   paragraph does, so there's no rectangle left to look disconnected. */
.filter-bar.filter-bar-inline {
    position: static;
    margin: 0 0 16px;
    padding: 0;
    background: none;
    border: none;
}
.filter-bar-title {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--sidebar-text-active);
    font-size: 16px;
    font-weight: 700;
    white-space: nowrap;
}
.filter-bar-title .lucide { width: 20px; height: 20px; color: var(--th-text-2); }
.filter-bar-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.filter-bar-divider { width: 1px; height: 20px; background: var(--sidebar-border); margin: 0 2px; }
.filter-bar .hint { color: var(--sidebar-text); }
.filter-bar .btn-secondary { color: var(--sidebar-text-active); border-color: var(--sidebar-border); }
.filter-bar .btn-secondary:hover { border-color: var(--sidebar-text); }
.filter-bar.filter-bar-inline .hint { color: var(--muted); }
.filter-bar.filter-bar-inline .btn-secondary { color: var(--text); border-color: var(--border); }
.filter-bar.filter-bar-inline .btn-secondary:hover { border-color: var(--muted); }
.filter-bar.filter-bar-inline .filter-bar-divider { background: var(--border); }

.segmented {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card);
    padding: 3px;
    gap: 2px;
}
.segmented button {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: transparent;
    border: none;
    color: var(--muted);
    padding: 6px 11px;
    font-size: 13px;
    border-radius: 6px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.12s, color 0.12s, transform 0.06s;
}
.segmented button:hover:not(.seg-active) { background: var(--surface-2); color: var(--text); }
.segmented button.seg-active {
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.segmented button:active { transform: scale(0.96); }

/* ---------- Readiness: training comparison ---------- */
.tc-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.tc-race-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.tc-race-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px 6px 10px; border-radius: 999px; border: 1px solid var(--border);
    background: var(--card); font-size: 13px; cursor: pointer; user-select: none;
    transition: border-color 0.12s, background 0.12s;
}
.tc-race-chip input { margin: 0; accent-color: var(--accent); }
.tc-race-chip:hover { border-color: var(--muted); }
.tc-race-chip.is-checked { border-color: var(--tc-chip-color, var(--accent)); background: color-mix(in srgb, var(--tc-chip-color, var(--accent)) 10%, var(--card)); }
.tc-race-chip-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--tc-chip-color, var(--accent)); flex-shrink: 0; }
.seg-icon { font-size: 13px; line-height: 1; }

.switch-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: var(--muted);
    user-select: none;
}
.switch-track {
    position: relative;
    width: 38px;
    height: 22px;
    background: var(--border);
    border-radius: 11px;
    transition: background 0.15s;
    flex-shrink: 0;
}
.switch-track::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.15s;
}
.switch-toggle input { display: none; }
.switch-toggle input:checked + .switch-track { background: var(--accent); }
.switch-toggle input:checked + .switch-track::after { transform: translateX(16px); }

.date-input { width: 140px; padding: 6px 8px; }

.custom-range { position: relative; }
.custom-range-toggle.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.custom-range-popover {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    flex-direction: column;
    gap: 10px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px;
    box-shadow: var(--shadow-card);
    z-index: 200;
    min-width: 190px;
}
.custom-range-popover.open { display: flex; }
.custom-range-popover label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.btn-small { padding: 6px 10px; font-size: 13px; }
.btn-taper, .btn-recovery { background: var(--th-surface-3); color: var(--th-text); }

.axis-picker {
    display: flex;
    gap: 24px;
    align-items: flex-end;
    margin-bottom: 16px;
    flex-wrap: wrap;
}
.axis-picker label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }

.gap-toggle-label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); cursor: pointer; white-space: nowrap; }

.burst-day-card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    margin-bottom: 10px;
}
.burst-day-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
.burst-activities { display: none; margin-top: 10px; }
.burst-activities.open { display: block; }
.burst-activity-row {
    display: grid;
    grid-template-columns: 130px 1fr 90px 70px 90px;
    gap: 8px;
    align-items: center;
    font-size: 13px;
    padding: 6px 0;
    border-top: 1px solid var(--border);
}
.drilldown-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 1000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    overflow-y: auto;
}
.drilldown-modal {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 24px;
    max-width: 1100px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.drilldown-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.drilldown-header h3 { margin: 0 0 4px; font-size: 18px; }
.drilldown-summary { font-size: 13px; color: var(--muted); margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.drilldown-table-wrap { max-height: 60vh; overflow-y: auto; }
.drilldown-table-wrap table { font-size: 13px; }
.chart-clickable { cursor: pointer; }

.data-link { color: var(--text); text-decoration: none; font-weight: 500; }
.data-link:hover { color: var(--accent); text-decoration: underline; }

.excluded-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 8px;
    font-size: 13px;
}

/* flex, not grid — grid's auto-fit locks every row to the same column
   tracks, so a leftover item alone on the last row (e.g. 5 cards at a
   width that fits 4 per row) can't stretch to fill it and leaves a huge
   gap. Flex-wrap distributes growth per row, so a lone last item always
   fills the row it's on. */
.discipline-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
}
.discipline-grid > * { flex: 1 1 220px; min-width: 220px; }

#compare-charts.discipline-grid { gap: 20px; }
#compare-charts.discipline-grid > * { flex-basis: 460px; }
.compare-metric-card h3 { font-size: 15px; margin: 0 0 12px; }

.stat-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}
.stat-cards > * { flex: 1 1 220px; min-width: 220px; }
/* Plain fallback tile — kinds the KPI-tile redesign below doesn't cover
   yet (a race-goal view's "Races confirmed" / "Next race"). */
.stat-card {
    display: flex; align-items: center; gap: 12px; min-width: 0;
    background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px;
}
.stat-card-icon {
    display: flex; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
    border-radius: 8px; padding: 8px; flex-shrink: 0;
}
.stat-card-icon .lucide { width: 20px; height: 20px; }
.stat-card-body { min-width: 0; flex: 1; }
.stat-card-value-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.stat-card-value { font-size: 22px; font-weight: 700; line-height: 1.1; }
.stat-card-label { color: var(--muted); font-size: 12px; margin-top: 2px; }
.sparkline { width: 56px; height: 22px; flex-shrink: 0; opacity: 0.85; }

/* ---------- KPI tiles: each number gets a picture that explains it ----------
   (ActivitiesTile/EarthTile/DaysTile/EverestTile/DialTile/StreakTile) —
   ported from the trihard-ui design kit's records.tsx. Each tile carries
   its own --tone (an accent color) for its icon chip and corner glow. */
.th-kpi {
    position: relative; overflow: hidden; isolation: isolate;
    display: flex; flex-direction: column; gap: 12px; min-width: 0; max-width: 420px;
    padding: 16px 18px 15px; border-radius: 20px;
    background: var(--card); border: 1px solid var(--border);
}
.th-kpi::before {
    content: ""; position: absolute; right: -25%; top: -45%; width: 80%; height: 130%;
    z-index: -1; pointer-events: none;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--tone) 24%, transparent), transparent);
}
.th-kpi__head { display: flex; align-items: center; gap: 10px; font: 500 13px/1 var(--th-font-ui); color: var(--muted); }
.th-kpi__ico {
    display: grid; place-items: center; width: 28px; height: 28px; border-radius: 9px;
    color: var(--tone); background: color-mix(in srgb, var(--tone) 16%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone) 32%, transparent);
}
.th-kpi__row { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; min-width: 0; }
.th-kpi__cap { font: 500 12px/1.35 var(--th-font-ui); color: var(--muted); }
.th-kpi__subcap { opacity: 0.7; }
.th-gauge-num { fill: var(--text); font: 600 17px/1 var(--th-font-data); }
.th-gauge-tick { fill: var(--muted); font: 500 10px/1 var(--th-font-data); }
/* EarthTile's arc fill-in and DialTile's needle sweep — both rendered at
   their resting state with the real value stashed in a data attribute,
   applied a frame later by mountKpiMotion() (filters.js) so these
   transitions have a "from" state to animate from. */
.th-earth-arc { transition: stroke-dashoffset 1500ms cubic-bezier(.16, .84, .24, 1); }
.th-dial-needle { transition: transform 1300ms cubic-bezier(.3, 1.5, .5, 1); }
@media (prefers-reduced-motion: reduce) { .th-earth-arc, .th-dial-needle, .th-days i { transition: none; animation: none; } }
.th-days { display: grid; grid-template-columns: repeat(auto-fill, 10px); gap: 3px; max-width: 100%; }
.th-days i { width: 10px; height: 10px; border-radius: 3px; background: linear-gradient(135deg, var(--th-chalk), color-mix(in srgb, var(--th-chalk) 55%, var(--th-text-muted))); animation: th-fade-in 500ms var(--th-ease) both; }
.th-days i.is-last { box-shadow: 0 0 10px var(--th-chalk); }
.th-flame { overflow: visible; }
.th-flame.is-live { transform-origin: 50% 90%; animation: th-flicker 1.6s ease-in-out infinite alternate; filter: drop-shadow(0 0 10px color-mix(in srgb, var(--th-bike) 70%, transparent)); }
@keyframes th-flicker { from { transform: scale(1, 1) rotate(-1deg); } to { transform: scale(1.04, 0.97) rotate(1deg); } }
.th-weeks { display: flex; gap: 5px; }
.th-weeks i { flex: 1; height: 8px; max-width: 18px; border-radius: 3px; background: color-mix(in srgb, var(--text) 10%, transparent); }
.th-weeks i.is-on { background: linear-gradient(180deg, var(--th-gold), var(--th-bike)); box-shadow: 0 0 8px -1px var(--th-bike); }
.th-odo {
    display: inline-flex; align-items: baseline; gap: .05em; max-width: 100%; white-space: nowrap;
    line-height: 1.12; font-family: var(--th-font-data); font-weight: 600; font-variant-numeric: tabular-nums;
    color: var(--odo, var(--text));
}
/* Mechanical rolling digits — mountOdometers() (filters.js) sets each
   drum's strip to translateY(-Nch * 1.12em) one frame after insertion,
   so the CSS transition below actually has a "from" state to animate. */
.th-odo__drum { position: relative; display: inline-block; height: 1.12em; overflow: hidden; padding: 0 .03em; border-radius: .16em; }
.th-odo__strip { display: flex; flex-direction: column; transition: transform 1500ms cubic-bezier(.16, .84, .24, 1); }
.th-odo__strip span { display: block; width: .6em; height: 1.12em; line-height: 1.12em; text-align: center; }
.th-odo__sep { opacity: .65; margin: 0 -.02em; }
.th-odo__unit { margin-left: .28em; font: 500 .38em/1 var(--th-font-ui); letter-spacing: .02em; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .th-odo__strip { transition: none; } }
.th-chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; border-radius: 999px; font: 600 12px/1 var(--th-font-data); font-variant-numeric: tabular-nums; }
.th-chip--good { color: var(--positive); background: color-mix(in srgb, var(--positive) 14%, transparent); }
.th-chip--bad { color: var(--negative); background: color-mix(in srgb, var(--negative) 14%, transparent); }

/* ---------- Lifetime distance by discipline (LifetimeBar + DisciplineCard) ---------- */
.th-life { display: flex; flex-direction: column; gap: 12px; }
.th-life__bar { display: flex; gap: 3px; height: 16px; }
.th-life__bar span { flex-basis: 0; min-width: 6px; border-radius: 6px; }
.th-life__legend { display: flex; flex-wrap: wrap; gap: 8px 22px; font: 500 13px/1 var(--th-font-ui); color: var(--muted); align-items: center; }
.th-life__legend i { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 8px; }
.th-life__legend b { font: 600 13px/1 var(--th-font-data); color: var(--text); margin-left: 4px; }
.th-life__total { margin-left: auto; font: 600 13px/1 var(--th-font-data); color: var(--text); }
/* flex, not grid — see .discipline-grid above for why (a lone card on the
   last row needs to stretch to fill it, which grid's auto-fit can't do). */
/* margin-top, not gap on the shared #lifetime-stats parent — .th-life
   (the share bar) and .th-discs are unrelated siblings dropped into that
   parent's innerHTML, so the parent has no gap of its own to inherit. */
.th-discs { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 20px; }
.th-discs > * { flex: 1 1 220px; min-width: 220px; }
.th-disc {
    position: relative; isolation: isolate; overflow: hidden;
    display: flex; flex-direction: column; gap: 16px; min-width: 0; max-width: 480px; padding: 18px 18px 16px; border-radius: 22px;
    background: var(--card);
    border: 1px solid color-mix(in srgb, var(--c) 45%, transparent);
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c) 45%, transparent);
}
.th-disc__mark { position: absolute; right: -26px; bottom: -22px; z-index: -1; color: var(--c); opacity: .09; transform: rotate(-8deg); }
.th-disc__mark .lucide { width: 150px; height: 150px; }
.th-disc__head { display: flex; align-items: center; gap: 10px; }
.th-disc__head b { font: 700 16px/1 var(--th-font-ui); }
.th-disc__ico { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 10px; color: var(--c); background: color-mix(in srgb, var(--c) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 34%, transparent); }
.th-disc__count { margin-left: auto; font: 500 12px/1 var(--th-font-ui); color: var(--muted); }
.th-disc__track { height: 8px; border-radius: 4px; overflow: hidden; background: color-mix(in srgb, var(--text) 9%, transparent); }
.th-disc__track i { display: block; height: 100%; border-radius: 4px; transition: width 1500ms cubic-bezier(.16, .84, .24, 1); box-shadow: 0 0 12px -1px var(--c); }
.th-disc__miletext { display: flex; justify-content: space-between; margin-top: 8px; font: 500 12px/1 var(--th-font-ui); color: var(--muted); }
.th-disc__miletext b { font-family: var(--th-font-data); color: var(--text); font-weight: 600; }
.th-disc__stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--text) 10%, transparent); }
.th-disc__stats dt { font: 500 11px/1 var(--th-font-ui); color: var(--muted); margin-bottom: 6px; }
.th-disc__stats dd { margin: 0; font: 600 14px/1 var(--th-font-data); font-variant-numeric: tabular-nums; color: var(--text); }
@media (prefers-reduced-motion: reduce) { .th-disc__track i { transition: none; } }

/* ---------- TrophyCase: the Personal Bests medal wall ---------- */
.th-cases { display: grid; gap: 16px; }
.th-case {
    position: relative; isolation: isolate; overflow: hidden; padding: 18px 22px 24px; border-radius: 22px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--case) 9%, var(--card)), var(--card) 62%);
    border: 1px solid color-mix(in srgb, var(--case) 30%, transparent);
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--case) 30%, transparent);
}
.th-case::before { content: ""; position: absolute; inset: 0 0 35% 0; z-index: -1; background: radial-gradient(64% 100% at 50% 0%, color-mix(in srgb, var(--case) 20%, transparent), transparent 72%); }
.th-case__head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.th-case__ico { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; color: var(--case); background: color-mix(in srgb, var(--case) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--case) 34%, transparent); }
.th-case__head h4 { margin: 0; font: 700 19px/1 var(--th-font-ui); }
.th-case__count { margin-left: auto; font: 500 12px/1 var(--th-font-data); color: var(--muted); }
.th-case__rail { position: relative; height: 9px; border-radius: 5px; margin-bottom: 16px; background: linear-gradient(180deg, color-mix(in srgb, var(--text) 40%, transparent), color-mix(in srgb, var(--text) 9%, transparent)); box-shadow: 0 8px 16px -8px rgb(0 0 0 / .6); }
.th-case__row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; align-items: start; }
.th-case__item { position: relative; margin: 0; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
.th-case__cone {
    position: absolute; top: 0; left: 50%; width: 160%; height: 100%; z-index: -1; transform: translateX(-50%); pointer-events: none;
    clip-path: polygon(46% 0, 54% 0, 100% 100%, 0 100%);
    background: linear-gradient(180deg, color-mix(in srgb, var(--case) 26%, transparent), transparent 88%); opacity: .75;
}
.th-case__medal { position: relative; }
.th-case__event { position: absolute; right: -14px; bottom: 4px; }
.th-case__item figcaption { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.th-case__time { font: 600 21px/1 var(--th-font-data); font-variant-numeric: tabular-nums; letter-spacing: -.02em; color: var(--text); }
.th-case__name { font: 700 10.5px/1.2 var(--th-font-ui); letter-spacing: .1em; text-transform: uppercase; color: var(--case); }
.th-case__meta { font: 500 12px/1.35 var(--th-font-ui); color: var(--muted); }
.th-case__item.is-locked .th-case__time { font: 500 15px/1 var(--th-font-ui); color: var(--muted); letter-spacing: 0; }
.th-case__item.is-locked .th-case__name { color: var(--muted); opacity: .8; }
.th-medal { display: block; overflow: visible; transform-origin: 50% 0; animation: th-sway 7s ease-in-out infinite alternate; }
.th-medal.is-locked { filter: grayscale(1); opacity: .34; animation: none; color: var(--text); }
@keyframes th-sway { from { transform: rotate(-1.8deg); } to { transform: rotate(1.8deg); } }
.th-medal__label { font: 800 30px/1 var(--th-font-display); font-stretch: 125%; letter-spacing: -.02em; fill: #101820; }
.th-twinkle { transform-box: fill-box; transform-origin: center; animation: th-twinkle 2.4s ease-in-out infinite; }
@keyframes th-twinkle { 0%, 100% { transform: scale(1) rotate(0); } 50% { transform: scale(1.22) rotate(14deg); } }
@media (prefers-reduced-motion: reduce) { .th-medal, .th-twinkle { animation: none; } }

/* ---------- RecordPlaque: hardest effort / longest activity / biggest week ---------- */
.records-row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}
.records-row > * { flex: 1 1 220px; min-width: 220px; }
.th-plaque {
    position: relative; isolation: isolate; overflow: hidden;
    display: flex; flex-direction: column; gap: 10px; min-width: 0;
    padding: 18px 20px 16px; border-radius: 20px;
    background: var(--card); border: 1px solid var(--border);
    cursor: pointer; transition: transform 0.12s;
}
.th-plaque:not([data-activity-id]) { cursor: default; }
.th-plaque:hover { transform: translateY(-2px); }
.th-plaque::after {
    content: ""; position: absolute; right: -40px; top: -40px; width: 160px; height: 160px; border-radius: 50%; z-index: -1;
    border: 1px solid color-mix(in srgb, var(--tone) 22%, transparent);
    box-shadow: 0 0 0 18px color-mix(in srgb, var(--tone) 5%, transparent), 0 0 0 40px color-mix(in srgb, var(--tone) 3%, transparent);
}
.th-plaque__top { display: flex; align-items: center; gap: 10px; }
.th-plaque__medallion {
    display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; color: #101820;
    background: radial-gradient(circle at 32% 26%, color-mix(in srgb, var(--tone) 55%, white), var(--tone) 55%, color-mix(in srgb, var(--tone) 55%, black));
    box-shadow: 0 8px 18px -6px var(--tone), inset 0 0 0 2px color-mix(in srgb, white 35%, transparent);
}
.th-plaque__label { font: 700 11px/1.2 var(--th-font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.th-plaque__event { margin-left: auto; }
.th-plaque__sub { margin: 0; font: 500 13px/1.4 var(--th-font-ui); color: var(--muted); }
.th-pctl { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.th-pctl__cap { font: 500 12px/1 var(--th-font-ui); color: var(--muted); }
.th-pctl__cap b { font-family: var(--th-font-data); }
.th-event {
    display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px 0 8px; border-radius: 999px;
    font: 700 10px/1 var(--th-font-ui); letter-spacing: .1em; text-transform: uppercase; color: var(--text);
    background: color-mix(in srgb, var(--text) 8%, transparent);
}
/* A real brand mark (see BRAND_ASSETS in filters.js) sits on a small
   white tile so a dark logo stays legible on the dark theme too — falls
   back to the plain .th-event chip above if the file 404s. */
.th-event--logo { width: 26px; height: 26px; padding: 0; justify-content: center; border-radius: 8px; background: #fff; box-shadow: 0 4px 10px -4px rgb(0 0 0 / .5); }
.th-event--logo img { max-width: 76%; max-height: 76%; object-fit: contain; }
.progress-track { height: 8px; background: var(--surface-2); border-radius: 4px; overflow: hidden; margin-top: 10px; }
.progress-fill { height: 100%; background: var(--accent); border-radius: 4px; transition: width 0.2s; }

.heatmap-wrap { overflow-x: auto; padding: 3px 4px 4px 0; }   /* room for today's 1.5px ring and the last month label, which the scroll box would otherwise clip */
/* Grid layout: months row spans the top, day-labels form a narrow left
   column, and the heat grid fills the remaining cell — the labels sit in
   the same grid row as the heat grid so they stretch to match its height
   (set by the grid's own aspect-ratio) and their 7 sub-rows line up with
   its 7 day-rows. */
.heatmap-composite {
    display: grid;
    grid-template-columns: 26px 1fr;
    grid-template-rows: auto 1fr;
    gap: 4px 6px;
}
.heatmap-months {
    grid-column: 2;
    grid-row: 1;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(6px, 1fr);
    gap: 3px;
}
.heatmap-month-cell { font-size: 10px; color: var(--muted); white-space: nowrap; overflow: visible; }
.heatmap-daylabels {
    grid-column: 1;
    grid-row: 2;
    display: grid;
    grid-template-rows: repeat(7, 1fr);
    gap: 3px;
    font-size: 10px;
    color: var(--muted);
    white-space: nowrap;
}
.heatmap-daylabels div { display: flex; align-items: center; }
.heatmap-grid {
    grid-column: 2;
    grid-row: 2;
    display: grid;
    grid-template-rows: repeat(7, 1fr);
    grid-auto-flow: column;
    grid-auto-columns: minmax(6px, 1fr);
    gap: 3px;
    width: 100%;
    aspect-ratio: 53 / 7;
}
.heat-cell { position: relative; border-radius: 2px; background: var(--surface-2); cursor: default; }
.heat-cell[data-date] { cursor: pointer; }
.heat-cell.heat-pad { background: transparent; }
/* A fixed "heat" scale (cool -> hot) rather than tints of the page's own
   accent color — a distinct, unmistakable ramp reads faster than shades
   of one hue, and doesn't disappear on discipline pages whose accent is
   already used elsewhere on the same card (e.g. records, stat icons). */
.heat-cell.heat-1 { background: var(--th-heat-1); }
.heat-cell.heat-2 { background: var(--th-heat-2); }
.heat-cell.heat-3 { background: var(--th-heat-3); }
.heat-cell.heat-4 { background: var(--th-heat-4); }
.heat-cell.is-today { box-shadow: 0 0 0 1.5px var(--th-chalk); position: relative; z-index: 1; }
.heatmap-legend { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); margin-top: 10px; }
.heatmap-legend .heat-cell { width: 11px; height: 11px; cursor: default; }

.hrzone-bar { display: flex; height: 28px; border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.hrzone-segment { height: 100%; transition: width 0.2s; }
.hrzone-legend {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 8px;
    margin-top: 14px;
}
.hrzone-legend-item { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.hrzone-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.hrzone-legend-value { color: var(--muted); font-size: 12px; margin-left: auto; }

.disc-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-left: 4px solid;
    border-radius: 10px;
    padding: 18px;
    box-shadow: var(--shadow-card);
    transition: transform 0.12s;
}
.disc-card:hover { transform: translateY(-2px); }

.disc-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.disc-icon { font-size: 20px; }
.disc-name { font-weight: 600; }
.disc-pct { font-size: 36px; font-weight: 700; line-height: 1; }
.disc-pct.disc-pct-empty { font-family: inherit; font-size: 16px; font-weight: 600; line-height: 1.3; color: var(--muted) !important; }
.disc-sub { color: var(--muted); font-size: 12px; margin: 4px 0 14px; }
.disc-sub strong { color: var(--text); font-weight: 600; }
/* The readiness composite's per-factor breakdown — see
   metrics.readiness_report() and the Logic settings page for the reasoning. */
.factor-breakdown { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.factor-chip {
    display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted);
    background: var(--surface-2); border-radius: 999px; padding: 3px 9px;
}
.factor-chip b { color: var(--text); font-weight: 600; }
.disc-row { display: flex; justify-content: space-between; font-size: 13px; padding: 4px 0; border-top: 1px solid var(--border); }
.disc-row span:first-child { color: var(--muted); }
.disc-row span:last-child { font-weight: 600; }

/* Overall readiness card: a full ring beside one plain sentence, then the things that move the score as tiles.
   The ring is coloured by status (red/amber/green), not by accent or sport, since it is a score and not an identity. */
.rd-hero { display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: 12px 36px; align-items: center; padding: 4px 0 0; }
.rd-ring { position: relative; width: 168px; height: 168px; }
.rd-ring svg { width: 100%; height: 100%; display: block; overflow: visible; }
.rd-ring-track { stroke: color-mix(in srgb, var(--text) 9%, transparent); }
.rd-ring-fill { stroke-linecap: round; transition: stroke-dashoffset .9s cubic-bezier(.2, .7, .2, 1); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--rc, var(--accent)) 45%, transparent)); }
.rd-ring-center { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; }
.rd-ring-value { font: 700 40px/1 var(--th-font-data); font-variant-numeric: tabular-nums; }
.rd-ring-value small { font-size: 18px; margin-left: 1px; opacity: .7; }
.rd-ring-label { margin-top: 6px; font-size: 12px; color: var(--muted); }
.rd-story { min-width: 0; display: grid; gap: 8px; align-content: center; }
.rd-headline { margin: 0; font: 700 clamp(20px, 2.4vw, 26px)/1.2 var(--th-font-display); letter-spacing: -0.01em; }
.rd-sub { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--muted); max-width: 62ch; }
.rd-sub b { color: var(--text); font-weight: 600; }
.rd-legs-title { margin: 10px 0 0; font: 600 11px/1.2 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.rd-story .gauge-bar-row { max-width: 420px; }
.rd-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; margin-top: 26px; }
.rd-fact { display: flex; flex-direction: column; gap: 6px; padding: 16px 18px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.rd-fact-l { font: 600 11px/1.2 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.rd-fact-v { font: 700 24px/1.1 var(--th-font-data); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.rd-fact-n { font-size: 13px; line-height: 1.5; color: var(--muted); }
.rd-fact-warn .rd-fact-v { color: var(--th-gold); }
@media (max-width: 640px) {
    .rd-hero { grid-template-columns: 1fr; justify-items: start; }
    .rd-facts { grid-template-columns: 1fr; }
}

.gauge-bar-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.gauge-bar-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.gauge-bar-label { width: 64px; flex-shrink: 0; font-weight: 500; }
.gauge-bar-track { flex: 1; height: 8px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
.gauge-bar-fill { height: 100%; border-radius: 4px; transition: width 0.4s ease; }
.gauge-bar-value { width: 38px; text-align: right; flex-shrink: 0; color: var(--muted); font-variant-numeric: tabular-nums; }

.mix-row { display: grid; grid-template-columns: 80px 1fr 240px; align-items: center; gap: 12px; margin-bottom: 14px; }
.mix-label { font-weight: 600; }
.mix-track { position: relative; height: 14px; background: var(--surface-2); border-radius: 7px; }
.mix-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 7px; }
.mix-target { position: absolute; top: -4px; height: 22px; background: rgba(255,255,255,0.08); border-left: 2px solid var(--muted); border-right: 2px solid var(--muted); pointer-events: none; }
.mix-value { font-size: 13px; line-height: 1.35; display: grid; gap: 1px; }
.mix-value b { font-weight: 600; }
.mix-value .hint { margin: 0; }

.connect-screen {
    max-width: 400px;
    margin: 120px auto;
    text-align: center;
}
.connect-logo {
    display: inline-flex;
    background: var(--th-ink);
    border-radius: var(--th-radius-lg);
    padding: 32px 40px;
    margin-bottom: 28px;
}
.connect-logo img { height: 96px; width: auto; display: block; }
.connect-screen p { color: var(--muted); margin-bottom: 20px; }

/* The login screen's mark is a live TraceLoader (loaders.js), not a static
   image — the same white-line-races-to-the-dot-then-ignites-orange
   animation every chart uses elsewhere, looping forever here instead of
   tied to a real fetch. Needs an explicit width (not inline-flex's
   shrink-to-content) since the mounted SVG sizes itself to fill its
   container at width:100%. */
.login-mark { width: 100%; max-width: 260px; margin: 0 auto 18px; }

/* Sit the form higher: the old fixed 120px top margin pushed the card well
   below the fold's midline on a laptop. Scales with the viewport instead. */
.connect-screen.login-screen { margin-top: clamp(20px, 6vh, 64px); margin-bottom: 40px; }

.connect-screen p.login-tagline {
    font: 800 20px/1.35 var(--th-font-display);
    font-stretch: 125%;
    letter-spacing: -0.01em;
    color: var(--text);
    margin-bottom: 18px;
}
.login-tagline span {
    display: block;
    margin-top: 8px;
    font: 500 13px/1.5 var(--th-font-ui);
    letter-spacing: 0;
    color: var(--muted);
}

/* A small row of discipline chips under the tagline — purely illustrative
   (what this app actually tracks), not interactive, so the login screen
   doesn't read as just an empty form on a black page. */
.login-disciplines {
    display: flex; justify-content: center; gap: 18px; flex-wrap: wrap;
    margin-bottom: 22px; color: var(--muted);
    font: 500 12px/1 var(--th-font-ui);
}
.login-disciplines span { display: flex; align-items: center; gap: 6px; }

/* The form itself sits in a real card (border + background + a soft
   brand-colored glow, same device the KPI tiles use) rather than floating
   directly on the page background — gives the screen some structure
   beyond "logo, then inputs". */
.login-card {
    position: relative; overflow: hidden; isolation: isolate;
    background: var(--card); border: 1px solid var(--border); border-radius: var(--th-radius-lg);
    padding: 28px 28px 26px; text-align: left;
    box-shadow: 0 24px 60px -30px rgba(0, 0, 0, .6);
}
.login-card::before {
    content: ""; position: absolute; right: -20%; top: -40%; width: 70%; height: 120%;
    z-index: -1; pointer-events: none;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--th-accent) 18%, transparent), transparent);
}

.login-form { display: flex; flex-direction: column; gap: 16px; }

.login-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 8px; }

/* The input's own bordered box IS this wrapper — icon, <input>, and the
   password toggle are flex siblings inside it, not stacked/absolutely
   positioned over each other, so this holds up regardless of how lucide
   swaps the <i> for an <svg> after load. */
.login-input-wrap {
    display: flex; align-items: center; gap: 10px;
    background: color-mix(in srgb, var(--bg) 70%, var(--card)); border: 1px solid var(--border); border-radius: 10px;
    padding: 0 14px; min-height: 48px;
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.login-input-wrap:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.login-input-wrap:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.login-input-wrap .lucide { color: var(--muted); flex-shrink: 0; transition: color .15s ease; }
.login-input-wrap:focus-within .lucide { color: var(--accent); }
/* 16px stops iOS zooming the page when a field is focused. */
.login-input-wrap input, .login-input-wrap select {
    flex: 1; min-width: 0; border: none; background: none; padding: 12px 0; margin: 0;
    font: 500 16px/1.3 var(--th-font-ui); color: var(--text);
}
.login-input-wrap input::placeholder { color: var(--muted); opacity: .6; }
.login-input-wrap input:focus, .login-input-wrap select:focus { outline: none; }
/* Browser autofill otherwise paints its own pale yellow/white over the field. */
.login-input-wrap input:-webkit-autofill {
    -webkit-text-fill-color: var(--text);
    box-shadow: 0 0 0 100px color-mix(in srgb, var(--bg) 70%, var(--card)) inset;
    caret-color: var(--text);
}
.login-password-toggle {
    background: none; border: none; color: var(--muted); cursor: pointer;
    display: flex; align-items: center; padding: 2px; flex-shrink: 0;
}
.login-password-toggle:hover { color: var(--text); }

.login-footer { margin-top: 20px !important; font-size: 12px !important; }

.login-submit { width: 100%; margin-top: 6px; min-height: 48px; font-size: 15px; font-weight: 700; border-radius: 10px; }
.login-submit:disabled { opacity: .7; cursor: default; }
.connect-screen p.login-alert {
    display: flex; align-items: center; gap: 8px; margin: 0; padding: 10px 12px;
    border-radius: 10px; font-size: 13px; line-height: 1.4; text-align: left;
}
.login-alert .lucide { flex-shrink: 0; }
.connect-screen p.login-alert-error { color: var(--negative); background: color-mix(in srgb, var(--negative) 12%, transparent); border: 1px solid color-mix(in srgb, var(--negative) 35%, transparent); }
.connect-screen p.login-alert-ok { color: var(--positive); background: color-mix(in srgb, var(--positive) 12%, transparent); border: 1px solid color-mix(in srgb, var(--positive) 35%, transparent); }

/* Onboarding wizard's 3-step progress strip (Profile/Strava/Garmin) —
   a plain numbered-dot + connecting-line pattern, same device as any
   other step indicator; "done"/"active" are purely a color state, not
   separate markup, so the line itself never needs to change shape. */
.onboard-steps { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 0 0 40px; }
.onboard-step {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--card); border: 1px solid var(--border); color: var(--muted);
    font: 600 13px/32px var(--th-font-ui); text-align: center; position: relative; flex-shrink: 0;
}
.onboard-step span {
    position: absolute; top: 38px; left: 50%; transform: translateX(-50%);
    font: 500 11px/1 var(--th-font-ui); color: var(--muted); white-space: nowrap;
}
.onboard-step.is-active { background: var(--th-accent); border-color: var(--th-accent); color: var(--th-on-accent); }
.onboard-step.is-done { background: color-mix(in srgb, var(--positive) 18%, transparent); border-color: var(--positive); color: var(--positive); }
.onboard-step-line { width: 32px; height: 1px; background: var(--border); flex-shrink: 0; }

/* The sync result text floats below the button instead of sitting inline
   in the filter bar's flex row — as an inline sibling it added its own
   width to that row every time it had text, which could push the row
   past its available width and force the range/grain buttons to wrap a
   line earlier than they otherwise would. */
.sync-btn-wrap { position: relative; }
#sync-status {
    position: absolute; top: 100%; right: 0; margin-top: 4px;
    color: var(--muted); font-size: 13px; white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity 200ms var(--th-ease, ease);
}
#sync-status:not(:empty) { opacity: 1; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 500; }
tr { cursor: pointer; transition: background 0.1s; }
tr:hover td { background: var(--surface-2); }
thead tr { cursor: default; }
thead tr:hover td { background: transparent; }

/* A Triathlon leaderboard row expands in place to show its swim/T1/bike/
   T2/run breakdown (race_performance.js) instead of navigating away —
   there's no single activity a multi-leg race could link to. */
.leaderboard-expand-chevron { transition: transform 0.15s ease; }
tr.is-expandable.is-open .leaderboard-expand-chevron { transform: rotate(90deg); }
tr.leg-detail-row { cursor: default; }
tr.leg-detail-row:hover td { background: transparent; }
tr.leg-detail-row td { border-bottom: none; padding: 4px 6px 12px; }

/* Compact density (Settings -> Appearance) — tightens the same components
   rather than introducing new ones, so it stays a drop-in override. */
html[data-density="compact"] main { gap: 12px; }
html[data-density="compact"] .card { padding: 12px 14px; }
html[data-density="compact"] .filter-bar { padding: 9px 20px; }
html[data-density="compact"] .tile { padding: 8px 14px; gap: 4px; }
html[data-density="compact"] .stat-cards, html[data-density="compact"] .discipline-grid, html[data-density="compact"] .records-row { gap: 8px; }
html[data-density="compact"] .stat-card { padding: 10px 12px; gap: 8px; }
html[data-density="compact"] .disc-card { padding: 12px; }
html[data-density="compact"] .global-field { padding: 8px; }
html[data-density="compact"] .race-card, html[data-density="compact"] .race-leg-row, html[data-density="compact"] .burst-day-card, html[data-density="compact"] .excluded-row { padding: 8px 10px; }
html[data-density="compact"] th, html[data-density="compact"] td { padding: 5px 6px; }
html[data-density="compact"] .health-event-row { padding: 7px 10px; }

/* Goal pace gap table under the Training comparison chart */
.tc-gap { margin-top: 1.25rem; }
.tc-gap-title { font-size: 0.95rem; margin: 0 0 0.5rem; }
.tc-gap-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.tc-gap-table th, .tc-gap-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border, rgba(255,255,255,0.08)); }
.tc-gap-table th { font-weight: 500; opacity: 0.7; font-size: 0.8rem; }
.tc-gap-behind { color: var(--th-negative); }
.tc-gap-ahead { color: var(--th-positive); }
.tc-gap .hint { margin: 0; }
.tc-gap > .hint { margin-top: 10px; }
.tc-gap-table tr { cursor: default; }
.tc-gap-table tr:hover td { background: transparent; }

/* ---- Public signup / checkout / account-recovery pages ---- */
.pub-body { padding-left: 0 !important; min-height: 100vh; display: flex; flex-direction: column; background: var(--th-bg); }
.pub-header { display: flex; align-items: center; justify-content: space-between; padding: 18px 28px; border-bottom: 1px solid var(--border); }
.pub-nav { display: flex; gap: 22px; align-items: center; font-size: 14px; }
.pub-nav a { color: var(--muted); text-decoration: none; }
.pub-nav a:hover { color: var(--text); }
.pub-nav .pub-nav-login { color: var(--text); font-weight: 600; }
.pub-main { flex: 1; width: 100%; max-width: 560px; margin: 0 auto; padding: 40px 20px 56px; }
.pub-main.pub-wide { max-width: 1040px; }
.pub-footer { display: flex; gap: 22px; justify-content: center; padding: 22px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--border); }
.pub-footer a { color: var(--muted); text-decoration: none; }
.pub-footer a:hover { color: var(--text); }
.pub-title { font-family: var(--th-font-display); font-weight: 800; font-stretch: 125%; letter-spacing: -0.02em; line-height: 1; font-size: clamp(28px, 5vw, 44px); margin: 0 0 12px; }
.pub-lede { color: var(--muted); font-size: 16px; line-height: 1.55; margin: 0 0 28px; max-width: 60ch; }
.pub-card { position: relative; background: linear-gradient(180deg, var(--th-surface-2), var(--th-surface)); border: 1px solid var(--border); border-radius: 20px; padding: 28px; }
.pub-center { text-align: center; }
.pub-center .pub-lede { margin-left: auto; margin-right: auto; }
.pub-icon-badge { width: 56px; height: 56px; border-radius: 16px; display: grid; place-items: center; margin: 0 auto 18px; background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.pub-icon-badge .lucide { width: 26px; height: 26px; }
.pub-error { color: var(--negative); font-size: 13px; margin: 0; }
.pub-notice { color: var(--positive); font-size: 13px; margin: 0 0 12px; }
.pub-small { font-size: 13px; color: var(--muted); }
.pub-small a, .pub-link { color: var(--accent); text-decoration: none; }
.pub-small a:hover, .pub-link:hover { text-decoration: underline; }
.pub-stack { display: flex; flex-direction: column; gap: 14px; }
.pub-btn-row { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.pub-btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }
.pub-steps { display: flex; justify-content: center; gap: 6px; margin: 0 0 32px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.pub-steps span { padding: 4px 10px; border: 1px solid var(--border); border-radius: 999px; }
.pub-steps .is-active { background: var(--th-accent); border-color: var(--th-accent); color: var(--th-on-accent); font-weight: 700; }
.pub-steps .is-done { border-color: var(--positive); color: var(--positive); }
.pub-pwmeter { height: 4px; border-radius: 2px; background: var(--border); overflow: hidden; margin-top: 8px; }
.pub-pwmeter > i { display: block; height: 100%; width: 0; background: var(--negative); transition: width var(--th-dur-base) var(--th-ease), background var(--th-dur-base); }
.pub-check { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; color: var(--muted); line-height: 1.45; }
.pub-check input { margin-top: 3px; accent-color: var(--accent); }
.pub-two { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .pub-two { grid-template-columns: 1fr; } .pub-header { padding: 14px 16px; } }

/* Plans */
.pub-plans { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin: 0 0 28px; }
@media (max-width: 760px) { .pub-plans { grid-template-columns: 1fr; } }
.pub-plan { position: relative; display: flex; flex-direction: column; cursor: pointer; background: linear-gradient(180deg, var(--th-surface-2), var(--th-surface)); border: 1px solid var(--border); border-radius: 20px; padding: 26px; transition: border-color var(--th-dur-fast), transform var(--th-dur-fast); }
.pub-plan:hover { border-color: var(--muted); }
.pub-plan input { position: absolute; opacity: 0; pointer-events: none; }
.pub-plan.is-selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 18px 50px -24px var(--accent); }
.pub-plan-name { font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.pub-plan-price { font-family: var(--th-font-data); font-weight: 600; font-size: 40px; letter-spacing: -0.02em; margin: 10px 0 2px; }
.pub-plan-price small { font-size: 14px; color: var(--muted); font-weight: 500; }
.pub-plan-sub { color: var(--muted); font-size: 13px; min-height: 20px; }
.pub-ribbon { position: absolute; top: -12px; right: 20px; background: var(--th-accent); color: var(--th-on-accent); font-size: 12px; font-weight: 700; padding: 4px 12px; border-radius: 999px; }
.pub-saving { display: inline-block; margin-top: 12px; padding: 4px 10px; border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--positive); background: color-mix(in srgb, var(--positive) 14%, transparent); }
.pub-features { list-style: none; padding: 0; margin: 18px 0 0; display: grid; gap: 8px; font-size: 14px; }
.pub-features li { display: flex; gap: 10px; align-items: flex-start; }
.pub-features .lucide { color: var(--positive); width: 16px; height: 16px; margin-top: 3px; flex-shrink: 0; }
/* Reassurance row under pricing and checkout (not the header's .pub-trust strip) */
.pub-assure { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; margin-top: 40px; padding-top: 28px; border-top: 1px solid var(--border); }
@media (max-width: 860px) { .pub-assure { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .pub-assure { grid-template-columns: 1fr; } }
.pub-assure > div { font-size: 13px; color: var(--muted); line-height: 1.5; text-align: left; }
.pub-assure b { display: flex; gap: 8px; align-items: center; color: var(--text); font-size: 14px; margin-bottom: 6px; }
.pub-assure .lucide { color: var(--th-text-2); width: 18px; height: 18px; flex-shrink: 0; }
.pub-alert { display: flex; gap: 12px; align-items: flex-start; max-width: 640px; margin: 0 auto 28px; padding: 14px 16px; border-radius: 12px; font-size: 14px; line-height: 1.5; text-align: left;
    color: var(--text); background: color-mix(in srgb, var(--negative) 10%, transparent); border: 1px solid color-mix(in srgb, var(--negative) 35%, transparent); }
.pub-alert .lucide { color: var(--negative); width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; }
.pub-alert b { display: block; margin-bottom: 2px; }
.pub-alert a { color: var(--text); text-decoration: underline; }
.pub-summary { display: grid; gap: 10px; font-size: 14px; }
.pub-summary > div { display: flex; justify-content: space-between; gap: 16px; }
.pub-summary .pub-total { border-top: 1px solid var(--border); padding-top: 12px; font-size: 16px; font-weight: 700; }
.pub-summary > div > span:last-child { font-weight: 600; text-align: right; }
.pub-summary .mono { font-family: var(--th-font-data); font-weight: 600; }
.pub-checkout-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 860px) { .pub-checkout-grid { grid-template-columns: 1fr; } }
.pub-nudge { margin-top: 14px; padding: 12px 14px; border-radius: 12px; border: 1px dashed var(--accent); font-size: 13px; color: var(--text); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.pub-nudge button { background: none; border: 0; color: var(--accent); font-weight: 700; cursor: pointer; padding: 0; font: inherit; font-weight: 700; }
.pub-table { width: 100%; font-size: 13px; }
.pub-table td, .pub-table th { padding: 8px 6px; vertical-align: top; }
.pub-table tr { cursor: default; }
.pub-table tr:hover td { background: transparent; }
.pub-mail { background: #fff; border-radius: 12px; overflow: hidden; }
.pub-mail iframe { width: 100%; height: 420px; border: 0; background: #101820; }

.login-link { color: var(--accent); text-decoration: none; font-size: inherit; }
.login-link:hover { text-decoration: underline; }

/* Settings > Billing */
.bill-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 8px; }
@media (max-width: 640px) { .bill-grid { grid-template-columns: 1fr; } }
.bill-box { border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px; background: color-mix(in srgb, var(--surface-2) 60%, transparent); }
.bill-label { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.bill-value { font-size: 16px; font-weight: 600; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.pill-ok, .pill-warn { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.pill-ok { color: var(--positive); background: color-mix(in srgb, var(--positive) 16%, transparent); }
.pill-warn { color: var(--th-gold); background: color-mix(in srgb, var(--th-gold) 16%, transparent); }
.bill-table { width: 100%; font-size: 13px; }
.bill-table tr { cursor: default; }
.bill-table tr:hover td { background: transparent; }
.bill-table a { color: var(--accent); text-decoration: none; font-family: var(--th-font-data); }
.bill-box .hint { margin: 6px 0 0; }
.bill-box[hidden] { display: none; }

/* ---------- Operator admin (/admin/*) ---------- */
.adm-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 18px; border-bottom: 1px solid var(--border); padding-bottom: 10px; }
.adm-tabs a { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 10px; color: var(--muted); text-decoration: none; font-weight: 600; font-size: 14px; }
.adm-tabs a:hover { color: var(--text); background: color-mix(in srgb, var(--text) 6%, transparent); }
.adm-tabs a.is-active { color: var(--text); background: color-mix(in srgb, var(--accent) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
.adm-badge { background: var(--th-surface-3); color: var(--th-text); border-radius: 999px; font-size: 11px; font-weight: 800; padding: 1px 7px; margin-left: 2px; }
.adm-h { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 22px 0 10px; }
.adm-h3 { font-size: 13px; color: var(--muted); margin: 18px 0 8px; font-weight: 600; }
.adm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 16px; margin: 16px 0; align-items: start; }
.adm-grid > .card { margin: 0; }
@media (max-width: 480px) { .adm-grid { grid-template-columns: 1fr; } }
.adm-scroll { overflow-x: auto; }
.adm-row { cursor: pointer; }
.adm-filter { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 14px; align-items: center; }
.adm-head { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.adm-pill { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; text-transform: capitalize; white-space: nowrap;
    color: var(--muted); background: color-mix(in srgb, var(--text) 10%, transparent); }
.adm-trialing, .adm-trial_ending { color: var(--th-text); background: var(--th-surface-3); }
.adm-active { color: var(--positive); background: color-mix(in srgb, var(--positive) 16%, transparent); }
.adm-cancelling, .adm-past_due, .adm-pending, .adm-unverified { color: var(--th-gold); background: color-mix(in srgb, var(--th-gold) 16%, transparent); }
.adm-canceled, .adm-deactivated { color: var(--negative); background: color-mix(in srgb, var(--negative) 14%, transparent); }
.adm-complimentary { color: var(--th-text-2); background: color-mix(in srgb, var(--th-text-muted) 18%, transparent); }
.adm-bar-row { display: grid; grid-template-columns: minmax(110px, 38%) 1fr auto; gap: 10px; align-items: center; margin: 7px 0; font-size: 13px; }
.adm-bar { height: 10px; border-radius: 6px; background: color-mix(in srgb, var(--text) 8%, transparent); overflow: hidden; }
.adm-bar > span { display: block; height: 100%; background: var(--th-chalk); border-radius: 6px; }
.adm-bar-value { min-width: 56px; text-align: right; font-variant-numeric: tabular-nums; }
.adm-quote { border-left: 2px solid var(--border); padding: 4px 0 4px 12px; margin: 10px 0; font-size: 13px; }
.adm-quote > div { color: var(--muted); margin-top: 3px; white-space: pre-wrap; }
.adm-reply { margin-top: 8px; padding: 8px 12px; border-radius: 10px; font-size: 13px; background: color-mix(in srgb, var(--positive) 10%, transparent); white-space: pre-wrap; }
.adm-act { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 10px 0; font-size: 13px; }
.adm-act > label { width: 120px; color: var(--muted); font-size: 12px; }
.adm-spark { display: flex; align-items: flex-end; gap: 3px; height: 90px; }
.adm-spark > span { flex: 1; background: var(--th-text-muted); border-radius: 3px 3px 0 0; min-height: 3px; }
.adm-ticket { border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px; margin: 12px 0; }
.adm-ticket-head { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.adm-msg { white-space: pre-wrap; margin: 10px 0 0; font-size: 14px; }
.adm-reply-box[hidden] { display: none; }
.adm-sub { color: var(--muted); font-size: 12px; margin: 2px 0 0; line-height: 1.4; }
.adm-flash { margin: 10px 0 0; font-size: 13px; }
.adm-flash:empty { display: none; }
.adm-cards > * { flex: 1 1 160px; min-width: 150px; }
.card .health-form-row label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }

/* Operator > Emails */
.adm-mail { display: grid; grid-template-columns: 300px 1fr; gap: 16px; align-items: start; margin-bottom: 16px; }
@media (max-width: 900px) { .adm-mail { grid-template-columns: 1fr; } }
.adm-mail > .card { margin: 0; }
.adm-mail-item { display: block; width: 100%; text-align: left; background: none; border: 1px solid transparent; color: var(--text); border-radius: 10px; padding: 9px 12px; margin: 2px 0; cursor: pointer; font: inherit; }
.adm-mail-item b { display: block; font-size: 14px; }
.adm-mail-item span { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; line-height: 1.35; }
.adm-mail-item:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.adm-mail-item.is-on { background: color-mix(in srgb, var(--accent) 14%, transparent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.adm-mail-bar { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.adm-seg { display: inline-flex; background: var(--surface-2); border-radius: 10px; padding: 4px; gap: 2px; }
.adm-seg button { background: none; border: 0; color: var(--muted); font: inherit; font-size: 13px; font-weight: 600; padding: 6px 14px; border-radius: 8px; cursor: pointer; }
.adm-seg button.is-on { background: var(--card); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.25); }
.adm-mail-meta { display: grid; grid-template-columns: 2fr 1.2fr 2fr; gap: 14px; font-size: 13px; margin-bottom: 14px; }
@media (max-width: 700px) { .adm-mail-meta { grid-template-columns: 1fr; } }
.adm-device { background: color-mix(in srgb, var(--text) 5%, transparent); border-radius: 14px; padding: 18px; display: flex; justify-content: center; overflow: auto; }
.adm-device iframe { width: 100%; max-width: 700px; border: 0; border-radius: 10px; background: #fff; min-height: 300px; }
.adm-device[data-mode="phone"] iframe { width: 375px; max-width: 100%; border: 8px solid var(--th-bg); border-radius: 28px; box-shadow: 0 0 0 1px var(--th-line); }
.adm-device pre { margin: 0; width: 100%; max-width: 700px; white-space: pre-wrap; word-break: break-word; font: 13px/1.6 var(--th-font-data); color: var(--text); background: var(--card); padding: 18px; border-radius: 10px; }
.adm-color { display: flex; gap: 6px; align-items: center; }
.adm-color input[type="color"] { width: 38px; height: 34px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: none; cursor: pointer; flex-shrink: 0; }
.adm-color .select { width: 100%; font-family: var(--th-font-data); text-transform: uppercase; }
.adm-check { display: flex; gap: 12px; align-items: flex-start; padding: 9px 0; border-bottom: 1px solid var(--border); }
.adm-check:last-child { border-bottom: 0; }
.adm-check .adm-pill { flex-shrink: 0; margin-top: 2px; min-width: 84px; text-align: center; }
.adm-ctl { display: flex; justify-content: space-between; gap: 16px; align-items: center; flex-wrap: wrap; }
.adm-val { word-break: break-word; }

/* Year at a glance: what the data says. Compact tiles that flex to fill each row, so an uneven
   count never leaves a gap, and one-line notes so every tile is the same height. Generous vertical
   rhythm: the grid, its legend, the insights title and the tiles each get room to breathe. */
.heatmap-wrap { margin-top: 12px; }
.heatmap-legend { margin-top: 16px !important; }
.heat-insights-title { margin: 30px 0 14px; font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 700; }
.heat-insights { display: flex; flex-wrap: wrap; gap: 12px; }
.heat-insight { flex: 1 1 158px; border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px 13px; background: color-mix(in srgb, var(--surface-2) 55%, transparent); min-width: 0; }
.heat-insight[data-date] { cursor: pointer; }
.heat-insight[data-date]:hover { border-color: var(--accent); }
.heat-insight-label { font-size: 12px; color: var(--muted); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.heat-insight-value { font-size: 18px; font-weight: 700; margin: 7px 0 5px; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.heat-insight-note { font-size: 12px; color: var(--muted); line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Illness / injury overlay on the year grid: faint, so the load colour still shows through. */
.heat-flag { position: absolute; display: block; color: #fff; opacity: .82; pointer-events: none;
    filter: drop-shadow(0 0 1px rgba(10, 16, 22, .9)) drop-shadow(0 0 .5px rgba(10, 16, 22, .9)); }
.heat-flag svg { display: block; width: 100%; height: 100%; }
.heat-cell.has-flag .heat-flag { inset: 5%; }
.heat-cell.has-both .heat-flag { width: 64%; height: 64%; }
.heat-cell.has-both .heat-flag-illness { top: 2%; left: 2%; }
.heat-cell.has-both .heat-flag-injury { bottom: 2%; right: 2%; }
.heat-key { display: inline-flex; align-items: center; gap: 4px; margin-left: 16px; }
.heat-key-icon { display: inline-block; width: 14px; height: 14px; color: var(--text); opacity: .8; }
.heat-key-icon svg { display: block; width: 100%; height: 100%; }

/* A titled sub-section inside a card (e.g. "Totals for this range" under a chart). */
.card-section-title { margin: 22px 0 10px; padding-top: 16px; border-top: 1px solid var(--border); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 700; }

/* Health log: quick actions, the "currently ill" strip, and the ongoing checkbox */
.health-event-row { gap: 12px; }
.health-event-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.health-done { font-size: 12px; color: var(--positive); white-space: nowrap; }
.health-now { display: flex; justify-content: space-between; gap: 12px; align-items: center; flex-wrap: wrap; padding: 12px 16px; margin-bottom: 12px; border-radius: 12px;
    border: 1px solid var(--border); border-left: 4px solid var(--th-negative); background: color-mix(in srgb, var(--th-negative) 10%, var(--card)); }
.health-now.injury { border-left-color: var(--th-warning); background: color-mix(in srgb, var(--th-warning) 10%, var(--card)); }
.health-now-text { font-size: 14px; }
.health-now-text .health-event-meta { margin-left: 6px; }
.health-form-card label.health-ongoing { display: flex; align-items: center; gap: 8px; margin-top: 8px; color: var(--text); font-size: 13px; }
.health-form-card label.health-ongoing input { width: auto; }

/* Aerobic efficiency: one panel per discipline */
.ef-note { font-size: 12px; color: var(--muted); }
.ef-row { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 22px; align-items: center; padding: 18px 0; border-top: 1px solid var(--border); }
.ef-row:first-of-type { border-top: 0; }
@media (max-width: 800px) { .ef-row { grid-template-columns: 1fr; gap: 12px; } }
.ef-disc { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.ef-change { font: 700 32px/1.1 var(--th-font-data); font-variant-numeric: tabular-nums; margin-top: 8px; }
.ef-state { font-size: 13px; font-weight: 700; margin-top: 2px; }
.ef-sentence { font-size: 13px; line-height: 1.5; margin: 10px 0 8px; }
.ef-meta { font-size: 11px; color: var(--muted); }
.ef-help { margin-top: 8px; font-size: 13px; color: var(--muted); border-top: 1px solid var(--border); padding-top: 12px; }
.ef-help summary { cursor: pointer; font-weight: 600; color: var(--text); }
.ef-help ul { margin: 10px 0 0; padding-left: 20px; display: grid; gap: 7px; line-height: 1.5; }
.ef-key { display: flex; gap: 18px; flex-wrap: wrap; justify-content: flex-end; font-size: 11px; color: var(--muted); margin-top: 6px; }
.ef-key span { display: inline-flex; align-items: center; gap: 6px; }
.ef-key i { display: inline-block; }
.ef-key .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); }
.ef-key .line { width: 18px; height: 3px; border-radius: 2px; background: var(--muted); }
.ef-key .dash { width: 18px; height: 0; border-top: 1.5px dashed var(--muted); }

/* Goals: past races at this distance */
.goal-history-title { font-size: 15px; margin: 24px 0 8px; }
.goal-history-scroll { overflow-x: auto; }
.goal-history-table { width: 100%; font-size: 13px; min-width: 560px; }
.goal-history-table th { white-space: nowrap; }
.goal-history-table td { vertical-align: top; }
.goal-history-table tr { cursor: default; }
.goal-history-table tr:hover td { background: transparent; }
.goal-history-table .mono { font-family: var(--th-font-data); font-variant-numeric: tabular-nums; font-weight: 600; }
.goal-history-table .hint { margin: 0; font-size: 11px; }
.delta-over { color: var(--negative); }
.delta-under { color: var(--positive); }
.goal-history-scroll + .hint { margin-top: 10px; }

/* Goals page: spacing, collapsible cards, nudge */
#goals-list { display: grid; gap: 20px; margin-bottom: 20px; }
#goals-list > .card, #goals-nudge > .card { margin: 0; }
#goals-nudge:not(:empty) { margin-bottom: 20px; }
.goals-toolbar { display: flex; justify-content: flex-end; gap: 8px; }
.goal-card > .goal-card-header { gap: 12px; cursor: pointer; margin: 0; }
.goal-chevron { display: inline-flex; transition: transform .15s; transform: rotate(-90deg); color: var(--th-text-muted, var(--text-muted)); }
.goal-card.is-open .goal-chevron { transform: none; }
.goal-summary { display: flex; flex-wrap: wrap; gap: 8px; flex: 1; min-width: 0; }
.goal-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-size: 12px; border: 1px solid var(--border); white-space: nowrap; }
.goal-chip-muted { opacity: .6; }
.goal-chip-behind { color: var(--th-negative); border-color: currentColor; }
.goal-chip-ahead { color: var(--th-positive); border-color: currentColor; }
.goal-chip[hidden] { display: none; }
.goal-body { display: none; padding-top: 18px; }
.goal-body > * + * { margin-top: 16px; }
.goal-body .goal-description:empty { display: none; }
.goal-body .hint { margin-top: 0; }
.goal-card.is-open .goal-body { display: block; }
.goal-nudge ul { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 12px; }
.goal-nudge li { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.goal-nudge li .hint { display: block; margin: 2px 0 0; }
.goal-chevron svg { width: 18px; height: 18px; }


/* Chart controls: one pattern everywhere. A row (.chart-tools) holding, in this order,
   a segmented picker (2-5 options: .segmented), a select (6+ options: .select) and on/off
   switches (.switch-toggle). In a card header it sits right of the title; under a hint it
   sits on its own row (.chart-tools-row). */
.chart-tools { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
.chart-tools-row { margin: 4px 0 14px; }
.chart-tools .segmented { max-width: 100%; overflow-x: auto; }
.chart-tools .tool-note { font-size: 12px; color: var(--muted); }
.tc-controls { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
@media (max-width: 640px) { .goal-card-header > .chart-tools { width: 100%; } }

/* Activities page */
.act-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
.act-head h2 { margin: 0 0 6px; }
.act-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.act-filters { display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; margin-bottom: 24px; background: var(--th-surface-2, rgba(255,255,255,0.03)); border-radius: 12px; }
.act-filter-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.act-search { flex: 1 1 260px; min-width: 200px; }
.act-type { min-width: 180px; }
.act-date .date-input { width: 138px; padding-left: 10px; padding-right: 8px; }
.act-date { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.act-summary { margin: 0; color: var(--muted); font-size: 14px; }
.act-table-wrap { overflow-x: auto; }
.act-table th[data-sort] { cursor: pointer; user-select: none; white-space: nowrap; }
.act-table th[data-sort]:hover { color: var(--text); }
.act-table th.sorted::after { content: ' ↓'; color: var(--th-chalk); }
.act-table th.sorted[data-dir="asc"]::after { content: ' ↑'; }
.act-table .num { text-align: right; white-space: nowrap; }
.act-table tbody tr[data-id] { cursor: pointer; }
.act-pager { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--th-border, rgba(255,255,255,0.08)); }
.act-pager-btns { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.view-all-link { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; font-size: 13px; font-weight: 600; }

/* Page header: the title/controls row is tall enough that its centre sits on the sidebar logo's centre
   (logo centre = 35px from the top: 20px sidebar padding + 4px + half the 22px wordmark). */
.filter-bar:not(.filter-bar-inline) .filter-bar-title { min-height: 46px; }
html[data-density="compact"] .filter-bar:not(.filter-bar-inline) .filter-bar-title { min-height: 52px; }

/* Goals: roomier fields */
.goal-body .select { padding: 9px 14px; min-height: 40px; }
.goal-body .health-form-row { gap: 16px 20px; }
.goal-body .health-form-row label { display: block; margin-bottom: 6px; }
.goal-body .goal-description { margin-top: 14px; line-height: 1.5; }
.goal-body .goal-time-inputs { gap: 8px 10px; }
.goal-history-sub { font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 6px; }
.goal-save-status { margin: 0; min-width: 44px; }

/* Plain-language chart copy: a lead line (.hint), a live "what this means for you" read-out
   (.chart-takeaway) and the technical detail tucked behind a click (.th-science). */
/* Insight panel: sits BELOW the chart it explains (never a coloured stripe above it). Neutral surface, one quiet label. */
.chart-foot { margin-top: 16px; display: grid; gap: 10px; }
.chart-takeaway { margin: 0; padding: 14px 16px; border: 1px solid var(--border); background: var(--surface-2); border-radius: 12px; font-size: 14.5px; line-height: 1.55; color: var(--text); }
.chart-takeaway::before { content: "What this means"; display: block; margin-bottom: 6px; font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.chart-takeaway:empty { display: none; }
.chart-foot .th-science { margin: 0; }
.th-science { margin: 0 0 14px; font-size: 13px; color: var(--muted); }
.th-science summary { cursor: pointer; display: inline-block; font-weight: 600; color: var(--muted); user-select: none; }
.th-science summary:hover { color: var(--text); }
.th-science p { margin: 8px 0 0; padding: 10px 14px; border: 1px solid var(--border); border-radius: 8px; line-height: 1.55; }

/* Coaching */
.coach-pill { position: fixed; right: 18px; bottom: 18px; z-index: 400; display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 999px;
    background: var(--card); border: 1px solid var(--accent); box-shadow: 0 8px 28px rgba(0,0,0,.45); font-size: 13px; }
.coach-pill .lucide { color: var(--accent); }
.coach-pitch { list-style: none; margin: 18px 0 8px; padding: 0; display: grid; gap: 14px; }
.coach-pitch li { display: flex; gap: 14px; align-items: flex-start; }
.coach-pitch .lucide { flex: none; width: 22px; height: 22px; color: var(--th-text-2); margin-top: 2px; }
.coach-pitch b { display: block; }
.coach-pitch span { color: var(--muted); font-size: 14px; line-height: 1.5; }
.coach-form-title { font-size: 18px; margin: 26px 0 10px; }
.coach-terms { margin: 14px 0 18px; padding: 14px 16px; border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: 10px; display: grid; gap: 4px; }
.coach-terms span { color: var(--muted); font-size: 13px; }
.coach-attn, .coach-race { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); }
.coach-attn:first-of-type, .coach-race:first-of-type { border-top: 0; }
.coach-days { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--th-chalk); }
.coach-flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.coach-flag { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; color: var(--muted); background: color-mix(in srgb, var(--text) 10%, transparent); }
.coach-flag-bad { color: var(--negative); background: color-mix(in srgb, var(--negative) 14%, transparent); }
.coach-flag-warn { color: var(--th-gold); background: color-mix(in srgb, var(--th-gold) 16%, transparent); }
.coach-form { font-size: 12px; font-weight: 700; }
.coach-form-good { color: var(--positive); } .coach-form-warn { color: var(--th-gold); } .coach-form-bad { color: var(--negative); } .coach-form-muted { color: var(--muted); }
.coach-table td { vertical-align: top; }
.coach-actions { display: flex; gap: 8px; align-items: center; white-space: nowrap; }
.coach-actions form { margin: 0; }

/* Public pages: fuller header nav and a trust strip */
.pub-nav { gap: 26px; }
.pub-trust { display: flex; justify-content: center; gap: 10px 28px; flex-wrap: wrap; padding: 9px 16px; font-size: 12px; color: var(--muted);
    background: color-mix(in srgb, var(--text) 4%, transparent); border-bottom: 1px solid var(--border); }
.pub-trust span { display: inline-flex; align-items: center; gap: 6px; }
.pub-trust .lucide { color: var(--positive); }
@media (max-width: 720px) { .pub-nav-opt { display: none; } .pub-nav { gap: 16px; } }

.pub-two > * { min-width: 0; }
.pub-two .login-input-wrap input { min-width: 0; width: 100%; }
.chart-legend-events { opacity: .85; font-size: 12px; }
.legend-bar { display: inline-block; width: 12px; height: 4px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.legend-line { display: inline-block; width: 12px; height: 0; border-top: 1px dashed rgba(255, 200, 87, .7); margin-right: 6px; vertical-align: middle; }

/* Fresh-or-tired card: readouts first, then one question at a time. */
.ff-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 14px 0; }
.ff-tile { display: flex; flex-direction: column; gap: 6px; padding: 14px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); }
.ff-tile-main { border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); }
.ff-l { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted); }
.ff-v { font-size: 26px; font-weight: 600; line-height: 1; letter-spacing: -.01em; }
.ff-s { font-size: 12px; color: var(--muted); }
.ff-chip { padding: 2px 8px; border-radius: 999px; font: 600 11px/1.3 var(--th-font-ui); }
.ff-pos { color: var(--positive); background: color-mix(in srgb, var(--positive) 16%, transparent); }
.ff-warm { color: var(--th-gold); background: color-mix(in srgb, var(--th-gold) 16%, transparent); }
.ff-neg { color: var(--negative); background: color-mix(in srgb, var(--negative) 14%, transparent); }
.ff-mode { margin: 4px 0 12px; }
@media (max-width: 640px) { .ff-tiles { grid-template-columns: 1fr; } }

/* Onboarding wizard */
.connect-screen.ob { max-width: 720px; margin: clamp(16px, 5vh, 56px) auto 56px; padding: 0 16px; }
.ob-note { text-align: center; margin: 0 0 12px; }
.ob-progress { display: grid; gap: 8px; margin: 4px auto 18px; max-width: 620px; width: 100%; }
.ob-bar { height: 4px; border-radius: 4px; background: color-mix(in srgb, var(--text) 10%, transparent); overflow: hidden; }
.ob-bar i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 4px; transition: width .3s; }
.ob-progress span { font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ob-card { max-width: 620px; margin-left: auto; margin-right: auto; text-align: left; }
.ob-card.ob-wide { max-width: 620px; }
.ob-error { display: none; color: var(--negative); font-size: 13px; margin: 8px 0 0; }
.ob-primary { min-width: 160px; justify-content: center; }
.ob-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 18px; }
.ob-actions .ob-primary:only-child { margin-left: auto; }
.ob-back { background: none; border: 0; color: var(--muted); font: inherit; font-size: 14px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; padding: 8px 4px; }
.ob-back:hover { color: var(--text); }
.ob-options { display: grid; gap: 8px; }
.ob-option { text-align: left; padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px; background: transparent; color: var(--text); font: inherit; font-size: 15px; cursor: pointer; transition: border-color .12s, background .12s; }
.ob-option:hover { border-color: var(--muted); }
.ob-option.is-on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.ob-sub, .ob-q { margin-top: 16px; display: grid; gap: 8px; }
.ob-q b, .ob-sub b { font-size: 14px; }
.ob-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.ob-chip { padding: 8px 16px; border-radius: 999px; border: 1px solid var(--border); background: transparent; color: var(--text); font: inherit; cursor: pointer; }
.ob-chip.is-on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); font-weight: 600; }
.ob-check { display: flex; align-items: center; gap: 10px; margin-top: 16px; font-size: 14px; cursor: pointer; }
.ob-points p { color: var(--muted); font-size: 14px; line-height: 1.55; margin: 0 0 14px; }
.ob-ok { display: flex; align-items: center; gap: 8px; color: var(--positive); font-weight: 600; margin: 4px 0 0; }
.ob-found { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 10px; background: color-mix(in srgb, var(--text) 6%, transparent); font-size: 14px; margin: 0 0 16px; }
.ob-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 640px) { .ob-cols { grid-template-columns: 1fr; } }
.ob-cols h3 { font-size: 13px; display: flex; align-items: center; gap: 6px; margin: 0 0 8px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.ob-cols ul { margin: 0; padding-left: 18px; display: grid; gap: 8px; font-size: 14px; line-height: 1.5; }
.ob-catch { margin: 16px 0 0; padding: 12px 14px; border-left: 3px solid var(--th-gold); background: color-mix(in srgb, var(--th-gold) 8%, transparent); border-radius: 0 10px 10px 0; font-size: 14px; line-height: 1.5; }
.ob-choice { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.ob-choice .btn { flex: 1 1 180px; justify-content: center; }
.ob-choice .btn.is-on { outline: 2px solid var(--th-accent); outline-offset: 2px; }
.ob-sum { display: grid; gap: 0; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.ob-sum > div { display: flex; justify-content: space-between; gap: 12px; padding: 10px 14px; border-top: 1px solid var(--border); font-size: 14px; }
.ob-sum > div:first-child { border-top: 0; }
.ob-sum span { color: var(--muted); }
.ob-on { color: var(--positive); } .ob-off { color: var(--muted); }
.ob-h3 { font-size: 14px; margin: 22px 0 10px; }
.ob-steps { display: grid; gap: 8px; }
.ob-step { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px; color: var(--text); text-decoration: none; }
.ob-step:hover { border-color: var(--accent); }
.ob-step span { flex: 1; display: grid; gap: 2px; }
.ob-step em { font-style: normal; color: var(--muted); font-size: 12px; }
.ob-wide .ob-options { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.adm-demo { color: var(--th-gold); background: color-mix(in srgb, var(--th-gold) 16%, transparent); }

/* Operator > System tabs, open items, forms */
.sys-tabs { margin: 0 0 16px; flex-wrap: wrap; }
.sys-pane[hidden] { display: none; }
.sys-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.sys-form .input { min-width: 150px; }
.sys-form label { display: flex; flex-direction: column; gap: 4px; }
.sys-actions { display: flex; align-items: center; gap: 12px; margin: 10px 0; }
tr.is-done { opacity: 0.5; }

/* Rich activity page */
.act-map { height: 380px; border-radius: 12px; overflow: hidden; background: var(--th-surface-2); }
.act-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.act-stat { background: var(--th-surface-2, rgba(255,255,255,0.04)); border-radius: 10px; padding: 10px 12px; }
.act-stat-v { font-weight: 600; font-size: 16px; }
.act-stat-l { font-size: 12px; color: var(--th-text-muted); margin-top: 2px; }

/* "The science" button + modal */
.chart-foot { position: relative; }
.sci-btn { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 1px solid var(--border); color: var(--muted); border-radius: 999px; padding: 4px 11px; font: 600 12px var(--th-font-ui, inherit); cursor: pointer; }
.sci-btn:hover { color: var(--text); border-color: var(--muted); }
.sci-btn-corner { position: absolute; top: 12px; right: 14px; z-index: 1; }
.chart-takeaway:empty ~ .sci-btn-corner { display: none; }
@media (max-width: 560px) { .sci-btn-corner span { display: none; } .sci-btn-corner { padding: 5px 7px; } }
.sci-modal[hidden] { display: none; }
.sci-modal { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 16px; }
.sci-backdrop { position: absolute; inset: 0; background: rgba(5, 8, 14, 0.72); backdrop-filter: blur(3px); }
.sci-dialog { position: relative; width: min(560px, 100%); max-height: 86vh; overflow: auto; background: var(--card); border: 1px solid var(--border); border-radius: 16px; padding: 26px 26px 22px; box-shadow: 0 24px 60px rgba(0,0,0,.5); }
.sci-dialog h3 { margin: 4px 0 10px; font-size: 22px; }
.sci-eyebrow { display: flex; align-items: center; gap: 6px; font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--th-accent, var(--muted)); }
.sci-x { position: absolute; top: 10px; right: 12px; background: none; border: 0; color: var(--muted); font-size: 26px; line-height: 1; cursor: pointer; }
.sci-x:hover { color: var(--text); }
.sci-lead { font-size: 16px; line-height: 1.55; margin: 0 0 14px; }
.sci-fig { background: var(--surface-2); border: 1px solid var(--border); border-radius: 12px; padding: 14px; margin-bottom: 16px; color: var(--muted); }
.sci-svg { width: 100%; height: auto; display: block; }
.sci-points { display: grid; gap: 10px; margin: 0; }
.sci-points div { padding-left: 12px; border-left: 2px solid var(--border); }
.sci-points dt { font-weight: 600; font-size: 14px; }
.sci-points dd { margin: 2px 0 0; color: var(--muted); font-size: 14px; line-height: 1.5; }
.sci-list { margin: 0; padding-left: 18px; color: var(--muted); line-height: 1.6; font-size: 14.5px; display: grid; gap: 6px; }
body.sci-open { overflow: hidden; }

/* Coach dashboard: tabs, charts, remove modal, billing */
.coach-pane[hidden] { display: none; }
.coach-charts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.coach-charts .coach-wide { grid-column: 1 / -1; }
@media (max-width: 900px) { .coach-charts { grid-template-columns: 1fr; } }
.coach-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.coach-chip { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 1px solid var(--border); color: var(--muted); border-radius: 999px; padding: 5px 11px; font: 600 12.5px var(--th-font-ui, inherit); cursor: pointer; }
.coach-chip i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.coach-chip.on { color: var(--text); border-color: var(--th-accent, var(--text)); background: rgba(255,107,31,.1); }
.cc-grid { border-collapse: separate; border-spacing: 3px; width: 100%; font-size: 12px; }
.cc-grid th { color: var(--muted); font-weight: 500; text-align: center; }
.cc-grid th, .cc-grid td { padding: 2px; border-bottom: 0; vertical-align: middle; }
.cc-grid tbody tr:hover td { background: transparent; }
.cc-grid .cc-name { text-align: left; white-space: nowrap; padding-right: 14px; width: 1%; }
.cc-grid .cc-total { text-align: right; padding-left: 12px; width: 1%; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cc-grid th.cc-total { color: var(--muted); }
.cc-grid tbody tr + tr td { padding-top: 4px; }
.cc-cell { display: block; min-width: 26px; height: 26px; line-height: 26px; text-align: center; border-radius: 5px; background: var(--th-heat-3); color: var(--th-ink); font-weight: 600; }
.rm-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .rm-cols { grid-template-columns: 1fr; } }
.rm-cols h4 { margin: 0 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.rm-bill { display: flex; justify-content: space-between; align-items: center; margin-top: 16px; padding: 12px 14px; border: 1px solid var(--border); background: var(--surface-2); border-radius: 10px; }
.rm-bill i { font-style: normal; color: var(--muted); padding: 0 4px; }
.rm-danger { background: var(--th-negative); border-color: var(--th-negative); color: var(--th-bg); }
.rm-lines { width: 100%; margin-top: 12px; }
.rm-lines td:last-child { text-align: right; }
.rm-total td { font-weight: 700; border-top: 1px solid var(--border); }

.rf-shot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 12px; margin: 4px 0 14px; border: 1px dashed var(--border); border-radius: 10px; }
.rf-shot.is-over { border-color: var(--th-accent, var(--text)); background: rgba(255,107,31,.06); }

/* Selects: room on both sides and a proper arrow, everywhere (the native arrow sat hard against the text) */
select, .select {
    -webkit-appearance: none; appearance: none;
    padding-left: 12px; padding-right: 36px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa3b2' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 12px center; background-size: 12px;
    text-overflow: ellipsis;
}
select[multiple], select[size]:not([size="1"]) { background-image: none; padding-right: 12px; }
.goal-body .select { padding-left: 14px; padding-right: 38px; }
input.select, textarea.select { background-image: none; padding-right: 12px; }

/* Goals: the time row wraps instead of colliding, and the status text no longer pushes into the Save button */
.goal-time-inputs { flex-wrap: wrap; }
.goal-time-inputs .btn { margin-left: 8px; }
.goal-time-inputs .goal-save-status { margin: 0 0 0 4px; min-width: 0; }

/* How ambitious is this goal */
.goal-ambition { border: 1px solid var(--border); background: var(--surface-2); border-radius: 12px; padding: 14px 16px; margin: 4px 0 14px; }
.goal-ambition-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.goal-ambition-title { font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.goal-ambition-chip { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--border); }
.goal-ambition-ahead .goal-ambition-chip { color: var(--positive); border-color: var(--positive); }
.goal-ambition-warm .goal-ambition-chip { color: var(--th-gold); border-color: var(--th-gold); }
.goal-ambition-behind .goal-ambition-chip { color: var(--negative); border-color: var(--negative); }
.goal-ambition p { margin: 0; line-height: 1.55; font-size: 14.5px; }
.goal-ambition-targets { display: flex; gap: 28px; margin-top: 12px; flex-wrap: wrap; }
.goal-ambition-targets div { display: grid; gap: 2px; }
.goal-ambition-targets span { font-size: 12px; color: var(--muted); }
.goal-ambition-targets b { font-family: var(--th-font-data); font-size: 18px; }
.goal-body input.select, .goal-body textarea.select, .goal-time-inputs input.select { padding-left: 8px; padding-right: 8px; }
.goal-outlook-good { color: var(--positive); border-color: var(--positive); }
.goal-outlook-warn { color: var(--th-gold); border-color: var(--th-gold); }
.goal-outlook-bad { color: var(--negative); border-color: var(--negative); }
.race-data-chip.race-chip-dnf { color: var(--negative); border-color: var(--negative); background: rgba(255, 90, 95, 0.08); font-weight: 700; }

/* Race popup: tabs, and room to breathe */
.race-tabs { margin: 0 0 20px; }
.race-pane[hidden] { display: none; }
.race-pane .race-detail-section { margin-top: 24px; padding-top: 22px; }
.race-pane .race-detail-section:first-child { margin-top: 0; padding-top: 0; }
.race-pane .race-transitions-row { margin-bottom: 14px; gap: 14px; }
.race-pane .race-transitions-row label { font-size: 13.5px; }
.race-detail-section-title { margin-bottom: 14px; }
.race-results-import-row { margin-bottom: 10px; }
.race-results-manual-title { margin: 26px 0 12px; }
.race-results-title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.race-results-card { border: 1px solid var(--border); background: var(--surface-2); border-radius: 12px; padding: 14px 16px 4px; margin-bottom: 14px; }
.race-results-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.race-results-card-head b { font-size: 14px; }
.race-results-card .race-transitions-row:last-child { margin-bottom: 12px; }
.race-pct { white-space: nowrap; }
#rr-leg-section, #rr-leg-section-toggle-row { margin-top: 6px; }

/* Login: way back to the marketing site, and the "not you" line */
.login-topbar { padding: 18px 24px 0; }
.login-back { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); text-decoration: none; font-size: 14px; }
.login-back:hover { color: var(--text); }
.login-mark-link { display: block; text-decoration: none; }
.login-notyou { margin: 6px 0 0; font-size: 13px; }

/* Coach dashboard (and System) top-of-page spacing: tabs hug their content, every block has air around it */
.sys-tabs { display: inline-flex; width: auto; max-width: 100%; margin: 4px 0 22px; }
.race-tabs { display: inline-flex; width: auto; max-width: 100%; }
.coach-pane > .stat-cards { margin-bottom: 20px; }
.coach-pane .coach-filter { margin: 0 0 20px; padding: 14px 18px; }
.coach-pane .coach-charts { margin-bottom: 20px; }
.coach-pane .coach-charts .card { margin: 0; }
.coach-pane .adm-grid { margin-bottom: 20px; }
.coach-pane .card + .card { margin-top: 20px; }
/* Cards side by side in a grid line up at the top and share a height */
.coach-pane .adm-grid > .card, .coach-pane .coach-charts > .card { margin: 0; }
.coach-pane .adm-grid, .coach-pane .coach-charts { align-items: stretch; }
/* main is a flex column with its own gap, so tabs need to hug their content and sit closer to the page header */
main > .sys-tabs, main > .race-tabs { align-self: flex-start; margin: -8px 0 0; }

/* The goals page's "Add a goal" card is only a card while its form is open; closed, it's just the button. */
.add-goal-section:not(:has(#add-goal-form:not(:empty))) { background: none; border: 0; box-shadow: none; padding: 0; }
.add-goal-section #add-goal-form:not(:empty) + #add-goal-btn { margin-top: 14px; }

/* Plain in-text links share one look instead of the browser's blue and purple. */
main a:not([class]), .card a:not([class]) { color: var(--accent); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); text-underline-offset: 3px; }
main a:not([class]):hover, .card a:not([class]):hover { text-decoration-color: var(--accent); }

/* Phones: filter controls wrap or scroll instead of pushing the page wider than the screen. */
@media (max-width: 640px) {
    .filter-bar-controls { flex-wrap: wrap; max-width: 100%; }
    .filter-bar-controls .segmented { max-width: 100%; overflow-x: auto; }
    .th-canvas-wrap { max-width: 100%; overflow: hidden; }
}

/* Operator > System > Dashboard rules */
.rl-bar { display: grid; gap: 12px; margin: 14px 0 16px; }
.rl-search { max-width: 320px; }
.rl-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.rl-chips button { font: inherit; font-size: 13px; color: var(--muted); background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 6px 14px; cursor: pointer; }
.rl-chips button em { font-style: normal; font-size: 11.5px; opacity: .7; margin-left: 4px; }
.rl-chips button:hover:not(:disabled) { color: var(--text); border-color: var(--accent); }
.rl-chips button.active { color: var(--text); background: color-mix(in srgb, var(--accent) 16%, transparent); border-color: var(--accent); }
.rl-chips button:disabled { opacity: .35; cursor: default; }
.rl-group { margin: 22px 0 10px; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.rl-list { display: grid; gap: 12px; }
.rl-card { border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); padding: 14px 16px; }
.rl-card.is-off { opacity: .55; }
.rl-card .rl-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rl-card h4 { margin: 0; font-size: 15px; display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
.rl-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.rl-kind { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; }
.rl-code { font-size: 12px; color: var(--muted); }
.rl-when { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 12px; }
.rl-when > div { padding: 10px 12px; border-radius: 10px; background: color-mix(in srgb, var(--text) 4%, transparent); }
.rl-when b { display: block; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 4px; }
.rl-show b { color: var(--positive); } .rl-hide b { color: var(--muted); }
.rl-when p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--text); }
.rl-card .rl-foot { margin-top: 10px; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.rl-card .rl-foot code { font-size: 11px; }
@media (max-width: 760px) { .rl-when { grid-template-columns: 1fr; } }

.rl-impact { font: 600 11.5px var(--th-font-data); color: var(--th-gold); }

/* CARTO's dark tiles are near-black next to the app's surfaces; lift them so roads and parks read. Tweak brightness to taste. */
#activity-map .leaflet-tile-pane { filter: brightness(2.3) contrast(1.08) saturate(0.9); }

/* Custom LankFit icons (design system A10): body stroke follows the text colour, the accent stroke reads --icon-accent. */
svg.th-ic { fill: none; stroke: currentColor; overflow: visible; }

/* ---------- Orange discipline (design system v0.4) ----------
   Orange is for brand roles only: primary buttons, active nav, focus ring, logo dot, "you, now" series.
   Selected chips, segments, tabs, option cards, decorative icon badges and hover borders are neutral. */
:root { --sel-bg: var(--th-surface-3); --sel-line: var(--th-line-strong); --sel-fg: var(--th-text); }
.segmented button.seg-active { background: var(--sel-bg); color: var(--sel-fg); box-shadow: inset 0 0 0 1px var(--sel-line); }
.custom-range-toggle.active { background: var(--sel-bg); color: var(--sel-fg); border-color: var(--sel-line); }
.tile-selected { border-color: var(--sel-line); background: var(--sel-bg); box-shadow: none; }
.tc-race-chip.is-checked { border-color: var(--tc-chip-color, var(--sel-line)); }
.settings-tab.active { border-bottom-color: var(--sel-fg); }
.ob-option.is-on, .ob-chip.is-on, .rl-chips button.active, .adm-mail-item.is-on { background: var(--sel-bg); border-color: var(--sel-line); color: var(--sel-fg); }
.adm-tabs a.is-active { background: var(--sel-bg); box-shadow: inset 0 0 0 1px var(--sel-line); }
.ob-choice .btn.is-on { outline-color: var(--sel-line); }
.ask-hero-icon, .stat-card-icon, .pub-icon-badge { color: var(--th-text-2); background: var(--th-surface-2); }
.ff-tile-main { border-color: var(--sel-line); }
.coach-pill { border-color: var(--sel-line); }
.coach-pill .lucide { color: var(--th-text-2); }
.coach-terms { border-left-color: var(--sel-line); }
.race-card-main:hover .race-name, .linked-race-card:hover strong, .data-link:hover { color: var(--th-text); }
.linked-race-card:hover, .race-leg-row:hover, .heat-insight[data-date]:hover, .ob-step:hover, .rl-chips button:hover:not(:disabled) { border-color: var(--sel-line); }
.card:has(#readiness-series-chart), .card:has(#tc-chart) { --card-glow: var(--th-text-muted); }
.pub-plan.is-selected { border-color: var(--sel-line); box-shadow: 0 0 0 1px var(--sel-line); }
.pub-nudge { border-color: var(--sel-line); }
.logo .lucide { color: var(--accent); } /* logo dot stays brand orange */

/* ---------- Component states (GL-08 buttons, GL-09 forms) ---------- */
.btn:hover { filter: none; background: var(--th-pace-hover); }
.btn:active { background: var(--th-pace-pressed); transform: none; }
.btn:disabled, .btn[disabled] { background: var(--th-surface-2); color: var(--th-text-disabled); box-shadow: none; cursor: not-allowed; }
.btn-secondary { border-color: var(--th-line-strong); font-weight: 500; }
.btn-secondary:hover { background: var(--th-surface-2); border-color: var(--th-line-strong); }
.btn-secondary:active { background: var(--th-surface-3); }
.btn-secondary:disabled, .btn-secondary[disabled] { background: transparent; color: var(--th-text-disabled); border-color: var(--th-line); }
.btn-tertiary { background: none; border: 0; box-shadow: none; color: var(--th-text); font-weight: 600; }
.btn-tertiary:hover { background: none; color: var(--th-pace-text); }
.btn-tertiary:active { color: var(--th-pace-pressed); background: none; }
.btn-danger, .btn-destructive { background: transparent; color: var(--th-negative); border: 1px solid color-mix(in srgb, var(--th-negative) 55%, transparent); box-shadow: none; font-weight: 600; }
.btn-danger:hover, .btn-destructive:hover { background: color-mix(in srgb, var(--th-negative) 12%, transparent); }
.btn-danger:active, .btn-destructive:active { background: color-mix(in srgb, var(--th-negative) 20%, transparent); }
.btn:focus-visible, .segmented button:focus-visible, .settings-tab:focus-visible, a:focus-visible, summary:focus-visible { outline: var(--th-focus-ring); outline-offset: 3px; }
input:not([type=checkbox]):not([type=radio]):not([type=range]):focus, select:focus, textarea:focus { outline: none; border-color: var(--th-pace); box-shadow: 0 0 0 3px var(--th-pace-soft); }
/* A field with an icon or button inside (.login-input-wrap) draws ONE ring on the
   wrapper (:focus-within). The bare input inside must not draw its own, or the ring's
   left and right edges show as vertical lines beside the icon and the eye toggle. */
.login-input-wrap input:not([type=checkbox]):not([type=radio]):not([type=range]):focus,
.login-input-wrap select:not([multiple]):focus { outline: none; border: 0; box-shadow: none; }
.login-input-wrap input:not([type=checkbox]):not([type=radio]):not([type=range]):-webkit-autofill:focus {
    box-shadow: 0 0 0 100px color-mix(in srgb, var(--bg) 70%, var(--card)) inset;
}
.login-input-wrap:focus-within { border-color: var(--th-pace); box-shadow: 0 0 0 3px var(--th-pace-soft); }
.login-password-toggle:focus, .login-password-toggle:focus-visible { outline: none; }
input.is-invalid, select.is-invalid, textarea.is-invalid, .field-error input { border-color: var(--th-negative); }
.field-msg { color: var(--th-negative); font-size: 12px; margin-top: 4px; }
input:disabled, select:disabled, textarea:disabled { color: var(--th-text-disabled); background: var(--th-surface-2); cursor: not-allowed; }
/* Numbers in mono (GL-05) */
.kpi-value, .stat-value, .metric, table td.num, .mono { font-family: var(--th-font-data); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; } }

/* ---------- Lockout / trial ---------- */
.lockout-built { margin-bottom: 24px; }
.lockout-stats { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.lockout-stats > div { flex: 1 1 150px; background: var(--th-surface-2); border-radius: 12px; padding: 14px 16px; }
.lockout-stats b { display: block; font-size: 30px; font-family: var(--th-font-data); font-weight: 600; }
.lockout-stats span { color: var(--th-text-muted); font-size: 13px; }
.lockout-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; }
.lockout-cols h2 { font-size: 16px; margin: 0 0 8px; }
.lockout-lose .lucide { color: var(--th-negative); }
.trial-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 16px; margin: 0 0 16px; border-radius: 12px; background: var(--th-surface-2); border: 1px solid var(--th-line); font-size: 14px; }
.trial-bar b { font-family: var(--th-font-data); }
.trial-bar .trial-bar-cta { margin-left: auto; }
.trial-bar.is-urgent { border-color: var(--th-warning); }

/* Section tabs (Training / Racing / Vitals): a clear row of pills at the top of the sticky page header,
   same selected look as the other tab rows (neutral fill and ring, orange stays for actions). */
.page-tabs { flex: 0 0 100%; display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; margin: 0 0 2px; padding: 6px 0 14px; border-bottom: 1px solid var(--border); }
.page-tabs::-webkit-scrollbar { display: none; }
.page-tabs a { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 10px; font: 600 14px/1 var(--th-font-ui); color: var(--muted); text-decoration: none; white-space: nowrap; box-shadow: inset 0 0 0 1px transparent; }
.page-tabs a .lucide { width: 16px; height: 16px; flex-shrink: 0; }
.page-tabs a:hover { color: var(--text); background: var(--surface-2); }
.page-tabs a.is-active { color: var(--sidebar-text-active); background: var(--sidebar-active-bg); box-shadow: inset 3px 0 0 var(--accent); }
@media (max-width: 760px) { .page-tabs a { padding: 8px 12px; font-size: 14px; } }

/* "More detail" on a card without an insight panel sits in the card's top right corner, never mid-content. */
.card.has-sci, section.has-sci { position: relative; }
.sci-btn-card { position: absolute; top: 16px; right: 18px; z-index: 1; }
@media (max-width: 560px) { .sci-btn-card span { display: none; } .sci-btn-card { padding: 5px 7px; } }

/* Training comparison: pick one past race (radio chips); the native radio is hidden, the chip shows the choice. */
.tc-race-label { align-self: center; font-size: 13px; color: var(--muted); margin-right: 2px; }
.tc-race-chip input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.tc-race-chip { position: relative; }

/* Legends wrap, never crop: long race names break onto a second line on a laptop-width card. */
.chart-legend-wrap { justify-content: flex-start; }
.chart-legend-wrap .chart-legend-item { white-space: normal; }

/* Readiness: the per-sport cards sit right under the overall card they break down. */
.readiness-by-sport { margin: -8px 0 24px; }
.readiness-by-sport .section-label { margin: 0 0 10px 4px; font: 600 11px/1 var(--th-font-data); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
/* Leave room for the corner "More detail" button when the card header already holds controls. */
.card.has-sci > .goal-card-header, .card.has-sci > .chart-tools:first-child { padding-right: 128px; }
@media (max-width: 560px) { .card.has-sci > .goal-card-header, .card.has-sci > .chart-tools:first-child { padding-right: 44px; } }

/* ---------- Ask: a chat, not a form ---------- */
.ask-page { max-width: 820px; min-height: calc(100vh - 150px); gap: 0; }
.ask-thread { flex: 1; display: flex; flex-direction: column; gap: 22px; padding: 8px 0 24px; }
.ask-thread.is-empty { justify-content: center; }
.ask-hero { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 24px 8px 8px; }
.ask-hero-title { font-size: 28px; }
.ask-hero-sub { max-width: 46ch; font-size: 15px; }
.ask-chip-row { max-width: 640px; margin-top: 14px; }
.ask-chip { padding: 10px 16px; font-size: 14px; }
.ask-msg { display: flex; gap: 12px; align-items: flex-start; }
.ask-msg-user { justify-content: flex-end; }
.ask-msg-user .ask-msg-bubble { max-width: 78%; padding: 10px 16px; border-radius: 18px 18px 4px 18px; background: var(--th-surface-3); color: var(--th-text); font-size: 15px; line-height: 1.55; border: 0; box-shadow: none; }
.ask-msg-avatar { margin-top: 2px; width: 28px; height: 28px; }
.ask-msg-main { flex: 1; min-width: 0; }
.ask-answer { font-size: 15px; line-height: 1.65; color: var(--text); }
.ask-answer p { margin: 0 0 12px; }
.ask-answer p:last-child { margin-bottom: 0; }
.ask-answer ul, .ask-answer ol { margin: 0 0 12px; padding-left: 22px; }
.ask-answer li { margin-bottom: 4px; }
.ask-answer-error { color: var(--th-negative); }
.ask-thinking { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 14px; padding-top: 4px; }
.ask-copy { margin-top: 8px; display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; color: var(--muted); font: 500 12px var(--th-font-ui); cursor: pointer; padding: 4px 6px; border-radius: 6px; opacity: 0; transition: opacity .12s; }
.ask-copy .lucide { width: 14px; height: 14px; }
.ask-msg-assistant:hover .ask-copy, .ask-copy:focus-visible { opacity: 1; }
.ask-copy:hover { color: var(--text); background: var(--surface-2); }
@media (hover: none) { .ask-copy { opacity: 1; } }
.ask-dock { position: sticky; bottom: 0; z-index: 5; padding: 14px 0 6px; background: linear-gradient(to bottom, transparent, var(--bg) 28%); }
.ask-dock.is-off { opacity: .6; }
.ask-composer { display: flex; align-items: flex-end; gap: 8px; padding: 10px 10px 10px 18px; border-radius: 24px; background: var(--card); border: 1px solid var(--th-line-strong); box-shadow: 0 8px 30px rgba(0, 0, 0, .35); }
.ask-composer:focus-within { border-color: var(--th-text-muted); }
.ask-composer textarea { flex: 1; border: 0; outline: 0; resize: none; background: none; color: var(--text); font: 400 15px/1.5 var(--th-font-ui); padding: 7px 0; max-height: 180px; min-height: 26px; }
.ask-composer textarea::placeholder { color: var(--muted); }
.ask-send-btn { width: 38px; height: 38px; }
.ask-foot { margin: 8px 0 0; text-align: center; font-size: 12px; color: var(--muted); }
/* .hint's negative top margin is for a line sitting under a heading; after a table or a block of rows it must sit clear of it. */
table + .hint, .table-wrap + .hint, ul + .hint, ol + .hint { margin-top: 14px; }
.ask-composer textarea, .ask-composer textarea:hover, .ask-composer textarea:focus, .ask-composer textarea:focus-visible { outline: 0; box-shadow: none; border: 0; background: none; }
#ask-new-btn[hidden] { display: none; }

/* Readiness: which race the page is measured against, one line plus a switcher for the others. */
.rd-head { display: flex; justify-content: space-between; align-items: center; gap: 12px 20px; flex-wrap: wrap; margin: 4px 0 18px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--th-surface-2); }
.rd-head-main { display: flex; align-items: baseline; gap: 6px 12px; flex-wrap: wrap; }
.rd-tag { font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.rd-name { font-size: 17px; }
.rd-meta { font-size: 13px; color: var(--muted); }
.rd-head-side { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.rd-switch { max-width: 300px; }
.rd-back { background: none; border: 0; padding: 0; color: var(--accent); font: 600 13px var(--th-font-ui); cursor: pointer; text-decoration: underline; }
.rd-no-target { margin: 4px 0 14px; }

/* One line under each compare chart; the one "What this means" panel for the whole section sits below all the cards. */
.compare-now { margin: 10px 0 0; font-size: 13px; color: var(--muted); }

/* Onboarding progress: one segment per stage, as wide as the time it takes, with minutes left. */
.ob-segs { display: flex; gap: 6px; }
.ob-seg { height: 6px; border-radius: 6px; background: color-mix(in srgb, var(--text) 10%, transparent); overflow: hidden; }
.ob-seg i { display: block; height: 100%; background: var(--accent); border-radius: 6px; transition: width .35s ease; }
.ob-seg.is-current { background: color-mix(in srgb, var(--text) 16%, transparent); }
.ob-progress-text { display: flex; justify-content: space-between; gap: 12px; }
.ob-progress-text span { font: 600 11px/1 var(--th-font-data); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ob-progress-text span:last-child { color: var(--text); }
/* Welcome step */
.ob-why { margin: 0 0 14px; font-size: 15px; line-height: 1.6; color: var(--text); }
.ob-rec { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 18px; padding: 12px 14px; border-radius: 10px; background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); font-size: 14px; line-height: 1.5; }
.ob-rec .lucide { flex: none; margin-top: 2px; color: var(--accent); }
.ob-stages { display: grid; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; margin-bottom: 14px; }
.ob-stage-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-top: 1px solid var(--border); }
.ob-stage-row:first-child { border-top: 0; }
.ob-stage-ic { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--muted); flex: none; }
.ob-stage-row > span:nth-child(2) { flex: 1; display: grid; gap: 2px; font-size: 14px; }
.ob-stage-row em { font-style: normal; color: var(--muted); font-size: 13px; }
.ob-stage-row > i { font: 600 12px/1 var(--th-font-data); font-style: normal; color: var(--muted); white-space: nowrap; }
.ob-saved { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; margin: 0; }

.ob-later { text-align: center; margin: 14px 0 0; font-size: 13px; }
.ob-later a { color: var(--muted); text-decoration: underline; }
.ob-later a:hover { color: var(--text); }
/* Who is signed in, and a way out, on every setup step: a second account made in the same browser otherwise has no exit. */
.ob-account { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 6px 10px; margin: 22px 0 0; font-size: 13px; color: var(--muted); }
.ob-account b { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
.ob-account-out { background: none; border: 0; padding: 0; font: inherit; color: var(--muted); text-decoration: underline; cursor: pointer; }
.ob-account-out:hover, .ob-account-out:focus-visible { color: var(--text); }

.cad-take { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; } .cad-take b { color: var(--th-chalk); }
.cad-click { margin: 10px 0 0; font-size: 12px; color: var(--th-text-muted); }
.drilldown-lens b { color: var(--th-chalk); font-family: var(--th-font-data, monospace); }

/* ---- Breathing room (3 Oct 2026): one vertical rhythm for the whole app. ----
   Everything was a few pixels tight: cards stacked 20px apart with 12px under headings and 5px rows. These raise the
   defaults; compact density (Settings > Display) keeps its own tighter values because its selectors are more specific. */
main { gap: 28px; }
.card { padding: 28px 28px 26px; }
h2 { margin-bottom: 16px; }
.hint { margin: -6px 0 20px; line-height: 1.55; }
th, td { padding: 11px 10px; }
.chart-foot { margin-top: 24px; gap: 14px; }
.chart-takeaway { padding: 18px 20px; line-height: 1.6; }
.chart-tools-row { margin: 6px 0 20px; }
.card-section-title { margin: 32px 0 16px; padding-top: 24px; }
.ff-tiles { gap: 14px; margin: 20px 0; }
.ff-tile { padding: 18px; gap: 8px; }
.stat-cards { gap: 16px; }
.discipline-grid { gap: 20px; }
#compare-charts.discipline-grid { gap: 28px; }
.th-science { margin-bottom: 18px; }
.chart-legend { margin-bottom: 14px; }
.segmented, .chart-tools { margin-bottom: 4px; }
.health-event-row { padding: 12px 14px; }
.race-card, .race-leg-row { padding: 14px 16px; }
@media (max-width: 640px) { main { gap: 20px; } .card { padding: 20px 18px 18px; } }

/* Ask, empty state: the question box sits right under the prompt chips, not at the foot of the page. */
.ask-page:has(.ask-thread.is-empty) { justify-content: center; padding-bottom: 8vh; }
.ask-page:has(.ask-thread.is-empty) .ask-thread { flex: 0 0 auto; padding-bottom: 20px; }
.ask-page:has(.ask-thread.is-empty) .ask-dock { position: static; background: none; padding-top: 0; }

/* Section tabs: the section name leads the row as a plain label (not clickable), then a divider, then the clickable tabs. */
.page-tabs { align-items: center; }
.page-tabs-section { flex: none; display: inline-flex; align-items: center; padding: 0 22px 0 6px; margin-right: 10px; border-right: 1px solid var(--th-line-strong, var(--border)); font: 800 12px/1 var(--th-font-mono, var(--th-font-ui)); letter-spacing: .14em; text-transform: uppercase; color: var(--th-text-muted, var(--muted)); cursor: default; user-select: none; align-self: stretch; }
@media (max-width: 760px) { .page-tabs-section { padding-right: 14px; margin-right: 6px; } }

/* Your sports editor: the save button and its message sit on their own lines so nothing is cropped */
.sp-actions { margin-top: 16px; }
.sp-status { margin: 10px 0 0; min-height: 20px; font-size: 14px; color: var(--muted); }
.sp-status.is-ok { color: var(--th-positive); }
.sp-status.is-bad { color: var(--th-negative); }
#sports-box .ob-options { flex-wrap: wrap; }
#setup-card { min-width: 0; }
.sp-confirm { margin-top: 12px; padding: 16px 18px; border: 1px solid var(--th-line-strong, var(--border)); border-radius: 12px; background: var(--th-surface-2, rgba(255,255,255,0.03)); }
.sp-confirm b { color: var(--text); }
.sp-confirm p { margin: 6px 0 12px; color: var(--muted); font-size: 14px; line-height: 1.5; }
.sp-confirm-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Phone fit (audit, 3 Oct 2026): nothing in the page body may be wider than the screen. */
@media (max-width: 640px) {
    .heatmap-wrap, .heatmap-grid-wrap { overflow-x: auto; }
    .heatmap-months { min-width: 0; }
    .heatmap-month-cell { overflow: hidden; text-overflow: clip; }
    .goal-card > .goal-card-header { flex-wrap: wrap; }
    .goal-chip { white-space: normal; max-width: 100%; }
    .segmented { max-width: 100%; overflow-x: auto; flex-wrap: nowrap; }
    .segmented button { flex-shrink: 0; }
    .chart-tools { flex-wrap: wrap; max-width: 100%; }
    .card canvas { max-width: 100% !important; }
    .gap-activity-row { grid-template-columns: 70px 1fr 56px; }
    .gap-activity-row span:nth-child(n+4) { display: none; }
    .gap-context-cols { grid-template-columns: 1fr; gap: 12px; }
    #gr-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
    #gr-actions .btn { width: 100%; white-space: normal; }
    .adm-sub, .adm-row { min-width: 0; overflow-wrap: anywhere; }
    .card .btn, .card button { max-width: 100%; }
    select.select { max-width: 100%; min-width: 0; }
    .mix-value { white-space: normal; }
    .mix-row { grid-template-columns: 64px 1fr; row-gap: 4px; }
    .mix-row .mix-value { grid-column: 1 / -1; padding-left: 76px; }
}
.page-sections-jump { display: none; gap: 8px; overflow-x: auto; margin: -8px 0 12px; padding-bottom: 4px; }
.page-sections-jump a { flex: 0 0 auto; padding: 6px 12px; border: 1px solid var(--border); border-radius: 999px; color: var(--muted); font-size: 13px; text-decoration: none; }
.page-sections-jump a:hover { color: var(--text); }
@media (max-width: 640px) { .page-sections-jump { display: flex; } .card select { max-width: 100%; min-width: 0; box-sizing: border-box; } }
.chart-empty { padding: 28px 8px; text-align: center; color: var(--muted); font-size: 14px; }

.ob-lang { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.ob-lang .btn { padding: 18px 12px; font-size: 17px; }
@media (max-width: 480px) { .ob-lang { grid-template-columns: 1fr; } }

/* Vitals pages: when Garmin was last checked, the newest reading, and a Sync button. */
.garmin-strip { display: flex; align-items: center; justify-content: space-between; gap: 10px 18px; flex-wrap: wrap; margin: 0 0 4px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); font-size: 14px; line-height: 1.5; }
.garmin-strip[hidden] { display: none; }
.garmin-strip .gs-msg { color: var(--text); flex: 1 1 320px; min-width: 0; }
.garmin-strip .gs-act { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.garmin-strip .hint { margin: 0; }
.garmin-strip .gs-busy { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.garmin-strip .gs-act .btn { white-space: nowrap; }
/* Operator insights */
.ins-tabs { margin: 0 0 8px; }
.ins-view[hidden] { display: none; }
.ins-scroll { overflow-x: auto; }
.ins-cohort { border-collapse: separate; border-spacing: 3px; font-size: 13px; width: 100%; }
.ins-cohort th { font-weight: 600; color: var(--muted); text-align: center; padding: 4px 6px; white-space: nowrap; }
.ins-cohort th:first-child, .ins-cohort td:first-child { text-align: left; }
.ins-cohort td { text-align: center; padding: 8px 6px; border-radius: 6px; color: var(--text); }
.ins-cohort td.ins-heat { background: color-mix(in srgb, var(--accent) calc(var(--v) * 0.8%), var(--surface-2)); }
.stat-card-value.is-bad { color: var(--negative, #e5484d); }
/* Ten operator tabs: tighter, and one row where the width allows */
.adm-tabs { gap: 2px; }
.adm-tabs a { padding: 8px 10px; }
/* Onboarding: the first import, shown while the rest of setup carries on */
.ob-sync { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; max-width: 620px; width: 100%; margin: 0 auto 16px; }
.ob-sync[hidden] { display: none; }
.ob-sync-row { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.ob-sync-ic { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--muted); flex: none; }
.ob-sync-row.is-done .ob-sync-ic { color: var(--th-positive, #3fb67a); background: color-mix(in srgb, var(--th-positive, #3fb67a) 16%, transparent); }
.ob-sync-row.is-running .ob-sync-ic { color: var(--accent); }
.ob-sync-body { display: grid; gap: 2px; min-width: 0; flex: 1; }
.ob-sync-body b { font-size: 14px; }
.ob-sync-body em { font-style: normal; font-size: 13px; color: var(--muted); line-height: 1.4; }
.ob-sync-body em b { color: var(--text); font-size: 13px; }
.ob-sync-bar { display: block; height: 4px; border-radius: 2px; background: color-mix(in srgb, var(--text) 10%, transparent); overflow: hidden; margin-top: 6px; }
.ob-sync-bar u { display: block; height: 100%; background: var(--th-positive, #3fb67a); text-decoration: none; border-radius: 2px; }
.ob-sync-bar.is-run u { width: 38%; background: var(--accent); animation: ob-sync-slide 1.4s ease-in-out infinite; }
@keyframes ob-sync-slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
@media (prefers-reduced-motion: reduce) { .ob-sync-bar.is-run u { animation: none; width: 100%; opacity: .5; } }
.ob-sync-body, .ob-sync-body em { text-align: left; }
/* Race suggestions: why we think it was a race */
.rc-why { margin: 4px 0 14px; padding-left: 18px; color: var(--muted); font-size: 14px; line-height: 1.55; }
.rc-cal { margin: 6px 0 2px; font-size: 14px; }
.rc-conf { display: inline-block; vertical-align: middle; margin-left: 8px; padding: 3px 10px; border-radius: 999px; font: 600 11px/1.2 var(--th-font-data); letter-spacing: .06em; text-transform: uppercase; border: 1px solid var(--border); color: var(--muted); }
.rc-conf-very-likely { color: var(--th-positive, #3fb67a); border-color: color-mix(in srgb, var(--th-positive, #3fb67a) 45%, transparent); }
.rc-bulk { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 14px 18px; margin-bottom: 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
#rc-modal .sci-dialog { background: var(--surface-2, #1a2431); max-height: 90vh; }
#rc-modal .global-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
/* Course and conditions on an upcoming race */
.rc-weather { padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); margin: 0 0 12px; }
.rc-weather p { margin: 0 0 4px; font-size: 14px; }
.rc-leg { padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px; margin: 0 0 10px; }
.rc-leg.is-missing { border-style: dashed; }
.rc-leg-head { display: flex; align-items: center; gap: 10px; }
.rc-src { font: 600 11px/1 var(--th-font-data); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px; }
.rc-src-missing { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.rc-route { display: block; width: 100%; max-width: 240px; height: auto; margin: 6px 0; color: var(--muted); }
.rc-eff { margin: 4px 0 6px; font-size: 13px; color: var(--muted); }
.rc-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Coach messaging: sidebar badge, "your coach" chip, the Messages page */
.nav-badge { margin-left: auto; min-width: 18px; padding: 1px 6px; border-radius: 999px; background: var(--accent); color: var(--th-ink, #0b0b0c); font: 600 11px/16px var(--th-font-mono, monospace); text-align: center; }
.coach-chip { display: flex; align-items: center; gap: 10px; margin: 0 10px 12px; padding: 9px 12px; border: 1px solid var(--sidebar-border); border-radius: 10px; color: var(--th-text-2); text-decoration: none; }
.coach-chip:hover { border-color: var(--sel-line); }
.coach-chip span { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.coach-chip small { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--th-text-3, var(--th-text-2)); }
.coach-chip b { font-weight: 600; color: var(--th-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-wrap { display: grid; grid-template-columns: 320px 1fr; gap: 0; min-height: 520px; height: calc(100vh - 210px); padding: 0; overflow: hidden; }
.msg-wrap.msg-solo { grid-template-columns: 1fr; }
.msg-list { border-right: 1px solid var(--th-border, var(--sidebar-border)); display: flex; flex-direction: column; min-height: 0; }
.msg-list-tools { padding: 14px; display: grid; gap: 10px; border-bottom: 1px solid var(--th-border, var(--sidebar-border)); }
.msg-rows { overflow-y: auto; flex: 1; }
.msg-row { display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--th-border, var(--sidebar-border)); padding: 12px 14px; color: inherit; cursor: pointer; font: inherit; }
.msg-row:hover { background: var(--sel-bg, rgba(255,255,255,.04)); }
.msg-row.is-active { background: var(--sel-bg, rgba(255,255,255,.06)); box-shadow: inset 3px 0 0 var(--accent); }
.msg-row-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.msg-row-top b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-row-top small, .msg-row-snip { color: var(--th-text-2); font-size: 12.5px; }
.msg-row-snip { margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-row.has-unread .msg-row-snip { color: var(--th-text); font-weight: 600; }
.msg-dot { display: inline-block; min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--accent); color: var(--th-ink, #0b0b0c); font: 600 11px/18px var(--th-font-mono, monospace); text-align: center; margin-left: 6px; }
.msg-pane { display: flex; flex-direction: column; min-height: 0; }
.msg-pane-head { padding: 14px 20px; border-bottom: 1px solid var(--th-border, var(--sidebar-border)); display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.msg-pane-head h2 { margin: 0; font-size: 17px; }
.msg-thread { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 8px; }
.msg-bubble { max-width: min(560px, 82%); padding: 9px 13px; border-radius: 14px; background: var(--th-surface-2, rgba(255,255,255,.07)); white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.45; }
.msg-bubble.mine { align-self: flex-end; background: var(--accent); color: var(--th-ink, #0b0b0c); }
.msg-bubble small { display: block; margin-top: 3px; font-size: 11px; opacity: .65; }
.msg-day { align-self: center; font-size: 12px; color: var(--th-text-2); margin: 6px 0; }
.msg-empty { margin: auto; text-align: center; color: var(--th-text-2); max-width: 340px; }
.msg-compose { border-top: 1px solid var(--th-border, var(--sidebar-border)); padding: 12px 16px; display: flex; gap: 10px; align-items: flex-end; }
.msg-compose textarea { flex: 1; resize: none; min-height: 44px; max-height: 160px; }
@media (max-width: 800px) {
    .msg-wrap { grid-template-columns: 1fr; height: auto; min-height: 0; }
    .msg-wrap.has-thread .msg-list { display: none; }
    .msg-wrap:not(.has-thread):not(.msg-solo) .msg-pane { display: none; }
    .msg-thread { min-height: 320px; max-height: 60vh; }
    .msg-back { display: inline-flex !important; }
}
.msg-back { display: none; }
@media (max-width: 760px) {
    .coach-chip { margin: 0 0 10px; padding: 8px; justify-content: center; }
    .coach-chip span { display: none; }
    .sidenav a { position: relative; }
    .nav-badge { position: absolute; top: 2px; right: 2px; margin: 0; min-width: 16px; padding: 0 4px; font-size: 10px; line-height: 15px; }
}
.msg-compose textarea { background: var(--th-bg, #0b0f14); color: var(--th-text); border: 1px solid var(--th-border, var(--sidebar-border)); border-radius: 10px; padding: 10px 12px; font: inherit; line-height: 1.4; }
.msg-compose textarea:focus { outline: none; border-color: var(--accent); }
.msg-bubble { font-size: 14.5px; }
.msg-switches { display: grid; gap: 8px; }
.msg-wait { margin-top: 4px; font-size: 12px; color: var(--th-warn, #e0a030); }
.msg-note { padding: 12px 20px; border-bottom: 1px solid var(--th-border, var(--sidebar-border)); display: grid; gap: 6px; }
.msg-note label { font-weight: 600; font-size: 13px; }
.msg-note label small { font-weight: 400; color: var(--th-text-2); margin-left: 6px; }
.msg-note textarea { resize: vertical; }
.msg-bc-pick { display: grid; gap: 10px; margin: 12px 0; }
.msg-bc-pick #msg-bc-list { max-height: 180px; overflow-y: auto; display: grid; gap: 6px; padding: 8px 4px; }
.msg-bc-row { display: flex; gap: 10px; align-items: center; }
.msg-notify { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 8px 20px; font-size: 13px; color: var(--th-text-2); border-bottom: 1px solid var(--th-border, var(--sidebar-border)); }
.msg-notify[hidden] { display: none; }
.msg-note[hidden], .msg-compose[hidden], .msg-bc-pick #msg-bc-list[hidden], .msg-back[hidden] { display: none !important; }
.ob-callout { display: flex; gap: 10px; align-items: flex-start; margin: 10px 0 0; padding: 12px 14px; border: 1px solid var(--th-line, rgba(255,255,255,.12)); border-radius: 12px; background: rgba(255,255,255,.03); color: var(--th-text-2); font-size: 14px; line-height: 1.5; }
.ob-callout .lucide { flex: none; margin-top: 2px; }
.where-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin: 10px 0; }
.where-grid [hidden]{display:none !important}
.nb-list { display: grid; gap: 10px; }
.nb-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--th-line, rgba(255,255,255,.08)); }
.nb-row:first-child { border-top: 0; }

.rd-trans { margin: 14px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--th-text-2); max-width: 62ch; }

/* Shared modal (dashboard lists, races browser) */
/* modal */
body.home-modal-open { overflow: hidden; }
.home-modal { position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center; padding: 24px; }
.home-modal-back { position: absolute; inset: 0; background: rgba(6, 10, 15, .66); backdrop-filter: blur(3px); }
.home-modal-card { position: relative; width: min(680px, 100%); max-height: min(86vh, 900px); display: flex; flex-direction: column; border-radius: 22px; background: var(--th-surface, #1b2430); border: 1px solid var(--th-line-strong, rgba(255,255,255,.14)); box-shadow: 0 30px 80px rgba(0,0,0,.5); }
.home-modal-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 24px 28px 8px; }
.home-modal-head h2 { margin: 0; font-size: 20px; }
.home-modal-x { background: none; border: 0; color: var(--muted); font-size: 28px; line-height: 1; cursor: pointer; padding: 4px 8px; border-radius: 8px; }
.home-modal-x:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.home-modal-body { padding: 12px 28px 28px; overflow-y: auto; }
@media (max-width: 560px) { .home-modal { padding: 0; align-items: end; } .home-modal-card { border-radius: 22px 22px 0 0; max-height: 90vh; } .home-hero { padding: 24px 20px; } }

/* this week: each day shows what was done, a tap opens it */
.home-strip { gap: 8px; margin-top: 20px; }
button.home-day { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; color: var(--muted); display: block; }
button.home-day:hover i { filter: brightness(1.12); }
.home-day-l { display: block; margin-top: 2px; }
.home-day-sessions { display: flex; justify-content: center; align-items: center; gap: 3px; min-height: 22px; margin-top: 6px; }
.home-day-ico { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 6px; color: var(--c); background: color-mix(in srgb, var(--c) 16%, transparent); }
.home-day-ico .lucide { width: 12px; height: 12px; }
.home-day-more-n { font-size: 11px; font-weight: 700; color: var(--th-text-2); }
.home-sess-list { display: grid; gap: 10px; }
.home-sess { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 14px; align-items: center; padding: 12px 14px; border-radius: 14px; border: 1px solid var(--border); background: var(--surface-2); text-decoration: none; color: inherit; }
.home-sess:hover { border-color: var(--th-line-strong); }
.home-sess-main { display: grid; gap: 2px; min-width: 0; }
.home-sess-main small { color: var(--muted); }
.nb-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.nb-bar h2 { margin: 0; font-size: 16px; display: flex; align-items: center; gap: 8px; }
.nb-card { padding-top: 22px; padding-bottom: 22px; }

/* Space is for content: an intro line sits right under the page title, and page-level controls live in the title bar, not on a row of their own. */
main > .hint:first-child { margin: -16px 0 -8px; }
.goals-toolbar-inline { justify-content: flex-start; }
#goals-list { margin-bottom: 0; }

/* Find races: one row of filters, months as compact lists */
.find-races { gap: 28px; }
.find-races > .fr-bar { margin-bottom: -8px; }
.fr-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.fr-bar .select { width: auto; min-width: 150px; }
.fr-bar .fr-search { flex: 1 1 220px; }
.fr-count { margin: 0 0 0 auto; white-space: nowrap; }
.fr-note { margin: 0; }
.fr-month { padding: 24px 28px 14px; }
.fr-month h2 { margin: 0 0 12px; font-size: 16px; }
.fr-row { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 18px; align-items: center; padding: 14px 0; border-top: 1px solid var(--th-line, rgba(255,255,255,.08)); }
.fr-row:first-child { border-top: 0; }
.fr-date { display: grid; justify-items: center; line-height: 1.1; }
.fr-date b { font: 600 22px var(--th-font-data); }
.fr-date span { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.fr-meta { margin: 2px 0 0; }
@media (max-width: 640px) { .fr-row { grid-template-columns: 40px minmax(0, 1fr); } .fr-row > :last-child { grid-column: 2; justify-self: start; } .fr-bar .select { flex: 1 1 140px; } }

/* Race popup, Course tab: the hint's built-in negative margin was pulling text up into the heading above it. */
div.race-tabs { margin: 0 0 18px; }
.race-pane { padding-top: 2px; }
.rc-leg { padding: 14px 16px; margin: 0 0 12px; }
.rc-leg-head { margin-bottom: 4px; }
.rc-leg .hint, .rc-weather .hint, #rc-cond > .hint, #rc-cond .race-detail-section-title + .hint { margin: 4px 0 10px; }
.rc-weather p { margin: 0 0 6px; }
.rc-weather p:last-child { margin-bottom: 0; }
.rc-form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; }
.rc-form .select { min-width: 120px; }
.rc-leg .logic-actions { margin-top: 10px; }
.race-detail-section-title { margin: 0 0 8px; }

/* Course preview: a small outline beside the leg's details, not a full-width picture under them. */
.rc-leg { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 18px; align-items: start; }
.rc-leg > * { grid-column: 1; min-width: 0; }
.rc-leg > svg.rc-route { grid-column: 2; grid-row: 1 / span 4; align-self: center; width: 132px; max-width: 132px; height: 76px; margin: 0; }
.rc-route polyline { stroke-width: 2.5px; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 560px) { .rc-leg > svg.rc-route { grid-column: 1; grid-row: auto; width: 100%; max-width: 160px; height: 70px; } }

/* Races you've done (Results): the tiles follow how many sports there are. */
.count-tiles { grid-template-columns: repeat(var(--count-cols, 4), minmax(0, 1fr)); }
@media (max-width: 640px) { .count-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Year-at-a-glance tiles: let dates and notes wrap instead of cutting them off with an ellipsis. */
.heat-insight-label, .heat-insight-value, .heat-insight-note { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }

/* Race ready over time: the main chart and the things that moved it, on the same days */
.rr-grid { display: grid; grid-template-columns: 1fr; gap: 24px; margin-top: 4px; }
.rr-panel { border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px 12px; background: var(--th-surface); min-width: 0; }
.rr-ptitle { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; font-weight: 600; }
.rr-ptitle b { font: 500 13px var(--th-font-data); color: var(--muted); font-variant-numeric: tabular-nums; }
.rr-phint { margin: 4px 0 10px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.rr-foot { margin: 14px 0 0; }
.rr-cv { position: relative; height: 280px; }
#rr-main { max-height: 320px; }
@media (max-width: 700px) { .rr-cv { height: 220px; } }

/* Readiness: race-day forecast, what would help, how the finish time is built */
.rd-forecast { display: grid; grid-template-columns: auto 1fr; gap: 20px; align-items: start; margin: 18px 0 6px; padding: 18px 20px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.rd-fc-num { font: 700 34px/1 var(--th-font-data); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; min-width: 3.2ch; }
.rd-fc-good .rd-fc-num { color: var(--th-positive); }
.rd-fc-warn .rd-fc-num { color: var(--th-gold); }
.rd-fc-bad .rd-fc-num { color: var(--th-negative); }
.rd-fc-label { font: 600 11px/1.2 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.rd-fc-line { margin: 0; font-size: 15px; line-height: 1.6; }
.rd-fc-notes { margin-top: 10px; font-size: 13px; color: var(--muted); }
.rd-fc-notes summary { cursor: pointer; }
.rd-fc-notes ul { margin: 8px 0 0; padding-left: 18px; display: grid; gap: 6px; }
.rd-fc-guide { margin: 10px 0 0; }
.disc-advice { margin: 14px 0 6px; padding-top: 12px; border-top: 1px solid var(--border); }
.adv-title { font: 600 11px/1.2 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.disc-advice ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.adv-factor { font-weight: 600; font-size: 13px; }
.adv-why, .adv-what { margin: 3px 0 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
.adv-why b { color: var(--text); font-weight: 600; }
.adv-what b { color: var(--text); font-weight: 600; }
.bld-scroll { overflow-x: auto; }
.bld-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.bld-table th { text-align: left; font: 600 11px/1.2 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); padding: 8px 12px 8px 0; border-bottom: 1px solid var(--border); white-space: nowrap; }
.bld-table td { padding: 14px 12px 14px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.bld-leg { white-space: nowrap; font-weight: 600; }
.bld-leg .gauge-bar-dot { display: inline-block; margin-right: 8px; }
.bld-time { font: 600 15px/1.2 var(--th-font-data); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bld-eff { display: inline-flex; flex-direction: column; margin: 0 14px 4px 0; font-variant-numeric: tabular-nums; }
.bld-eff small { color: var(--muted); font-size: 12px; }
.bld-chip { display: block; margin: 0 0 4px; font-size: 13px; color: var(--muted); }
.bld-chip b { color: var(--text); font-variant-numeric: tabular-nums; }
.bld-help p { margin: 0 0 6px; font-size: 13px; line-height: 1.5; color: var(--muted); max-width: 46ch; }
.bld-help b { color: var(--text); }
.bld-none { color: var(--muted); font-size: 13px; }
.bld-note { margin: 12px 0 0; font-size: 13px; color: var(--muted); }
.bld-note b { color: var(--text); }
.bld-cal td, .bld-cal th { padding-top: 10px; padding-bottom: 10px; }
.bld-excluded { opacity: .55; }
@media (max-width: 640px) { .rd-forecast { grid-template-columns: 1fr; gap: 8px; } }
.fc-rows { display: grid; gap: 0; margin-top: 10px; }
.fc-row { display: grid; grid-template-columns: minmax(140px, 220px) 90px 1fr; gap: 14px; align-items: baseline; padding: 9px 0; border-bottom: 1px solid var(--border); }
.fc-row-note { grid-template-columns: 1fr; }
.fc-l { color: var(--text); font-weight: 600; font-size: 13px; }
.fc-v { font: 600 14px/1.2 var(--th-font-data); font-variant-numeric: tabular-nums; color: var(--text); }
.fc-n { color: var(--muted); font-size: 13px; line-height: 1.45; }
@media (max-width: 640px) { .fc-row { grid-template-columns: 1fr auto; } .fc-n { grid-column: 1 / -1; } }

.rd-forecast.rd-fc-solo { grid-template-columns: 1fr; }

.bld-legs { margin-top: 4px; font-size: 12px; color: var(--muted); line-height: 1.5; }
.bld-legs-p { opacity: .8; }

/* Readiness reads top down: where you stand, what would move it, then bands of detail (5 Oct 2026). */
.rd-band { margin: 20px 4px 0; padding-top: 22px; border-top: 1px solid var(--border); scroll-margin-top: 90px; }
.rd-band .section-label { margin: 0 0 6px; font: 600 12px/1 var(--th-font-data); letter-spacing: .1em; text-transform: uppercase; color: var(--text); }
.rd-band-intro { margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted); max-width: 760px; }
main > section.card { scroll-margin-top: 90px; }
.lever-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lever { display: grid; grid-template-columns: 28px 1fr auto; gap: 14px; align-items: start; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--th-surface-2, rgba(255,255,255,.02)); }
.lever-n { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font: 600 13px/1 var(--th-font-data); color: var(--text); border: 1px solid var(--border); }
.lever-body p { margin: 4px 0 0; font-size: 14px; line-height: 1.5; color: var(--muted); }
.lever-body b { color: var(--text); font-weight: 600; }
.lever-tag { font: 600 11px/1 var(--th-font-data); letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.lever-link { align-self: center; white-space: nowrap; font-size: 13px; color: var(--muted); text-decoration: none; display: inline-flex; gap: 4px; align-items: center; padding: 6px 10px; border-radius: 999px; border: 1px solid var(--border); }
.lever-link:hover { color: var(--text); border-color: var(--muted); }
.lever-link .lucide { width: 14px; height: 14px; }
.lever-none { grid-template-columns: 1fr; }
.adv-more { margin-top: 10px; }
.adv-more summary { cursor: pointer; font-size: 13px; color: var(--muted); list-style: none; }
.adv-more summary::-webkit-details-marker { display: none; }
.adv-more summary::before { content: '+ '; }
.adv-more[open] summary::before { content: '\2212 '; }
.adv-more ul { margin-top: 10px; }
@media (max-width: 700px) {
    .lever { grid-template-columns: 26px 1fr; }
    .lever-link { grid-column: 2; justify-self: start; }
}

/* Race popup > On the day: incidents that explain a result (race_incidents.py). */
.rinc-intro { margin: 0 0 14px; font-size: 14px; line-height: 1.55; color: var(--muted); }
.rinc-list { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 8px; }
.rinc-item { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; }
.rinc-item b { font-weight: 600; }
.rinc-lost { margin-left: 6px; font: 600 12px/1 var(--th-font-data); color: var(--text); }
.rinc-unknown { color: var(--th-warning); font-weight: 500; }
.rinc-note { margin: 6px 0 0 !important; }
.rinc-none { margin: 0 0 14px !important; }
.rinc-form { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 12px; align-items: end; }
.rinc-form label { display: grid; gap: 6px; font-size: 13px; color: var(--muted); }
.rinc-form .rinc-note-field { grid-column: 1 / 3; }
.rinc-form .btn-primary { justify-self: start; }
.rinc-err { color: var(--th-negative); margin-top: 8px !important; }
@media (max-width: 700px) { .rinc-form { grid-template-columns: 1fr; } .rinc-form .rinc-note-field { grid-column: auto; } }

/* How well this has predicted your races: course checks and incidents under each leg. */
.bld-check { display: block; font-size: 12px; color: var(--muted); margin: 1px 0 4px 0; }
.bld-check.bld-warn { color: var(--th-warning); }
.bld-inc { display: inline-flex; gap: 4px; align-items: center; margin: 6px 6px 0 0; padding: 3px 8px; border-radius: 999px; font-size: 12px; border: 1px solid var(--border); color: var(--text); }
.bld-raw { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.bld-why { display: block; font-size: 12px; color: var(--th-warning); margin-top: 2px; }
.rd-tab-intro { margin: 0 4px 4px; font-size: 15px; line-height: 1.55; color: var(--muted); max-width: 820px; }
#rd-target:empty { display: none; }

/* Readiness: the race it is measured against, at the right end of the tab row on every tab. */
.page-tabs-aside { margin-left: auto; flex: none; display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 18px; white-space: nowrap; }
.page-tabs-aside:empty { display: none; }
.page-tabs-aside .rd-tag { font-size: 11px; }
.page-tabs-aside .rd-race-text { display: inline-flex; align-items: baseline; gap: 8px; }
.page-tabs-aside .rd-name { font-size: 15px; font-weight: 700; color: var(--text); max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.page-tabs-aside .rd-meta { font-size: 13px; }
.page-tabs-aside .rd-switch { max-width: 170px; padding-top: 6px; padding-bottom: 6px; font-size: 13px; }
.page-tabs-aside .rd-set { font-size: 13px; color: var(--accent); }
@media (max-width: 1280px) { .page-tabs-aside .rd-meta { display: none; } }
@media (max-width: 900px) { .page-tabs-aside .rd-switch { display: none; } }
@media (max-width: 760px) {
    .page-tabs:has(.page-tabs-aside) { flex-wrap: wrap; row-gap: 6px; }
    .page-tabs-aside { flex: 0 0 100%; margin-left: 0; padding: 4px 6px 0; white-space: normal; flex-wrap: wrap; }
    .page-tabs-aside .rd-meta { display: inline; }
}

/* Section pages: the tab row already names the page, so the title under it is not repeated (5 Oct 2026). */
.filter-bar .page-tabs ~ .filter-bar-title { display: none; }

/* Gaps modal on the dashboard (openGaps in home.js) */
.gap-intro { margin: 0 0 12px; }
.gap-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; padding: 14px 0; border-top: 1px solid var(--th-line, rgba(255,255,255,.08)); transition: opacity .2s; }
.gap-row.is-done { opacity: .4; pointer-events: none; }
.gap-when .hint { margin: 0 0 0 6px; }
.gap-acts { display: flex; flex-wrap: wrap; gap: 8px; }

/* Spacing fixes (6 Oct 2026): stacked form rows get the same gap between rows as within a row;
   a hint under an empty-state heading must not climb into it (.hint has a negative top margin). */
.health-form-row + .health-form-row { margin-top: 12px; }
.msg-empty .hint { margin: 6px 0 0; }

/* Phone layout (8 Oct 2026): under 760px the sidebar becomes a bottom tab bar
   (Dashboard, Readiness, Training, Racing, More). "More" opens the sidebar
   itself as a sheet, so every link stays in one place (_nav.html). */
.tabbar, .tabbar-scrim { display: none; }
@media (max-width: 760px) {
    :root { --sidebar-width: 0px; --tabbar-h: calc(62px + env(safe-area-inset-bottom, 0px)); }
    body { padding: 16px max(14px, env(safe-area-inset-right, 0px)) calc(var(--tabbar-h) + 28px) max(14px, env(safe-area-inset-left, 0px)); }
    .filter-bar { margin: -16px -14px 18px; padding: 10px 14px; }
    header { top: auto; right: 0; width: auto; height: var(--tabbar-h); overflow: visible; border-right: 0; border-top: 1px solid var(--sidebar-border); z-index: 900; }
    /* The bar is as tall as the header (62px of buttons plus the home-indicator strip) and pads the strip off at the
       bottom; at a fixed 62px the iPhone's 34px strip left the buttons 28px and pushed the labels out of sight. */
    .tabbar { display: flex; align-items: stretch; height: var(--tabbar-h); padding: 0 max(4px, env(safe-area-inset-right, 0px)) 0 max(4px, env(safe-area-inset-left, 0px)); }
    .tabbar a, .tabbar button { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 6px 2px; position: relative;
        background: none; border: 0; color: var(--sidebar-text); font: 600 11px/1.1 var(--th-font-ui); text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
    .tabbar .lucide { width: 22px; height: 22px; }
    .tabbar span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .tabbar a.active, .tabbar button.active, body.sheet-open .tabbar-more { color: var(--sidebar-text-active); }
    .tabbar a.active::before, .tabbar button.active::before { content: ""; position: absolute; top: 0; left: 30%; right: 30%; height: 3px; border-radius: 0 0 3px 3px; background: var(--accent); }
    .tabbar-dot { position: absolute; top: 9px; left: calc(50% + 8px); width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }

    /* The sidebar, as a sheet over the page when More is open. */
    .sidebar-inner { display: none; position: fixed; left: 0; right: 0; bottom: var(--tabbar-h); height: auto; max-height: calc(100dvh - var(--tabbar-h) - 48px); overflow-y: auto;
        padding: 12px 12px 14px; gap: 2px; align-items: stretch; background: var(--sidebar-bg); border-top: 1px solid var(--sidebar-border); border-radius: 18px 18px 0 0; box-shadow: 0 -18px 40px rgba(0, 0, 0, .45); }
    body.sheet-open .sidebar-inner { display: flex; }
    body.sheet-open { overflow: hidden; }
    .tabbar-scrim:not([hidden]) { display: block; position: fixed; inset: 0 0 var(--tabbar-h) 0; background: rgba(8, 12, 18, .6); z-index: -1; }
    .sidebar-inner .logo { display: none; }
    .sidenav { flex: none; overflow: visible; }
    .sidenav a, .sidenav-settings, .sidenav-bottom-item { justify-content: flex-start; padding: 13px 12px; width: 100%; font-size: 15px; }
    .sidenav a span, .sidenav-settings span, .sidenav-bottom-item span { display: inline; }
    .sidenav .nav-in-tabbar { display: none; }
    .sidenav .nav-in-tabbar + .sidenav-divider, .sidenav > .sidenav-divider:first-child { display: none; }
    .sidebar-inner .coach-chip { margin: 0 0 8px; padding: 10px 12px; justify-content: flex-start; }
    .sidebar-inner .coach-chip span { display: flex; }
    .page-tabs-section { display: none; }
    .page-tabs, .page-tabs:has(.page-tabs-aside) { flex-wrap: nowrap; padding-bottom: 10px; }
    .filter-bar > .page-tabs-aside { flex: 0 0 100%; margin: -4px 0 0; padding: 0 2px; white-space: normal; flex-wrap: wrap; font-size: 13px; }

    /* Things pinned to the bottom of the screen sit above the tab bar. */
    .ask-dock { bottom: var(--tabbar-h); }
    .th-return { bottom: calc(var(--tabbar-h) + 14px); right: 14px; }
    .coach-pill { bottom: calc(var(--tabbar-h) + 12px); right: 12px; left: 12px; justify-content: space-between; }
    .th-pl { bottom: var(--tabbar-h); }
}
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
@media (max-width: 760px) {
    .table-scroll { margin: 0 -16px; padding: 0 16px; }
    .phone-table th, .phone-table td { white-space: nowrap; }
    .phone-table .cell-wrap { white-space: normal; min-width: 180px; }
    .card { padding: 20px 16px 18px; border-radius: 18px; }
    main { gap: 18px; }
    h2 { font-size: 18px; }
    .hint { margin-bottom: 16px; }
    .chart-takeaway { padding: 14px 14px; }
    .chart-foot { margin-top: 18px; }
    /* Comfortable tap targets for small buttons and form fields. */
    .btn, button.btn, .select, select, input[type="text"], input[type="email"], input[type="number"], input[type="date"], input[type="search"], input[type="password"] { min-height: 40px; }
    input, select, textarea { font-size: 16px; } /* under 16px iOS zooms the page on focus */
}
@media (max-width: 760px) {
    /* Race popup and goal forms: the label sits above its inputs, and "of" stays between the two numbers. */
    .race-transitions-row { flex-wrap: wrap; row-gap: 6px; }
    .race-transitions-row > label { flex: 0 0 100%; }
    .race-transitions-row .goal-time-inputs { flex-wrap: nowrap; }
    .goal-time-inputs .hint, .race-transitions-row .race-pct { margin: 0; }
}
@media (max-width: 760px) {
    /* Public pages (sign-up, pricing, support): a header that fits a phone. */
    .pub-header { gap: 14px; padding: 12px 16px; }
    .pub-logo { flex: none; display: flex; }
    .pub-logo img { height: 20px; width: auto; }
    .pub-nav { gap: 14px; white-space: nowrap; flex-wrap: nowrap; min-width: 0; }
    .pub-trust { font-size: 12px; }
}
@media (max-width: 760px) { .pub-nav .th-lang-toggle { margin-left: 0; } .pub-nav .th-lang-toggle button { padding: 6px 8px; } }
@media (max-width: 400px) { .pub-nav a[href="/support"] { display: none; } }

/* Phone charts (8 Oct 2026): the page's filter bar scrolls away instead of sitting over the
   charts, number tiles sit three across, and chart cards lose a little padding. */
@media (max-width: 760px) {
    .filter-bar { position: static; }
    .ff-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 14px 0; }
    .ff-tile { padding: 10px; gap: 4px; min-width: 0; }
    .ff-tile > * { overflow-wrap: anywhere; }
    .ff-tile .ff-s { font-size: 12px; line-height: 1.3; }
    .ff-tile .ff-v { font-size: 24px; }
    .ff-tile .ff-l { font-size: 12px; display: flex; flex-wrap: wrap; gap: 4px; }
    .chart-tools .segmented { max-width: 100%; overflow-x: auto; }
}

/* Native app feel (8 Oct 2026): phone type scale, compact header, iOS-style More sheet,
   underline section tabs, full-width forms. Phones only; desktop is untouched. */
@media (max-width: 760px) {
    body { font-size: 15px; line-height: 1.45; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
    main { gap: 16px !important; }
    h1 { font-stretch: 100% !important; font-size: 26px !important; line-height: 1.15 !important; letter-spacing: -0.01em; }
    h2 { font-size: 18px !important; line-height: 1.25 !important; margin-bottom: 8px !important; }
    h3 { font-size: 16px !important; }
    .hint, .adm-sub, .chart-takeaway, .card p { font-size: 14px !important; line-height: 1.45; }
    .hint { margin-bottom: 12px !important; }
    .card { padding: 16px !important; border-radius: 16px !important; }
    table { font-size: 14px; }
    th { font-size: 12px !important; letter-spacing: 0.02em !important; }
    td, th { padding: 9px 8px !important; }

    /* Compact header: small title, icon-only sync */
    .filter-bar { padding: 10px 16px !important; gap: 8px !important; min-height: 0 !important; }
    .filter-bar-title { font-size: 20px !important; font-weight: 700; }
    .filter-bar-title .lucide { display: none; }
    #sync-btn, #home-sync-btn { min-width: 0 !important; width: 36px; height: 36px; padding: 0 !important; border-radius: 50% !important; font-size: 0 !important; justify-content: center; }
    #sync-btn .lucide, #home-sync-btn .lucide { width: 18px; height: 18px; }
    #sync-status { font-size: 12px !important; }

    /* Section tabs: a native underline strip */
    .page-tabs { gap: 4px !important; padding: 0 12px !important; border-bottom: 1px solid var(--th-line, rgba(255,255,255,.08)); scrollbar-width: none; }
    .page-tabs::-webkit-scrollbar { display: none; }
    .page-tabs a { font-size: 14px !important; padding: 10px 10px !important; border-radius: 0 !important; background: none !important; border: 0 !important; box-shadow: none !important; color: var(--th-text-muted, #9aa) !important; white-space: nowrap; position: relative; min-height: 40px; }
    .page-tabs a .lucide, .page-tabs a svg { display: none !important; }
    .page-tabs a::before { display: none !important; }
    .page-tabs a.is-active { color: var(--th-text, #fff) !important; font-weight: 600; }
    .page-tabs a.is-active::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--th-accent, #ff6a1a); }

    /* Jump chips: quiet pills, not underlined links */
    .page-sections-jump { gap: 8px !important; overflow-x: auto; flex-wrap: nowrap !important; scrollbar-width: none; }
    .page-sections-jump a { text-decoration: none !important; white-space: nowrap; font-size: 13px !important; font-family: inherit !important; text-transform: none !important; letter-spacing: 0 !important; padding: 6px 12px; border-radius: 999px; background: var(--th-surface-2); color: var(--th-text, #fff) !important; }
    .page-tabs-aside, #rd-race { font-family: inherit !important; text-transform: none !important; letter-spacing: 0 !important; font-size: 13px !important; }

    /* Mono uppercase labels read as web chrome on a phone */
    .ff-l, .stat-label, .card-section-title, .eyebrow { text-transform: none !important; letter-spacing: 0 !important; font-family: inherit !important; font-size: 12px !important; }
    .ff-v, .stat-value { font-size: 22px !important; }

    .segmented .lucide, .segmented svg { display: none !important; }
    /* Forms: full width, stacked buttons */
    main input:not([type=checkbox]):not([type=radio]):not([type=range]), main select, main textarea, main .select { width: 100% !important; max-width: none !important; min-height: 44px; border-radius: 12px !important; }
    .health-form-row, .form-row { flex-direction: column !important; align-items: stretch !important; display: flex !important; gap: 12px !important; }
    .health-form-row > *, .form-row > * { width: 100% !important; min-width: 0 !important; flex: 1 1 auto !important; }
    .health-form-card .btn { flex: 1 1 0; justify-content: center; }
    main form .btn, .health-form-actions .btn, .form-actions .btn, .modal-actions .btn { width: 100%; justify-content: center; min-height: 44px; }
    .form-actions, .modal-actions { flex-direction: column !important; gap: 8px !important; }
    .btn { border-radius: 12px !important; }

    /* Tab bar: blurred, safe-area aware, accent icon instead of a bar */
    .tabbar { background: color-mix(in srgb, var(--th-bg, #0b0d10) 82%, transparent) !important; backdrop-filter: saturate(160%) blur(18px); -webkit-backdrop-filter: saturate(160%) blur(18px); border-top: 0.5px solid rgba(255,255,255,.1) !important; padding-bottom: env(safe-area-inset-bottom) !important; }
    .tabbar a, .tabbar button { font-size: 10.5px !important; font-weight: 500; gap: 3px !important; }
    .tabbar a::before, .tabbar button::before, .tabbar a::after, .tabbar button::after { display: none !important; }
    .tabbar .lucide { width: 24px !important; height: 24px !important; }
    .tabbar a.active, .tabbar button.active { color: var(--th-accent, #ff6a1a) !important; background: none !important; }

    /* More: an iOS-style sheet with a handle, title and grouped rounded rows */
    body.sheet-open #sidebar-sheet { border-radius: 20px 20px 0 0 !important; padding: 8px 16px calc(var(--tabbar-h, 64px) + 16px) !important; background: var(--th-bg, #0b0d10) !important; }
    body.sheet-open #sidebar-sheet::before { content: ""; display: block; width: 36px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.25); margin: 0 auto 12px; }
    body.sheet-open #sidebar-sheet .logo { display: none !important; }
    body.sheet-open #sidebar-sheet .sidenav { background: var(--th-surface, #15181d); border-radius: 14px; overflow: hidden; padding: 0 !important; gap: 0 !important; margin-bottom: 16px; }
    body.sheet-open #sidebar-sheet .sidenav-divider { display: none; }
    body.sheet-open #sidebar-sheet .sidenav a, body.sheet-open #sidebar-sheet .sidenav-bottom-item, body.sheet-open #sidebar-sheet .sidenav-settings { display: flex; align-items: center; gap: 14px; min-height: 50px; padding: 0 16px !important; font-size: 16px !important; border-radius: 0 !important; margin: 0 !important; background: var(--th-surface, #15181d) !important; color: var(--th-text, #fff) !important; position: relative; width: 100%; border: 0; }
    body.sheet-open #sidebar-sheet .sidenav a:not(:last-child)::before { content: ""; position: absolute; bottom: 0; left: 52px; right: 0; height: 0.5px; background: rgba(255,255,255,.1); display: block !important; }
    body.sheet-open #sidebar-sheet .sidenav a::after, body.sheet-open #sidebar-sheet .sidenav-bottom-item::after { content: ""; margin-left: auto; width: 8px; height: 8px; border-right: 2px solid rgba(255,255,255,.3); border-top: 2px solid rgba(255,255,255,.3); transform: rotate(45deg); }
    body.sheet-open #sidebar-sheet .sidenav a.active { color: var(--th-accent, #ff6a1a) !important; box-shadow: none !important; }
    body.sheet-open #sidebar-sheet .sidenav-bottom-item { border-radius: 14px !important; margin-bottom: 8px !important; }
    body.sheet-open #sidebar-sheet .sidenav-settings { border-radius: 14px !important; color: var(--th-negative, #ff5a5a) !important; justify-content: center; }
    body.sheet-open #sidebar-sheet .lucide { width: 20px; height: 20px; }
    body.sheet-open #sidebar-sheet .sidenav a.nav-in-tabbar { display: none !important; }
    body.sheet-open #sidebar-sheet .coach-chip small { text-transform: none; letter-spacing: 0; font-family: inherit; }
    .rd-tag, .rd-set, .rd-fact-l, .rd-fact-v { font-family: inherit !important; text-transform: none !important; letter-spacing: 0 !important; }
    .rd-tag { font-size: 13px !important; color: var(--th-text-muted, #9aa) !important; }
    .rd-set { font-size: 13px !important; text-decoration: none !important; }
    .rd-fact-l { font-size: 12px !important; color: var(--th-text-muted, #9aa) !important; }
    .rd-fact-v { font-size: 20px !important; }
    body.sheet-open #sidebar-sheet .coach-chip { border-radius: 14px; margin-bottom: 12px; }
}

/* Store apps (9 Oct 2026): room for the status bar at the top. html.th-native is set by native.js
   only inside the App Store / Google Play app; in a browser env() is 0 anyway. */
html.th-native header { padding-top: env(safe-area-inset-top, 0px); }
/* A solid strip behind the status bar, so the page doesn't scroll under the clock. */
html.th-native body::before { content: ""; position: fixed; left: 0; right: 0; top: 0; height: env(safe-area-inset-top, 0px); background: var(--th-bg, #0b0d10); z-index: 2000; pointer-events: none; }
@media (max-width: 760px) {
    html.th-native header { padding-top: 0; }
    html.th-native body { padding-top: calc(16px + env(safe-area-inset-top, 0px)); }
}

/* Continue with Google / Apple (_social_buttons.html). The two marks and the dark button colours follow Google's
   and Apple's own button guidelines (dark theme), so they don't use the --th-* tokens. */
.social-login { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
.social-btn { display: flex; align-items: center; justify-content: center; gap: 12px; height: 48px; padding: 0 16px; border-radius: 10px;
    font: 600 15px/1 var(--th-font-ui); text-decoration: none; background: #131314; color: #E3E3E3; border: 1px solid #8E918F; transition: border-color .15s, background .15s; }
.social-btn:hover { background: #1c1c1e; border-color: #c4c7c5; color: #fff; }
.social-btn:focus-visible { outline: 2px solid var(--th-accent); outline-offset: 2px; }
.social-btn-apple { background: #000; color: #fff; border-color: #fff; }
.social-btn-apple:hover { background: #111; border-color: #fff; }
.social-ic { width: 20px; height: 20px; flex: none; }
.social-or { display: flex; align-items: center; gap: 12px; margin: 8px 0 4px; color: var(--muted); font-size: 13px; }
.social-or::before, .social-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.signin-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.signin-row:last-child { border-bottom: 0; }
.signin-row .social-ic { width: 18px; height: 18px; }
.signin-row-main { flex: 1; min-width: 0; }

.act-filters-toggle { display: none !important; }
/* App pass (9 Oct 2026): on phones the page's tab row and its controls stay pinned to the top while the page scrolls
   (they hold the range and period pickers), in one compact row that scrolls sideways instead of wrapping. */
@media (max-width: 760px) {
    .filter-bar:not(.filter-bar-inline) { position: sticky !important; top: 0; z-index: 160; margin: -16px -14px 14px !important; padding: 4px 0 8px !important; gap: 0 !important;
        background: color-mix(in srgb, var(--sidebar-bg) 90%, transparent); -webkit-backdrop-filter: saturate(160%) blur(16px); backdrop-filter: saturate(160%) blur(16px);
        border-bottom: 0.5px solid rgba(255, 255, 255, .08); }
    html.th-native .filter-bar:not(.filter-bar-inline) { top: env(safe-area-inset-top, 0px); }
    .filter-bar:not(.filter-bar-inline) > .page-tabs { padding: 0 14px !important; }
    .filter-bar:not(.filter-bar-inline) > .filter-bar-title { padding: 6px 16px; min-height: 40px !important; }
    .filter-bar:not(.filter-bar-inline) > .filter-bar-controls { flex: 1 1 100%; min-width: 0; flex-wrap: nowrap; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 8px 14px 0; -webkit-overflow-scrolling: touch; }
    .filter-bar:not(.filter-bar-inline) > .filter-bar-controls::-webkit-scrollbar { display: none; }
    .filter-bar:not(.filter-bar-inline) > .filter-bar-controls > * { flex: none; }
    .filter-bar:not(.filter-bar-inline) > .filter-bar-controls .segmented { max-width: none; overflow: visible; }
    .filter-bar:not(.filter-bar-inline) .filter-bar-divider { display: none; }
    .filter-bar:not(.filter-bar-inline) .segmented button, .filter-bar:not(.filter-bar-inline) .segmented label { min-height: 34px; padding-top: 6px; padding-bottom: 6px; }
    .filter-bar:not(.filter-bar-inline) .sync-btn-wrap { display: flex; align-items: center; gap: 8px; }
    .filter-bar:not(.filter-bar-inline) #sync-status { white-space: nowrap; }
    /* No tab row (Dashboard, Activities): the title and its few controls share one line. */
    .filter-bar:not(.filter-bar-inline):not(:has(.page-tabs)) { flex-wrap: nowrap; align-items: center; padding: 4px 0 !important; }
    .filter-bar:not(.filter-bar-inline):not(:has(.page-tabs)) > .filter-bar-title { flex: 1 1 auto; min-width: 0; }
    .filter-bar:not(.filter-bar-inline):not(:has(.page-tabs)) > .filter-bar-controls { flex: 0 1 auto; padding: 0 14px 0 0; margin-left: auto; }
    /* The custom date range opens under the bar, full width, instead of inside the scrolling row where it was cut off. */
    .filter-bar:not(.filter-bar-inline) .custom-range-popover { position: fixed; left: 12px; right: 12px; top: calc(var(--th-sticky-h, 110px) + env(safe-area-inset-top, 0px) + 6px); width: auto; z-index: 170; flex-wrap: wrap; }
    .filter-bar:not(.filter-bar-inline) .custom-range-popover label { flex: 1 1 140px; }
    /* Jumping to a section lands below the pinned bar, not under it. */
    html { scroll-padding-top: calc(var(--th-sticky-h, 0px) + env(safe-area-inset-top, 0px) + 12px); }

    /* The More sheet: slides up, scrolls on its own without dragging the page behind it, sits clear of the
       status bar, and has no dead space under Log out (it already sits on top of the tab bar). */
    body.sheet-open #sidebar-sheet { padding-bottom: 16px !important; max-height: calc(100dvh - var(--tabbar-h) - env(safe-area-inset-top, 0px) - 24px);
        overscroll-behavior: contain; -webkit-overflow-scrolling: touch; animation: th-sheet-up .22s cubic-bezier(.2, .8, .2, 1); z-index: 2; }
    .tabbar-scrim:not([hidden]) { z-index: 1; touch-action: none; animation: th-fade-in .2s ease-out; }
    .tabbar { position: relative; z-index: 3; }
    body.sheet-locked { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }

    /* Feels like an app: no grey tap flash or long-press menus on navigation, a quick pressed state, no double-tap zoom delay. */
    .tabbar, .page-tabs, #sidebar-sheet .sidenav { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
    a, button, .btn, .segmented button, .segmented label, summary { touch-action: manipulation; }
    .tabbar a:active, .tabbar button:active, body.sheet-open #sidebar-sheet .sidenav a:active, body.sheet-open #sidebar-sheet .sidenav-bottom-item:active,
    body.sheet-open #sidebar-sheet .sidenav-settings:active, .page-tabs a:active { opacity: .55; }
    .btn:active { transform: scale(.98); }

    /* Activities: search stays in view, the other filters fold away behind one button. */
    .act-filters-toggle { display: inline-flex !important; justify-content: center; align-items: center; gap: 8px; width: 100%; }
    .act-filters:not(.is-open) .act-filter-row > :not(.act-search):not(.act-filters-toggle),
    .act-filters:not(.is-open) .act-filter-row + .act-filter-row { display: none !important; }
    .act-filters { padding: 12px !important; gap: 10px !important; margin-bottom: 16px !important; }
    .act-head { margin-bottom: 14px !important; }
}
@keyframes th-sheet-up { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes th-fade-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { body.sheet-open #sidebar-sheet, .tabbar-scrim:not([hidden]) { animation: none; } }

/* Pull down to sync (pull_refresh.js): a small pill that slides in under the status bar. */
html { overscroll-behavior-y: contain; }
.ptr { position: fixed; left: 50%; top: calc(env(safe-area-inset-top, 0px) + 8px); z-index: 2100; display: flex; align-items: center; gap: 8px;
    padding: 8px 14px; border-radius: 999px; background: var(--th-surface-2, #1a1d22); color: var(--th-text-2, #c9ced6); border: 1px solid var(--th-border, #2a2f36);
    font-size: 13px; box-shadow: 0 6px 20px rgba(0,0,0,.35); pointer-events: none; opacity: 0;
    transform: translate(-50%, calc(var(--ptr-y, 0px) - 56px)); transition: opacity .15s; }
.ptr.ptr-show { opacity: 1; }
.ptr-dot { display: inline-flex; transform: rotate(var(--ptr-rot, 0deg)); }
.ptr.ptr-ready { color: var(--th-text, #fff); border-color: var(--th-accent, #ff6a1a); }
.ptr.ptr-busy { transform: translate(-50%, 8px); transition: opacity .15s, transform .2s; }
.ptr.ptr-busy .ptr-dot { animation: ptr-spin .9s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ptr.ptr-busy .ptr-dot { animation: none; } }

/* Race day ring on Readiness shows a time, not a % (10 Oct 2026) */
.rd-ring-value.rd-ring-time { font-size: 22px; white-space: nowrap; }

/* Ready now / Ready when fresh (Readiness overview, 10 Oct 2026) */
.rd-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 18px 0 0; max-width: 640px; }
.rd-pair-item { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-2); }
.rd-pair-l { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.rd-pair-v { font: 700 28px/1.1 var(--th-font-data); font-variant-numeric: tabular-nums; }
.rd-pair-v small { font-size: 15px; margin-left: 1px; }
.rd-pair-n { font-size: 13px; line-height: 1.5; color: var(--muted); }
.rd-pair-n b { color: var(--text); font-weight: 600; }
.rd-pair-warn { margin: 10px 0 0; font-size: 13px; color: var(--th-warning); }
.rd-pair-foot { margin: 10px 0 0; font-size: 13px; color: var(--muted); max-width: 62ch; }
@media (max-width: 520px) { .rd-pair { grid-template-columns: 1fr; } }

/* Racing > Results (10 Oct 2026): page filters pinned under the tab row, summary tiles, one placement chart and the
   race list, newest first. race_performance.html / race_performance.js. */
.filter-bar > .filter-bar-controls:has(.rs-filters) { flex: 1 1 100%; justify-content: flex-start; }
.rs-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.rs-filters .select { width: auto; min-width: 150px; }
.rs-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; }
.rs-tiles .ff-s { overflow-wrap: anywhere; }
@media (max-width: 900px) { .rs-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.rs-count { margin: 0; white-space: nowrap; }
.rs-list { display: flex; flex-direction: column; }
.rs-head, .rs-main { display: grid; grid-template-columns: 128px minmax(0, 1fr) 128px 140px 140px 20px; gap: 16px; align-items: center; }
.rs-head { padding: 0 14px 8px; font-size: 12.5px; font-weight: 600; color: var(--muted); border-bottom: 1px solid var(--border); }
.rs-head .is-sel, .rs-place.is-sel .rs-k { color: var(--text); }
.rs-year { display: flex; align-items: baseline; justify-content: space-between; padding: 20px 14px 8px; font-weight: 600; font-size: 15px; }
.rs-year .rs-muted { font-size: 13px; font-weight: 500; }
.rs-row { border-bottom: 1px solid var(--border); }
.rs-main { width: 100%; padding: 12px 14px; background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: 10px; }
.rs-main:hover { background: var(--surface-2); }
.rs-row.is-open .rs-main { background: var(--surface-2); border-radius: 10px 10px 0 0; }
.rs-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rs-cell > b { font-weight: 600; font-size: 15px; }
.rs-cell > span, .rs-race-txt > span { font-size: 13px; color: var(--muted); }
.rs-k { display: none; font-size: 12px; color: var(--muted); }
.rs-race { flex-direction: row; align-items: center; gap: 10px; }
.rs-race-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rs-race-txt > b { font-weight: 600; font-size: 15px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rs-ic { display: inline-flex; flex: none; width: 30px; height: 30px; align-items: center; justify-content: center; border-radius: 8px; background: var(--surface-2); }
.rs-main:hover .rs-ic, .rs-row.is-open .rs-ic { background: var(--surface-3, var(--bg)); }
.rs-place.is-sel > b { color: var(--text); }
.rs-place:not(.is-sel) > b { color: var(--th-text-2, var(--muted)); font-weight: 500; }
.rs-muted { color: var(--muted); font-weight: 500; }
.rs-chip { padding: 2px 8px; border-radius: 999px; font: 600 11px/1.4 var(--th-font-ui); }
.rs-chip-pb { color: var(--th-gold, #E9B949); background: color-mix(in srgb, var(--th-gold, #E9B949) 16%, transparent); }
.rs-chip-dnf { color: var(--th-negative); background: color-mix(in srgb, var(--th-negative) 16%, transparent); }
.rs-chev { color: var(--muted); transition: transform .15s; display: inline-flex; }
.rs-row.is-open .rs-chev { transform: rotate(180deg); }
.rs-detail { padding: 6px 14px 18px 158px; background: var(--surface-2); border-radius: 0 0 10px 10px; margin-bottom: 6px; display: flex; flex-direction: column; gap: 14px; }
.rs-detail[hidden] { display: none; }
.rs-legs { display: flex; flex-direction: column; gap: 2px; }
.rs-leg { display: grid; grid-template-columns: 30px 70px 90px 110px minmax(0, 1fr); gap: 12px; align-items: center; padding: 6px 8px; border-radius: 8px; color: inherit; text-decoration: none; font-size: 14px; }
a.rs-leg:hover { background: var(--surface-3, var(--bg)); }
.rs-leg .rs-ic { width: 26px; height: 26px; }
.rs-facts { display: flex; flex-wrap: wrap; gap: 12px 32px; }
.rs-facts > div { display: flex; flex-direction: column; gap: 3px; }
.rs-facts .rs-k { display: block; }
.rs-facts b { font-weight: 600; }
.rs-links { display: flex; flex-wrap: wrap; gap: 8px; }
.rs-note { margin: 0; font-size: 14px; }
.rs-small { margin: 0; font-size: 13px; }
@media (max-width: 1100px) {
    .rs-head, .rs-main { grid-template-columns: 110px minmax(0, 1fr) 110px 120px 120px 20px; gap: 12px; }
    .rs-detail { padding-left: 14px; }
}
@media (max-width: 760px) {
    .rs-head { display: none; }
    .rs-main { grid-template-columns: repeat(3, minmax(0, 1fr)) 20px; gap: 10px 12px; padding: 12px 10px; }
    .rs-date { grid-column: 1 / 4; grid-row: 2; flex-direction: row; gap: 8px; align-items: baseline; order: -1; }
    .rs-date > b { font-size: 13px; font-weight: 500; color: var(--muted); }
    .rs-race { grid-column: 1 / 4; grid-row: 1; }
    .rs-chev { grid-column: 4; grid-row: 1; justify-self: end; }
    .rs-time, .rs-place { grid-row: 3; }
    .rs-k { display: block; }
    .rs-detail { padding: 6px 10px 16px; }
    .rs-leg { grid-template-columns: 26px 44px 72px minmax(0, 1fr); font-size: 13px; }
    .rs-leg > span:last-child { grid-column: 2 / -1; }
    .rs-year { padding: 18px 10px 6px; }
}
@media (max-width: 760px) { .rs-filters { flex-wrap: nowrap; } .rs-filters .select { min-width: 0; } }
@media (max-width: 760px) { .rs-main { align-items: start; } .rs-place .notranslate { white-space: nowrap; } }

/* Phone health data (Apple Health / Health Connect), phone_health.js: Settings > Health data, onboarding, Vitals */
.ph-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0 0 10px; color: var(--th-text-2); line-height: 1.5; }
.ph-line .lucide { align-self: center; flex: none; }
.ph-ok .lucide { color: var(--th-positive); }
.ph-sub { font-size: 13.5px; color: var(--th-text-muted); }
.ph-n { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--th-text); }
.ph-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 6px; }
.ph-msg { margin: 0; }
.soon-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  background: var(--th-surface-2); color: var(--th-text-2); border: 1px solid var(--th-line); }

/* Strava brand assets (Strava API brand guidelines): the official button unchanged,
   "Powered by Strava" kept small and apart from the LankFit logo, "View on Strava" bold in Strava orange. */
.strava-connect { display: inline-flex; line-height: 0; border-radius: 6px; }
.strava-connect img { height: 48px; width: auto; display: block; }
.strava-connect:focus-visible { outline: 2px solid var(--th-focus, #fff); outline-offset: 3px; }
.sidenav-strava { padding: 8px 16px 4px; opacity: .8; line-height: 0; }
.sidenav-strava img { height: 11px; width: auto; }
.view-on-strava { font-weight: 700; color: #FC5200 !important; text-decoration: underline; }

/* Plan picker: make the chosen plan unmistakable (20 Oct 2026) */
.pub-plans .pub-plan { padding-right: 64px; }
.pub-plans .pub-plan .pub-plan-radio { position: absolute; top: 24px; right: 24px; width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--muted); display: grid; place-items: center; transition: border-color var(--th-dur-fast), background var(--th-dur-fast); }
.pub-plans .pub-plan.is-selected { border: 2px solid var(--accent); padding: 25px 63px 25px 25px; background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 12%, var(--th-surface-2)), var(--th-surface)); box-shadow: 0 18px 50px -24px var(--accent); transform: translateY(-3px); }
.pub-plans .pub-plan.is-selected .pub-plan-radio { border-color: var(--accent); background: var(--accent); }
.pub-plans .pub-plan.is-selected .pub-plan-radio::after { content: ""; width: 9px; height: 5px; border: solid #fff; border-width: 0 0 2.5px 2.5px; transform: translateY(-1px) rotate(-45deg); }
.pub-plans .pub-plan.is-selected .pub-plan-name { color: var(--accent); }
.pub-plans .pub-plan:not(.is-selected) { opacity: .82; }
.pub-plans .pub-plan:not(.is-selected):hover { opacity: 1; }
.pub-plans .pub-plan input:focus-visible ~ .pub-plan-radio { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Powered by Strava on the login page (Strava's own file, unmodified) */
.login-strava { display: flex; justify-content: center; margin-top: 24px; opacity: .8; line-height: 0; }
.login-strava img { height: 13px; width: auto; }
