*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#0A0A0F;--s1:#13131C;--s2:#1C1C28;--s3:#242433;
  --b1:#2A2A3E;--b2:#363650;
  --acc:#6C63FF;--acc2:#9B8FFF;--acc-text:#FFFFFF;
  --grn:#3ECF8E;--org:#F59E0B;--red:#EF4444;
  --txt:#EEEEF5;--mut:#7878A0;--mut2:#9898B8;--pencil:#565E6A;
  --r:14px;--rsm:8px;--rxs:5px;
  --hue-chest:20;--hue-back:255;--hue-legs:150;--hue-shoulders:60;
  --hue-biceps:285;--hue-triceps:340;--hue-traps:185;--hue-calves:125;
  --hue-abs:95;--hue-obliques:215;--hue-cardio:310;
  --badge-l:.78;--badge-c:.13;
  --font-ui:'Instrument Sans','Inter',system-ui,sans-serif;
  --font-num:'JetBrains Mono',monospace;
  --font-hand:'Caveat',cursive;
  --font-heading:var(--font-ui);
  /* Bottom-tab stroke icons (SPEC R1: no emoji as icons). Declared here as data-URI
     masks so the tab bar can tint them with currentColor; see the .ntab::before rules
     in the mobile media query. 1.75px stroke, matching WL_ICONS in js/workout/ui.js. */
  --icon-home:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11l9-8 9 8'/%3E%3Cpath d='M5 10v10h14V10'/%3E%3C/svg%3E");
  --icon-history:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
  --icon-progress:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20V10M10 20V4M16 20v-7M22 20H2'/%3E%3C/svg%3E");
  --icon-plans:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='3' width='16' height='18' rx='2'/%3E%3Cpath d='M8 8h8M8 12h8M8 16h5'/%3E%3C/svg%3E");
  /* Tints derived from the live theme's own accent/status colours (T-R1 token
     re-skin) so every theme gets a correct dim/glow without a per-theme table.
     color-mix has solid support on the phones this ships to (iOS 16.2+ / recent
     Chrome); no fallback needed since the base solid colours are still set above. */
  --adim:color-mix(in srgb, var(--acc) 15%, transparent);
  --aglow:color-mix(in srgb, var(--acc) 30%, transparent);
  --gdim:color-mix(in srgb, var(--grn) 12%, transparent);
  --odim:color-mix(in srgb, var(--org) 12%, transparent);
  --rdim:color-mix(in srgb, var(--red) 12%, transparent);
}
/* R1 token re-skin: three themes bridged from design-handoff/workout-redesign/export/handoff/tokens.css
   into this file's existing var names (see docs/build-notes/R1-token-reskin.md AC-1). The bare :root
   above holds the OLD legacy dark (purple accent) palette, but that is not what an unset preference
   actually paints: applyAppearance()'s APPEARANCE_DEFAULT forces data-theme="dark" at boot, so the
   NEW dark palette (#000000 / gold accent) below is what unset resolves to in practice (AC-2). */
:root[data-theme="light"]{
  --bg:#EDEFF2;--s1:#FFFFFF;--s2:#F2F4F6;--s3:#E1E4E9;
  --b1:#C7CBD2;--b2:#8C919A;
  --acc:#A93B2A;--acc2:#A93B2A;--acc-text:#FFFFFF;
  --grn:#1F6B37;--org:#8F5F04;--red:#9C1F13;
  --txt:#121418;--mut:#6E7278;--mut2:#3C4048;--pencil:#989CA4;
  --badge-l:.47;--badge-c:.14;
  /* HT2-T2: fixed outcome ramp (History Tab v2 HANDOFF.md sec 1). Meaning is the
     same across themes (gray=missed, green=met, gold=surpassed); only lightness
     differs. Values are the doc's light-theme "contrast-tuned proposal" column. */
  --outcome-missed:#8A9099;--outcome-met:#3E9B5D;--outcome-surpassed:#C9971E;
  --outcome-met-ink:#FFFFFF;--outcome-surp-ink:#2A1E00;--goal-met-check:#2F8F4E;
  /* HT2-T3: bar-structure + banner tokens. HANDOFF.md sec 1's "Bar structure -
     banners" table gives DARK values only (a documented gap, flagged by HT2-T2);
     these are COORDINATOR-DERIVED to match this theme's surface palette, with the
     hue meaning held stable across themes. */
  --neutral-fill:#B8BEC9;--goal-outline:#B8BEC9;
  --reserve-fill:#E4E7EC;--reserve-border:#D3D7DE;
  --bar-track-goal:#DDE1E7;--bar-track-free:#E7EAEF;
  --deficit-ink:#6E7278;
  /* Fix round 1, F2 (blind-audit MEDIUM): the missed-set reps text sits ON the
     --outcome-missed fill, not the surface behind it - --deficit-ink (for the
     chip OUTSIDE the fill) measured 1.50:1 there. --outcome-missed-ink is the
     same pattern as --outcome-met-ink/--outcome-surp-ink above: an ink color
     chosen for legibility ON its matching fill.
     CORRECTION (see BUILD-NOTES.md fix round 1): the ruling's per-theme
     assignment (dark #0E1116, light #FFFFFF, notebook #FFFFFF) is inverted -
     this theme's fill (#8A9099, a light-mid gray) measures 3.22:1 against
     white and 5.88:1 against #0E1116. Same two colors, swapped to the pairing
     that actually clears 4.5:1 (verified by the test's own relative-luminance
     computation), not new colors. */
  --outcome-missed-ink:#0E1116;
  --banner-levelup:#3E9B5D;--banner-fatigue:#8F5F04;--banner-repeat:#C7CBD2;
}
:root[data-theme="dark"]{
  --bg:#000000;--s1:#0E1116;--s2:#161B22;--s3:#20262F;
  --b1:#20252D;--b2:#3A424D;
  --acc:#E0B356;--acc2:#E0B356;--acc-text:#000000;
  --grn:#8FD69B;--org:#F09048;--red:#F2705F;
  --txt:#F0EEE6;--mut:#67675F;--mut2:#A6A69A;--pencil:#565E6A;
  --badge-l:.78;--badge-c:.13;
  /* HT2-T2: fixed outcome ramp, exact dark values from HANDOFF.md sec 1 (the
     design's source-of-truth set). Never substitute --acc/--grn for these even
     though a couple of hexes coincide today - they are a separate semantic axis. */
  --outcome-missed:#5A6B80;--outcome-met:#8FD69B;--outcome-surpassed:#E0B356;
  --outcome-met-ink:#06140A;--outcome-surp-ink:#1A1408;--goal-met-check:#7FAE86;
  /* Bar-structure + banner tokens the Effort view (HT2-T3) needs. HANDOFF sec 1's
     "Bar structure - banners" table only gives dark-theme hex (no light/notebook
     column exists in the doc); added here, dark-only, so HT2-T3 does not have to
     invent them mid-build. A light/notebook set is unspecified - flagged in
     docs/build-notes/HT2-T2.md for whoever extends Effort view to those themes. */
  --neutral-fill:#3A4656;--goal-outline:#3A4656;
  --reserve-fill:#1B2431;--reserve-border:#232C38;
  --bar-track-goal:#0B0E12;--bar-track-free:#171D25;
  --deficit-ink:#8B93A0;
  /* Fix round 1, F2: see the light-theme block's comment above (this theme's
     fill, #5A6B80, is the one pairing where the ruling's literal assignment
     was already the correct direction - kept as #FFFFFF, 5.46:1). */
  --outcome-missed-ink:#FFFFFF;
  --banner-levelup:#8FD69B;--banner-fatigue:#F09048;--banner-repeat:#3A424D;
}
:root[data-theme="notebook"]{
  --bg:#F4EDDD;--s1:#FBF5E7;--s2:#EFE7D3;--s3:#E5DBC2;
  --b1:#DCD1B4;--b2:#C0B28C;
  --acc:#33518F;--acc2:#33518F;--acc-text:#FBF5E7;
  --grn:#3F7048;--org:#9C6A08;--red:#A6382C;
  --txt:#2C2F38;--mut:#8C8570;--mut2:#5B5747;--pencil:#A19A83;
  --badge-l:.45;--badge-c:.09;
  /* HT2-T2: fixed outcome ramp, notebook proposal column from HANDOFF.md sec 1. */
  --outcome-missed:#8C8570;--outcome-met:#3F7048;--outcome-surpassed:#A9791A;
  --outcome-met-ink:#FFFFFF;--outcome-surp-ink:#2A1E00;--goal-met-check:#3F7048;
  /* HT2-T3: bar-structure + banner tokens, COORDINATOR-DERIVED for this theme
     (HANDOFF.md sec 1 documents dark values only). Same hue meanings as dark,
     lightness tuned to the notebook paper surfaces. */
  --neutral-fill:#CFC5A9;--goal-outline:#CFC5A9;
  --reserve-fill:#EDE4CC;--reserve-border:#E0D6BA;
  --bar-track-goal:#EAE1C6;--bar-track-free:#F0E8D2;
  --deficit-ink:#5B5747;
  /* Fix round 1, F2: see the light-theme block's comment above (this theme's
     fill, #8C8570, needs the dark ink too). */
  --outcome-missed-ink:#0E1116;
  --banner-levelup:#3F7048;--banner-fatigue:#9C6A08;--banner-repeat:#DCD1B4;
}
:root[data-voice="handwritten"]{--font-heading:var(--font-hand)}
html{font-size:16px}
body{background:var(--bg);color:var(--txt);font-family:var(--font-ui);min-height:100vh;overscroll-behavior:none}

/* NAV */
nav{position:sticky;top:0;z-index:200;background:var(--s1);background:color-mix(in srgb, var(--bg) 95%, transparent);backdrop-filter:blur(16px);border-bottom:1px solid var(--b1);display:flex;align-items:center;height:54px;padding:0 16px;gap:8px}
.logo{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.95rem;color:var(--acc2);letter-spacing:-.02em;margin-right:auto;white-space:nowrap;text-decoration:none;cursor:pointer}
.session-back-btn{display:none;align-items:center;gap:5px;flex:none;font-size:.78rem;font-weight:600;color:var(--txt);background:var(--s2,#1a1a24);border:1px solid var(--b1);border-radius:18px;padding:5px 11px;white-space:nowrap;cursor:pointer}
.session-back-btn svg{width:14px;height:14px;flex:none}
.session-back-btn:active{opacity:.65}
.session-person-label{display:none;font-family:'JetBrains Mono',monospace;font-size:.78rem;font-weight:700;color:var(--acc2);padding:0 4px}
nav.in-session .person-toggle{display:none}
nav.in-session .session-back-btn{display:inline-flex}
nav.in-session .session-person-label{display:block;margin-left:auto}
.logo:hover{opacity:.75}
/* F0905-T6: staging-only TEST pill, next to the logo. hidden attr keeps it out
   of layout entirely on the live site (byte-identical header otherwise). Uses
   the existing --banner-fatigue warning tint via color-mix, no new tokens. */
.test-host-badge{font-family:'JetBrains Mono',monospace;font-size:.62rem;font-weight:700;letter-spacing:.04em;color:var(--banner-fatigue);background:color-mix(in srgb, var(--banner-fatigue) 16%, transparent);border:1px solid var(--banner-fatigue);border-radius:5px;padding:2px 5px;margin-left:6px;white-space:nowrap;pointer-events:none}
.test-host-badge[hidden]{display:none}
/* A2 (screen 22): wordmark = "Self" accent + "Craft" ink, both weight 700. */
.logo span{color:var(--txt);font-weight:700}
.ntabs{display:flex;gap:2px}
.ntab{background:none;border:none;color:var(--mut);font-family:var(--font-ui);font-size:.78rem;font-weight:500;padding:7px 11px;border-radius:var(--rsm);cursor:pointer;transition:all .18s;white-space:nowrap}
.ntab.active{background:var(--adim);color:var(--acc2)}
.ntab:hover:not(.active){color:var(--txt);background:var(--s2)}

/* PAGES */
.page{display:none;padding:16px}
.page.active{display:block}
@media(min-width:700px){.page{padding:24px 28px}.logo{font-size:1rem}.ntab{font-size:.82rem;padding:7px 14px}}

/* NEW SESSION BUTTON */
.new-session-btn{width:100%;background:var(--acc);border:none;border-radius:var(--r);color:var(--acc-text);font-family:var(--font-ui);font-size:1rem;font-weight:700;padding:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:20px;transition:all .2s;box-shadow:0 4px 20px var(--aglow)}
.new-session-btn:hover{opacity:.88;transform:translateY(-1px)}
.new-session-btn:active{transform:scale(.98)}
.new-session-btn svg{flex-shrink:0}

/* WORKOUT TYPE PICKER */
.wt-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:20px}
@media(min-width:500px){.wt-grid{grid-template-columns:repeat(4,1fr)}}
.wt-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:16px 12px;cursor:pointer;text-align:center;transition:all .2s}
.wt-card:hover,.wt-card.sel{border-color:var(--acc);background:var(--adim);transform:translateY(-2px);box-shadow:0 4px 16px var(--aglow)}
.wt-icon{font-size:1.8rem;margin-bottom:8px}
.wt-name{font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:600;color:var(--acc2);line-height:1.3}
.picker-section-label{font-family:'JetBrains Mono',monospace;font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--mut);margin-bottom:10px}

/* HOME DASHBOARD (Slice 1) */
.dash-strip{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:20px}
@media(min-width:700px){.dash-strip{grid-template-columns:repeat(2,1fr)}}
.dash-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:16px}
.dash-card-hdr{font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--mut);margin-bottom:12px}
.dash-week-body{display:flex;align-items:center;gap:16px}
.dash-ring{flex-shrink:0;position:relative;width:72px;height:72px}
.dash-ring svg{transform:rotate(-90deg)}
.dash-ring-track{fill:none;stroke:var(--b1);stroke-width:7}
.dash-ring-fill{fill:none;stroke:var(--acc);stroke-width:7;stroke-linecap:round;transition:stroke-dashoffset .5s ease}
.dash-ring-num{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-family:'JetBrains Mono',monospace;font-size:.82rem;font-weight:700;color:var(--txt)}
.dash-week-stats{flex:1;display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.dash-stat-v{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:700;color:var(--txt);line-height:1.1}
.dash-stat-l{font-size:.65rem;color:var(--mut);margin-top:2px;text-transform:uppercase;letter-spacing:.03em}
.dash-last-title{font-family:'JetBrains Mono',monospace;font-size:.95rem;font-weight:700;color:var(--acc2)}
.dash-last-sub{font-size:.72rem;color:var(--mut);margin-top:2px;margin-bottom:10px}
.dash-last-nums{display:flex;gap:16px;flex-wrap:wrap;align-items:baseline}
/* .dash-bw-row/-v/-trend removed at Batch A close-out: the Home bodyweight card they
   styled is gone in the v2 redesign. Bodyweight is still CAPTURED at session start; the
   display returns with the Progress > Body tab (WS9, Batch C). Nothing references these. */
.dash-spark{margin-top:10px}
.dash-empty{font-size:.75rem;color:var(--mut);padding:6px 0}

/* ACTIVE SESSION */
.session-header{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:14px 16px;margin-bottom:16px;display:flex;align-items:center;gap:12px}
.session-header-info{flex:1}
.session-header-type{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.95rem;color:var(--acc2)}
.session-header-date{font-size:.78rem;color:var(--mut);margin-top:2px}
.session-group{margin-bottom:20px}
.group-label{display:flex;align-items:center;gap:8px;font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:700;letter-spacing:.08em;color:var(--mut);padding:8px 0 10px;text-transform:uppercase}
/* .ord-btns / .ord-btn removed in Batch B.2 (2026-08-14): D3+D5 made exercises
   orderable freely across muscle categories and deleted the per-group up/down
   arrow buttons, leaving the drag handle as the sole reorder affordance
   (Brandon's ruling). Verified dead before removal - the three rules had zero
   references in any JS file or in the shell markup. */
.ex-block{background:var(--s1);border:1px solid var(--b1);border-radius:var(--rsm);margin-bottom:10px;overflow:hidden}
.ex-block-header{padding:12px 14px 8px;border-bottom:1px solid var(--b1)}
.ex-title{font-size:.85rem;font-weight:600;color:var(--txt);line-height:1.3;margin-bottom:4px}
.last-time{font-size:.75rem;color:var(--mut);line-height:1.4}
.last-time strong{color:var(--acc2)}
.rec-line{font-size:.75rem;margin-top:4px;display:flex;align-items:center;gap:5px}
.rec-up{color:var(--grn)}.rec-same{color:var(--acc2)}.rec-new{color:var(--org)}.rec-hold{color:var(--red)}
.sets-area{padding:10px 14px 12px}
.set-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}
.set-num{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--mut);width:22px;flex-shrink:0}
.set-input{flex:1;background:var(--s2);border:1px solid var(--b1);border-radius:6px;color:var(--txt);font-family:'JetBrains Mono',monospace;font-size:.88rem;padding:8px 10px;outline:none;text-align:center;-webkit-appearance:none}
.set-input:focus{border-color:var(--acc)}
.set-input::placeholder{color:var(--b2)}
/* T0c (bug wave 3, 2026-08-02): a value the APP wrote (prefill, cascade, propagation)
   renders muted; hardening it by typing flips it to full colour. Until this shipped the
   soft/hard model of ADR 0005 F was completely invisible - app-written numbers looked
   exactly like Brandon's own, so he could not tell what the app had guessed. */
.set-input.soft{color:var(--mut2)}
.set-sep{color:var(--mut);font-size:.8rem;flex-shrink:0}
.set-done-btn{background:var(--s3);border:1px solid var(--b1);border-radius:6px;color:var(--mut);font-size:.85rem;padding:7px 10px;cursor:pointer;transition:all .15s;flex-shrink:0}
.set-done-btn.done{background:var(--gdim);border-color:var(--grn);color:var(--grn)}
.set-controls{display:flex;gap:6px;padding:6px 0 2px}
.add-set-btn{background:none;border:1px dashed var(--b2);border-radius:6px;color:var(--mut);font-size:.78rem;padding:7px 16px;cursor:pointer;transition:all .15s;font-family:var(--font-ui);flex:1}
.add-set-btn:hover{border-color:var(--acc);color:var(--acc2)}
.rem-set-btn{background:none;border:1px dashed var(--b2);border-radius:6px;color:var(--mut);font-size:.78rem;padding:7px 16px;cursor:pointer;transition:all .15s;font-family:var(--font-ui);flex:1}
.rem-set-btn:hover{border-color:var(--red);color:var(--red)}
.finish-btn{width:100%;background:var(--grn);border:none;border-radius:var(--r);color:var(--bg);font-family:var(--font-ui);font-size:1rem;font-weight:700;padding:16px;cursor:pointer;margin-top:8px;transition:all .2s}
.finish-btn:hover{opacity:.88}

/* HISTORY */
.history-filter{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding-bottom:4px;margin-bottom:14px}
.history-filter::-webkit-scrollbar{display:none}
.hf-chip{flex-shrink:0;background:var(--s1);border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-size:.75rem;font-family:'JetBrains Mono',monospace;padding:5px 12px;cursor:pointer;transition:all .18s;white-space:nowrap}
.hf-chip.active{background:var(--adim);border-color:var(--acc);color:var(--acc2)}
.sess-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);margin-bottom:10px;overflow:hidden;cursor:pointer;transition:all .2s}
.sess-card:hover{border-color:var(--acc)}
.sess-hdr{padding:13px 15px;display:flex;align-items:center;gap:10px}
.sess-date{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.9rem;color:var(--acc2);flex:1}
.sess-badges{display:flex;flex-wrap:wrap;gap:4px}
.mbadge{font-size:.65rem;font-family:'JetBrains Mono',monospace;padding:2px 6px;border-radius:3px;font-weight:600}
/* R1 token re-skin: 11 muscle badges rewired to the tokens.css OKLCH hue system
   (one hue per muscle, lightness/chroma from --badge-l/--badge-c so every badge
   stays legible per-theme instead of a hardcoded rgba pair tuned for dark only). */
.bCHEST,.bTRICEPS,.bBACK,.bBICEPS,.bLEGS,.bSHOULDERS,.bTRAPS,.bCALVES,.bABS,.bOBLIQUES,.bCARDIO{color:var(--txt);background:var(--s2)}
.bCHEST{background:oklch(var(--badge-l) var(--badge-c) var(--hue-chest) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-chest))}
.bTRICEPS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-triceps) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-triceps))}
.bBACK{background:oklch(var(--badge-l) var(--badge-c) var(--hue-back) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-back))}
.bBICEPS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-biceps) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-biceps))}
.bLEGS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-legs) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-legs))}
.bSHOULDERS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-shoulders) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-shoulders))}
.bTRAPS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-traps) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-traps))}
.bCALVES{background:oklch(var(--badge-l) var(--badge-c) var(--hue-calves) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-calves))}
.bABS{background:oklch(var(--badge-l) var(--badge-c) var(--hue-abs) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-abs))}
.bOBLIQUES{background:oklch(var(--badge-l) var(--badge-c) var(--hue-obliques) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-obliques))}
.bCARDIO{background:oklch(var(--badge-l) var(--badge-c) var(--hue-cardio) / .16);color:oklch(var(--badge-l) var(--badge-c) var(--hue-cardio))}
/* Directive (Brandon, 2026-08-14): abs + obliques merge under a parent CORE at
   GROUP-OVERVIEW badge spots (Home session cards, Progress weekly muscle rows).
   CORE is a grouping label, not a 12th muscle, so it gets NO new hue - it takes
   the same neutral inverted treatment plans.css already uses for TAG_TREE parent
   chips (.wl-tag.parent: bg var(--txt), text var(--bg)), keeping the badge system
   at its documented "11 muscle groups, one hue set" (SPEC). ABS/OBLIQUES keep
   their own hues wherever they render as leaves (Plan editor tag children,
   per-exercise badges, Progress sub-rows) - see BUILD-NOTES for the full list.
   Stored session data is untouched: s.groups still keys on ABS/OBLIQUES only. */
.bCORE{background:var(--txt);color:var(--bg);font-weight:700}
.sess-chev{color:var(--mut);font-size:1rem;transition:transform .2s}
.sess-card.open .sess-chev{transform:rotate(90deg)}
.sess-body{display:none;padding:0 15px 14px;border-top:1px solid var(--b1)}
.sess-card.open .sess-body{display:block}
.sg-title{font-family:'JetBrains Mono',monospace;font-size:.68rem;color:var(--mut);letter-spacing:.06em;padding:10px 0 5px;font-weight:700}
.ex-row{padding:6px 0;border-bottom:1px solid var(--b1)}
.ex-row:last-child{border:none}
.ex-row-name{font-size:.8rem;font-weight:500;color:var(--txt);margin-bottom:4px}
.sets-pills{display:flex;flex-wrap:wrap;gap:4px}
.spill{background:var(--s3);border:1px solid var(--b1);border-radius:4px;font-size:.7rem;font-family:'JetBrains Mono',monospace;padding:2px 7px;color:var(--mut2)}
.spill.flag{border-color:var(--org);color:var(--org)}

/* PROGRESS */
.prog-mode{display:flex;gap:6px;margin-bottom:14px}
.prog-mode-btn{flex:1;background:var(--s1);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--mut);font-family:var(--font-ui);font-size:.82rem;font-weight:600;padding:9px;cursor:pointer;transition:all .18s;text-align:center}
.prog-mode-btn.active{background:var(--adim);border-color:var(--acc);color:var(--acc2)}
.prog-sel{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}
.prog-sel select{background:var(--s1);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.85rem;padding:9px 12px;outline:none;-webkit-appearance:none;appearance:none;width:100%}
.prog-sel select:focus{border-color:var(--acc)}
.sess-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:13px 14px;margin-bottom:10px}
.sess-card-hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}
.sess-card-date{font-family:'JetBrains Mono',monospace;font-size:.8rem;color:var(--acc2);font-weight:600}
.sess-card-vol{font-family:'JetBrains Mono',monospace;font-size:.78rem;color:var(--mut2)}
.sess-ex-list{display:flex;flex-direction:column;gap:5px}
.sess-ex-row{display:flex;justify-content:space-between;align-items:center;font-size:.78rem;border-bottom:1px solid var(--b1);padding-bottom:5px}
.sess-ex-row:last-child{border-bottom:none;padding-bottom:0}
.sess-ex-name{color:var(--txt);flex:1;padding-right:8px}
.sess-ex-val{font-family:'JetBrains Mono',monospace;color:var(--mut2);white-space:nowrap}
.chart-wrap{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:14px;margin-bottom:12px}
.chart-ttl{font-family:'JetBrains Mono',monospace;font-size:.78rem;color:var(--mut2);margin-bottom:10px;font-weight:600}
.chart-box{position:relative;height:220px}
.stat-row{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
.stat-box{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);padding:10px;text-align:center}
.stat-v{font-family:'JetBrains Mono',monospace;font-size:1.05rem;font-weight:700;color:var(--acc2)}
.stat-l{font-size:.68rem;color:var(--mut);margin-top:2px}
.gu{color:var(--grn)}.gd{color:var(--red)}.gf{color:var(--mut)}

/* PROGRESS — SESSION VIEW MINI CHARTS */
.prog-sess-meta{font-family:'JetBrains Mono',monospace;font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--mut);margin-bottom:10px}
.mini-ex-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:12px 14px;margin-bottom:10px}
.mini-ex-hdr{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:8px}
.mini-ex-name{font-size:.8rem;font-weight:600;color:var(--txt);line-height:1.3;flex:1}
.mini-ex-delta{font-family:'JetBrains Mono',monospace;font-size:.68rem;font-weight:700;padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}
.mini-ex-delta.up{background:var(--gdim);color:var(--grn)}
.mini-ex-delta.dn{background:var(--rdim);color:var(--red)}
.mini-ex-delta.eq{background:var(--s3);color:var(--mut)}
.mini-ex-chart{position:relative;height:64px;margin-bottom:8px}
.mini-ex-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.mini-stat{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);padding:7px 6px;text-align:center}
.mini-stat-v{font-family:'JetBrains Mono',monospace;font-size:.78rem;font-weight:700;color:var(--acc2)}
.mini-stat-l{font-size:.6rem;color:var(--mut);margin-top:2px}

/* MISC */
.empty{text-align:center;padding:50px 20px;color:var(--mut)}
.empty-icon{font-size:2.2rem;margin-bottom:10px;opacity:.4}
.empty h3{font-size:.95rem;margin-bottom:5px;color:var(--mut2)}
.empty p{font-size:.82rem;line-height:1.5}
.sec-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.sec-title{font-family:'JetBrains Mono',monospace;font-size:.88rem;font-weight:700;color:var(--txt)}
.sec-meta{font-size:.75rem;color:var(--mut)}
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(12px);background:var(--grn);color:var(--bg);font-size:.8rem;font-weight:600;padding:9px 20px;border-radius:20px;opacity:0;transition:all .22s;pointer-events:none;z-index:999;white-space:nowrap}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.btn{display:inline-flex;align-items:center;gap:6px;padding:9px 16px;border-radius:var(--rsm);border:none;font-family:var(--font-ui);font-size:.85rem;font-weight:600;cursor:pointer;transition:all .15s}
.btn-sec{background:var(--s2);border:1px solid var(--b2);color:var(--mut2)}
.btn-sec:hover{color:var(--txt)}
::-webkit-scrollbar{width:4px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--b1);border-radius:4px}

/* STICKY WORKOUT TIMER BAR */
.workout-timer{display:none;position:sticky;top:54px;z-index:190;background:rgba(19,19,28,.97);backdrop-filter:blur(12px);border-bottom:1px solid var(--b1);align-items:center;justify-content:center;gap:20px;padding:9px 16px}
.workout-timer.show{display:flex}
.wt-block{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:72px}
.wt-label{font-size:.62rem;font-family:'JetBrains Mono',monospace;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--mut)}
.wt-time{font-family:'JetBrains Mono',monospace;font-size:1.35rem;font-weight:700;letter-spacing:-.02em;color:var(--acc2)}
.wt-time.rest-active{color:var(--grn)}
.wt-divider{width:1px;height:32px;background:var(--b2)}
.wt-rest-tap{font-size:.68rem;color:var(--mut);font-family:var(--font-ui);margin-top:1px;cursor:pointer}
.wt-done-btn{font-size:.68rem;color:var(--grn);font-family:var(--font-ui);font-weight:600;margin-top:1px;cursor:pointer;background:none;border:none;padding:0}

/* ── ONE REST CLOCK (T3, batch 2) ── */
/* There used to be TWO: this bar's count-UP stopwatch and a separate floating countdown
   pill, and BOTH fired on the same ✓ done tap. Brandon read the app as counting up even
   when the pill was working ("timer still counts up instead of down"), so the pill is
   gone and the bar below is the single surface, driven by wt_timer_prefs.mode. */
.wt-rest-block{flex-direction:row;gap:8px;min-width:0}
.wt-rest-main{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:72px}
.wt-time.rest-over{color:var(--org);animation:restOverPulse 1s ease-in-out infinite}
@keyframes restOverPulse{0%,100%{opacity:1}50%{opacity:.55}}
/* T4: in-session rest adjustment. Big enough to hit with a thumb mid-set. */
.rest-adj{
  background:var(--s3);border:1px solid var(--b2);border-radius:var(--rsm);color:var(--txt);
  font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:700;
  min-width:42px;padding:9px 6px;cursor:pointer;flex:none;
}
.rest-adj:active{background:var(--adim);border-color:var(--acc)}
/* ── TIMER SETTINGS (T3) ── */
.tset-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;border-bottom:1px solid var(--b1)}
.tset-row:last-of-type{border-bottom:none}
.tset-lbl{font-size:.85rem;color:var(--txt)}
.tset-sub{font-size:.7rem;color:var(--mut)}
.tset-num{width:82px;background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:'JetBrains Mono',monospace;font-size:.9rem;padding:9px 10px;outline:none;text-align:center;-webkit-appearance:none}
.tset-num:focus{border-color:var(--acc)}
.tset-modes{display:flex;gap:6px}
.tset-mode{flex:1;background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--mut2);font-family:var(--font-ui);font-size:.82rem;font-weight:600;padding:11px 8px;cursor:pointer}
.tset-mode.active{background:var(--adim);border-color:var(--acc);color:var(--txt)}
.wt-done-btn:hover{opacity:.75}
/* SESSION TIMER (legacy in header — hidden, we use sticky bar now) */
.session-timer{display:none}
.set-rest{font-size:.68rem;color:var(--mut);font-family:'JetBrains Mono',monospace;margin-left:auto;white-space:nowrap}


/* POST-SESSION STATS MODAL */
.stats-overlay{position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:500;display:flex;align-items:flex-end;justify-content:center;opacity:0;pointer-events:none;transition:opacity .22s}
.stats-overlay.open{opacity:1;pointer-events:all}
.stats-sheet{background:var(--s1);border-radius:20px 20px 0 0;width:100%;max-width:480px;max-height:88vh;overflow-y:auto;padding:20px 18px 40px;transform:translateY(100%);transition:transform .32s cubic-bezier(.22,1,.36,1)}
.stats-overlay.open .stats-sheet{transform:translateY(0)}
.stats-pill-bar{width:36px;height:4px;background:var(--b2);border-radius:2px;margin:0 auto 18px}
.stats-title{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:1.05rem;color:var(--acc2);margin-bottom:2px}
.stats-sub{font-size:.78rem;color:var(--mut);margin-bottom:18px}
.stats-grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:18px}
.scard{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);padding:12px 10px;text-align:center}
.scard-v{font-family:'JetBrains Mono',monospace;font-size:1.25rem;font-weight:700;color:var(--txt);line-height:1.1}
.scard-l{font-size:.67rem;color:var(--mut);margin-top:3px;text-transform:uppercase;letter-spacing:.04em}
.scard-delta{font-size:.72rem;font-family:'JetBrains Mono',monospace;margin-top:5px;font-weight:600}
.sdelta-up{color:var(--grn)}.sdelta-dn{color:var(--red)}.sdelta-eq{color:var(--mut)}
.stats-ex-toggle{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);padding:10px 14px;display:flex;align-items:center;justify-content:space-between;cursor:pointer;font-size:.82rem;color:var(--mut2);margin-bottom:10px;font-family:'JetBrains Mono',monospace}
.stats-ex-toggle:hover{border-color:var(--acc);color:var(--acc2)}
.stats-ex-list{display:none;margin-bottom:14px}
.stats-ex-list.open{display:block}
.stats-ex-row{padding:10px 0;border-bottom:1px solid var(--b1)}
.stats-ex-row:last-child{border:none}
.stats-ex-name{font-size:.8rem;font-weight:600;color:var(--txt);margin-bottom:6px}
.stats-ex-nums{display:flex;gap:8px;flex-wrap:wrap}
.stats-ex-pill{background:var(--s3);border:1px solid var(--b1);border-radius:4px;font-size:.7rem;font-family:'JetBrains Mono',monospace;padding:3px 8px;color:var(--mut2)}
.stats-ex-delta{margin-left:4px;font-size:.65rem;font-weight:700}
.stats-ex-delta.up{color:var(--grn)}.stats-ex-delta.dn{color:var(--red)}.stats-ex-delta.eq{color:var(--mut)}
.stats-done-btn{width:100%;background:var(--acc);border:none;border-radius:var(--r);color:var(--acc-text);font-family:var(--font-ui);font-size:1rem;font-weight:700;padding:15px;cursor:pointer;margin-top:6px;transition:all .2s;box-shadow:0 4px 16px var(--aglow)}
.stats-done-btn:hover{opacity:.88}

/* REST TIMER BAR */
.rest-bar{position:fixed;bottom:0;left:0;right:0;background:var(--s1);border-top:2px solid var(--acc);padding:14px 16px;display:flex;align-items:center;gap:12px;z-index:300;transform:translateY(100%);transition:transform .25s}
.rest-bar.show{transform:translateY(0)}
.rest-circle{width:48px;height:48px;flex-shrink:0;position:relative}
.rest-circle svg{transform:rotate(-90deg)}
.rest-circle-track{fill:none;stroke:var(--b1);stroke-width:4}
.rest-circle-fill{fill:none;stroke:var(--grn);stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .9s linear,stroke .3s}
.rest-num{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-family:'JetBrains Mono',monospace;font-size:.85rem;font-weight:700;color:var(--grn)}
.rest-info{flex:1}
.rest-label{font-size:.82rem;font-weight:600;color:var(--txt)}
.rest-sub{font-size:.72rem;color:var(--mut);margin-top:2px}
.rest-skip{background:var(--s2);border:1px solid var(--b2);border-radius:var(--rsm);color:var(--mut2);font-size:.78rem;font-weight:600;padding:8px 14px;cursor:pointer;font-family:var(--font-ui);flex-shrink:0}
.rest-skip:hover{color:var(--txt)}

/* DELOAD NUDGE BANNER (T5) */
.deload-banner{background:var(--s1);border:1px solid var(--acc);border-radius:var(--r);padding:14px 16px;margin-bottom:16px;display:flex;align-items:center;gap:12px}
.deload-banner-info{flex:1}
.deload-banner-title{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.88rem;color:var(--acc2);margin-bottom:3px}
.deload-banner-sub{font-size:.75rem;color:var(--mut)}
.deload-banner-x{background:var(--s2);border:1px solid var(--b2);border-radius:var(--rsm);color:var(--mut2);font-family:var(--font-ui);font-size:.82rem;font-weight:600;padding:8px 12px;cursor:pointer;flex-shrink:0}
.deload-banner-x:hover{color:var(--red);border-color:var(--red)}

/* WEEKLY SETS-PER-MUSCLE (T5) */
.vol-week-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:14px 16px;margin-bottom:12px}
.vol-week-hdr{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:10px}
.vol-week-label{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.82rem;color:var(--txt)}
.vol-week-meta{font-size:.68rem;color:var(--mut)}
.vol-row{display:flex;align-items:center;gap:8px;padding:5px 0}
.vol-row-bar-wrap{flex:1;background:var(--s3);border-radius:3px;height:8px;overflow:hidden}
.vol-row-bar{height:100%;background:var(--acc);border-radius:3px}
.vol-row-n{font-family:'JetBrains Mono',monospace;font-size:.72rem;color:var(--mut2);min-width:44px;text-align:right}
/* CORE grouping sub-rows (Directive 2026-08-14): abs/obliques still show as
   their own leaf lines under the merged CORE parent row, just indented and
   dimmed so the hierarchy reads without a second bar-and-percent layout. */
.vol-row-sub{padding-left:22px;opacity:.75}
.vol-row-sub .vol-row-bar-wrap{display:none}

/* RESUME BANNER - removed at Batch A close-out.
   The old banner markup is gone: WS1's resume chip (css/home.css) is now the single
   owner of the #resume-banner ELEMENT, and it carries both Continue and Discard. Only
   the id survives, as a render target; none of these classes were referenced any more.
   Kept as a note rather than silently deleted so a reader who greps "resume-banner" and
   lands here knows where the styling went. */

/* SMALL PHONE NAV FIX */
@media(max-width:360px){.ntab{padding:6px 8px;font-size:.72rem}.logo{font-size:.82rem}}

/* PLANS */
.plan-card{background:var(--s1);border:1px solid var(--b1);border-radius:var(--r);padding:14px 16px;margin-bottom:10px;display:flex;align-items:flex-start;gap:12px}
.plan-card-info{flex:1;min-width:0}
.plan-card-name{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.92rem;color:var(--txt);margin-bottom:4px}
.plan-card-meta{font-size:.75rem;color:var(--mut);line-height:1.5}
.plan-card-actions{display:flex;gap:6px;flex-shrink:0}
.plan-icon-btn{background:var(--s2);border:1px solid var(--b1);border-radius:6px;color:var(--mut2);font-size:.85rem;padding:6px 9px;cursor:pointer;transition:all .15s}
.plan-icon-btn:hover{color:var(--txt);border-color:var(--acc)}
.plan-icon-btn.start{background:var(--adim);border-color:var(--acc);color:var(--acc2);font-size:.75rem;font-weight:600;padding:6px 11px}
.plan-icon-btn.start:hover{background:var(--acc);color:var(--acc-text)}
/* Plan builder modal */
.plan-modal-bg{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:400;display:flex;align-items:flex-end;justify-content:center}
.plan-modal{background:var(--s1);border-radius:var(--r) var(--r) 0 0;width:100%;max-width:600px;max-height:90vh;overflow-y:auto;overflow-x:hidden;padding:20px 18px 32px}
.plan-modal-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.plan-modal-title{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:1rem;color:var(--txt)}
.plan-name-input{width:100%;background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.95rem;padding:10px 12px;outline:none;margin-bottom:16px}
.plan-name-input:focus{border-color:var(--acc)}
.plan-section-label{font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:700;letter-spacing:.08em;color:var(--mut);text-transform:uppercase;margin-bottom:8px}
.plan-add-row{display:flex;gap:8px;margin-bottom:12px}
.plan-add-row select,.plan-add-row input{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.83rem;padding:8px 10px;outline:none;-webkit-appearance:none;appearance:none}
.plan-add-row select:focus,.plan-add-row input:focus{border-color:var(--acc)}
.plan-add-row select{flex-shrink:0;width:110px}
.plan-add-row input{flex:1;min-width:0;width:0}
.plan-add-row .add-ex-btn{background:var(--adim);border:1px solid var(--acc);border-radius:var(--rsm);color:var(--acc2);font-size:1.1rem;padding:0 12px;cursor:pointer;flex-shrink:0}
.plan-ex-list{margin-bottom:16px}
.plan-ex-item{display:flex;flex-direction:column;gap:6px;padding:8px 10px;background:var(--s2);border-radius:var(--rsm);margin-bottom:5px}
.plan-ex-top{display:flex;align-items:center;gap:8px;min-width:0}
.plan-ex-ctrls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.plan-ex-group{font-size:.65rem;font-family:'JetBrains Mono',monospace;font-weight:700;padding:2px 6px;border-radius:3px;flex-shrink:0}
.plan-ex-name{flex:1;min-width:0;overflow-wrap:anywhere;font-size:.82rem;color:var(--txt)}
.plan-ex-sets{display:flex;align-items:center;gap:4px;flex-shrink:0}
.plan-ex-sets input{width:34px;background:var(--b1);border:1px solid var(--b2);border-radius:4px;color:var(--txt);font-family:'JetBrains Mono',monospace;font-size:.82rem;padding:4px 6px;outline:none;text-align:center}
.plan-ex-sets label{font-size:.7rem;color:var(--mut)}
.plan-ex-del{background:none;border:none;color:var(--mut);font-size:.9rem;cursor:pointer;padding:2px 4px;flex-shrink:0}
.plan-ex-del:hover{color:var(--red)}
.plan-ex-tag-btn{background:var(--b1);border:1px solid var(--b2);color:var(--mut);font-size:.65rem;font-family:'JetBrains Mono',monospace;border-radius:12px;padding:3px 9px;cursor:pointer;flex-shrink:0;white-space:nowrap}
.plan-save-btn{width:100%;background:var(--acc);border:none;border-radius:var(--r);color:var(--acc-text);font-family:var(--font-ui);font-size:.95rem;font-weight:700;padding:14px;cursor:pointer;margin-top:8px}
.plan-save-btn:hover{opacity:.88}
.person-toggle{display:inline-flex;gap:2px;background:var(--b1,#222);border-radius:20px;padding:3px;margin-right:auto;margin-left:14px}
.pt-btn{background:none;border:none;color:var(--mut2,#888);font-family:'JetBrains Mono',monospace;font-size:.72rem;padding:5px 12px;border-radius:18px;cursor:pointer}
.pt-btn.active{background:var(--acc,#27ae60);color:var(--acc-text)}
.sync-dot{width:9px;height:9px;border-radius:50%;background:var(--mut2,#888);margin-left:10px;flex:none;transition:background .3s}
.sync-dot.ok{background:#27ae60}
.sync-dot.syncing{background:#f1c40f;animation:pulse 1s infinite}
.sync-dot.err{background:#c0392b}
@keyframes pulse{50%{opacity:.3}}

/* FEEDBACK BOTTOM SHEET */
.feedback-overlay{position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:600;display:flex;align-items:flex-end;justify-content:center;opacity:0;pointer-events:none;transition:opacity .22s}
.feedback-overlay.open{opacity:1;pointer-events:all}
/* Sheet motion (2026-09-08, one system for every sheet): enter from off-screen on
   one curve; the swipe gesture in js/workout/ui.js flies it back out the same way. */
.feedback-sheet{background:var(--s1);border-radius:20px 20px 0 0;width:100%;max-width:480px;padding:20px 18px 40px;transform:translateY(100%);transition:transform .32s cubic-bezier(.22,1,.36,1)}
.feedback-overlay.open .feedback-sheet{transform:translateY(0)}
.fb-title{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:1rem;color:var(--acc2);margin-bottom:4px}
.fb-sub{font-size:.78rem;color:var(--mut);margin-bottom:20px}
.fb-label{font-family:'JetBrains Mono',monospace;font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--mut);margin-bottom:8px}
.rpe-row{display:flex;gap:4px;margin-bottom:20px}
.rpe-btn{flex:1;background:var(--s2);border:1px solid var(--b1);border-radius:6px;color:var(--mut2);font-family:'JetBrains Mono',monospace;font-size:.82rem;font-weight:700;padding:9px 0;cursor:pointer;transition:all .15s;text-align:center;min-width:0}
.rpe-btn.sel{background:var(--adim);border-color:var(--acc);color:var(--acc2)}
.feel-row{display:flex;gap:5px;margin-bottom:20px}
.feel-btn{flex:1;background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);padding:9px 2px;cursor:pointer;text-align:center;transition:all .15s;display:flex;flex-direction:column;align-items:center;gap:3px;min-width:0}
.feel-btn .feel-emoji{font-size:1.3rem}
.feel-btn .feel-label{font-size:.58rem;color:var(--mut);font-family:'JetBrains Mono',monospace;white-space:nowrap}
.feel-btn.sel{border-color:var(--acc);background:var(--adim)}
.feel-btn.sel .feel-label{color:var(--acc2)}
.fb-input{width:100%;background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.9rem;padding:10px 12px;outline:none;margin-bottom:16px;-webkit-appearance:none}
.fb-input:focus{border-color:var(--acc)}
.fb-actions{display:flex;gap:10px;margin-top:4px}
.fb-submit{flex:1;background:var(--grn);border:none;border-radius:var(--r);color:var(--bg);font-family:var(--font-ui);font-size:.95rem;font-weight:700;padding:14px;cursor:pointer;transition:all .2s}
.fb-submit:hover{opacity:.88}
.fb-skip{background:var(--s2);border:1px solid var(--b1);border-radius:var(--r);color:var(--mut2);font-family:var(--font-ui);font-size:.9rem;font-weight:600;padding:14px 20px;cursor:pointer;transition:all .15s}
.fb-skip:hover{color:var(--txt)}

/* RIR CHIP ROW */
.rir-chip{background:var(--s2);border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:600;padding:4px 10px;cursor:pointer;transition:all .15s;flex-shrink:0}
.rir-chip:hover{border-color:var(--grn);color:var(--grn)}
.rir-chip.sel{background:var(--gdim);border-color:var(--grn);color:var(--grn)}
.set-rir{display:flex;align-items:center;gap:4px;flex-basis:100%;justify-content:flex-end;margin-top:3px}
.set-rir.open{justify-content:flex-start;flex-wrap:wrap}
.rir-toggle{background:var(--s2);border:1px solid var(--b1);border-radius:20px;color:var(--mut);font-family:'JetBrains Mono',monospace;font-size:.7rem;font-weight:600;padding:5px 14px;cursor:pointer;transition:all .15s}
.rir-toggle:hover{border-color:var(--grn);color:var(--grn)}
.rir-toggle.logged{background:var(--gdim);border-color:var(--grn);color:var(--grn)}
.set-rir-label{font-family:'JetBrains Mono',monospace;font-size:.64rem;color:var(--mut);white-space:nowrap;margin-right:2px}
.set-rir .rir-chip{font-size:.74rem;padding:5px 12px}
.rir-clear{background:none;border:1px solid var(--b1);border-radius:20px;color:var(--mut);font-size:.72rem;padding:4px 10px;cursor:pointer;flex-shrink:0}
.rir-clear:hover{border-color:var(--red);color:var(--red)}

/* PAIN FLAG */
.pain-btn{background:none;border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-size:.72rem;font-family:var(--font-ui);padding:3px 9px;cursor:pointer;transition:all .15s;flex-shrink:0;margin-top:2px}
.pain-btn:hover{border-color:var(--org);color:var(--org)}
.pain-btn.active{background:var(--odim);border-color:var(--org);color:var(--org)}
.pain-tag-wrap{display:none;margin-top:6px}
.pain-tag-wrap.show{display:block}
.pain-tag-input{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.8rem;padding:6px 10px;outline:none;width:100%;-webkit-appearance:none}
.pain-tag-input:focus{border-color:var(--org)}

/* PER-SET WARM-UP TOGGLE + INJURY FLAG (Phase 0a) */
.wu-btn{background:none;border:1px solid var(--b1);border-radius:6px;color:var(--mut);font-family:'JetBrains Mono',monospace;font-size:.7rem;font-weight:600;padding:7px 9px;cursor:pointer;transition:all .15s;flex-shrink:0}
.wu-btn:hover{border-color:var(--acc2);color:var(--acc2)}
.wu-btn.on{background:var(--adim);border-color:var(--acc2);color:var(--acc2)}
.set-row.warmup .set-input,.set-row.warmup .set-num,.set-row.warmup .set-sep{opacity:.55}
/* Column headers over the two set inputs (T5). These MUST mirror .set-row's leading
   flex geometry exactly, or the labels sit over the wrong boxes, which is worse than
   having no labels at all (audit 2026-08-02: "reps" measured at centre x=162, i.e. over
   the WEIGHT input, because it was flex:1 with no cap while the reps input IS capped).
   The reps input is `.set-input{flex:1}` + inline max-width:72px, and the weight input
   is inline width:72px;flex:none, so the header columns copy both, and a flex:1 tail
   spacer absorbs the leftover width the way the row's trailing controls do. */
.set-hdr{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.set-hdr .set-num{visibility:hidden}
.set-hdr-reps{flex:1;max-width:72px;text-align:center;font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:var(--mut2)}
.set-hdr-lbs{width:72px;flex:none;text-align:center;font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:var(--mut2)}
.set-hdr-tail{flex:1 1 auto;min-width:0}
.set-hdr .set-sep{visibility:hidden}
/* Role chip beside the exercise name in a live session (T6). Accessory and untagged
   show nothing: untagged silently means Accessory and that stays. */
.bw-chip{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:20px;background:none;border:1px solid var(--b2);color:var(--mut2);font-family:'JetBrains Mono',monospace;font-size:.62rem;font-weight:600;letter-spacing:.04em;vertical-align:middle;white-space:nowrap;cursor:pointer}
.bw-chip.on{border-color:var(--acc2);color:var(--acc2);background:var(--s3)}
.plan-ex-tag-btn.on{border-color:var(--acc2);color:var(--acc2)}
.main-chip{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:20px;border:1px solid var(--acc);color:var(--acc);font-size:.62rem;font-weight:600;letter-spacing:.04em;vertical-align:middle;white-space:nowrap}
.inj-btn{background:none;border:1px solid var(--b1);border-radius:6px;color:var(--mut);font-size:.78rem;padding:6px 9px;cursor:pointer;transition:all .15s;flex-shrink:0}
.inj-btn:hover{border-color:var(--org);color:var(--org)}
.inj-btn.on{background:var(--odim);border-color:var(--org);color:var(--org)}
.set-inj{display:none;flex-basis:100%;margin-top:4px}
.set-inj.open{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.set-inj-label{font-family:'JetBrains Mono',monospace;font-size:.64rem;color:var(--org);white-space:nowrap;margin-right:2px}
.inj-chip{background:var(--s2);border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-family:'JetBrains Mono',monospace;font-size:.74rem;font-weight:600;padding:5px 12px;cursor:pointer;transition:all .15s;flex-shrink:0}
.inj-chip:hover{border-color:var(--org);color:var(--org)}
.inj-chip.sel{background:var(--odim);border-color:var(--org);color:var(--org)}
.inj-note-input{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.78rem;padding:6px 10px;outline:none;flex:1;min-width:130px;-webkit-appearance:none}
.inj-note-input:focus{border-color:var(--org)}
.inj-clear{background:none;border:1px solid var(--b1);border-radius:20px;color:var(--mut);font-size:.72rem;padding:4px 10px;cursor:pointer;flex-shrink:0}
.inj-clear:hover{border-color:var(--red);color:var(--red)}
.spill-rest{margin-left:6px;opacity:.65;font-size:.62rem;letter-spacing:-.01em}
.spill.wu{opacity:.6}
.spill.inj{border-color:var(--org);color:var(--org)}
/* EX NOTE */
.note-btn{background:none;border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-size:.72rem;font-family:var(--font-ui);padding:3px 9px;cursor:pointer;transition:all .15s;flex-shrink:0;margin-top:2px}
.note-btn:hover{border-color:var(--acc);color:var(--acc)}
.note-btn.active{background:var(--adim);border-color:var(--acc);color:var(--acc)}
.model-btn{background:none;border:1px solid var(--b1);border-radius:20px;color:var(--mut2);font-size:.72rem;font-family:var(--font-ui);padding:3px 9px;cursor:pointer;transition:all .15s;flex-shrink:0;margin-top:2px;white-space:nowrap}
.model-btn:hover{border-color:var(--acc);color:var(--acc)}
.model-btn.drop{background:var(--adim);border-color:var(--acc);color:var(--acc)}
.note-tag-wrap{display:none;margin-top:6px}
.note-tag-wrap.show{display:block}
.note-tag-input{background:var(--s2);border:1px solid var(--b1);border-radius:var(--rsm);color:var(--txt);font-family:var(--font-ui);font-size:.8rem;padding:6px 10px;outline:none;width:100%;-webkit-appearance:none}
.note-tag-input:focus{border-color:var(--acc)}

/* ── MOBILE BOTTOM NAV ── */
@media(max-width:640px){
  /* Contain horizontal overflow on <html> ONLY. Putting overflow-x:hidden on
     <body> too makes the body a nested scroll container, which breaks touch
     scrolling on iOS Safari (scrolls programmatically but not by finger). */
  html{overflow-x:hidden}

  /* Move tab buttons to a fixed bottom bar (SPEC screen 1: Home · History · Progress ·
     Workouts). Re-skinned off the theme vars (was a hardcoded dark rgba) so it matches
     tokens.css in all three themes; env(safe-area-inset-bottom,10px) covers most devices
     but Android installed-PWAs (Samsung) can report the env() itself as 0, so a hard
     10px floor is added separately in the standalone media query below. */
  .ntabs{
    position:fixed;bottom:0;left:0;right:0;z-index:250;
    background:var(--s1);
    background:color-mix(in srgb, var(--bg) 97%, transparent);backdrop-filter:blur(16px);
    border-top:1px solid var(--b1);
    display:flex;padding:6px 0 env(safe-area-inset-bottom,10px);
  }
  .ntab{
    flex:1;border-radius:0;padding:4px 2px 6px;min-height:44px;box-sizing:border-box;
    font-size:.6rem;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:2px;white-space:nowrap;
  }
  /* Bottom-tab icons. SPEC R1: "No emoji-as-icons anywhere ... 1.5-2px stroke,
     currentColor". These were emoji glyphs (calendar / chart / clipboard) plus a
     typographic house character, which also rendered as four different vendor
     illustrations across devices and ignored the theme entirely.
     Implemented as CSS masks rather than inline SVG because the tab markup lives in
     the shared shell: mask-image + background:currentColor keeps the stroke icon
     following .ntab's own colour, so the active/inactive token colours (and all three
     themes) work with no markup change and no JS. */
  .ntab::before{
    content:"";
    width:22px;height:22px;
    background:currentColor;
    -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    -webkit-mask-position:center;mask-position:center;
    -webkit-mask-size:contain;mask-size:contain;
  }
  .ntab[data-page="home"]::before{
    -webkit-mask-image:var(--icon-home);mask-image:var(--icon-home);
  }
  .ntab[data-page="history"]::before{
    -webkit-mask-image:var(--icon-history);mask-image:var(--icon-history);
  }
  .ntab[data-page="progress"]::before{
    -webkit-mask-image:var(--icon-progress);mask-image:var(--icon-progress);
  }
  .ntab[data-page="plans"]::before{
    -webkit-mask-image:var(--icon-plans);mask-image:var(--icon-plans);
  }

  /* Top nav: just logo + person toggle + sync dot.
     backdrop-filter must be OFF here: a filtered ancestor becomes the
     containing block for position:fixed children, which would trap the
     fixed .ntabs bottom bar inside the nav (pinned to the top of the
     screen) instead of the viewport bottom. The 95%-opaque bg makes the
     blur imperceptible anyway. */
  nav{padding:0 14px;gap:8px;height:50px;backdrop-filter:none;-webkit-backdrop-filter:none}
  /* Batch 2026-08-28 (item 5): the top-left Home button (the former brand/home
     anchor on phones) was removed, so the wordmark is un-hidden here - it is now
     the only brand element left in the top nav on small screens. */
  .person-toggle{margin-left:auto;margin-right:0}

  /* Page content — pad bottom so it clears the bottom nav */
  .page{padding:14px 14px 90px}

  /* Active session timer bar sits above bottom nav */
  .workout-timer{
    position:fixed;bottom:calc(56px + env(safe-area-inset-bottom,0px));
    top:auto;left:0;right:0;
  }
}
/* Installed Android PWA hard floor (Samsung reports safe-area-inset-bottom as 0 even
   though the OS nav bar is present) — force a minimum bottom padding so the tab bar
   never sits under the gesture/nav bar. Desktop/browser-tab users never match this
   media query, so it never touches the non-installed layout. */
@media(max-width:640px) and (display-mode:standalone){
  .ntabs{padding-bottom:max(env(safe-area-inset-bottom,10px),10px)}
}
/* R1 token re-skin (AC-5): true headings (never numerals) follow --font-heading, which
   is --font-ui in clean voice and --font-hand (Caveat) in handwritten voice. Numeral
   classes (dash-stat-v, dash-bw-v, wt-time, set-input, dash-ring-num, sess-date, etc.)
   are deliberately NOT in this list - they stay JetBrains Mono in every theme/voice. */
.sec-title,.stats-title,.plan-modal-title,.fb-title,.dash-last-title,
.empty h3,.dash-card-hdr,.picker-section-label{font-family:var(--font-heading)}
/* A2 (screen 22): the wordmark is JetBrains Mono in clean voice (its base rule) and
   Caveat only in handwritten - unlike other headings it must NOT fall back to
   Instrument Sans in clean, so it is out of the --font-heading list above. */
:root[data-voice="handwritten"] .logo{font-family:var(--font-hand);font-size:1.15rem}
