/* gym.css — consumer-first redesign stylesheet, scoped to gym mode */

/* Self-hosted display + data type system — CSP font-src 'self', no CDN, font-display:swap (no FOIT) */
@font-face{font-family:'Space Grotesk';font-weight:500 700;font-display:swap;src:url('./fonts/space-grotesk-latin.woff2') format('woff2');}
@font-face{font-family:'JetBrains Mono';font-weight:400 700;font-display:swap;src:url('./fonts/jetbrains-mono-latin.woff2') format('woff2');}
@font-face{font-family:'Inter';font-weight:400 700;font-display:swap;src:url('./fonts/inter-400.woff2') format('woff2');}

:root{
  --bg: #0d0e12; --bg-2: #0a0b0e;
  --card: rgba(20, 22, 32, 0.5);
  --panel: rgba(15, 18, 25, 0.6);
  --elev: rgba(25, 28, 40, 0.7);
  --line: rgba(255,255,255,.08); --line-2: rgba(255,255,255,.15);
  --text: #eef2f8; --muted: #9aa6b8; --faint: #475569;
  --cy:#e0b271; --cy-deep:#c9974f; --cy-soft:rgba(224,178,113,.15);
  --good: #0d9488; --green: #0d9488; --green-light: #0d9488; --warn: #2563eb;
  --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
  --font-display:'Space Grotesk',ui-sans-serif,system-ui,sans-serif;
  --font-body:'Inter',ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,"SFMono-Regular","Segoe UI Mono",monospace;
  --pad:16px;
  --atk-primary:#e0b271; --atk-secondary:#c97a5b; --atk-effort:#e0b271; --atk-gravity:#ff5d73; --atk-bg:#0d0e12; --atk-bone:#5b6472;
  /* shell endpoints — the hardcoded frame/HUD/sheet colors, tokenized so themes can flip them */
  --shell-top:#090b0f; --shell-bot:#070809; --hud-top:#0b0d11; --hud-bot:rgba(11,13,17,.92); --sheet-bg:#0f1116;
}

/* 4-theme cycle — same [data-theme] hook home.js/map.js set on <html> (canonical
   "eccentryx.theme" key), carried to the gym cockpit. :root above IS the dark theme.
   Text/muted pairs are computed >= WCAG AA per theme in gym_theme_polarity_contract_test.js.
   The gold accent (--cy) darkens on light shells so accent text stays >= AA. */
[data-theme="light"]{
  --bg:#f4f6fa; --bg-2:#e9edf4;
  --card:rgba(255,255,255,0.72); --panel:rgba(255,255,255,0.60); --elev:rgba(255,255,255,0.85);
  --line:rgba(8,12,20,0.10); --line-2:rgba(8,12,20,0.18);
  --text:#0e1116; --muted:#4a5568; --faint:#64748b;
  --cy:#8a5a00; --cy-deep:#6d4700; --cy-soft:rgba(138,90,0,.12);
  --good:#047857; --green:#047857; --green-light:#047857;
  --glass-shadow:0 8px 32px 0 rgba(15,23,42,0.12);
  --shell-top:#eef1f6; --shell-bot:#e7ebf2; --hud-top:#f7f9fc; --hud-bot:rgba(247,249,252,.92);
  --sheet-bg:#ffffff;
}
[data-theme="obsidian"]{
  --bg:#050506; --bg-2:#0d0d0f;
  --card:rgba(20,20,24,0.55); --panel:rgba(13,13,15,0.60); --elev:rgba(26,26,30,0.70);
  --line:rgba(255,255,255,0.08); --line-2:rgba(255,255,255,0.14);
  --text:#f5f5f7; --muted:#a1a1aa; --faint:#71717a;
  --cy:#ffba08; --cy-deep:#e0a106; --cy-soft:rgba(255,186,8,.15);
  --glass-shadow:0 8px 32px 0 rgba(0,0,0,0.5);
  --shell-top:#070708; --shell-bot:#030304; --hud-top:#0a0a0c; --hud-bot:rgba(10,10,12,.92);
  --sheet-bg:#0d0d0f;
}
[data-theme="clinical"]{
  --bg:#f7faf9; --bg-2:#eef4f2;
  --card:rgba(255,255,255,0.75); --panel:rgba(255,255,255,0.62); --elev:rgba(255,255,255,0.88);
  --line:rgba(4,120,87,0.12); --line-2:rgba(4,120,87,0.20);
  --text:#0d1512; --muted:#3f4f49; --faint:#5c6f68;
  --cy:#047857; --cy-deep:#036249; --cy-soft:rgba(4,120,87,.12);
  --good:#047857; --green:#047857; --green-light:#047857;
  --glass-shadow:0 8px 32px 0 rgba(4,60,45,0.12);
  --shell-top:#eef4f2; --shell-bot:#e8f0ed; --hud-top:#f4f8f6; --hud-bot:rgba(244,248,246,.92);
  --sheet-bg:#ffffff;
}
html{color-scheme:dark;}
[data-theme="light"],[data-theme="clinical"]{color-scheme:light;}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
*:focus-visible{outline:2px solid var(--warn, #2563eb);outline-offset:2px;border-radius:2px;}
.skip-link{position:absolute;top:-40px;left:0;background:var(--warn);color:#fff;padding:8px 12px;z-index:1000;text-decoration:none;font:600 13px var(--font-body);border-radius:0 0 6px 0;}
.skip-link:focus{top:0;}

html,body{margin:0;background:var(--bg);color:var(--text);
  font:16px/1.45 var(--font-body);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}

/* phone frame so the mobile-first intent is obvious on desktop */
/* padding-bottom clears the iOS home indicator: viewport-fit=cover (set on the page) makes
   env() resolve, and without this the last control sits under the indicator on notched phones. */
.phone{max-width:440px;margin:0 auto;min-height:100vh;padding-bottom:calc(56px + env(safe-area-inset-bottom));
  background:
    radial-gradient(125% 80% at 50% -8%, rgba(224,178,113,.07), transparent 58%),
    radial-gradient(100% 55% at 50% 112%, rgba(224,178,113,.045), transparent 55%),
    linear-gradient(180deg,var(--shell-top) 0%,var(--bg) 42%,var(--shell-bot) 100%);
  background-attachment: fixed;
  border-left:1px solid var(--line);border-right:1px solid var(--line);
  display:flex;flex-direction:column;position:relative;overflow:hidden;}

/* engineering-grid wallpaper — top-masked so it fades into the floor view; static (motion-safe) */
.phone::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.6;
  background-image:
    linear-gradient(rgba(255,255,255,.016) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.016) 1px,transparent 1px);
  background-size:34px 34px,34px 34px;
  -webkit-mask-image:radial-gradient(135% 100% at 50% 0%,#000 55%,transparent 88%);
          mask-image:radial-gradient(135% 100% at 50% 0%,#000 55%,transparent 88%);}

/* sticky top: only what matters at a glance */
.top{position:sticky;top:0;z-index:5;background:linear-gradient(180deg,var(--hud-top),var(--hud-bot));
  backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,.04);
  /* the sticky HUD is the top of the screen — it must clear the status bar / notch, not sit under it */
  padding:calc(18px + env(safe-area-inset-top)) 22px 18px;display:flex;align-items:center;gap:14px;}
/* 44px is the WCAG 2.5.5 AAA floor — tapped mid-session to check readiness, same as the
   other HUD controls below. min-height/min-width grow the hit box; the ring+text stay
   their existing visual size, centered inside it. */
.readiness-hud{display:flex;align-items:center;justify-content:center;gap:6px;margin-right:auto;
  cursor:pointer;min-height:44px;min-width:44px;}
.r-ring{width:20px;height:20px;transform:rotate(-90deg);}
.r-val{transition:stroke-dashoffset 0.8s cubic-bezier(0.4,0,0.2,1);}
.r-text{font:700 11px var(--font-mono);color:var(--cy);letter-spacing:0.04em;}
.top .live{display:flex;align-items:center;gap:7px;font:600 11px/1 var(--font-mono);letter-spacing:.1em;color:var(--good);white-space:nowrap;}

/* Responsive HUD for narrow mobile viewports */
@media (max-width: 390px) {
  .top { padding: 12px 14px; gap: 8px; }
  .top .live .live-text { display: none; }
  .top .live { gap: 0; }
  .readiness-hud { gap: 4px; }
  .r-text { font-size: 10px; }
  .top .t { font-size: 14px; }
  .top .planbtn { padding: 6px 8px; font-size: 10px; }
}
@media (max-width: 350px) {
  .readiness-hud .r-text { display: none; }
}
/* CRITICAL — header overflow on mobile. The six-control row (exit / live / readiness /
   title / plan / close) is wider than a 320px viewport: the plan button and the ✕ close
   render off the right edge (close at right~=385 in a 320 viewport) and .phone clips the
   overflow, so the close is UNREACHABLE — no scroll can reach it. The brand is already
   carried by the .exit-app "← ECCENTRYX" link, so the redundant .top .t title is dropped on
   mobile and the plan/close cluster is anchored to the right edge with margin-left:auto.
   Every control — especially the ✕ close — then renders fully on-screen and >=44px at
   320/360/390. Canonical 480px mobile breakpoint; desktop (>=1024) is untouched. */
@media (max-width: 480px) {
  .top { padding: calc(10px + env(safe-area-inset-top)) 12px 10px; gap: 6px; }
  .top .t { display: none; }
  .top .planbtn { margin-left: auto; }
  .exit-app { margin-right: 0; }
}
@media (max-width: 350px) {
  /* 320px floor: with the toggle added the six-control row needs the tighter gutter
     to keep the ✕ close fully on-screen (readiness + controls keep their 44px floors). */
  .top { padding-left: 8px; padding-right: 8px; gap: 4px; }
}

/* Universal Motion Silencer */
@media (prefers-reduced-motion: reduce) {
  .top .live .dot, .mrv-event-horizon { animation: none !important; }
  .top .live .dot { opacity: 1; }
}
.top .live .dot{width:7px;height:7px;border-radius:50%;background:var(--good);box-shadow:0 0 8px var(--good);animation:p 1.6s infinite;}
@keyframes p{0%,100%{opacity:1}50%{opacity:.4}}
.top .t{font:700 16px var(--font-display);letter-spacing:.06em;margin-left:auto;}
/* min-height:44px on planbtn + explicit 44x44 on x: WCAG AAA floor for the HUD's session-
   level controls (view plan, exit session) — same rationale as readiness-hud above. */
.top .planbtn{display:flex;align-items:center;justify-content:center;gap:6px;border:1px solid var(--line);
  background:rgba(224,178,113,.08);color:var(--cy);border-radius:12px;padding:7px 11px;min-height:44px;
  font:700 11px/1 var(--font-mono);letter-spacing:.08em;cursor:pointer;}
/* theme cycle button — same 44px tap floor as .planbtn; label always names the CURRENT theme */
.top .theme-toggle{display:flex;align-items:center;justify-content:center;border:1px solid var(--line-2);
  background:transparent;color:var(--muted);border-radius:12px;padding:7px 11px;min-height:44px;
  font:700 10px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;cursor:pointer;white-space:nowrap;}
.top .theme-toggle:active{transform:scale(.96);}
/* The full theme label ("Obsidian mode" ~86px) pushes the ✕ close off-screen on the narrow
   header — the exact overflow the 480px block above fixed (#317). Below the canonical 480px
   breakpoint the toggle compacts to a 44px icon-only control: font-size:0 hides the text
   label (textContent stays intact for the JS cycle + label contract) and the aria-label
   still names the current theme (no visible text => WCAG 2.5.3 satisfied). This rule sits
   AFTER the base rule above because the base `font:` shorthand would otherwise re-set it. */
@media (max-width: 480px) {
  .top .theme-toggle { font-size: 0; letter-spacing: 0; min-width: 44px; padding: 0; }
  .top .theme-toggle::before { content: "◐"; font-size: 16px; line-height: 1; }
}
.top .planbtn:active{transform:scale(.96);}
.top .x{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;
  min-width:44px;min-height:44px;color:var(--muted);font-size:20px;background:transparent;
  border:0;padding:0;text-decoration:none;line-height:1;cursor:pointer;}
.body{flex:1;padding:var(--pad);display:flex;flex-direction:column;gap:14px;position:relative;z-index:1;}

/* Deep-minimal cockpit: default-lean. The focal glance (day stepper, hero lift +
   target + strength readout, the log controls, LOG SET, the rest timer) stays; one
   calm "more" reveal (#cockpitMoreToggle) shows everything else. DOM order is
   preserved (the source-order contracts stay green) — the reveal is a class toggle,
   not a re-nest, so tucked sections collapse in place and reappear where they live. */
body.cockpit-lean #gymNextAction,
body.cockpit-lean #autoregSuggest,
body.cockpit-lean #gymLoopCard,
body.cockpit-lean #programModeCard,
body.cockpit-lean #nowCard,
body.cockpit-lean #upNext,
body.cockpit-lean #swapDetails,
body.cockpit-lean #skipBtn,
body.cockpit-lean #missBtn,
body.cockpit-lean #undoSetBtn,
body.cockpit-lean .prog,
body.cockpit-lean .voice-preview,
body.cockpit-lean .strip,
body.cockpit-lean #sessionActions,
body.cockpit-lean #sessionLogDetails{ display:none !important; }
/* generous breathing room around the single focal action in lean mode */
body.cockpit-lean .body{ gap:20px; }
.cockpit-more-toggle{-webkit-appearance:none;appearance:none;align-self:center;
  background:transparent;border:0;color:var(--muted);font:600 12px var(--font-mono);
  letter-spacing:.12em;text-transform:uppercase;min-height:44px;padding:0 16px;
  cursor:pointer;border-radius:10px;transition:color .15s;display:inline-flex;
  align-items:center;gap:8px;}
.cockpit-more-toggle::after{content:"▾";font-size:14px;transition:transform .2s;}
body:not(.cockpit-lean) .cockpit-more-toggle::after{transform:rotate(180deg);}
.cockpit-more-toggle:hover{color:var(--cy);}

/* day switcher — compact stepper through the saved plan's days (‹ Day 2 of 4 ›) */
.day-stepper{display:none;}
.day-stepper:not([hidden]){display:flex;align-items:center;justify-content:center;gap:14px;
  padding:8px 12px;border:1px solid var(--line);border-radius:12px;background:var(--panel);}
/* 44px is the a11y 2.5.5 touch floor — these arrows are used mid-set with sweaty hands */
.day-step-btn{appearance:none;-webkit-appearance:none;border:1px solid var(--line-2);
  background:transparent;color:var(--text);width:44px;height:44px;border-radius:10px;
  font:400 20px/1 var(--font-display);cursor:pointer;display:flex;align-items:center;
  justify-content:center;transition:border-color .15s,color .15s,opacity .15s;}
.day-step-btn:hover:not(:disabled){border-color:var(--cy);color:var(--cy);}
.day-step-btn:disabled{opacity:.28;cursor:default;}
.day-step-label{font:600 13px var(--font-mono);color:var(--muted);letter-spacing:.06em;
  min-width:88px;text-align:center;text-transform:uppercase;}

/* Mode switcher — three training sessions (Strength / Functional / Recovery). One shows
   at a time; Strength defaults. FOCAL: never in the cockpit-lean hide rule. 44px tap floor
   (WCAG 2.5.5). flex:1 1 0 + min-width:0 so the three tabs fill and never overflow at 320px. */
.gym-mode-switch{display:flex;gap:6px;padding:5px;border:1px solid var(--line);
  border-radius:14px;background:var(--panel);}
.gym-mode-tab{flex:1 1 0;min-width:0;min-height:44px;appearance:none;-webkit-appearance:none;
  border:1px solid transparent;background:transparent;color:var(--muted);
  font:600 12px var(--font-mono);letter-spacing:.08em;text-transform:uppercase;
  border-radius:10px;cursor:pointer;padding:0 6px;
  transition:color .15s,background .15s,border-color .15s;}
.gym-mode-tab:hover{color:var(--text);}
.gym-mode-tab.is-active{color:var(--bg);background:var(--cy);border-color:var(--cy);}
.gym-mode-tab:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}

/* Per-mode SESSION EXERCISE LIST. Mobile: a compact one-line strip (the .gsl-strip button)
   under the mode tabs that expands the full rows on tap — the rows are display:none by
   default (collapsed) so the deep-minimal lean glance is never turned into a second
   always-open block; .is-open reveals them. Desktop (>=1024): a slim side rail beside the
   cockpit (grid-area slist) with the rows always visible. 44px tap floor on the strip and on
   every row (WCAG 2.5.5). Load-free rows in recovery mode (honesty). */
.gym-session-list{display:flex;flex-direction:column;gap:6px;}
.gsl-strip{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;text-align:left;
  appearance:none;-webkit-appearance:none;cursor:pointer;
  border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:8px 12px;color:var(--text);}
.gsl-strip:hover{border-color:var(--line-2);}
.gsl-strip:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}
.gsl-head{font:700 10px var(--font-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--cy);
  white-space:nowrap;flex:none;}
.gsl-preview{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:600 12px var(--font-mono);color:var(--muted);letter-spacing:.02em;}
.gsl-caret{flex:none;color:var(--muted);font-size:12px;transition:transform .2s;}
.gym-session-list.is-open .gsl-caret{transform:rotate(180deg);}
/* Rows collapsed by default (mobile) — expanded only via .is-open. */
.gsl-rows{display:none;list-style:none;margin:0;padding:0;flex-direction:column;gap:4px;}
.gym-session-list.is-open .gsl-rows{display:flex;}
.gsl-row{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;text-align:left;
  appearance:none;-webkit-appearance:none;cursor:pointer;
  border:1px solid transparent;border-radius:10px;background:rgba(255,255,255,.03);
  padding:7px 10px;color:var(--text);transition:border-color .15s,background .15s;}
.gsl-row:hover{border-color:var(--line-2);background:rgba(255,255,255,.05);}
.gsl-row:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}
.gsl-idx{flex:0 0 22px;width:22px;height:22px;border-radius:11px;border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  font:700 10px var(--font-mono);color:var(--muted);}
.gsl-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:600 13px var(--font-body);color:var(--text);}
.gsl-meta{flex:none;font:600 11px var(--font-mono);color:var(--muted);letter-spacing:.02em;white-space:nowrap;}
.gsl-now{flex:none;font:700 9px var(--font-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--cy);}
.gsl-row.done .gsl-idx{background:var(--good);border-color:var(--good);color:#04140a;}
.gsl-row.done .gsl-nm{color:var(--muted);text-decoration:line-through;}
.gsl-row.cur{background:rgba(224,178,113,.10);border-color:var(--cy);}
.gsl-row.cur .gsl-idx{background:var(--cy);border-color:var(--cy);color:#000;}
.gsl-row.cur .gsl-nm{color:var(--text);}
.gsl-empty{font:600 12px/1.4 var(--font-body);color:var(--muted);padding:8px 12px;
  border:1px dashed var(--line);border-radius:12px;}
.gsl-empty[hidden]{display:none;}
.gsl-empty-link{color:var(--cy);text-decoration:none;font-weight:700;}
.gsl-empty-link:hover{text-decoration:underline;}

/* progress */
/* Smart status line (operator 2026-07-25): progress count + streak + week truth share
   ONE calm row under the hairline bar — the chips keep their pinned markup and rules,
   the container simply lays them inline instead of stacking. */
.prog{display:flex;flex-wrap:wrap;align-items:center;gap:7px 10px;}
.prog .bar{flex:1 1 100%;height:5px;border-radius:12px;background:rgba(255,255,255,.07);overflow:hidden;}
.prog .bar i{display:block;height:100%;width:20%;background:var(--cy);border-radius:12px;transition:width .4s;position:relative;overflow:hidden;}
@media (prefers-reduced-motion:no-preference){.prog .bar i::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.5),transparent);transform:translateX(-100%);will-change:transform;animation:progSheen 2.4s linear infinite;}
  .prog.near-complete .bar i::before { content:""; position:absolute; inset:0; border-radius:inherit; background:rgba(224,178,113,.38); opacity:.35; will-change:opacity,transform; animation:auraPulse 2s infinite alternate; }
}
@keyframes progSheen{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@keyframes auraPulse{from{opacity:.35;transform:scaleX(.98)}to{opacity:.86;transform:scaleX(1)}}
.prog.near-complete .bar i { box-shadow: 0 0 12px var(--cy); }
.prog .n{font:600 12px var(--font-mono);color:var(--muted);margin-right:auto;}
/* earned streak chip — derived from the real sessions store, hidden under 2 days
   (honest, never fabricated); static, no motion */
.prog .streak{justify-self:end;font:700 11px var(--font-mono);color:var(--cy);letter-spacing:.04em;
  border:1px solid rgba(224,178,113,.3);border-radius:999px;padding:3px 10px;background:rgba(224,178,113,.08);}
.prog .streak[hidden]{display:none;}
/* weekly truth chip — rolling 7-day volume + days from the real sessions store;
   hidden when the window holds no real work (honest, never a fabricated zero) */
.prog .week{justify-self:end;font:700 11px var(--font-mono);color:var(--cy);letter-spacing:.04em;
  border:1px solid rgba(224,178,113,.3);border-radius:999px;padding:3px 10px;background:rgba(224,178,113,.08);}
.prog .week[hidden]{display:none;}
/* unified chip stack: every prog pill lives in the right column, one line each —
   the week chip used to scatter into column 1 at 390 and wrap mid-pill */
.prog .streak,.prog .week,.prog .skip-rate{grid-column:2;justify-self:end;white-space:nowrap;}
/* offline-trust indicator (blueprint 1.8): once the first set persists, confirm the
   no-account consumer their data is safe locally. Static, muted, spans the row. */
.prog .saved-note{grid-column:1/-1;flex:1 1 100%;font:600 11px var(--font-mono);color:var(--muted);letter-spacing:.02em;display:flex;align-items:center;gap:6px;}
.prog .saved-note::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--good);flex:none;}
.prog .saved-note[hidden]{display:none;}
.prog .segments{grid-column:1/-1;flex:1 1 100%;display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:4px;min-height:5px;}
.prog .seg{height:5px;border-radius:999px;background:rgba(255,255,255,.08);}
.prog .seg.done,.prog .seg.current{background:linear-gradient(90deg,var(--cy),#78d6a3);}
.prog .seg.current{outline:1px solid rgba(255,255,255,.18);outline-offset:1px;}
/* Glassmorphism card system - unified styling tokens across cockpit cards */
.now, .loop-card, .next-action-card, .autoreg-card, .swipe-scrubber, .load-entry, .rpe-slider, .stat, details, .restcd {
  background: var(--card);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--glass-shadow), inset 0 0 0 1px rgba(255,255,255,0.05);
  transition: transform .15s ease-out, border-color .15s ease-out, box-shadow .15s ease-out;
}
.now:hover, .loop-card:hover, .next-action-card:hover, .autoreg-card:hover, .swipe-scrubber:hover, .load-entry:hover, .rpe-slider:hover, .stat:hover, details:hover, .restcd:hover {
  border-color: rgba(255,255,255,0.12);
  box-shadow: 0 12px 40px rgba(0,0,0,0.45), inset 0 0 0 1px rgba(255,255,255,0.08);
}
.now:focus-within, .loop-card:focus-within, .next-action-card:focus-within, .autoreg-card:focus-within, .swipe-scrubber:focus-within, .load-entry:focus-within, .rpe-slider:focus-within, .stat:focus-within, details:focus-within, .restcd:focus-within {
  border-color: rgba(224,178,113,0.28);
}

/* autoregulation suggestion (blueprint 1.5): propose, never command. Static, hot-surface. */
.autoreg-card{border-color:rgba(224,178,113,.28);padding:14px;display:grid;gap:6px;}
.autoreg-card[hidden]{display:none;}
.swipe-scrubber[hidden]{display:none;} /* anti-cheat slice 2b: load is prescribed, no swipe-to-adjust */
.autoreg-kicker{font:800 10px var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--cy);}
.autoreg-main{font:800 15px/1.2 var(--font-display);color:var(--text);}
.autoreg-why{font:600 12px/1.35 var(--font-body);color:var(--muted);}
.autoreg-actions{display:flex;gap:8px;margin-top:4px;}
.autoreg-actions button{min-height:44px;flex:1;border-radius:10px;font:700 13px var(--font-body);cursor:pointer;}
.autoreg-apply{background:var(--cy);color:#0a0b10;border:none;}
.autoreg-keep{background:transparent;color:var(--text);border:1px solid var(--line);}
.next-action-card{background:linear-gradient(135deg,rgba(224,178,113,.12),rgba(13,148,136,.08)),var(--card);border-color:rgba(224,178,113,.28);display:grid;gap:5px;min-height:86px;padding:14px;position:relative;overflow:hidden;}
.next-action-card::before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(224,178,113,.16),transparent 42%,rgba(13,148,136,.12));opacity:.26;pointer-events:none;}
.next-action-kicker{font:800 10px var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--cy);}
.next-action-main{font:800 18px/1.18 var(--font-display);letter-spacing:-.01em;color:var(--text);}
.next-action-sub{font:600 12px/1.35 var(--font-body);color:var(--muted);max-width:52ch;}
.next-action-card[data-state="rest"]{border-color:rgba(34,211,238,.36);}
.next-action-card[data-state="complete"]{border-color:rgba(52,211,153,.38);}
.loop-card{padding:13px;display:grid;gap:10px;}
.loop-h{font:800 10px var(--font-mono);letter-spacing:.14em;color:var(--cy);text-transform:uppercase;}
.loop-summary{font:600 13px/1.35 var(--font-body);color:var(--text);}
.loop-row{display:grid;grid-template-columns:1fr auto;align-items:center;gap:10px;}
.loop-row label{font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;}
.loop-row output{font:800 16px var(--font-mono);color:var(--cy);}
.loop-card input[type=range]{width:100%;appearance:none;background:rgba(255,255,255,.07);height:8px;border-radius:12px;outline:none;}
.loop-card input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;border-radius:12px;background:var(--cy);cursor:pointer;}
.loop-card input[type=range]::-moz-range-thumb{width:22px;height:22px;border-radius:12px;background:var(--cy);cursor:pointer;border:0;}
.loop-call{font:600 12px/1.35 var(--font-body);color:var(--muted);border-top:1px solid var(--line);padding-top:9px;}

.program-mode-card{padding:14px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px 14px;align-items:center;border-color:rgba(224,178,113,.28);}
.program-mode-kicker{font:800 9px var(--font-mono);letter-spacing:.14em;color:var(--cy);text-transform:uppercase;}
.program-mode-card h2{margin:4px 0;font:800 18px/1.1 var(--font-display);}
.program-mode-card p{margin:0;color:var(--muted);font:600 12px/1.4 var(--font-body);}
.program-mode-privacy{grid-column:1/-1;border-top:1px solid var(--line);padding-top:9px;}
.program-mode-switch{display:grid;grid-template-columns:auto auto;gap:5px 8px;align-items:center;cursor:pointer;min-height:44px;}
.program-mode-switch input{position:absolute;opacity:0;pointer-events:none;}
.program-mode-switch span{width:48px;height:26px;border:1px solid var(--line-2);border-radius:99px;background:rgba(255,255,255,.07);position:relative;transition:background .18s,border-color .18s;}
.program-mode-switch span::after{content:"";position:absolute;width:18px;height:18px;left:3px;top:3px;border-radius:50%;background:var(--muted);transition:transform .18s,background .18s;}
.program-mode-switch b{grid-column:1/-1;text-align:center;font:800 10px var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.program-mode-switch input:checked + span{background:rgba(224,178,113,.2);border-color:var(--cy);}
.program-mode-switch input:checked + span::after{transform:translateX(22px);background:var(--cy);}
.program-mode-switch input:focus-visible + span{outline:2px solid var(--cy);outline-offset:3px;}
.program-mode-card[data-enabled="true"]{border-color:rgba(224,178,113,.56);box-shadow:inset 0 0 0 1px rgba(224,178,113,.08);}
body.program-mode-on #nReps{cursor:default;}
/* undo stays visible in Program Mode — a skip is undoable (hRaw/sRaw snapshot) */
body.program-mode-on .voice-preview{display:none;}

/* Biokinetic Test UI */
.bio-test-btn { width: 100%; padding: 14px; background: rgba(13, 148, 136, 0.1); border: 1px solid var(--cy); border-radius: 12px; font: 800 14px var(--font-mono); color: var(--cy); cursor: pointer; text-transform: uppercase; letter-spacing: 0.1em; transition: 0.2s; outline: none; }
.bio-test-btn:active { transform: scale(0.96); background: rgba(13, 148, 136, 0.3); }
.bio-test-btn.testing { background: var(--cy); color: #000; animation: pulseBio 0.5s infinite alternate; }
.bio-test-bar { height: 4px; background: rgba(255,255,255,0.1); border-radius: 4px; overflow: hidden; display: none; }
.bio-test-bar.show { display: block; }
.bio-fill { height: 100%; width: 0%; background: var(--cy); transition: width 0.1s linear; }
@keyframes pulseBio { from { opacity:.82; transform:scale(1); } to { opacity:1; transform:scale(.99); } }

/* THE hero: current exercise — one job */
.now{padding:18px;}
.now .eyebrow{font:700 10px var(--font-mono);letter-spacing:.18em;color:var(--cy);text-transform:uppercase;}
.now h1{margin:5px 0 2px;font:800 28px/1.04 var(--font-display);letter-spacing:-.015em;}
.now .set{color:var(--muted);font-size:13px;}
.now .last{margin-top:7px;font:600 12px var(--font-mono);color:var(--muted);}
.now .last b{color:var(--cy);}
.now .last.pr b{color:var(--good);}
.now details.avatar-cue { margin-top:16px; font-size:13px; color:var(--text); background:rgba(224,178,113,0.04); border-left:2px solid var(--cy); border-radius:12px; cursor:pointer; overflow:hidden; border:none; border-left:2px solid var(--cy); box-shadow:none; }
.now details.avatar-cue summary { display:flex; gap:12px; align-items:center; padding:12px; outline:none; }
.now details.avatar-cue summary::-webkit-details-marker { display:none; }
.now details.avatar-cue .av-icon{width:24px;height:24px;border-radius:12px;background:var(--cy);display:flex;align-items:center;justify-content:center;font-size:12px;flex-shrink:0;}
.now details.avatar-cue b{color:var(--cy);display:block;font-size:11px;letter-spacing:0.05em;text-transform:uppercase;}
.now details.avatar-cue .cue-content { padding: 0 12px 12px 48px; }

/* MRV Saturation Bar (Phase 28) */
.mrv-bar{margin-top:12px;display:flex;flex-direction:column;gap:6px;border-top:1px solid var(--line);padding-top:12px;}
.mrv-bar .mrv-h{font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;display:flex;justify-content:space-between;}
.mrv-bar .mrv-track{height:4px;border-radius:12px;background:rgba(255,255,255,.07);overflow:hidden;position:relative;}
.mrv-bar .mrv-fill{height:100%;width:0%;background:var(--cy);transition:width 0.4s, background 0.4s;}

.mrv-event-horizon {
  border-color: rgba(37,99,235,.5) !important;
  box-shadow: 0 0 20px rgba(37,99,235,.2) !important;
}
@media (prefers-reduced-motion: no-preference) {
  .mrv-event-horizon { animation: eventHorizonPulse 1.5s infinite; }
}
@keyframes eventHorizonPulse {
  0%, 100% { opacity: 1; transform: translateY(0); }
  50% { opacity: .94; transform: translateY(-1px); }
}
.mrv-event-horizon .mrv-fill {
  background: linear-gradient(90deg, #2563eb, #2563eb) !important;
}
.mrv-event-horizon .mrv-h b { color: var(--warn); }

/* up-next: the immediate next lift, always visible, one tap to the full plan */
.upnext{display:flex;align-items:center;gap:10px;background:transparent;border:1px dashed var(--line);
  border-radius:12px;padding:11px 13px;cursor:pointer;}
.upnext:active{background:rgba(255,255,255,.03);}
.upnext .lab{font:700 10px var(--font-mono);letter-spacing:.12em;color:var(--muted);text-transform:uppercase;}
.upnext .nm{font-weight:600;font-size:14px;}
.upnext .sch{color:var(--muted);font-size:12px;}
.upnext .go{margin-left:auto;color:var(--cy);font:700 11px var(--font-mono);}

/* the three numbers — big, thumb-friendly */
.nums{display:flex;gap:7px;margin-bottom:15px;}
.num{flex:1;background:rgba(255,255,255,.05);border:1px solid var(--line);border-radius:12px;padding:12px;text-align:center;box-shadow:inset 0 0 0 1px rgba(255,255,255,0.02);}
.num label{display:block;font:700 9px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;margin-bottom:6px;}
.num .v{font:800 24px/1 var(--font-mono);color:var(--text);margin-bottom:4px;}
.num .u{font-size:11px;color:var(--muted);}
.num.on{border-color:var(--cy);box-shadow:none;}

/* Phase 40: Glycolytic Tachometer */
.tachometer-wrap { position: relative; overflow: hidden; cursor: ew-resize; }
.tachometer-svg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; transform: rotate(-90deg); pointer-events: none; }
.tacho-bg { fill: none; stroke: rgba(255,255,255,0.05); stroke-width: 6; }
.tacho-fill { fill: none; stroke: var(--cy); stroke-width: 6; stroke-linecap: round; stroke-dasharray: 276; stroke-dashoffset: 276; transition: stroke-dashoffset 0.2s cubic-bezier(0.2,0.8,0.2,1), stroke 0.3s; }
.tacho-fill.hypertrophy { stroke: var(--cy); filter: drop-shadow(0 0 8px var(--cy-soft)); }

/* Kinetic Swipe Scrubber */
.swipe-scrubber { padding: 14px; margin-bottom: 10px; position: relative; touch-action: none; overflow: hidden; }
.swipe-scrubber .lab { font: 700 10px var(--font-mono); letter-spacing: .1em; color: var(--muted); text-transform: uppercase; margin-bottom: 10px; pointer-events: none; }
.scrub-track { height: 44px; background: rgba(0,0,0,0.3); border-radius: 8px; position: relative; display: flex; align-items: center; justify-content: center; box-shadow: inset 0 2px 10px rgba(0,0,0,0.5); }
.scrub-knob { width: 50px; height: 36px; background: var(--cy); border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #000; font-weight: 900; font-size: 14px; letter-spacing: 2px; cursor: grab; box-shadow: 0 0 10px rgba(13, 148, 136, 0.5); transition: transform 0.1s; position: absolute; left: calc(50% - 25px); }
.scrub-knob:active { cursor: grabbing; background: var(--cy); box-shadow: 0 0 20px rgba(224,178,113,.6); }

/* Holographic Share Modal */
.share-preview-modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: flex-start; justify-content: center; padding: 20px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.share-preview-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.8); backdrop-filter: blur(8px); }
.share-preview-content { position: relative; z-index: 1001; width: 100%; max-width: 400px; display: flex; flex-direction: column; perspective: 1000px; margin: auto 0; padding: 8px 0 24px; }
.holographic-wrapper { position: relative; width: 100%; aspect-ratio: 1; border-radius: 20px; box-shadow: 0 20px 50px rgba(0,0,0,0.8); transform-style: preserve-3d; transition: transform 0.1s ease-out; }
.holographic-wrapper canvas { width: 100%; height: 100%; border-radius: 20px; display: block; }
.holo-sheen { position: absolute; inset: 0; border-radius: 20px; background: linear-gradient(105deg, transparent 20%, rgba(255,255,255,0.4) 25%, transparent 30%); pointer-events: none; mix-blend-mode: color-dodge; z-index: 2; transform: translateZ(1px); background-size: 200% 200%; background-position: -50% 0; transition: background-position 0.1s ease-out; }
.download-holo-btn { width: 100%; padding: 16px; margin-top: 30px; background: var(--cy); color: #000; font: 800 16px var(--font-mono); border-radius: 12px; border: none; cursor: pointer; box-shadow: 0 0 20px rgba(13,148,136,0.4); text-transform: uppercase; }

.load-entry{padding:12px;margin-top:10px;}
.load-entry label{display:block;font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;margin-bottom:8px;}
.load-entry input{width:100%;appearance:textfield;background:rgba(255,255,255,.06);border:1px solid var(--line-2);border-radius:12px;color:var(--text);font:800 20px/1 var(--font-mono);padding:12px;outline:none;}
.load-entry input:focus{border-color:var(--cy);}
.load-entry input[readonly]{cursor:default;opacity:.9;border-style:dashed;background:rgba(255,255,255,.03);}
.rpe-slider input:disabled{cursor:default;opacity:.75;}
.load-target-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;margin-top:8px;}
.load-target-row span{color:var(--muted);font:600 11px/1.35 var(--font-body);}
.load-target-row button{min-height:44px;border:1px solid rgba(224,178,113,.36);background:rgba(224,178,113,.10);color:var(--text);border-radius:12px;padding:8px 10px;font:800 11px var(--font-mono);cursor:pointer;white-space:nowrap;}
.load-target-row button:active{transform:scale(.98);}

/* Recovery / mobility logging surface. A recovery drill (breathing, stretch, mobility) is
   not "lifted", so in recovery mode the load-centric controls — the WEIGHT / REPS cards, the
   swipe-to-adjust-load scrubber, the actual-load entry and the RPE slider — are hidden and the
   honest mark-complete surface is shown instead. Class toggled at runtime by setGymMode; the
   strength / functional log UI is untouched. Pinned by gym_recovery_logging_contract_test.js. */
.recovery-log{display:none;padding:14px;margin-bottom:12px;}
body.gym-recovery-mode .nums,
body.gym-recovery-mode #nextTargetDisplay,
body.gym-recovery-mode #weightScrubber,
body.gym-recovery-mode #loadEntry,
body.gym-recovery-mode .rpe-slider{display:none !important;}
body.gym-recovery-mode .recovery-log{display:block;}
/* Recovery flows are continuous — no rest timer surface at all (chips, countdown, coaching). */
body.gym-recovery-mode .rest,
body.gym-recovery-mode .restcd,
body.gym-recovery-mode .rest-coach{display:none !important;}
body.gym-recovery-mode .rest-meta{display:none !important;}

/* ── Metabolic rest read (2026-07-23): energy system drained by the current rep
      target + which chip matches it. Static token inks only (AA per shell); the
      recommended chip is a steady border/glow state, never a pulse — nothing to
      guard beyond the file's existing reduced-motion wildcard. ── */
.rest-meta{margin:8px 0 0;font:600 .72rem var(--font-mono,monospace);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted,#9aa3af);}
.rest button.rec{border-color:var(--good,#36e07f);color:var(--good,#36e07f);
  box-shadow:0 0 0 1px var(--good,#36e07f) inset;}

/* ── Between-set coaching card: rest-target rule (transparent heuristic) + one honest
      coach line. States: counting (neutral) -> in-window near target (subtle green) ->
      over-window past target (quiet amber). Static color states only — no pulsing.
      State inks are TOKENS (--good / --cy) so each theme keeps AA per shell (#341 precedent). ── */
.rest-coach{display:flex;align-items:center;gap:10px;margin-top:10px;padding:10px 12px;
  border:1px solid var(--line-2,rgba(255,255,255,.12));border-radius:12px;
  background:rgba(255,255,255,.04);transition:border-color .18s ease,background .18s ease;}
.rest-coach[hidden]{display:none;}
.rest-coach-copy{flex:1 1 auto;min-width:0;}
.rest-coach-rule{font:700 13px/1.35 var(--font-mono);color:var(--muted);}
.rest-coach-line{margin-top:4px;font:600 13px/1.4 var(--font-body);color:var(--text);}
.rest-hist-line{margin-top:3px;font:600 12px/1.4 var(--font-body);color:var(--muted);}
.rest-median-line{margin-top:3px;font:600 12px/1.4 var(--font-body);color:var(--muted);}
.rest-coach.near{border-color:rgba(13,148,136,.45);background:rgba(13,148,136,.08);}
.rest-coach.near .rest-coach-rule{color:var(--good);}
.rest-coach.over{border-color:rgba(224,178,113,.40);background:rgba(224,178,113,.07);}
.rest-coach.over .rest-coach-rule{color:var(--cy);}
.rest-coach-hide{flex:none;min-width:44px;min-height:44px;border:1px solid var(--line-2,rgba(255,255,255,.12));
  border-radius:10px;background:transparent;color:var(--muted);font:700 12px var(--font-body);cursor:pointer;padding:8px 10px;}
.rest-coach-hide:hover{color:var(--text);border-color:var(--muted);}
.rest-coach-hide:focus-visible{outline:2px solid var(--warn);outline-offset:2px;}
@media (prefers-reduced-motion: reduce){.rest-coach{transition:none;}}
.recovery-honest{color:var(--text);font:700 13px/1.4 var(--font-body);margin-bottom:12px;}
.recovery-dur-label{display:block;font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;margin-bottom:8px;}
.recovery-dur-row{display:flex;align-items:center;gap:10px;}
.recovery-dur-input{flex:1 1 auto;min-width:0;min-height:44px;appearance:textfield;background:rgba(255,255,255,.06);border:1px solid var(--line-2);border-radius:12px;color:var(--text);font:800 20px/1 var(--font-mono);padding:12px;outline:none;}
.recovery-dur-input:focus-visible{outline:2px solid var(--warn);outline-offset:2px;border-color:var(--cy);}
.recovery-dur-unit{color:var(--muted);font:700 12px var(--font-mono);text-transform:uppercase;letter-spacing:.08em;white-space:nowrap;}

/* RPE Slider */
.rpe-slider{padding:14px;margin-bottom:14px;}
.rpe-slider .lab{font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;margin-bottom:12px;}
.rpe-track{position:relative;}
/* WCAG 2.5.5 — runnable-track technique on the REAL effort slider (#rpeInput lives in
   .rpe-slider > .slider > input; the old .rpe-track selectors above match no element in the
   DOM, so the slider had shipped as a bare 129x16 native range). The input box is grown to a
   44px-tall hit target while the *visible* track stays thin (8px) by painting the background
   on ::-slider-runnable-track / ::-moz-range-track instead of the input itself; the thumb is
   nudged up (margin-top) to stay centred on the thin track. */
.rpe-slider .slider input{width:100%;-webkit-appearance:none;appearance:none;background:transparent;height:44px;border-radius:12px;outline:none;cursor:pointer;margin:0;}
.rpe-slider .slider input::-webkit-slider-runnable-track{height:8px;border-radius:12px;background:rgba(255,255,255,.07);}
.rpe-slider .slider input::-moz-range-track{height:8px;border-radius:12px;background:rgba(255,255,255,.07);}
.rpe-slider .slider input::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:24px;height:24px;margin-top:-8px;border-radius:12px;background:var(--cy);cursor:pointer;box-shadow:none;}
.rpe-slider .slider input::-moz-range-thumb{width:24px;height:24px;border-radius:12px;background:var(--cy);cursor:pointer;border:0;box-shadow:none;}
.effort-guide{margin-top:10px;color:var(--text);font:700 12px/1.35 var(--font-body);}
.rpe-ticks{display:flex;justify-content:space-between;margin-top:8px;padding:0 8px;font:600 10px var(--font-mono);color:var(--muted);}
.rpe-warn{font-size:12px;color:var(--warn);margin-top:10px;font-weight:700;display:none;align-items:center;gap:6px;}
.rpe-warn.show{display:flex;}

/* THE PREMIUM ACTION BUTTON */
.log{width:100%;border:none;border-radius:16px;padding:18px;font:800 20px/1 var(--font-display);
  letter-spacing:0.04em;cursor:pointer;color:#000;
  background: linear-gradient(135deg, var(--cy), var(--cy-deep));
  box-shadow: 0 4px 15px rgba(224,178,113,0.4);
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.2s;
  position: relative; overflow: hidden;
}
.log::after { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(rgba(255,255,255,0.2), transparent); transform: rotate(45deg); transition: 0.3s; pointer-events: none; opacity: 0; }
.log:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(224,178,113,0.5); filter: brightness(1.1); }
.log:hover::after { opacity: 1; top: -100%; left: -100%; }
.log:active{transform: translateY(2px); box-shadow: 0 2px 10px rgba(224,178,113,0.3);}
/* anti-cheat slice 3: honest "not completed" — muted secondary, never competes with LOG SET */
.warmup-toggle{width:auto;margin:0 0 8px;align-self:center;border:1px solid var(--line-2);border-radius:999px;padding:0 18px;min-height:44px;font:700 12px var(--font-mono);letter-spacing:.06em;cursor:pointer;background:transparent;color:var(--muted);}
.warmup-toggle:hover{color:var(--text);border-color:var(--muted);}
.warmup-toggle.on{color:var(--cy);border-color:var(--cy);background:rgba(224,178,113,.08);}
.miss{width:100%;margin-top:8px;border:1px solid var(--line-2);border-radius:14px;padding:13px;font:700 13px/1 var(--font-mono);letter-spacing:0.04em;cursor:pointer;background:transparent;color:var(--muted);}
.miss:hover{color:var(--text);border-color:var(--muted);}
.miss:active{transform:translateY(1px);}

/* Skip button — first-class logged event, honest and neutral (not punishing).
   Equal visual weight to LOG SET but neutral accent: skipping a set you can't do
   is the correct, respected move — same status as logging one you completed.
   (The old .program-mode-bar toggle is gone — the Program Mode card is the one switch.) */
.skip{width:100%;margin-top:8px;border:1px solid var(--line-2);border-radius:16px;padding:16px;font:800 14px/1 var(--font-mono);letter-spacing:0.06em;cursor:pointer;
  background:rgba(255,255,255,.04);color:var(--text);display:none;transition:border-color .18s ease,background .18s ease;}
.skip:hover{border-color:var(--muted);background:rgba(255,255,255,.07);}
.skip:active{transform:translateY(1px);}
.skip:focus-visible{outline:2px solid var(--cy);outline-offset:3px;}

/* one-level undo — always visible after a log (free-mode pattern), ghost weight so
   LOG SET stays the System-1 primary; >=44px hit area per tap-sovereignty */
.undo-set{width:100%;min-height:44px;margin-top:8px;background:transparent;color:var(--text);
  border:1px solid var(--line);border-radius:12px;padding:12px;font:700 13px/1 var(--font-mono);
  letter-spacing:0.06em;cursor:pointer;transition:border-color .18s ease,color .18s ease;}
.undo-set:hover:not(:disabled){border-color:var(--cy);color:var(--cy);}
.undo-set:disabled{opacity:.35;cursor:not-allowed;}
.undo-set:focus-visible{outline:2px solid var(--cy);outline-offset:3px;}

/* Program Mode visual language — sealed prescribed values vs alive RPE input */
/* pm-locked: prescribed weight/reps read as sealed, not merely disabled-gray.
   Solid border (not dashed), muted background, and a "LOCKED" micro-stamp via ::after
   so a glance mid-set immediately knows the value can't be fudged. */
.num.pm-locked{border:1px solid var(--line-2);background:rgba(255,255,255,.02);box-shadow:inset 0 0 0 1px rgba(255,255,255,.03);}
.num.pm-locked .v{color:var(--muted);}
.num.pm-locked::after{content:"LOCKED";display:block;font:700 7px/1 var(--font-mono);letter-spacing:.12em;color:var(--faint);margin-top:4px;}
.load-entry.pm-locked input[readonly]{border-style:solid;border-color:var(--line-2);background:rgba(255,255,255,.02);opacity:.85;}
.load-entry.pm-locked label::after{content:" · sealed";color:var(--faint);font-weight:400;letter-spacing:.04em;}

/* pm-alive: RPE is the one editable input — visually obvious by contrast.
   Brighter accent border, subtle inner glow, and "your call" micro-label. */
.num.pm-alive{border:1px solid var(--cy);box-shadow:0 0 12px rgba(224,178,113,.15);}
.rpe-slider.pm-alive{border:1px solid rgba(224,178,113,.3);box-shadow:0 0 16px rgba(224,178,113,.08);}
.rpe-slider.pm-alive .slider input{background:rgba(224,178,113,.15);}
.rpe-slider.pm-alive .slider input::-webkit-slider-thumb{box-shadow:0 0 8px rgba(224,178,113,.4);}
.rpe-slider.pm-alive .slider input::-moz-range-thumb{box-shadow:0 0 8px rgba(224,178,113,.4);}

/* Skip-rate readout chip — System 1 glance in summary, System 2 detail on expand.
   Follows the streak chip pattern: earned, static, no animation. */
.prog .skip-rate{justify-self:end;}
.prog .skip-rate-summary{font:700 11px var(--font-mono);color:var(--muted);letter-spacing:.04em;
  border:1px solid var(--line-2);border-radius:999px;padding:3px 10px;background:rgba(255,255,255,.03);
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;min-height:44px;}
.prog .skip-rate-summary::-webkit-details-marker{display:none;}
.prog .skip-rate[open] .skip-rate-summary{border-color:var(--cy);color:var(--cy);}
.prog .skip-rate-detail{font:600 10px/1.4 var(--font-body);color:var(--muted);padding:6px 10px 2px 0;text-align:right;}
.skip-lift{margin-top:2px;}
.prog .skip-rate[hidden]{display:none;}

/* Training History overlay — full-page read-only view */
.history-overlay{position:absolute;inset:0;z-index:50;background:var(--bg);overflow-y:auto;-webkit-overflow-scrolling:touch;}
.history-overlay[hidden]{display:none;}
.history-header{position:sticky;top:0;z-index:1;background:var(--bg-2);border-bottom:1px solid var(--line);padding:14px 18px;display:flex;align-items:center;justify-content:space-between;}
.history-header h2{margin:0;font:700 20px var(--font-display);letter-spacing:-.01em;color:var(--text);}
.history-close{background:none;border:0;color:var(--muted);font-size:24px;cursor:pointer;line-height:1;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;border-radius:8px;}
.history-close:active{transform:scale(.96);}
.history-close:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}
.history-body{padding:12px 16px 80px;}
.history-empty{text-align:center;padding:60px 20px;color:var(--muted);font:600 14px/1.5 var(--font-body);}
.history-session{background:var(--card);backdrop-filter:blur(16px) saturate(150%);-webkit-backdrop-filter:blur(16px) saturate(150%);border:1px solid var(--line);border-radius:12px;margin-bottom:8px;overflow:hidden;}
.history-session-summary{display:grid;grid-template-columns:auto 1fr auto;gap:8px;align-items:center;padding:14px 16px;cursor:pointer;list-style:none;}
.history-session-summary::-webkit-details-marker{display:none;}
.history-session-summary::after{content:"\25BC";font-size:8px;color:var(--faint);transition:transform .2s;}
.history-session[open] .history-session-summary::after{transform:rotate(180deg);}
.history-date{font:700 11px var(--font-mono);color:var(--cy);letter-spacing:.04em;white-space:nowrap;}
.history-lifts{font:600 13px/1.3 var(--font-body);color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.history-top{font:700 12px var(--font-mono);color:var(--muted);white-space:nowrap;text-align:right;}
.history-count{grid-column:2;font:600 10px var(--font-mono);color:var(--faint);letter-spacing:.04em;}
.history-sets{padding:4px 16px 14px;border-top:1px solid var(--line);}
.history-set{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid rgba(255,255,255,.04);}
.history-set:last-child{border-bottom:0;}
.history-set-label{font:700 8px var(--font-mono);letter-spacing:.1em;padding:2px 6px;border-radius:4px;flex:none;}
.history-set-done .history-set-label{background:rgba(13,148,136,.15);color:var(--good);}
.history-set-skip .history-set-label{background:rgba(255,255,255,.06);color:var(--muted);}
.history-set-miss .history-set-label{background:rgba(255,93,115,.12);color:var(--atk-gravity);}
.history-set-recovered .history-set-label{background:rgba(224,178,113,.1);color:var(--cy);}
.history-set-detail{font:600 12px/1.3 var(--font-body);color:var(--text);}
.history-set-skip .history-set-detail,.history-set-miss .history-set-detail{color:var(--muted);}
.history-recovered-header{font:700 11px var(--font-mono);color:var(--cy);letter-spacing:.08em;text-transform:uppercase;margin:16px 0 8px;padding-top:12px;border-top:1px solid var(--line);}
/* pinned to the bottom edge -> its buttons would fall under the home indicator without the inset */
.history-footer{position:sticky;bottom:0;z-index:1;background:var(--bg-2);border-top:1px solid var(--line);padding:12px 16px calc(12px + env(safe-area-inset-bottom));display:flex;gap:8px;}
.history-footer .sharebtn{flex:1;}
/* WCAG 2.5.5: the history link was a 161x14 inline hit box in the plan-modal footer.
   inline-flex + min-height:44px grows the tap height; visual text size is unchanged. */
.history-link{color:var(--cy);text-decoration:none;font:700 11px var(--font-mono);letter-spacing:.04em;display:inline-flex;align-items:center;min-height:44px;}
.history-link:hover{text-decoration:underline;}
.saved-note-link{color:var(--cy);text-decoration:underline;cursor:pointer;}

/* The old "Cognitive Focus Trap" blurred and disabled the entire logging surface
   (every .blur-target) whenever the Atlas HUD or Training Read opened, and had no
   reliable removal path, so the working UI got stuck blurred. Removed: opening a
   read-out or HUD must never blur or inert the sets a lifter is mid-way through. */
/* System 2 Analytical Drawer */
.system-2-drawer {
  display: none;
  background: rgba(5, 10, 16, 0.95);
  border: 1px solid var(--cy);
  border-radius:12px;
  padding: 12px;
  margin: 12px var(--pad) 0;
  box-shadow: none;
  font: 600 11px ui-monospace, monospace;
  color: var(--muted);
}
.system-2-drawer.show {
  display: block;
  animation: slideDown 0.3s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes slideDown {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}
.system-2-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.s2-metric { display: flex; flex-direction: column; margin-bottom: 6px; }
.s2-metric .val { font-size: 14px; color: var(--cy); font-weight: 800; }
.s2-metric .val.warn { color: var(--warn); text-shadow: 0 0 8px rgba(239,68,68,0.5); }
.rest{display:flex;gap:8px;}
.rest button{flex:1;min-height:44px;border:1px solid var(--line);background:transparent;color:var(--text);border-radius:12px;padding:13px 0;font:700 14px/1 inherit;cursor:pointer;}
.rest button:active{transform:scale(.96);background:rgba(224,178,113,.08);}

/* rest countdown — auto-starts after a logged set so log -> rest -> next set is unbroken */
.restcd{display:none;align-items:center;gap:12px;position:relative;overflow:hidden;border-color:rgba(224,178,113,.4);
  padding:14px 16px;box-shadow:none;}
.restcd.show{display:flex;}
/* Temperature doctrine (REDESIGN_PLAN principle 5): rest is literal cooldown —
   the hot gold surface crossfades toward teal as the timer runs. Driven by the
   --cooldown custom property (0 at rest start -> 1 at done); opacity-only =
   compositor-safe; digits warm gold -> teal via color-mix (gold fallback kept). */
.restcd::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;border-radius:inherit;background:linear-gradient(135deg,rgba(45,212,191,.18),rgba(13,148,136,.10));opacity:var(--cooldown,0);transition:opacity .9s linear;}
.restcd>*{position:relative;z-index:1;}
.restcd .t{font:800 30px/1 var(--font-mono);font-variant-numeric:tabular-nums;color:var(--cy);color:color-mix(in srgb, #2dd4bf calc(var(--cooldown,0)*100%), var(--cy));min-width:92px;letter-spacing:.02em;}
.restcd .mid{flex:1;min-width:0;}
.restcd .lab{font:700 10px var(--font-mono);letter-spacing:.1em;color:var(--muted);text-transform:uppercase;}
.restcd .next{margin-top:3px;font:700 13px/1.25 var(--font-body);color:var(--text);}
.restcd .next-load{margin-top:2px;font:600 12px/1.3 var(--font-body);color:var(--muted);}
.restcd .barwrap{height:6px;border-radius:12px;background:rgba(255,255,255,.08);overflow:hidden;margin-top:7px;}
.restcd .barwrap i{display:block;height:100%;width:100%;background:var(--cy);transform-origin:left;transform:scaleX(1);transition:transform 1s linear;}
@media (prefers-reduced-motion: reduce){
  .restcd::before{transition:none;}
  .restcd .barwrap i{transition:none;}
}
.restcd .skip{border:1px solid var(--line);background:transparent;color:var(--text);border-radius:12px;padding:9px 14px;font:700 12px inherit;cursor:pointer;}

/* compact session strip — was a whole column, now one line */
.strip{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
.strip[hidden]{display:none;}
.stat{padding:10px;text-align:center;}
.stat .v{font:800 18px/1;}
.stat .k{font:600 9px var(--font-mono);letter-spacing:.08em;color:var(--muted);text-transform:uppercase;margin-top:4px;}

/* everything else: collapsed, deferred, out of the way */
details{overflow:hidden;}
details summary{list-style:none;cursor:pointer;padding:14px 16px;display:flex;justify-content:space-between;align-items:center;
  font-weight:600;font-size:14px;}
details summary::-webkit-details-marker{display:none;}
details summary .c{color:var(--muted);font-size:13px;transition:.2s;}
details[open] summary .c{transform:rotate(180deg);}
details .inner{padding:0 16px 16px;color:var(--muted);font-size:13.5px;}
details .inner .swap-hint{font-weight:700;color:var(--text);line-height:1.35;}
details .inner .swap{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px;}
details .inner .swap button{min-height:44px;border:1px solid var(--line);background:transparent;color:var(--text);border-radius:12px;padding:10px;font:600 13px inherit;cursor:pointer;text-align:left;}
.swap-card{border-color:rgba(224,178,113,.30);background:linear-gradient(135deg,rgba(224,178,113,.08),rgba(13,148,136,.05)),var(--card);}
.swap-card summary span:first-child{color:var(--text);}
.swap-card .swap button:active{transform:scale(.98);}
/* the set-logged confirmation must land ABOVE the home indicator, not behind it */
.toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom));transform:translateX(-50%) translateY(20px);opacity:0;
  background:var(--good);color:#04140a;font-weight:700;padding:12px 20px;border-radius:12px;transition:.3s;pointer-events:none;z-index:30;}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

/* PLAN reference — a bottom sheet that OVERLAYS the log (never navigates away).
   Logging state lives in JS module vars and is untouched while the sheet is open,
   so dismissing returns the user to the exact set they were mid-logging. */
.backdrop{position:absolute;inset:0;background:rgba(2,4,8,.6);opacity:0;visibility:hidden;
  transition:.25s;z-index:20;pointer-events:none;}
.backdrop.show{opacity:1;visibility:visible;pointer-events:auto;}
.sheet{position:absolute;left:0;right:0;bottom:0;z-index:25;background:var(--sheet-bg);border:1px solid var(--line);
  border-bottom:0;border-radius:12px;transform:translateY(102%);transition:transform .28s cubic-bezier(.2,.8,.2,1);
  max-height:82%;display:flex;flex-direction:column;box-shadow:none;}
.sheet.show{transform:translateY(0);}
.sheet .grab{width:38px;height:4px;border-radius:99px;background:rgba(255,255,255,.18);margin:10px auto 4px;}
.sheet .head{padding:6px 18px 12px;display:flex;align-items:baseline;justify-content:space-between;border-bottom:1px solid var(--line);}
.sheet .head h2{margin:0;font:700 18px var(--font-display);letter-spacing:-.01em;}
.sheet .head .day{font:700 11px var(--font-mono);letter-spacing:.1em;color:var(--cy);text-transform:uppercase;}
.sheet .head .close{background:none;border:0;color:var(--muted);font-size:20px;cursor:pointer;line-height:1;}
/* WCAG 2.5.5: the plan-modal close shipped at 28x22 — a one-thumb mid-session action.
   inline-flex + 44px min box grows the hit target; flex-shrink:0 holds it in the .head row. */
#planClose{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;flex-shrink:0;padding:0;}
.sheet .list{overflow-y:auto;padding:8px 12px 18px;}
.plan-row{display:flex;align-items:center;gap:12px;padding:12px 12px;border-radius:12px;cursor:pointer;border:1px solid transparent;}
.plan-row:active{background:rgba(255,255,255,.03);}
.plan-row .idx{width:24px;height:24px;flex:0 0 24px;border-radius:12px;border:1px solid var(--line);display:flex;margin-right:12px;
  align-items:center;justify-content:center;font:700 11px var(--font-mono);color:var(--muted);}
.plan-row .meta{flex:1;min-width:0;}
.plan-row .meta .nm{font-weight:600;font-size:15px;}
.plan-row .meta .sch{color:var(--muted);font-size:12.5px;margin-top:1px;}
.plan-row.done .idx{background:var(--good);border-color:var(--good);color:#04140a;}
.plan-row.done .meta .nm{color:var(--muted);text-decoration:line-through;}
.plan-row.cur{background:rgba(224,178,113,.08);border-color:var(--cy);}
.plan-row.cur .idx{background:var(--cy);border-color:var(--cy);color:#000;}
.plan-row.cur .meta .nm{color:var(--text);}
.plan-row .tag{font:700 9px var(--font-mono);letter-spacing:.1em;color:var(--cy);text-transform:uppercase;}
.plan-thumb{width:40px;height:40px;margin-right:12px;background:var(--glass-bg);border-radius:6px;display:flex;align-items:center;justify-content:center;overflow:hidden;}
.sfr-tag{color:var(--good);font-size:11px;}
.sheet .foot{padding:10px 18px 16px;color:var(--muted);font-size:12px;border-top:1px solid var(--line);text-align:center;}

/* ---- session-end actions — offer the recap card + honest receipt. The mid-set
   weakness radar / avatar / progression HUD were removed (focused-cockpit refactor);
   the radar lives in the Weak-Link report. */
.session-actions{margin:4px var(--pad) 4px;display:flex;flex-direction:column;gap:8px;}
.session-actions .sharebtn{width:100%;min-height:44px;padding:12px;border:1px solid var(--line);border-radius:12px;
  background:rgba(255,255,255,.03);color:var(--muted);font:700 12px/1 var(--font-mono);letter-spacing:.12em;cursor:pointer;
  transition:border-color .15s,color .15s,background .15s;}
.session-actions .sharebtn:hover{border-color:var(--line-2);color:var(--text);}

/* Feature 1 — inline "Last time" from the real sessions store. Quieter than the
   demo-cache PR line above it; the number-to-beat glances, never shouts. */
.now .last-session{margin-top:5px;font:600 12px var(--font-mono);color:var(--muted);letter-spacing:.02em;}
.now .last-session b{color:var(--cy);}
.now .last-session.is-empty{color:var(--faint);}

/* Feature 2 — end-of-session summary card. Reuses the cockpit's glass-card
   language (--card / --line / --cy), so it reads as part of the same surface. */
.session-summary{margin:6px var(--pad) 4px;border:1px solid rgba(224,178,113,.28);border-radius:14px;
  background:var(--card);padding:14px 16px;box-shadow:var(--glass-shadow);}
.session-summary .ss-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px;}
.session-summary .ss-title{font:700 12px/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--cy);}
.session-summary .ss-dismiss{appearance:none;-webkit-appearance:none;border:1px solid var(--line);background:transparent;
  color:var(--muted);min-width:44px;min-height:44px;border-radius:10px;cursor:pointer;font-size:16px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;transition:border-color .15s,color .15s;}
.session-summary .ss-dismiss:hover{border-color:var(--line-2);color:var(--text);}
.session-summary .ss-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;}
.session-summary .ss-stat{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:9px 10px;min-width:0;}
.session-summary .ss-stat .ss-v{font:700 18px/1.1 var(--font-display);color:var(--text);overflow-wrap:anywhere;}
.session-summary .ss-stat .ss-k{margin-top:3px;font:600 10px/1.2 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.session-summary .ss-highlight{margin-top:10px;font:600 12px/1.4 var(--font-body);color:var(--good);}
.session-summary .ss-empty{font:600 12px/1.4 var(--font-body);color:var(--muted);}
/* Recap trend fold (cycle 33): the "am I progressing?" answer. Colour is the ONLY
   thing that reacts to direction — the numbers and the sparkline are the engine's
   own points, unsmoothed. A flat trend gets muted text, not a fake win colour. */
.session-summary .ss-trend{margin-top:12px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--card);}
.session-summary .ss-trend-head{font:600 10px/1.2 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.session-summary .ss-spark{display:block;margin:8px 0 6px;color:var(--muted);}
.session-summary .ss-trend[data-trend="up"] .ss-spark{color:var(--good);}
.session-summary .ss-trend[data-trend="down"] .ss-spark{color:var(--warn,var(--muted));}
.session-summary .ss-trend-num{font:700 20px/1.1 var(--font-display);color:var(--text);overflow-wrap:anywhere;}
.session-summary .ss-trend[data-trend="up"] .ss-trend-num{color:var(--good);}
.session-summary .ss-trend-note{margin-top:4px;font:500 11px/1.4 var(--font-body);color:var(--muted);}
/* Next-session hook (cycle 34): the recap ends by naming what is already queued.
   Warm accent is the live-session signal and stays OFF this cold surface — the
   hook is an invitation, not an active workout. */
.session-summary .ss-next{margin-top:12px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:var(--card);}
.session-summary .ss-next-head{font:600 10px/1.2 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.session-summary .ss-next-title{margin-top:4px;font:700 18px/1.15 var(--font-display);color:var(--text);overflow-wrap:anywhere;}
.session-summary .ss-next-line{margin-top:6px;font:600 13px/1.45 var(--font-body);color:var(--text);overflow-wrap:anywhere;}
.session-summary .ss-next-note{margin-top:4px;font:500 11px/1.4 var(--font-body);color:var(--muted);}
@media (max-width:400px){ .session-summary .ss-stats{grid-template-columns:repeat(2,minmax(0,1fr));} }

/* session end: the share loop offers itself. Static accent is the base;
   the pulse only runs for motion-tolerant users. */
.session-actions .sharebtn.session-end{border-color:var(--cy);background:rgba(224,178,113,.14);color:var(--text);}
@media (prefers-reduced-motion: no-preference){
  .session-actions .sharebtn.session-end{animation:shareNudge 1.6s ease-in-out 3;}
  @keyframes shareNudge{0%,100%{transform:scale(1);}50%{transform:scale(1.03);}}
}



/* Scoped highlight motion cards styling */
.now, .num, .loop-card, .next-action-card, .radar, .load-entry, .rpe-slider {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  --gym-motion-x: 0;
  --gym-motion-y: 0;
  transition: border-color .18s ease, transform .18s ease;
}
.now > *, .num > *, .loop-card > *, .next-action-card > *, .radar > *, .load-entry > *, .rpe-slider > * {
  position: relative;
  z-index: 1;
}
.now::after, .num::after, .loop-card::after, .next-action-card::after, .radar::after, .load-entry::after, .rpe-slider::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at calc(50% + (var(--gym-motion-x) * 18%)) calc(50% + (var(--gym-motion-y) * 18%)), rgba(224,178,113,.12), transparent 58%);
  pointer-events: none;
  opacity: 0;
  z-index: 0;
  border-radius: inherit;
  transition: opacity .18s ease;
}
@media (prefers-reduced-motion: no-preference) {
  .now[data-gym-motion-active="true"], .num[data-gym-motion-active="true"], .loop-card[data-gym-motion-active="true"], .next-action-card[data-gym-motion-active="true"], .radar[data-gym-motion-active="true"], .load-entry[data-gym-motion-active="true"], .rpe-slider[data-gym-motion-active="true"],
  .load-entry:focus-within, .rpe-slider:focus-within {
    transform: translateY(-2px);
    box-shadow: 0 14px 28px rgba(0,0,0,.38), 0 0 0 1px rgba(224,178,113,.16);
  }
  .now[data-gym-motion-active="true"]::after, .num[data-gym-motion-active="true"]::after, .loop-card[data-gym-motion-active="true"]::after, .next-action-card[data-gym-motion-active="true"]::after, .radar[data-gym-motion-active="true"]::after, .load-entry[data-gym-motion-active="true"]::after, .rpe-slider[data-gym-motion-active="true"]::after,
  .load-entry:focus-within::after, .rpe-slider:focus-within::after {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .now, .num, .loop-card, .next-action-card, .radar, .load-entry, .rpe-slider {
    transform: none !important;
    transition: none !important;
  }
  .now::after, .num::after, .loop-card::after, .next-action-card::after, .radar::after, .load-entry::after, .rpe-slider::after {
    display: none !important;
  }
}

/* Locked voice-logging paid preview (monetization surface; twin of free_mode's).
   Inert by contract: gym_voice_preview_contract_test.js. Muted/dim keeps it
   outside the hot-gold state vocabulary (it is a non-choice, not chrome). */
.voice-preview{margin-top:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.voice-preview-btn{border:1px dashed var(--line-2);background:transparent;color:var(--muted);padding:10px 16px;font:700 13px var(--font-display);border-radius:10px;cursor:not-allowed;opacity:.75;}
.voice-preview-tag{font:700 10px var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);}
.voice-preview-info{flex-basis:100%;color:var(--muted);font-size:12.5px;}
.voice-preview-info summary{cursor:pointer;min-height:34px;display:inline-flex;align-items:center;}

/* Tomorrow preview — the session-end return hook (blueprint 1.7 Zeigarnik).
   Rendered into the share moment; honest fallback when no plan is loaded. */
.tomorrow-preview{margin:10px 0 0;font:700 12px var(--font-mono);letter-spacing:.06em;color:var(--cy);text-align:center;}

/* === NEW COCKPIT GRID AND SLICE COMPONENTS === */

/* Mobile: lead with what you're lifting. Below the desktop grid, .body stacks by
   source order, which buried the exercise + target under the enter-load hint, the
   plan card, and the Program Mode toggle. Pull the progress bar and the exercise
   hero to the top so the first thing on screen is the set you're about to do.
   Desktop is unaffected — grid-area placement (below) overrides flex order. */
@media (max-width: 1023px) {
  .prog { order: -1; }
  .hero-block { order: -1; }
  /* The mode switcher is the primary organizing structure: it leads the cockpit,
     above the hero and the progress bar. */
  .gym-mode-switch { order: -2; }
  /* The session list sits directly under the mode tabs (tie broken by DOM order, so the
     tabs stay first) — the compact strip is the glance; its full rows stay collapsed. */
  .gym-session-list { order: -2; }
}

@media (min-width: 1024px) {
  .phone {
    max-width: none;
    width: 100vw;
    padding: 24px;
  }
  
  .body {
    display: grid;
    grid-template-columns: minmax(300px, 1fr) minmax(340px, 1.2fr) minmax(300px, 1fr);
    grid-template-rows: repeat(13, max-content) 1fr;
    grid-template-areas:
      "mode  mode  mode"
      "prog  prog  prog"
      "hero  nxtc  rest"
      "hero  auto  recd"
      "slist loop  strp"
      "slist pmode sact"
      "slist nums  sact"
      "now   swip  sact"
      "now   load  sact"
      "upnx  rpes  sact"
      "slog  logb  sact"
      "swap  miss  sact"
      ".     undo  sact"
      ".     voic  sact";
    align-items: start;
    gap: 14px 24px;
    max-width: 1440px;
    margin: 0 auto;
  }

  .gym-mode-switch { grid-area: mode; }
  /* Desktop side rail beside the cockpit: the full rows are always visible (there is vertical
     space), and the collapse affordances (caret + one-line preview) are dropped — it is not a
     collapsible strip here, it is the rail. */
  .gym-session-list { grid-area: slist; align-self: start; }
  .gym-session-list .gsl-rows { display: flex; }
  .gym-session-list .gsl-caret,
  .gym-session-list .gsl-preview { display: none; }
  .gym-session-list .gsl-strip { cursor: default; }
  .prog { grid-area: prog; }
  .hero-block { grid-area: hero; }
  .now { grid-area: now; }
  .upnext { grid-area: upnx; }
  #swapDetails { grid-area: swap; }

  .next-action-card { grid-area: nxtc; }
  .autoreg-card { grid-area: auto; }
  .loop-card { grid-area: loop; }
  .program-mode-card { grid-area: pmode; }
  .nums { grid-area: nums; }
  .swipe-scrubber { grid-area: swip; }
  .load-entry { grid-area: load; }
  .rpe-slider { grid-area: rpes; }
  .log { grid-area: logb; }
  .miss { grid-area: miss; }
  .undo-set { grid-area: undo; }
  .voice-preview { grid-area: voic; }

  .rest { grid-area: rest; }
  .restcd { grid-area: recd; }
  .strip { grid-area: strp; }
  .session-actions { grid-area: sact; align-self: start; }
  #sessionLogDetails { grid-area: slog; }
  .gym-earned-upsell { grid-column: 1 / -1; }
  .medical-disclaimer { grid-column: 1 / -1; grid-row: 15; }
}

/* EARNED PREVIEW (operator design law 2026-07-30): revealed after the 4th
   completed working set, once per session. Quiet card, single link, honest
   dismiss. Lean cockpit mode keeps its single-focal-action promise — the
   panel never renders there. */
.gym-earned-upsell{position:relative; margin:10px 0 0; padding:12px 40px 12px 14px; border:1px solid var(--line-strong); border-radius:12px; background:var(--surface);}
.gym-earned-upsell .geu-kicker{margin:0 0 4px; font-family:var(--mono); font-size:0.66rem; letter-spacing:0.08em; text-transform:uppercase; color:var(--teal-ink);}
.gym-earned-upsell .geu-body{margin:0 0 6px; font-size:0.82rem; line-height:1.5; color:var(--muted);}
.gym-earned-upsell .geu-link{font-size:0.85rem; font-weight:700; color:var(--action-ink); text-decoration:none;}
.gym-earned-upsell .geu-link:hover{text-decoration:underline;}
.gym-earned-upsell .geu-close{position:absolute; top:2px; right:2px; min-width:44px; min-height:44px; border:0; background:transparent; color:var(--muted); font-size:1.1rem; cursor:pointer; border-radius:10px;}
.gym-earned-upsell .geu-close:hover{color:var(--text);}
body.cockpit-lean .gym-earned-upsell{ display:none !important; }

.hero-block {
  margin-top: 12px;
  margin-bottom: 22px;
}
.hero-block h1 {
  margin: 0 0 12px;
  font: 800 27px/1.08 var(--font-display);
  color: var(--text);
  letter-spacing: -0.02em;
}
/* Live session layer (gym_live_layer.js): pace chip, loud pre-lift PR reach,
   readiness-reactive hero tint. Observational only — engines stay the source. */
.gym-live-pace{margin:8px var(--pad) 0;font:600 11px/1.4 var(--font-mono);letter-spacing:.03em;color:var(--muted);}
.gym-live-pace[hidden]{display:none;}
.gym-live-pace.is-over{color:var(--cy);}
.pr-reach{margin:0 0 10px;padding:10px 14px;border:1px solid var(--good);border-radius:12px;background:var(--cy-soft);font:600 12px/1.45 var(--font-body);color:var(--text);}
.pr-reach[hidden]{display:none;}
.pr-reach .pr-reach-tag{font:800 12px var(--font-mono);letter-spacing:.1em;color:var(--good);}
@media (prefers-reduced-motion:no-preference){
  .pr-reach{animation:prReachIn .35s ease-out;}
  @keyframes prReachIn{from{opacity:0;transform:translateY(-4px);}to{opacity:1;transform:none;}}
}
.hero-block.live-reach #nextTargetValue .value,
.hero-block.live-reach .next-target-display .value{color:var(--good);}
.hero-block.live-ease .next-target-display .value{color:var(--cy);}

/* Training Read deep charts (gym_deep_charts.js): real-data charts in the drawer.
   Locked state blurs the lifter's OWN charts behind an honest unlock card. */
.gdc{position:relative;margin-top:12px;border-top:1px solid var(--line);padding-top:10px;}
.gdc[hidden]{display:none;}
.gdc-wrap{display:grid;gap:10px;}
.gdc-card{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:10px 12px;color:var(--cy);}
.gdc-title{display:block;font:700 11px var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:6px;}
.gdc-svg{display:block;width:100%;height:auto;}
.gdc-summary{display:block;margin-top:6px;font:600 11px/1.4 var(--font-mono);letter-spacing:.02em;color:var(--muted);}
.gdc-empty{font:600 12px/1.45 var(--font-body);color:var(--muted);}
.gdc-blur{filter:blur(7px);pointer-events:none;user-select:none;}
.gdc-lock{position:absolute;inset:10px 0 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;padding:12px;}
.gdc-lock-title{font:800 14px var(--font-display);color:var(--text);}
.gdc-lock-copy{font:600 11px/1.45 var(--font-body);color:var(--muted);max-width:32ch;}
.gdc-cta{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 16px;margin-top:2px;border:1px solid var(--cy);border-radius:10px;background:var(--cy-soft);color:var(--cy);font:700 12px var(--font-mono);letter-spacing:.04em;text-decoration:none;}
.gdc-cta:focus-visible{outline:2px solid var(--cy);outline-offset:3px;}

/* 4-set paid-ladder preview (gym_ladder_preview.js): what today's real sets are
   worth on each paid rung. Locked rungs blur the lifter's OWN numbers — same
   honest-preview law as .gdc-blur above, never a mock. */
.glp{position:relative;margin-top:12px;border-top:1px solid var(--line);padding-top:10px;}
.glp[hidden]{display:none;}
.glp-wrap{display:grid;gap:10px;}
.glp-title{display:block;font:700 11px var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}
.glp-rung{position:relative;border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:10px 12px;}
.glp-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;}
.glp-name{font:800 14px var(--font-display);color:var(--text);}
.glp-price{font:700 12px var(--font-mono);letter-spacing:.03em;color:var(--cy);}
.glp-body{display:grid;gap:6px;margin-top:8px;}
.glp-line{margin:0;display:flex;flex-direction:column;gap:1px;}
.glp-val{font:800 15px var(--font-mono);letter-spacing:.02em;color:var(--cy);}
.glp-cap{font:600 11px/1.4 var(--font-body);color:var(--muted);}
.glp-blur{filter:blur(7px);pointer-events:none;user-select:none;}
.glp-lock{position:absolute;inset:34px 0 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;text-align:center;padding:10px;}
/* a rung with nothing real to hide carries a note, not an overlay */
.glp-lock-static{position:static;inset:auto;padding:8px 0 0;}
.glp-lock-copy{font:600 11px/1.45 var(--font-body);color:var(--muted);max-width:32ch;}
.glp-soon{font:600 11px/1.45 var(--font-mono);letter-spacing:.03em;color:var(--muted);}
.glp-cta{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 16px;border:1px solid var(--cy);border-radius:10px;background:var(--cy-soft);color:var(--cy);font:700 12px var(--font-mono);letter-spacing:.04em;text-decoration:none;}
.glp-cta:focus-visible{outline:2px solid var(--cy);outline-offset:3px;}

/* Hero strength trend sparkline: quiet, theme-token colors, honest-hidden default. */
.hero-trend{display:flex;align-items:center;gap:10px;margin-top:10px;color:var(--cy);}
.hero-trend[hidden]{display:none;}
.hero-trend-svg{width:120px;height:28px;flex:none;}
.hero-trend.is-up{color:var(--good);}
.hero-trend-text{font:600 11px/1.35 var(--font-mono);letter-spacing:.03em;color:var(--muted);}

.next-target-display {
  margin: 0;
  padding: 0;
  background: transparent;
  border: none;
}
.next-target-display .eyebrow {
  font: 700 12px var(--font-mono);
  letter-spacing: 0.12em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 6px;
}
/* Strength level: one dim mono line under the target. Density, not a panel — the
   cockpit was deliberately stripped, so this must not read as another card. */
.strength-level {
  font: 600 12px var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-top: 6px;
}
.strength-level[hidden] { display: none; }
.next-target-display .value {
  font: 800 64px/1 var(--font-display);
  color: var(--cy);
  letter-spacing: -0.03em;
}
.next-target-display .value .u {
  font-size: 28px;
  color: var(--cy-deep);
  font-weight: 700;
}

.medical-disclaimer {
  font: 500 11px/1.4 var(--font-body);
  color: var(--muted);
  text-align: center;
  padding: 16px;
  margin-top: 24px;
  border-top: 1px solid var(--line);
  opacity: 0.7;
}


/* NEXT TARGET zone accent — the cockpit's themed gold (AA-safe on every shell), one accent per zone */
.next-target-color { color: var(--cy) !important; }

/* Miss Path (Option C - Warning Tint) */
.miss {
  border: 1px solid rgba(239, 68, 68, 0.3) !important;
  background: transparent !important;
  color: #ef4444 !important;   /* opaque — the 0.8-alpha red composites to 3.6:1 on dark shells */
  min-height: 44px;   /* WCAG 2.5.5 tap floor (was 41px) */
}
/* Light shells: bright red washes out (3.5:1) — deepen it to keep the same
   warning tint legible (measured ~6:1 on light + clinical backgrounds) */
[data-theme="light"] .miss { color: #b91c1c !important; border-color: rgba(185, 28, 28, .45) !important; }
[data-theme="clinical"] .miss { color: #b91c1c !important; border-color: rgba(185, 28, 28, .45) !important; }

/* ── externalized style= attrs from gym_mode_redesign.html ── */
/* Calm standard: the WebGL shader is texture, not content. ops/matrix_bg.js drives inline
   opacity (0.3 running, 0 in zen), so CSS opacity alone cannot quiet it — filter:opacity()
   MULTIPLIES the inline value (0.3 x 0.4 = ~0.12 effective) and still lets the zen fade
   reach true 0. On the light shells the dark-tuned speckle reads as dirt: visibility:hidden
   (inline opacity can't override it) removes it entirely. */
.gym-matrix-bg{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:0.12;filter:opacity(40%);}
[data-theme="light"] .gym-matrix-bg,[data-theme="clinical"] .gym-matrix-bg{visibility:hidden;}
/* WCAG 2.5.5: the exit link was an 85x16 inline hit box. inline-flex + min-height:44px
   grows the hit box to the 44px floor without changing the text's visual size; flex-shrink:0
   keeps it from collapsing on the header's flex main axis at narrow widths. */
.exit-app{color:var(--text);text-decoration:none;font-size:11px;letter-spacing:.5px;opacity:.85;margin-right:8px;align-self:center;white-space:nowrap;display:inline-flex;align-items:center;min-height:44px;flex-shrink:0;}
.readiness-hud[hidden]{display:none;}
.now .eyebrow.now-eyebrow-flex{display:flex;justify-content:space-between;}
.avatar-cue summary{display:flex;justify-content:space-between;align-items:center;width:100%;outline:none;}
.avatar-cue-header{display:flex;gap:12px;align-items:center;}
.avatar-cue-label{font-size:11px;letter-spacing:0.05em;text-transform:uppercase;}
.cue-content{padding:12px;display:flex;flex-direction:column;gap:12px;border-top:1px solid var(--line);}
.cue-section-label{color:var(--cy);font-size:11px;letter-spacing:0.05em;text-transform:uppercase;}
.cue-text{margin-top:4px;font-size:13px;color:var(--text);}
.cue-row{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--line);padding-top:12px;}
.metabolic-tag{font-weight:700;font-size:12px;}
.mrv-bar.mrv-bar-flush{margin-top:0;border-top:1px solid var(--line);padding-top:12px;}
.mrv-pattern{color:var(--cy);}
.system-2-drawer.s2-drawer-inline{display:block;margin:0;border:none;padding:12px 0 0;background:transparent;border-top:1px solid var(--line);}
.data-stream{display:flex;flex-wrap:wrap;gap:6px;}
.data-stream-chip{background:rgba(255,255,255,0.05);border:1px solid var(--line);border-radius:16px;padding:4px 10px;font-size:10px;font-family:var(--font-mono);text-transform:uppercase;color:var(--muted);}
.s2-chip-num{opacity:0.5;margin-right:4px;}
.s2-metric-val{color:var(--atk-effort,#e0b271);font-weight:bold;}
/* Effort card: consistent with the Weight/Reps tiles (dark card, gold value) —
   no more inverted white block fighting the dark theme and the gold primary CTA. */
.num-rpe{background:rgba(255,255,255,.05);}
.num-rpe label{color:var(--muted);}
.num-rpe .v{color:var(--cy);}
.num-rpe .u{color:var(--muted);opacity:1;}
.warmup-ramp{margin-top:6px;font:700 11px var(--font-mono);color:var(--cy);opacity:.85;letter-spacing:0.04em;text-align:center;line-height:1.5;padding:0 10px;}
.plate-math{margin-top:8px;font:700 12px var(--font-mono);color:var(--cy);letter-spacing:0.05em;text-align:center;line-height:1.5;padding:0 10px;}
.share-preview-modal[hidden]{display:none;}
.share-card-title{font:800 18px var(--font-display);color:#fff;text-align:center;margin-bottom:20px;}
.share-close-btn{background:none;border:none;color:var(--muted);font:800 14px var(--font-mono);margin-top:15px;cursor:pointer;display:block;width:100%;}
.gym-footer-disclaimer{font-size:10px;color:var(--muted);text-align:center;margin-top:2rem;}
.gym-footer-credit{font-size:10px;color:var(--muted);text-align:center;margin-top:6px;}

/* Motion safety: honor prefers-reduced-motion for any animation not already gated above. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── visual-calm pass 2026-07-15: unify accent-tinted card borders into one quiet
   system (less color noise), tighten the vertical rhythm, and firm up the primary
   action. Presentation only — no contrast reduction, no structural change. ── */
.next-action-card,.autoreg-card,.program-mode-card,.loop-card{border-color:var(--line);}
.next-action-card{background:var(--card);}
main{gap:14px;}
.rest button{transition:border-color .15s,color .15s;}
.enter-load-btn,button.primary,.set-log-primary{letter-spacing:.04em;}

/* ── focused-cockpit hierarchy 2026-07-15: with the mid-set HUDs stripped, make the
   one focal point obvious — the current lift + target (hero) and the do-this-now card
   carry a quiet gold accent; the log controls stay the primary action; secondary
   context sits calmer. Presentation only — tokens only, no contrast reduction. ── */
.hero-block{margin-top:12px;}
#nowCard{border-color:rgba(224,178,113,.22);box-shadow:var(--glass-shadow),inset 0 0 0 1px rgba(224,178,113,.06);}
.strip{margin-top:4px;}

/* ── In-session PR celebration (rest-rail zone banner + session-list chip) ──
   Celebrates a GENUINE new best e1RM the moment the set logs. The one-time
   shine/pulse lives ONLY behind prefers-reduced-motion:no-preference — reduced
   motion gets the static banner (and the universal reduce catch-all above kills
   any residue). Recovery mode has no e1RM, so the banner is display-locked off
   there alongside the rest rail. */
.gym-pr-banner{position:relative;overflow:hidden;margin-top:2px;padding:12px 14px;
  border:1px solid rgba(224,178,113,.45);border-radius:14px;background:var(--cy-soft);
  font:700 13px/1.35 var(--font-mono);color:var(--text);}
.gym-pr-banner[hidden]{display:none;}
.gym-pr-banner b{color:var(--cy);letter-spacing:.1em;margin-right:2px;}
@media (prefers-reduced-motion: no-preference){
  .gym-pr-banner.pr-shine{animation:prPulse .5s ease-out 1;}
  .gym-pr-banner.pr-shine::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.35) 50%,transparent 80%);
    transform:translateX(-100%);will-change:transform;animation:prShine 1.1s ease-out 1;}
}
@keyframes prShine{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@keyframes prPulse{0%{transform:scale(.985)}60%{transform:scale(1.008)}100%{transform:scale(1)}}
body.gym-recovery-mode .gym-pr-banner{display:none !important;}
/* session-list PR chip — the durable this-session mark after the banner quiets */
.gsl-pr{flex:none;font:800 9px var(--font-mono);letter-spacing:.08em;color:var(--cy);
  border:1px solid rgba(224,178,113,.5);border-radius:6px;padding:2px 5px;}
/* session-list per-row set progress — done/target (+ skipped/missed) from the
   current session's real sets; muted sibling of the PR chip, honest counts only */
.gsl-prog{flex:none;font:700 9px var(--font-mono);letter-spacing:.08em;color:var(--muted);
  border:1px solid rgba(224,178,113,.25);border-radius:6px;padding:2px 5px;}
/* end-of-session summary PR line — derives from the same celebrated records */
/* PR celebration (cycle 35): presentation only — the records are unchanged. A PR is
   the most shareable moment in the product; it was rendering at footnote weight.
   Cyan is the existing PR signal on this surface, kept; the warm live-session accent
   still stays off the cold recap. */
.session-summary .ss-prs{margin-top:12px;padding:12px 14px;border:1px solid var(--cy);border-radius:12px;background:var(--card);}
.session-summary .ss-prs-head{font:600 10px/1.2 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--cy);}
.session-summary .ss-pr-row{margin-top:8px;display:flex;align-items:baseline;justify-content:space-between;gap:12px;}
.session-summary .ss-pr-name{font:600 13px/1.35 var(--font-body);color:var(--text);overflow-wrap:anywhere;min-width:0;}
.session-summary .ss-pr-val{font:700 20px/1.1 var(--font-display);color:var(--cy);white-space:nowrap;}
.session-summary .ss-prs-note{margin-top:8px;font:500 11px/1.4 var(--font-body);color:var(--muted);}
.ss-credit{margin-top:12px;padding-top:10px;border-top:1px solid var(--line-2);font:600 10px/1.4 var(--font-body);color:var(--muted);text-align:center;}

/* --- UX ratchet 2026-07-22 (additive block): focus restoration + tap floors + AA contrast ---
   Restores the keyboard ring on controls whose outline:none beat the global
   *:focus-visible; raises two sub-44px hit targets; moves real content off
   --faint (~2.5:1 on the dark shell) to the AA-passing --muted token. */
.bio-test-btn:focus-visible,
.now details.avatar-cue summary:focus-visible,
.avatar-cue summary:focus-visible,
.load-entry input:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}
.restcd .skip{min-height:44px;}
.voice-preview-info summary{min-height:44px;}
.history-count{color:var(--muted);}
.num.pm-locked::after{color:var(--muted);}
.load-entry.pm-locked label::after{color:var(--muted);}

/* --- units coherence (2026-07-22): kg equivalent rides under the lb hero target --- */
.kg-eq{display:block;font:700 13px var(--font-mono);letter-spacing:.08em;color:var(--muted);margin-top:2px;}
/* Plate breakdown rendered at the target so it needs zero taps. One line, so the
   one-screen loop (target -> HIT IT -> next) does not move off the fold. */
.plate-at-target{display:block;font:700 12px var(--font-mono);letter-spacing:.05em;color:var(--cy);margin-top:3px;line-height:1.4;}

/* --- [GYMLOG v1] weight-only progression hint: quiet one-liner under NEXT TARGET --- */
.prog-hint{margin:4px 0 0;font:600 12px/1.45 var(--font-mono);letter-spacing:.03em;color:var(--muted);}

/* --- Live training week (Mon-Sun calendar, anchored to the real date) --- */
.week-cal{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:0 0 10px;}
.wc-day{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;min-height:48px;border:1px solid var(--line);border-radius:10px;background:rgba(255,255,255,.02);color:var(--muted);cursor:pointer;padding:4px 0;}
.wc-nm{font:700 9.5px var(--font-mono);letter-spacing:.08em;text-transform:uppercase;}
.wc-dt{font:800 13px var(--font-mono);color:var(--text);}
.wc-day.is-today{border-color:var(--cy);}
.wc-day.is-active{background:rgba(13,148,136,.16);border-color:var(--cy);color:var(--text);}
.wc-day.is-rest{opacity:.38;cursor:default;}
.wc-day.is-rest .wc-nm::after{content:" ·R";}
.wc-log{position:absolute;top:4px;right:5px;width:5px;height:5px;border-radius:50%;background:var(--cy);}
.wc-day:focus-visible{outline:2px solid var(--cy);outline-offset:2px;}
