/* Dialled — UI styling.
   Desktop: dark left sidebar + a light content column; British racing green accent.
   Mobile: bottom tabs. No CSS framework: Bootstrap was removed because its own
   .modal / .row rules collided with ours and hid the dialogs. */
:root {
    --bg: #e9e9ea;
    --card: #ffffff;
    --card2: #f4f4f5;
    --card3: #ebebed;
    --line: #e3e4e8;
    --line2: #d3d5da;
    --text: #17181b;
    --muted: #6b7280;
    --muted2: #9aa1ac;
    --accent: #004225;          /* British racing green */
    --accent-d: #00301b;
    --accent-soft: #e2ece6;
    --accent-soft2: #f0f5f2;
    --accent-text: #0b5a36;
    --ok: #2f9e44;
    --ok-soft: #e5f5e9;
    --info: #1a73e8;
    --info-soft: #e7f0fe;
    --mid: #d99a1c;
    --over: #e0563b;
    --danger: #d8483f;
    --danger-soft: #fdecea;
    --note-bg: #fff8e1;
    --note-line: #f0e3b0;
    --note-text: #5f4b12;
    --sidebar: #222327;
    --sidebar-2: #2d2e33;
    --sidebar-text: #e8e9eb;
    --sidebar-muted: #8b8f97;
    /* Tinted surfaces and the text that sits on them. These were literal colours in the rules,
       which meant a dark palette would have had to find and fix each one. Named here so a theme is
       a set of values rather than a search. Light values are exactly what they replaced. */
    --input-bg: #f4f4f5;         /* what you type into; recessed on dark, raised on light */
    --focus-bg: #ffffff;          /* what an input lifts to while you are typing in it */
    --ok-line: #cfe9d6;
    --ok-text: #38614f;
    --ok-tint: #eef4f1;
    --ok-tint-line: #d5e3dc;
    --bad-tint: #fbeeec;
    --bad-line: #f0d2cf;
    --bad-text: #8c3a30;
    --warn-tint: #fdf3e3;
    --warn-text-c: #8a6320;
    --warncard-tint: #fdf3f1;
    --warncard-line: #e5b8b0;
    --warncard-text: #8c2f1c;
    --info-tint: #eaf1fb;
    --info-text-c: #2f5c96;
    --deload: #55618a;
    --deload-tint: #eef0ff;
    --deload-line: #d5daf5;
    --deload-text: #3b4685;
    --zone-mv: #e6e6e9;
    --zone-mev: #fdf0d2;
    --zone-good: #dff0e4;
    --error-tint: #fff3cd;
    --sum-empty: #cfd8d3;      /* the pale end of the summary heat scale */

    --r: 12px;
    --sh: 0 1px 2px rgba(20,22,30,.05), 0 4px 14px rgba(20,22,30,.05);
    --safe-b: env(safe-area-inset-bottom, 0px);
    --safe-t: env(safe-area-inset-top, 0px);
    --tab-h: 56px;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }

/* Stops the rubber-band bounce past the top and bottom of the page. On iOS that bounce drags
   fixed elements with it, so the bottom bar appears to slide about. It also disables
   pull-to-refresh, which mid-workout is a feature: an accidental refresh is the last thing you
   want two sets in.

   No scrollbar-gutter here: reserving room for a scrollbar costs a real 15px of width on every
   page, which the browser suite caught immediately as the feedback sheet coming up 375px wide on
   a 390px screen. A phone has no scrollbar to reserve room for anyway. */
html { overscroll-behavior-y: none; }

body {
    /* Kills the double-tap-to-zoom gesture, which iOS honours even where it ignores
       user-scalable=no. Panning and scrolling are untouched. */
    touch-action: manipulation;
    background: var(--bg); color: var(--text);
    font: 15px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-text); text-decoration: none; }
button { font-family: inherit; }
input, select, textarea { font-family: inherit; }

/* ---- shell ---- */
/* svh, not dvh. The "dynamic" viewport height is exactly that: on an iPhone it changes
   continuously while Safari's toolbar slides away as you scroll, so anything sized against it
   resizes on every scroll — which is felt as the page moving under your thumb and which a
   desktop browser cannot reproduce. svh is the small viewport, the same number whether the
   toolbar is there or not. vh first, for anything that has not heard of svh. */
.app-shell { min-height: 100vh; min-height: 100svh; display: flex; }

/* Shown only on the test copy. Amber rather than red: this is a signpost, not an error. It takes
   the safe-area padding itself so the page below it does not have to, which is why .is-test flattens
   the top padding the main column would otherwise add. */
.testbar { background: #8a6320; color: #fff; font-size: 12.5px; font-weight: 600; text-align: center;
           padding: calc(6px + var(--safe-t)) 12px 6px; letter-spacing: .02em; }
.testbar b { letter-spacing: .06em; }
.app-shell.is-test .app-main { padding-top: 14px; }

/* The strip that says what the sync is doing - and only when there is something to say. With a
   connection and everything sent, which is nearly always, it is not there at all. It sits where
   the test strip sits and is built the same way: in normal flow, so it pushes the page down
   rather than covering the top of it, and carrying the safe-area padding itself when it is the
   first thing on the screen.

   Three moods, all from the palette's own variables so each is right in light and in dark.
   "offline" is deliberately calm: having no signal in a gym is ordinary, and the message is that
   nothing is wrong. */
.syncbar { font-size: 12.5px; font-weight: 600; text-align: center; line-height: 1.35;
    padding: calc(6px + var(--safe-t)) 14px 6px; background: var(--card3); color: var(--text);
    border-bottom: 1px solid var(--line2); }
.testbar + .syncbar { padding-top: 6px; }
.syncbar.warn { background: var(--warn-tint); color: var(--warn-text-c); border-bottom-color: transparent; }
.syncbar.update { background: var(--accent); color: #fff; border-bottom-color: transparent; }
.syncbar a { color: inherit; text-decoration: underline; }
.syncbar-btn { margin-left: 8px; padding: 2px 10px; border-radius: 999px; border: 1px solid currentColor;
    background: transparent; color: inherit; font: inherit; cursor: pointer; }
.syncbar ~ .app-shell .app-main { padding-top: 14px; }

/* What is on screen before the app has started, and if it cannot. The same mark as the sign-in
   page, in the middle of an otherwise empty screen. */
.boot { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 12px; padding: 24px; text-align: center; color: var(--text); }
.boot .brand-mark { width: 56px; height: 56px; border-radius: 13px; font-size: 24px; }
.boot-word { font-weight: 800; letter-spacing: .14em; font-size: 15px; }
.boot-note { color: var(--muted); font-size: 14px; }
.boot-problem { max-width: 340px; color: var(--muted); font-size: 14.5px; line-height: 1.45; margin: 4px 0 8px; }
.content-wrap { flex: 1; min-width: 0; }
.app-main { padding: calc(22px + var(--safe-t)) 26px 48px; }
.page { max-width: 660px; margin: 0 auto; }
.page.mid { max-width: 880px; }
.page.wide { max-width: none; }
.loading { text-align: center; color: var(--muted); padding: 50px; }
.spacer { height: 40px; }

/* ---- sidebar (desktop) ---- */
.sidebar {
    width: 250px; flex: 0 0 250px; background: var(--sidebar); color: var(--sidebar-text);
    min-height: 100dvh; position: sticky; top: 0; align-self: flex-start;
    display: flex; flex-direction: column; padding: 18px 12px;
}
.brand { display: flex; align-items: center; gap: 11px; padding: 6px 8px 26px; }
.brand-mark { width: 40px; height: 40px; border-radius: 9px; background: var(--accent); color: #fff; font-weight: 800; display: flex; align-items: center; justify-content: center; font-size: 15px; letter-spacing: -.5px; flex: 0 0 auto; }
.brand-word { display: flex; flex-direction: column; line-height: 1.08; }
.brand-word span { font-size: 10.5px; letter-spacing: .13em; color: #8fc8a8; font-weight: 700; }
.brand-word b { font-size: 15px; letter-spacing: .01em; }
.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-bottom { margin-top: auto; display: flex; flex-direction: column; gap: 2px; padding-top: 16px; }
.side-link { display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: 8px; color: var(--sidebar-text); font-weight: 600; font-size: 14.5px; }
.side-link:hover { background: rgba(255,255,255,.06); }
.side-link.active { background: rgba(255,255,255,.13); }
.side-link .si { display: flex; width: 22px; justify-content: center; color: var(--sidebar-muted); }
.side-link:hover .si, .side-link.active .si { color: inherit; }
.side-link.as-btn { width: 100%; background: transparent; border: none; cursor: pointer; text-align: left; }
.side-logout { margin: 0; }
.side-foot { padding: 14px 12px 0; color: var(--sidebar-muted); font-size: 11px; font-family: ui-monospace, Consolas, monospace; }

/* ---- line icons (Icon.razor) ---- */
/* They take the colour of whatever they sit in, which is the whole point of using
   drawings rather than emoji — a button, a muted caption and an active tab all get
   the right shade with no extra rules. */
.ic { display: inline-block; vertical-align: -.15em; flex: 0 0 auto; }
.ex-last .ic { vertical-align: -.2em; margin-right: 2px; }
.warn .ic, .banner .ic { vertical-align: -.2em; margin-right: 4px; }
h3 .ic { vertical-align: -.12em; margin-right: 6px; }

/* ---- typography / bits ---- */
h1 { font-size: 26px; margin: 0; letter-spacing: -.02em; }
h1:focus { outline: none; }   /* the router focuses h1 after navigation; no ring needed */
h2 { font-size: 20px; margin: 0 0 8px; }
h3 { font-size: 16px; margin: 0 0 10px; }
.nomargin { margin: 0; }
.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.center { text-align: center; }
.center-x { justify-content: center; }
.eyebrow { color: var(--accent-text); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.section { margin: 22px 4px 10px; color: var(--muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; }
code { background: var(--card2); padding: 1px 5px; border-radius: 5px; font-size: 12px; }

.hrow { display: flex; align-items: center; }
.hrow.between { justify-content: space-between; gap: 10px; }
.hrow.gap { gap: 8px; flex-wrap: wrap; }
.grow { flex: 1; }
.pos-rel { position: relative; }

/* ---- buttons ---- */
.btn { appearance: none; border: 1px solid var(--line); background: var(--card2); color: var(--text); padding: 11px 16px; border-radius: 9px; font-size: 14.5px; font-weight: 600; cursor: pointer; transition: transform .1s, background .12s; text-align: center; display: inline-block; line-height: 1.3; }
.btn:hover { background: var(--card3); }
.btn:active { transform: scale(.97); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-d); }
.btn.primary:disabled { opacity: .45; cursor: default; }
.btn:disabled { opacity: .45; cursor: default; }
.btn.big { width: 100%; padding: 15px; font-size: 16px; margin-top: 6px; }
.btn.small { padding: 8px 13px; font-size: 13px; border-radius: 8px; }
.btn.ghost { background: transparent; }
.btn.danger { background: transparent; border-color: var(--bad-line); color: var(--danger); }
.ibtn { background: transparent; border: none; color: var(--text); width: 36px; height: 36px; border-radius: 8px; font-size: 17px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.ibtn:hover { background: var(--card2); }
.ibtn.sm { width: 30px; height: 30px; font-size: 15px; }
.ibtn.boxed { border: 1px solid var(--line); background: var(--card); box-shadow: var(--sh); }
.link { background: none; border: none; color: var(--text); font-weight: 600; cursor: pointer; font-size: 14.5px; padding: 8px 10px; }
.link:disabled { opacity: .4; cursor: default; }
.link-btn { background: none; border: none; padding: 0; color: var(--accent-text); text-decoration: underline; cursor: pointer; font-size: inherit; }

/* ---- cards ---- */
.card, .wcard { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; margin-bottom: 12px; box-shadow: var(--sh); display: block; }
.wcard.empty, .card.empty { text-align: center; padding: 40px 20px; }
.wcard.empty h2 { margin-bottom: 8px; }
.wcard.empty .hrow { margin-top: 18px; }
.panel { background: var(--card); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--sh); padding: 8px 22px; }
.stack > * { margin-bottom: 12px; }

/* ---- workout header ---- */
.whead { position: relative; padding: 16px 16px 18px; display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.wk { font-weight: 800; font-size: 18px; letter-spacing: .02em; }
.wk .dy { color: var(--muted); font-weight: 700; }
.wsub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.whead-actions { display: flex; align-items: center; gap: 6px; }
.wprog { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--card3); overflow: hidden; border-bottom-left-radius: var(--r); border-bottom-right-radius: var(--r); }
.wprog > div { height: 100%; background: var(--accent); transition: width .2s; }

/* calendar popover (week × day grid) */
.cal { padding: 14px 16px 16px; }
.cal-title { font-weight: 800; font-size: 17px; margin-bottom: 10px; }
.cal-grid { display: grid; gap: 6px; overflow-x: auto; }
.cal-w { text-align: center; font-weight: 800; font-size: 13px; padding: 4px 0 2px; color: var(--text); }
.cal-w.cur { color: var(--accent-text); }
.cal-cell { border: 1px solid var(--line); background: var(--card); border-radius: 6px; padding: 8px 2px; font-size: 12px; font-weight: 600; color: var(--text); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: clip; text-align: center; font-family: ui-monospace, Consolas, monospace; }
.cal-cell:hover { background: var(--card2); }
.cal-cell.done { background: var(--ok-soft); border-color: var(--ok-line); color: var(--ok); }
.cal-cell.skipped { background: var(--card3); color: var(--muted); text-decoration: line-through; }
.cal-cell.started { background: var(--accent-soft2); border-color: var(--accent-soft); color: var(--accent-text); }
.cal-cell.cur { border: 2px solid var(--text); }

/* ---- exercise card ---- */
.wcard.ex { padding: 0 0 6px; overflow: visible; margin-top: 24px; position: relative; }
.wcard.ex:first-of-type { margin-top: 12px; }
.mtag { position: absolute; top: -12px; left: 12px; display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px 3px 7px; border-radius: 6px; font-size: 10.5px; font-weight: 800; letter-spacing: .05em; color: var(--c); background: color-mix(in srgb, var(--c) 10%, white); border: 1px solid color-mix(in srgb, var(--c) 28%, white); }
.mtag .bars { display: inline-flex; gap: 2px; align-items: flex-end; height: 10px; }
.mtag .bars b { display: block; width: 3px; border-radius: 1px; background: currentColor; height: 10px; }
.mtag.static { position: static; margin-bottom: 8px; }
.ex-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 16px 12px 8px 14px; }
.ex-name { font-weight: 700; font-size: 16px; line-height: 1.25; }
.ex-type { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.ex-icons { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }
.ex-note { margin: 0 14px 8px; padding: 8px 11px; border-radius: 8px; background: var(--accent-soft2); border-left: 3px solid var(--accent); font-size: 12.5px; color: var(--accent-text); }
.note-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 14px 6px; padding: 6px 10px; border-radius: 6px; background: var(--card2); border: 1px solid var(--line); color: var(--muted); font-size: 12.5px; }
.note-bar.pinned { background: var(--note-bg); border-color: var(--note-line); color: var(--note-text); }
.note-actions { display: flex; gap: 2px; flex: 0 0 auto; }
.pin { background: none; border: none; cursor: pointer; font-size: 13px; opacity: .4; padding: 2px 4px; color: inherit; }
.pin:hover { opacity: .8; }
.pin.on { opacity: 1; }
.pin.on .ic { fill: currentColor; }
.set-grid { display: grid; grid-template-columns: 30px 56px 1fr 1fr 22px 54px; align-items: center; gap: 7px; padding: 0 10px 0 6px; }
.set-grid.head { font-size: 11px; color: var(--muted); font-weight: 700; letter-spacing: .04em; margin: 8px 0 4px; text-align: center; }
.set-grid.head span:last-child { text-align: right; padding-right: 6px; }
.set-grid.row { padding-top: 7px; padding-bottom: 7px; border-top: 1px solid var(--line); }
.set-grid.row.done { background: var(--card2); }
.info-i { display: inline-flex; align-items: center; justify-content: center; width: 13px; height: 13px; border-radius: 50%; border: 1px solid var(--muted2); font-size: 9px; font-style: normal; font-weight: 700; margin-left: 3px; color: var(--muted2); cursor: help; }
.set-kebab { background: none; border: none; color: var(--muted); font-size: 17px; cursor: pointer; width: 30px; height: 30px; border-radius: 6px; }
.set-kebab:hover { background: var(--card3); }
.num { width: 100%; background: var(--input-bg); border: 1.5px solid var(--input-bg); color: var(--text); border-radius: 7px; padding: 9px 8px; font-size: 15px; text-align: center; font-weight: 600; }
.num::placeholder { color: var(--muted2); font-weight: 500; }
.num:focus { outline: none; border-color: var(--accent); background: var(--focus-bg); }

/* A ticked set is a record, not a field. Making it readonly refused the edit but nothing more:
   tapping it still focused the box, so it turned white with an accent border - the whole
   appearance of something you can type in - and then nothing happened and no keyboard came up.
   On a phone that reads as the app being broken rather than the set being finished. A locked box
   now ignores the tap and stays exactly as it looks. Un-tick the set to change it. */
.num[readonly] { pointer-events: none; }
.num[readonly]:focus { border-color: var(--card2); background: var(--card2); }
.num.bw { cursor: pointer; }
.logbox { justify-self: end; width: 28px; height: 28px; border-radius: 5px; border: 2px solid var(--line2); background: var(--card); color: #fff; font-weight: 800; cursor: pointer; font-size: 15px; line-height: 1; display: flex; align-items: center; justify-content: center; margin-right: 6px; }
.logbox.next { border-color: var(--ok); }
.logbox.on { background: var(--ok); border-color: var(--ok); }
.toast { margin: 8px 14px 6px; padding: 9px 12px; border-radius: 8px; background: var(--danger); color: #fff; font-weight: 600; font-size: 13px; }
.toast.float { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 60; margin: 0; background: var(--text); box-shadow: 0 8px 30px rgba(0,0,0,.25); max-width: 90vw; }
.finish-hint { text-align: center; padding: 14px; }
.gate { text-align: center; padding: 28px 20px; }
.gate h2 { margin-top: 12px; }
.gate .hrow { margin-top: 18px; justify-content: center; }

/* ---- menus ---- */
.menu-back { position: fixed; inset: 0; z-index: 30; }
.menu-pop { position: absolute; right: 0; top: 100%; z-index: 40; background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 30px rgba(0,0,0,.14); min-width: 170px; overflow: hidden; padding: 4px 0; }
.menu-pop.left { left: 0; right: auto; }
.menu-pop.wide { min-width: 190px; }
.menu-pop button { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: none; padding: 9px 14px; font-size: 13.5px; cursor: pointer; color: var(--text); font-weight: 500; }
.menu-pop button:hover { background: var(--card2); }
.menu-pop button:disabled { color: var(--muted2); cursor: default; background: none; }
.menu-pop button.danger { color: var(--danger); }
.menu-h { padding: 8px 14px 4px; font-weight: 800; font-size: 13px; color: var(--muted); }

/* ---- mesocycle list ---- */
.listcard { padding: 10px 18px 14px; }
.list-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 2px 6px; }
.list-head h1 { font-size: 24px; }
.add-round { width: 38px; height: 38px; border-radius: 50%; border: none; background: transparent; color: var(--text); font-size: 26px; cursor: pointer; line-height: 1; }
.add-round:hover { background: var(--card2); }
.meso-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 2px; border-bottom: 1px solid var(--line); cursor: pointer; }
.meso-row:last-child { border-bottom: none; }
.meso-row:hover .meso-name { color: var(--accent-text); }
.meso-name { font-weight: 700; font-size: 17px; }
.meso-sub { color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; margin-top: 3px; }
.meso-right { display: flex; align-items: center; gap: 8px; }
.badge { font-size: 11px; font-weight: 700; padding: 5px 9px; border-radius: 5px; white-space: nowrap; letter-spacing: .03em; display: inline-block; }
.badge.current { background: var(--info-soft); color: var(--info); }
.badge.done { background: var(--accent); color: #fff; }
.badge.draft { background: var(--card3); color: var(--muted); }
.badge.skipped { background: var(--card3); color: var(--muted); }
.badge.phase { background: var(--accent-soft); color: var(--accent-text); }
.kebab { background: none; border: none; color: var(--text); font-size: 20px; cursor: pointer; padding: 2px 8px; line-height: 1; border-radius: 6px; }
.kebab:hover { background: var(--card2); }

/* ---- plan chooser ---- */
.choice { display: flex; align-items: center; gap: 16px; width: 100%; text-align: left; background: var(--card2); border: 1px solid var(--line); border-radius: 12px; padding: 18px; margin-bottom: 12px; cursor: pointer; color: var(--text); }
.choice:hover { background: var(--card3); }
.choice .ci { width: 44px; height: 44px; border-radius: 50%; background: var(--card); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; font-size: 19px; flex: 0 0 auto; }
.choice .ct { flex: 1; }
.choice .ct b { font-size: 15.5px; }
.choice .ct div { color: var(--muted); font-size: 13px; margin-top: 2px; }
.choice .cv { color: var(--muted2); font-size: 20px; }

/* ---- meso builder (kanban) ---- */
.builder-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; gap: 12px; }
.builder-top h1 { font-size: 24px; }
.builder-actions { display: flex; align-items: center; gap: 8px; }
.meso-board { display: flex; gap: 16px; align-items: flex-start; overflow-x: auto; padding: 6px 2px 16px; }
.day-col { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px; width: 282px; flex: 0 0 282px; box-shadow: var(--sh); min-height: 120px; }
/* The column you are about to drop into. A dashed outline appearing from nowhere reads as an
   error; this lifts and tints instead, which reads as "yes, here". */
.day-col { transition: background .16s ease, box-shadow .16s ease, transform .16s ease; }
.day-col.over { background: var(--accent-soft2); box-shadow: 0 0 0 2px var(--accent-soft), var(--sh); transform: translateY(-2px); }
.day-col-head { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.drag-dots { color: var(--muted2); cursor: grab; font-size: 16px; user-select: none; padding: 4px 2px; touch-action: none; -webkit-user-select: none; }
.drag-dots:active { cursor: grabbing; }
.day-label { flex: 1; padding: 9px 2px; font-size: 12px; font-weight: 800; letter-spacing: .08em; color: var(--muted); min-width: 0; }
.slot-card { background: var(--card2); border: 1px solid var(--line); border-radius: 10px; padding: 10px 10px 10px 6px; margin-bottom: 8px; display: grid; grid-template-columns: 26px 1fr 28px; gap: 6px; align-items: center; cursor: grab; }
.slot-card:active { cursor: grabbing; }
/* Being dragged with a mouse. The browser is already carrying a picture of the card around, so
   what is left behind should look like the gap it came out of - flattened and receded - rather
   than the same card at 40% opacity, which just looks broken. */
.slot-card.dragging { opacity: .3; transform: scale(.97); border-style: dashed; background: transparent; box-shadow: none; }

/* Lifted under a finger. This one really is the card in your hand, so it rises off the page.
   No transition on transform: that is the drag itself. */
.slot-card.drag-live { position: relative; z-index: 5; box-shadow: 0 12px 28px rgba(0,0,0,.22); border-color: var(--accent); background: var(--card); }

/* Everything not under the hand animates: cards sliding aside on touch, a card settling into its
   new place after a drop, and the flatten/lift above. */
.slot-card:not(.drag-live) { transition: transform .18s cubic-bezier(.2, .8, .2, 1), opacity .14s ease, box-shadow .16s ease, background .16s ease, border-color .16s ease; }
.slot-card:hover:not(.dragging):not(.drag-live) { border-color: var(--line2); }
@media (prefers-reduced-motion: reduce) {
    .slot-card, .slot-card:not(.drag-live), .day-col { transition: none; }
}
.slot-grip { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.nudge { background: none; border: none; color: var(--muted2); font-size: 11px; line-height: 1; padding: 5px 3px; cursor: pointer; border-radius: 5px; }
.nudge:hover:not(:disabled) { color: var(--accent-text); background: rgba(0,0,0,.05); }
.nudge:disabled { opacity: .25; cursor: default; }
.slot-body { min-width: 0; }
.slot-muscle { display: flex; align-items: center; gap: 7px; font-weight: 700; font-size: 14px; margin-bottom: 6px; }
.muscle-bars { display: inline-flex; gap: 2px; align-items: flex-end; height: 12px; }
.muscle-bars i { width: 3px; border-radius: 1px; background: currentColor; height: 12px; }
.prio { display: inline-flex; gap: 2px; align-items: flex-end; height: 13px; background: none; border: none; padding: 0 2px; cursor: pointer; border-radius: 3px; }
.prio:hover { background: rgba(0,0,0,.06); }
.prio i { width: 3px; height: 13px; border-radius: 1px; background: currentColor; opacity: .22; }
.prio i.on { opacity: 1; }
.rep-chip { margin-top: 6px; background: none; border: 1px dashed var(--line2); color: var(--muted); border-radius: 6px; padding: 3px 8px; font-size: 11.5px; font-weight: 600; cursor: pointer; }
.rep-chip:hover { color: var(--accent-text); border-color: var(--accent); }
.ico { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; display: block; }
.slot-del { background: none; border: none; color: var(--muted); cursor: pointer; width: 32px; height: 32px; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.slot-del:hover { background: var(--danger-soft); color: var(--danger); }
.prio-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 4px; border-bottom: 1px solid var(--line); }
.prio-pick { display: flex; gap: 6px; }
.prio-pick button { display: inline-flex; align-items: center; gap: 6px; border: 1.5px solid var(--line); background: var(--card2); color: var(--muted); border-radius: 7px; padding: 6px 10px; font-size: 12px; font-weight: 700; cursor: pointer; }
.prio-pick button.sel { border-color: var(--accent); background: var(--accent-soft2); color: var(--accent-text); }
.choose-ex { width: 100%; text-align: left; background: var(--card); border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px; color: var(--muted); cursor: pointer; font-size: 13.5px; line-height: 1.3; }
.choose-ex:hover { border-color: var(--line2); }
.choose-ex.filled { color: var(--text); font-weight: 600; }
.add-mg { width: 100%; display: flex; align-items: center; gap: 9px; justify-content: flex-start; background: var(--card2); border: 1px solid var(--line); border-radius: 10px; padding: 12px; cursor: pointer; font-weight: 600; font-size: 14px; color: var(--text); }
.add-mg:hover { background: var(--card3); }
.add-mg .plus { color: var(--muted); font-size: 17px; line-height: 1; }
.add-day-col { flex: 0 0 200px; }
.add-day-btn { width: 100%; display: flex; align-items: center; justify-content: center; gap: 10px; background: var(--card2); border: 1px solid var(--line); border-radius: 12px; padding: 16px; cursor: pointer; font-weight: 700; font-size: 15px; color: var(--text); box-shadow: var(--sh); }
.add-day-btn:hover { background: var(--card3); }

/* segmented control */
.segmented { display: flex; border: 1px solid var(--accent); border-radius: 7px; overflow: hidden; }
.segmented button { flex: 1; padding: 13px 6px; background: var(--accent-soft2); border: none; border-right: 1px solid var(--accent-soft); cursor: pointer; font-weight: 700; font-size: 15px; color: var(--accent-text); }
.segmented button:last-child { border-right: none; }
.segmented button.sel { background: var(--accent); color: #fff; }

/* ---- muscle-group picker (with counters) ---- */
.mg-cat { font-weight: 800; font-size: 16px; margin: 16px 0 8px; }
.mg-item { display: flex; align-items: center; justify-content: space-between; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 10px 10px 10px 15px; margin-bottom: 8px; }
.mg-item.sel { border-color: var(--accent); background: var(--accent-soft2); }
.mg-name { display: flex; align-items: center; font-size: 15px; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 9px; flex: 0 0 auto; }
.mg-ctl { display: flex; align-items: center; gap: 8px; }
.mg-ctl b { min-width: 16px; text-align: center; font-size: 15px; }
.mg-btn { width: 32px; height: 32px; border-radius: 7px; border: 1px solid var(--line); background: var(--card2); font-size: 18px; cursor: pointer; color: var(--text); line-height: 1; }
.mg-btn:hover { background: var(--card3); }

/* ---- exercise chooser / list rows ---- */
.filter-row { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; color: var(--muted); font-size: 13px; }
.filter-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--card3); border-radius: 6px; padding: 5px 10px; font-weight: 600; color: var(--text); }
.filter-chip button { background: none; border: none; cursor: pointer; font-size: 13px; color: var(--muted); padding: 0; }
.ex-item { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: var(--card); border: none; border-bottom: 1px solid var(--line); padding: 13px 6px; cursor: pointer; color: var(--text); }
.ex-item:hover { background: var(--card2); }
.ex-item .radio { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line2); flex: 0 0 auto; }
.ex-item.sel .radio { border-color: var(--accent); background: radial-gradient(circle at center, var(--accent) 0 6px, var(--card) 6px 100%); }
.ex-meta { flex: 1; min-width: 0; }
.ex-n { font-weight: 600; font-size: 15px; }
.ex-tag { font-size: 12px; color: var(--muted); margin-top: 2px; display: flex; align-items: center; gap: 5px; }
.ex-tag .m { font-weight: 700; }
.ex-last { display: inline-block; font-size: 11px; color: var(--muted); background: var(--card3); border-radius: 4px; padding: 2px 6px; margin-top: 5px; }
.ex-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line); padding: 14px 4px; cursor: pointer; color: var(--text); }
.ex-row:hover { background: var(--card2); }
.ex-row .chev { color: var(--muted2); font-size: 22px; }
.filters { display: flex; gap: 8px; margin: 0 0 6px; }
.select.sm { padding: 8px 10px; font-size: 13.5px; border-radius: 8px; width: auto; flex: 1; }
.tabs2 { display: flex; background: var(--card2); border-radius: 8px; padding: 3px; margin: 14px 0; }
.tabs2 button { flex: 1; padding: 8px; border: none; border-radius: 6px; background: transparent; font-weight: 700; color: var(--muted); cursor: pointer; }
.tabs2 button.sel { background: var(--card); color: var(--text); box-shadow: var(--sh); }
.kv { font-size: 14px; margin: 2px 0; }
.kv b { font-weight: 700; }
.video-box { background: var(--card2); border-radius: 10px; padding: 14px; margin-bottom: 14px; }
.video-box iframe { width: 100%; aspect-ratio: 16/9; border: 0; border-radius: 8px; }
.hist-meso { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin: 18px 0 4px; }
.hist-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--line); }
/* One workout is one row; inside it, one line per weight. A two-column grid rather than
   wrapped text, so the weights right-align into a column and the multiplication signs line up -
   which is what lets you run your eye down the loads instead of hunting for where each group
   starts. Only the numbers carry weight; repeating the unit against every set is what made this
   a wall of type in the first place. */
.hist-sets { display: grid; grid-template-columns: max-content 1fr; align-items: baseline; gap: 3px 7px; min-width: 0; font-variant-numeric: tabular-nums; }
/* Left-aligned, not right. The reps sit in the grid's second column, so the multiplication signs
   line up whichever way this goes; the only question is which edge of the weight frays. Right
   alignment lines up the small grey "kg" and leaves 32.5 hanging out to the left of 30, which
   reads as a mistake. The number is the thing being scanned, so the number gets the clean edge. */
.hist-w { text-align: left; white-space: nowrap; }
.hist-sets b { font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.hist-sets small { font-size: 11px; color: var(--muted); font-weight: 500; margin-left: 2px; }
.hist-sets i { font-size: 12.5px; color: var(--muted2); font-style: normal; margin-right: 3px; }
.hist-when { flex: 0 0 auto; text-align: right; font-size: 11px; color: var(--muted); letter-spacing: .04em; line-height: 1.5; }
.hist-when b { font-size: 15px; color: var(--text); }

/* templates */
.tpl { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 4px; border-bottom: 1px solid var(--line); }
.tpl:last-child { border-bottom: none; }
.tpl-days { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip-s { background: var(--card3); border-radius: 5px; padding: 3px 8px; font-size: 12px; font-weight: 600; color: var(--muted); }

/* ---- meso detail: week chips / banners / day cards / volume ---- */
.chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 12px; }
.chip { flex: 0 0 auto; padding: 9px 14px; border-radius: 22px; border: 1px solid var(--line); background: var(--card); color: var(--muted); font-weight: 600; font-size: 13px; cursor: pointer; box-shadow: var(--sh); }
.chip.sel { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip.deload { border-style: dashed; }
.chip.sel.deload { background: var(--deload); border-color: var(--deload); }
.banner { padding: 12px 15px; border-radius: 10px; margin-bottom: 12px; font-size: 13.5px; font-weight: 500; }
.banner.deload { background: var(--deload-tint); border: 1px solid var(--deload-line); color: var(--deload-text); }
.day-card { display: block; width: 100%; text-align: left; cursor: pointer; color: var(--text); }
.day-card:hover { border-color: var(--line2); }
.day-name { font-weight: 700; font-size: 16px; }
.pill { font-size: 11.5px; padding: 5px 11px; border-radius: 20px; background: var(--card2); color: var(--muted); font-weight: 700; white-space: nowrap; }
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.mid { background: rgba(217,154,28,.16); color: var(--mid); }
.vol-list { margin-top: 12px; }
.vol-row { display: grid; grid-template-columns: 124px 1fr 66px; align-items: start; gap: 12px; padding: 7px 0 4px; border-bottom: 1px solid var(--line); }
.vol-row:last-child { border-bottom: none; }
.vol-row.idle .vol-label, .vol-row.idle .vol-num { color: var(--muted2); }
.vol-label { font-size: 13.5px; font-weight: 600; padding-top: 1px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.vol-prio { font-size: 9.5px; font-weight: 800; letter-spacing: .04em; padding: 2px 5px; border-radius: 4px; background: var(--accent-soft); color: var(--accent-text); }
.vol-bar { position: relative; height: 16px; margin-bottom: 15px; }
.vol-track { position: absolute; inset: 0; background: var(--card3); border-radius: 4px; overflow: hidden; }
.vol-track .zone { position: absolute; top: 0; bottom: 0; }
.vol-track .z-mv { background: var(--zone-mv); }
.vol-track .z-mev { background: var(--zone-mev); }
.vol-track .z-good { background: var(--zone-good); }
.vol-fill { position: absolute; left: 0; top: 3px; bottom: 3px; border-radius: 3px; background: var(--muted2); min-width: 0; }
.vol-fill.none { display: none; }
.vol-fill.under { background: var(--mid); }
.vol-fill.good { background: var(--accent); }
.vol-fill.over { background: var(--over); }
.vol-target { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--text); transform: translateX(-1px); }
.vol-target::after { content: ""; position: absolute; left: -3px; top: -4px; border: 4px solid transparent; border-top-color: var(--text); }
.vol-ticks { position: absolute; left: 0; right: 0; top: 17px; height: 12px; font-size: 9.5px; color: var(--muted); font-weight: 600; letter-spacing: .02em; white-space: nowrap; }
.vol-ticks span { position: absolute; top: 0; }
.vol-ticks .t-mv { transform: translateX(-100%); padding-right: 3px; }
.vol-ticks .t-mev { padding-left: 3px; border-left: 1px solid var(--line2); }
.vol-ticks .t-mrv { right: 0; }
.vol-num { font-size: 13px; text-align: right; font-variant-numeric: tabular-nums; padding-top: 1px; }
.vol-num b { font-size: 15px; }

/* ---- landmark editor ---- */
.lm-table { margin-top: 10px; max-height: 40vh; overflow-y: auto; border: 1px solid var(--line); border-radius: 8px; }
.lm-head, .lm-row { display: grid; grid-template-columns: 1fr 64px 64px 64px; gap: 6px; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--line); }
.lm-row:last-child { border-bottom: none; }
.lm-head { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; background: var(--card2); position: sticky; top: 0; }
.lm-head span:not(:first-child) { text-align: center; }
.lm-row > span { font-size: 13.5px; display: flex; align-items: center; }
.dlg .lm-row input[type=number] { width: 100%; padding: 6px 4px; text-align: center; border-radius: 6px; border: 1px solid var(--line); background: var(--card2); font-size: 13px; }

/* ---- feedback dialog ---- */
.fb-q { font-weight: 700; font-size: 16.5px; margin-top: 20px; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.fb-help { color: var(--muted); font-size: 14px; line-height: 1.35; margin: 3px 0 10px; }
.whybtn { flex: 0 0 auto; width: 19px; height: 19px; border-radius: 50%; border: 1.4px solid var(--muted2); background: none; color: var(--muted); font-size: 11px; font-weight: 700; line-height: 1; cursor: pointer; padding: 0; }
.whybtn:hover { border-color: var(--accent); color: var(--accent-text); }
.whytext { flex: 1 0 100%; font-size: 13px; line-height: 1.45; color: var(--accent-text); background: var(--accent-soft2); border-left: 2px solid var(--accent-soft); border-radius: 0 6px 6px 0; padding: 8px 10px; margin-top: 6px; font-weight: 500; }
/* Settings: "How it works" — small headings so it reads as steps rather than a wall of text. */
.how-q { font-weight: 700; font-size: 13.5px; margin: 14px 0 3px; }
.how-q:first-of-type { margin-top: 10px; }

/* Calendar header: the +/- that lengthen or shorten a block still being trained. */
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.cal-head .cal-title { margin: 0; }
.cal-weeks-btns { display: flex; gap: 8px; }
.roundbtn { width: 32px; height: 32px; border-radius: 50%; border: 1.5px solid var(--line2); background: var(--card);
            color: var(--text); font-size: 19px; line-height: 1; cursor: pointer; display: inline-flex;
            align-items: center; justify-content: center; padding: 0; }
.roundbtn:hover:not(:disabled) { background: var(--card2); border-color: var(--text); }
.roundbtn:disabled { opacity: .3; cursor: default; }
.cal-msg { background: var(--note-bg); border: 1px solid var(--note-line); color: var(--note-text);
           border-radius: 6px; font-size: 12.5px; padding: 8px 10px; margin-bottom: 10px; }

.lastcol { font-size: 11.5px; color: var(--muted2); text-align: center; font-family: ui-monospace, Consolas, monospace;
           white-space: nowrap; overflow: hidden; }

/* A skipped workout is shown, not edited: flat cells in place of the inputs. */
.num.flat { display: flex; align-items: center; justify-content: center; color: var(--muted2);
            background: var(--card2); border: 1px solid transparent; border-radius: 8px; font-size: 13.5px; }
.logbox.skipmark { display: inline-flex; align-items: center; justify-content: center;
                   color: var(--accent-text); background: var(--accent-soft2); border: 1px solid var(--accent-soft); cursor: default; }
.banner.skipped { background: var(--card2); border: 1px solid var(--line); color: var(--muted); }

/* Settings: result of a backup or an import. */
.note-ok { background: var(--ok-tint); border: 1px solid var(--ok-tint-line); border-radius: 6px; color: var(--ok-text);
           font-size: 12.5px; margin: 10px 0 0; padding: 9px 11px; word-break: break-all; }
.plainlist { list-style: none; margin: 4px 0 0; padding: 0; }
.plainlist li { padding: 2px 0; }

/* ---- Problem reports ------------------------------------------------------------------ */

/* The browser's own file button says "No file chosen" in a font nothing else here uses, so it is
   hidden and the label around it is the control. */
.filepick { display: block; position: relative; margin-top: 2px; }
.filepick input[type=file] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.fp-face { display: block; border: 1px dashed var(--line); border-radius: 9px; background: var(--card2);
           padding: 13px 14px; font-size: 14px; color: var(--muted); text-align: center;
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filepick:hover .fp-face { background: var(--card3); }

.shot-preview { display: block; margin: 10px 0 0; max-width: 100%; max-height: 320px;
                border: 1px solid var(--line); border-radius: 9px; }

.note-bad { background: var(--bad-tint); border: 1px solid var(--bad-line); border-radius: 6px; color: var(--bad-text);
            font-size: 12.5px; margin: 10px 0; padding: 9px 11px; }
.warn-text { color: var(--bad-text); margin: 8px 0 0; }

/* New / Open / Done, on both the reporter's list and the owner's. */
.status { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
          border-radius: 5px; padding: 3px 7px; background: var(--card3); color: var(--muted); }
.status.new { background: var(--info-tint); color: var(--info-text-c); }
.status.open { background: var(--warn-tint); color: var(--warn-text-c); }
.status.done { background: var(--ok-tint); color: var(--ok-text); }

.wcard.report { display: flex; flex-direction: column; gap: 10px; }
.rep-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.rep-who { font-weight: 600; font-size: 13.5px; }
.rep-text { white-space: pre-wrap; font-size: 14.5px; line-height: 1.45; }
.rep-meta { display: flex; gap: 6px; flex-wrap: wrap; }
.rep-meta span:not(:last-child)::after { content: " ·"; }
.rep-res { background: var(--card2); border-radius: 8px; padding: 9px 11px; font-size: 13px; }

.report-mine li { padding: 10px 0; border-top: 1px solid var(--line); }
.report-mine li:first-child { border-top: 0; }
.rm-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.rm-res { margin-top: 4px; font-style: italic; }

/* Shown in place of the soreness buttons the first time a muscle is trained in a block. */
.fb-na { background: var(--ok-tint); border: 1px solid var(--ok-tint-line); border-radius: 6px; color: var(--ok-text);
         font-size: 12.5px; margin: 2px 0 14px; padding: 9px 11px; }
/* RP fits all four answers on one row: 95.5px wide, 47px tall, 5px apart, measured off its
   own screenshot at 430px. Two rows of two made the sheet twice as tall for no gain. */
.fb-opts { display: grid; gap: 5px; }
.fb-opts.c3 { grid-template-columns: repeat(3, 1fr); }
.fb-opts.c4 { grid-template-columns: repeat(4, 1fr); }
.fb-opt { display: flex; align-items: center; justify-content: center; text-align: center; min-height: 47px; border: 1.5px solid var(--accent); background: var(--accent-soft2); color: var(--accent-text); border-radius: 8px; padding: 6px 4px; font-weight: 700; font-size: 12.5px; cursor: pointer; line-height: 1.2; }
.fb-opt.sel { background: var(--accent); color: #fff; }

/* ---- forms ---- */
.field { display: block; margin: 12px 0; }
.field span { display: block; font-size: 13px; color: var(--text); margin-bottom: 6px; font-weight: 600; }
.field input, .select, .dlg input[type=text], .dlg input[type=number], .dlg textarea, .field textarea, .field select { width: 100%; background: var(--input-bg); border: 1.5px solid var(--card2); color: var(--text); border-radius: 8px; padding: 12px; font-size: 15px; }
.field input:focus, .select:focus, .dlg input:focus, .dlg textarea:focus, .field textarea:focus { outline: none; border-color: var(--accent); background: var(--focus-bg); }
.dlg textarea { min-height: 120px; resize: vertical; }
.field textarea { resize: vertical; line-height: 1.45; }
.check { display: flex; align-items: center; gap: 10px; font-size: 14px; margin: 12px 0; cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--accent); }
.unit-in { display: flex; align-items: center; background: var(--card2); border-radius: 8px; padding-right: 12px; }
.unit-in input { flex: 1; background: transparent; border: none; padding: 12px; font-size: 15px; }
.unit-in input:focus { outline: none; }
.unit-in span { color: var(--muted); font-size: 13px; }
.warn { background: var(--note-bg); border: 1px solid var(--note-line); color: var(--note-text); border-radius: 6px; padding: 8px 10px; font-size: 12.5px; margin: 8px 0 12px; }

/* ---- charts ---- */
.chart { width: 100%; height: auto; margin-top: 12px; background: var(--card2); border-radius: 12px; border: 1px solid var(--line); }
.chart .axl { fill: var(--muted2); font-size: 9px; }
.legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; font-size: 12px; color: var(--muted); }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: middle; }

/* ---- tab bar (mobile) ---- */
.tabbar { position: fixed; bottom: 0; left: 0; right: 0; z-index: 40; display: none; height: calc(var(--tab-h) + var(--safe-b)); padding: 4px 0 calc(var(--safe-b) + 5px); background: var(--card); border-top: 1px solid var(--line); transform: translateZ(0); will-change: transform; }
.tab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 0; color: var(--muted2); font-size: 12px; line-height: 15px; font-weight: 600; }
.tab .ti { display: flex; align-items: center; justify-content: center; height: 28px; }
.tab .ti .ic { stroke-width: 2; }
.tab.active { color: var(--accent-text); }
.tab.active .ti { color: inherit; }

/* ---- dialogs ---- */
.dlg-back { position: fixed; inset: 0; z-index: 60; background: rgba(20,22,30,.5); display: flex; align-items: center; justify-content: center; padding: 16px; }
.dlg { background: var(--card); border-radius: 14px; width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto; padding: 22px 22px 18px; position: relative; box-shadow: 0 20px 60px rgba(0,0,0,.3); display: block; }
.dlg.tall { max-width: 600px; }
.dlg h3 { font-size: 22px; margin: 6px 0 4px; }
.dlg .sub { color: var(--muted); font-size: 14px; margin-bottom: 10px; }
.dlg-x { position: absolute; top: 14px; right: 14px; background: none; border: none; color: var(--text); width: 34px; height: 34px; border-radius: 8px; cursor: pointer; font-size: 18px; }
.dlg-x:hover { background: var(--card2); }
.dlg-actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-top: 20px; }
.dlg-actions.spread { justify-content: flex-start; }
.search { width: 100%; background: var(--input-bg); border: 1.5px solid var(--input-bg); color: var(--text); border-radius: 8px; padding: 11px 12px; font-size: 15px; margin: 10px 0 12px; }
.search:focus { outline: none; border-color: var(--accent); background: var(--focus-bg); }
.pick-list { max-height: 50vh; overflow-y: auto; border-top: 1px solid var(--line); }
.pick-list.short { max-height: 36vh; }

/* ---- auth (login) ---- */
.auth-wrap { min-height: 100dvh; background: var(--sidebar); display: flex; align-items: center; justify-content: center; padding: 20px; }
.auth-card { width: 100%; max-width: 400px; background: var(--card); border-radius: 16px; padding: 28px 26px; box-shadow: 0 20px 60px rgba(0,0,0,.35); }
.auth-card .brand { padding: 0 0 22px; }
.auth-card .brand-word span { color: var(--accent-text); }
.auth-card h1 { font-size: 22px; margin-bottom: 14px; }
.auth-card .field input { background: var(--card2); }
.auth-err { color: var(--danger); font-size: 13px; margin: 8px 0; }
.validation-message { color: var(--danger); font-size: 12px; margin-top: 4px; display: block; }

/* ---- Identity "Manage" pages (scaffolded markup uses Bootstrap-style classes) ---- */
.form-floating { display: flex; flex-direction: column; margin-bottom: 12px; }
.form-floating > label { order: -1; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.form-control { width: 100%; background: var(--card2); border: 1.5px solid var(--card2); color: var(--text); border-radius: 8px; padding: 12px; font-size: 15px; }
.form-control:focus { outline: none; border-color: var(--accent); background: var(--focus-bg); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-d); }
.btn-lg { padding: 14px; font-size: 16px; }
.w-100 { width: 100%; }
.text-danger { color: var(--danger); font-size: 13px; }
.alert { padding: 12px 14px; border-radius: 8px; margin: 10px 0; font-size: 14px; }
.alert-success { background: var(--ok-soft); color: var(--ok); }
.alert-danger { background: var(--danger-soft); color: var(--danger); }
.nav.nav-pills { list-style: none; padding: 0; margin: 0 0 18px; display: flex; flex-wrap: wrap; gap: 6px; }
.nav-pills .nav-link { display: inline-block; padding: 8px 12px; border-radius: 8px; background: var(--card2); color: var(--text); font-weight: 600; font-size: 13.5px; }
.nav-pills .nav-link.active { background: var(--accent); color: #fff; }
.manage-wrap { max-width: 660px; margin: 0 auto; }
.manage-wrap hr { border: none; border-top: 1px solid var(--line); margin: 14px 0; }
.manage-wrap h1 { font-size: 24px; margin-bottom: 4px; }
.manage-wrap h2 { font-size: 15px; color: var(--muted); font-weight: 500; }
.manage-wrap h3 { font-size: 18px; margin: 10px 0 14px; }
.manage-wrap form { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 18px; box-shadow: var(--sh); }
.manage-wrap ul.text-danger { padding-left: 18px; }

/* ---- responsive ---- */
@media (max-width: 900px) {
    .sidebar { display: none; }
    .tabbar { display: flex; }
    .app-main { padding: calc(14px + var(--safe-t)) 12px calc(var(--tab-h) + var(--safe-b) + 16px); }
    .panel { padding: 4px 14px; }
    h1 { font-size: 23px; }
    .list-head h1 { font-size: 22px; }
    .builder-top h1 { font-size: 20px; }
    .set-grid { grid-template-columns: 22px 50px 1fr 1fr 16px 42px; gap: 4px; }
    /* RP's dialogs are bottom sheets: full width, anchored to the bottom edge, rounded only at
       the top, filling everything below the status bar. Only the two marked .sheet - feedback and
       exercise history - become one; a bodyweight prompt is still a small centred box. */
    .dlg-back.sheet { align-items: flex-end; padding: 0; }
    .dlg-back.sheet > .dlg { max-width: none; height: calc(100dvh - 96px); max-height: none;
                             border-radius: 22px 22px 0 0; padding: 24px 16px 0;
                             display: flex; flex-direction: column; }
    .dlg-back.sheet > .dlg > h3 { font-size: 26px; margin: 2px 0 2px; }
    /* Everything between the title and the actions scrolls; the actions stay put, so Save is
       always reachable without paging to the end of a long history. */
    .dlg-back.sheet > .dlg > .dlg-actions { margin-top: auto; position: sticky; bottom: 0;
                                            background: var(--card); border-top: 1px solid var(--line);
                                            padding: 12px 0 calc(10px + var(--safe-b)); }
    .dlg-back.sheet > .dlg { overflow-y: auto; overscroll-behavior: contain; }

    /* In a sheet the exercise list is the sheet: it takes the height rather than sitting in a
       36vh window with the rest of the phone empty below it, which is how RP's picker reads. The
       sheet itself stops scrolling so the list scrolls instead, or the two fight each other. */
    .dlg-back.sheet > .dlg:has(.pick-list) { overflow-y: hidden; }
    .dlg-back.sheet > .dlg .pick-list { max-height: none; flex: 1 1 auto; min-height: 0; }

    /* The builder stacks: one full-width day after another, and nothing to scroll sideways. */
    .builder-top { flex-wrap: wrap; }
    .builder-top h1 { flex: 1 0 100%; }
    /* Priorities, the three icon buttons and Create on one row, with Create taking the slack
       rather than being orphaned on a line of its own. */
    .builder-actions { width: 100%; flex-wrap: nowrap; gap: 6px; }
    .builder-actions .btn { font-size: 13px; padding: 9px 10px; }
    .builder-actions .btn.small { flex: 0 0 auto; }
    .builder-actions .btn.primary { flex: 1 1 auto; min-width: 0; }
    .meso-board { display: block; overflow-x: visible; padding: 6px 0 16px; }
    .day-col, .add-day-col { width: auto; flex-basis: auto; margin-bottom: 12px; }
    .day-col { min-height: 0; }
}

#blazor-error-ui { position: fixed; bottom: 0; left: 0; right: 0; background: var(--error-tint); padding: 10px 14px; box-shadow: 0 -1px 6px rgba(0,0,0,.1); z-index: 100; display: none; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* ---- per-set progress mark (how this set compares with last time) ---- */
.set-mark { display: flex; align-items: center; justify-content: center; font-size: 12px; }
.pmark { font-weight: 800; line-height: 1; cursor: help; }
.pmark.up { color: var(--ok); }
.pmark.same { color: var(--muted2); }
.pmark.down { color: var(--over); }

/* ---- block summary ---- */
.sum-block { margin-top: 16px; }
.sum-h { margin: 0 0 6px; font-size: 15px; display: flex; align-items: baseline; gap: 8px; }
.sum-row { display: flex; align-items: center; gap: 10px; padding: 9px 2px; border-bottom: 1px solid var(--line); font-size: 14px; }
.sum-row b { margin-left: auto; font-variant-numeric: tabular-nums; }
.sum-row .si { width: 18px; text-align: center; color: var(--muted); }
.sum-row .si.ok { color: var(--ok); }
.sum-scroll { overflow-x: auto; }
.sum-grid { display: grid; align-items: center; gap: 2px 4px; min-width: 100%; }
.sum-wk { font-size: 10px; color: var(--muted); font-weight: 700; text-align: center; letter-spacing: .03em; }
.sum-m { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 600; padding: 5px 0; }
.sum-avg { display: block; font-size: 11px; color: var(--muted); font-weight: 500; }
.sum-avg b { font-size: 12px; color: var(--text); }
.sum-cell { text-align: center; font-size: 12px; font-variant-numeric: tabular-nums; border-radius: 5px; padding: 7px 0; color: var(--muted2); background: var(--card2); }
.sum-cell.on { color: #fff; background: color-mix(in srgb, var(--accent) calc(35% + var(--i) * 65%), var(--sum-empty)); }

/* ---- templates ---- */
.filter-bar { display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: none; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 10px 2px; font-size: 13.5px; color: var(--muted); cursor: pointer; font-weight: 600; }
.filter-bar .fi { font-size: 14px; }
.filter-count { background: var(--accent); color: #fff; border-radius: 10px; padding: 1px 7px; font-size: 11px; }
.tpl-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line); padding: 12px 2px; cursor: pointer; color: var(--text); }
.tpl-row:hover { background: var(--card2); }
.tpl-row:last-of-type { border-bottom: none; }
.tpl-main { flex: 1; min-width: 0; }
.tpl-emph { display: block; font-size: 10px; font-weight: 700; color: var(--muted2); letter-spacing: .06em; }
.tpl-name { display: block; font-size: 15.5px; font-weight: 600; margin: 2px 0 6px; }
.tpl-meta { display: flex; gap: 6px; flex-wrap: wrap; }
.chip-s.mine { background: var(--accent-soft); color: var(--accent-text); }
.tpl-row .cv { color: var(--muted2); font-size: 20px; }
.tpl-list { margin-top: 10px; }
.tpl-item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 2px; border-bottom: 1px solid var(--line); font-size: 14px; }
.tpl-item:last-child { border-bottom: none; }
.tpl-n { color: var(--muted2); font-size: 12px; width: 14px; text-align: right; padding-top: 3px; }
.tpl-muscle { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; }
.tpl-item .muted { font-size: 13.5px; font-weight: 500; margin-top: 1px; }
.mg-item .radio { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line2); flex: 0 0 auto; }
.mg-item .radio.on { border-color: var(--accent); background: radial-gradient(circle at center, var(--accent) 0 6px, var(--card) 6px 100%); }
.mg-item.sel { cursor: pointer; }
button.mg-item { width: 100%; text-align: left; cursor: pointer; font: inherit; color: inherit; }

/* ---- release notes ---- */
.rel-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 10px; }
.rel-v { flex: 0 0 auto; background: var(--accent-soft2); color: var(--accent-text); border: 1px solid var(--accent-soft); border-radius: 7px; padding: 4px 9px; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rel-list { margin: 0; padding-left: 18px; }
.rel-list li { font-size: 14px; line-height: 1.5; margin-bottom: 8px; }
.rel-list li:last-child { margin-bottom: 0; }

/* A card that is telling you something is wrong, rather than showing you something. */
.warncard { border: 1px solid var(--warncard-line); background: var(--warncard-tint); }
.warncard h3 { color: var(--warncard-text); }

/* ---- first-run plan picker ---- */
.pick-row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line); padding: 14px 2px; cursor: pointer; color: inherit; font: inherit; }
.pick-row:last-of-type { border-bottom: none; }
.pick-row.sel { background: var(--accent-soft2); border-radius: 8px; }
.pick-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pick-main b { font-size: 15.5px; font-weight: 600; }
.pick-main .muted { font-size: 13px; }

/* ---- the invitations list ----
   It used to be one wrapping line per invitation, joined by full stops: code, status, address and
   a Withdraw link all inline. On a phone that wrapped wherever it ran out of width, so an address
   could sit on one line and its own Withdraw button on the next. A row is now a row: who it went
   to, the code and what happened to it underneath, and one action pinned to the right. */
.inv-list { margin-top: 8px; }
.inv-row { display: flex; align-items: center; gap: 12px; padding: 11px 2px; border-bottom: 1px solid var(--line); }
.inv-row:last-child { border-bottom: none; }
/* Spent and withdrawn invitations are history: still readable, no longer competing for attention. */
.inv-row.done { opacity: .6; }
.inv-main { flex: 1; min-width: 0; }
.inv-who { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.inv-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; font-size: 11.5px; color: var(--muted); }
.inv-meta code { font-size: 11px; letter-spacing: .04em; background: var(--card2); border-radius: 5px; padding: 2px 6px; }
.inv-tag { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); background: var(--card2); border-radius: 20px; padding: 4px 10px; }
.inv-tag.ok { color: var(--accent-text); background: var(--accent-soft2); }
.inv-row .btn.small { flex: 0 0 auto; }

/* The "your invitation is fine, just pick a password" line on the sign-up form. */
.auth-ok { background: var(--accent-soft2); border: 1px solid var(--accent-soft); color: var(--accent-text); border-radius: 8px; padding: 11px 13px; font-size: 13.5px; font-weight: 600; margin-bottom: 14px; }

/* "(78 + 10)" beside a bodyweight-loadable load. Small and grey: it explains the big number
   rather than competing with it. */
.hsplit { font-style: normal; font-size: 11px; color: var(--muted2); font-variant-numeric: tabular-nums; margin-right: 7px; }

/* Send feedback: what sort of thing it is, asked as three buttons rather than a dropdown so the
   choice is visible without a tap. */
.kind-row { display: grid; gap: 8px; margin-top: 2px; }
.kind { text-align: left; border: 1.5px solid var(--card2); background: var(--card2); border-radius: 9px;
        padding: 11px 13px; cursor: pointer; font-family: inherit; color: var(--text); }
.kind b { display: block; font-size: 14.5px; font-weight: 600; }
.kind small { display: block; color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.kind:hover { background: var(--card3); }
.kind.sel { border-color: var(--accent); background: var(--focus-bg); }
.kind.sel b { color: var(--accent); }

/* The search box and the "new exercise" button share a line inside a picker dialog. */
.pick-head { display: flex; gap: 8px; align-items: center; }
.pick-head .search { flex: 1; margin: 0; }

/* The exercise picker, closer to how RP draws it: taller rows with when you last did the
   exercise, a filter bar of its own, and "create a custom exercise" at the foot of the list
   rather than a + beside the search - which is where you look for it, after scrolling to the
   end and not finding what the gym has. */
.ex-item { padding: 15px 6px; gap: 13px; }
.ex-n { font-size: 16px; }
.ex-when { display: inline-flex; align-items: center; gap: 5px; margin-top: 6px; padding: 3px 8px;
           border-radius: 999px; background: var(--card2); color: var(--muted); font-size: 11.5px; font-weight: 600; }
.ex-create { display: block; width: 100%; padding: 18px 6px; background: none; border: none;
             color: var(--accent); font-size: 15px; font-weight: 700; text-align: center; cursor: pointer; }
.ex-create:hover { background: var(--card2); }

.filter-bar { display: flex; align-items: center; gap: 9px; padding: 9px 6px; margin: 0;
              border-top: 1px solid var(--line); color: var(--muted); }
.filter-bar .filter-chip { background: var(--card2); border-radius: 999px; padding: 5px 12px;
                           font-size: 13px; font-weight: 600; color: var(--text); }
.filter-bar .link { padding: 2px 4px; font-size: 12.5px; }
.filter-clear { margin-left: auto; background: none; border: none; color: var(--muted);
                font-size: 15px; cursor: pointer; padding: 2px 6px; }

/* The scope tick sits with the buttons that apply it, with its "?" beside it - RP has the same
   pairing on its Repeat tick. The explanation lifts above the row rather than growing it, so the
   buttons do not move under a thumb that is already on the way to them. */
.dlg-actions .act-left { margin-right: auto; font-size: 13px; position: relative;
                         display: inline-flex; align-items: center; gap: 7px; }
.dlg-actions .act-left .whytext { position: absolute; bottom: calc(100% + 8px); left: 0;
                                  width: max(220px, 60vw); max-width: 340px; z-index: 2;
                                  background: var(--card2); border: 1px solid var(--line);
                                  border-radius: 10px; padding: 9px 11px; }

/* Feedback that is owed, over the sets it is holding up, exactly where RP puts it.
   
   At the foot of the card it read as a footnote. In the middle of the sets, with those sets faded
   behind it, it reads as what it is: the thing in the way. The fade is what carries the urgency -
   the exercise visibly stops being available until the question is answered.
   
   RP's is red. Red here would be the only red on a screen that is otherwise entirely the brand
   green, and this is not an error - it is the next thing to do. */
.set-area { position: relative; }
.set-area.blocked > .set-grid { opacity: .5; transition: opacity .15s; }

.fb-required { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
               z-index: 3; display: inline-flex; align-items: center; justify-content: center;
               gap: 9px; white-space: nowrap; max-width: calc(100% - 24px);
               padding: 15px 22px; border: none; border-radius: 12px;
               background: var(--accent); color: #fff; font-size: 15px; font-weight: 700;
               cursor: pointer; box-shadow: 0 6px 22px rgba(0, 0, 0, .28); }
.fb-required:hover { background: var(--accent-d); }
.fb-required:active { transform: translate(-50%, -50%) scale(.97); }
.fb-required svg { flex: 0 0 auto; }

/* A list of choices inside a dialog scrolls on its own, so whatever sits under it - Back, most of
   all - does not end up below everything the person has ever trained. */
.choice-scroll { margin-top: 6px; max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }

/* The muscle chip is a button now - it opens that muscle's weekly volume - and has to look
   exactly as it did as a span. .mtag already sets colour, border, padding and weight; a button
   additionally brings its own font family, line height, cursor and native appearance. */
button.mtag { font-family: inherit; line-height: normal; cursor: pointer;
             -webkit-appearance: none; appearance: none; }

/* One muscle on its own: no name column. The row is a three-column grid, so the column has to go
   as well as the label - otherwise the bar simply inherits the 124px the name had and comes out
   narrower than it was, with the MEV and MRV ticks printed on top of each other. */
.vol-row.solo { grid-template-columns: 1fr auto; }
.vol-row.solo .vol-bar { height: 20px; }
.vol-row.solo .vol-num { padding-left: 6px; white-space: nowrap; }

/* Where a logged figure is shown, solid has to mean "done" and nothing else.

   The planned fill is the same solid green as a healthy week, so on a week nobody had started the
   bar showed a confident green block that meant "this is the plan" and read as "this is finished".
   With a done figure present the plan drops back to a ghost of itself and the logged sets are
   drawn solid over it: the bar fills up as the week is trained, and an untouched week is empty. */
.vol-row.has-done .vol-fill { opacity: .22; }
.vol-done { position: absolute; left: 0; top: 3px; bottom: 3px; border-radius: 3px;
            background: var(--accent); }
.vol-row.has-done.idle .vol-fill { opacity: .16; }

.vol-headline { margin: 2px 2px 14px; font-size: 15px; color: var(--text); }
.vol-headline b { font-weight: 800; }

/* ================================ dark ====================================================
   Three states, and the order matters.

   `data-theme` is stamped on <html> by the server from a cookie, so an explicit choice is already
   on the page before the first paint - no flash of the wrong theme while Blazor starts.

     - data-theme="dark"      chosen dark
     - data-theme="light"     chosen light, which must beat the phone being dark
     - no attribute           follow the phone, via prefers-color-scheme

   Only the variables are redefined. Every rule in this file already reads them, which is what the
   pass before this one was for.

   The accent stays British racing green in both. It is the brand, and white on it reads either
   way; what changes is everything it sits on.
   ========================================================================================= */

:root[data-theme="dark"],
:root:not([data-theme="light"]) [data-theme="dark"] { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) { color-scheme: dark; }
}

:root[data-theme="dark"] {
    --bg: #121316;
    --card: #1c1e22;
    --card2: #24262b;
    --card3: #2b2e34;
    --line: #2e3138;
    --line2: #3d4148;
    --text: #e9eaec;
    --muted: #9aa1ac;
    --muted2: #6f7681;

    /* Lifted, not darkened: on a dark ground the accent has to give light back or every primary
       button reads as disabled. The soft variants become tints of the dark card instead of tints
       of white. */
    --accent: #1f7a4d;
    --accent-d: #175f3c;
    --accent-soft: #1a2b23;
    --accent-soft2: #16211c;
    --accent-text: #6cc294;

    --ok: #4bb85f;
    --ok-soft: #16281a;
    --info: #5a9dfb;
    --info-soft: #16202e;
    --mid: #d99a1c;
    --over: #e0563b;
    --danger: #e05a50;
    --danger-soft: #2c1a18;


    /* The sidebar was the one dark thing on a light page. In dark mode it stops being a contrast,
       so it steps away from the page rather than toward it. */
    --sidebar: #0e0f11;
    --sidebar-2: #1a1c1f;
    --sidebar-text: #e9eaec;
    --sidebar-muted: #7d838c;

    --input-bg: #0f1013;
    --note-bg: #7a6f33;
    --note-line: #8d8140;
    --note-text: #fbf6e4;
    --focus-bg: #2b2e34;
    --ok-line: #2a4a33;
    --ok-text: #7fc79b;
    --ok-tint: #17241c;
    --ok-tint-line: #274031;
    --bad-tint: #2a1917;
    --bad-line: #4a2b27;
    --bad-text: #e79b91;
    --warn-tint: #2a2313;
    --warn-text-c: #d9b168;
    --warncard-tint: #2a1a16;
    --warncard-line: #4d2f28;
    --warncard-text: #eda392;
    --info-tint: #16202e;
    --info-text-c: #8ab6f5;
    --deload: #6d79a6;
    --deload-tint: #1b1f2e;
    --deload-line: #333a52;
    --deload-text: #a8b2d8;
    --zone-mv: #26282c;
    --zone-mev: #33291a;
    --zone-good: #1a2b21;
    --error-tint: #3a3116;
    --sum-empty: #2b2e34;
}

/* The same values again for a phone set to dark that has made no choice in the app. Duplicated
   rather than shared because a media query cannot be aliased to an attribute selector, and a
   preprocessor for one duplicate is a worse trade than the duplicate. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: #121316;
        --card: #1c1e22;
        --card2: #24262b;
        --card3: #2b2e34;
        --line: #2e3138;
        --line2: #3d4148;
        --text: #e9eaec;
        --muted: #9aa1ac;
        --muted2: #6f7681;
        --accent: #1f7a4d;
        --accent-d: #175f3c;
        --accent-soft: #1a2b23;
        --accent-soft2: #16211c;
        --accent-text: #6cc294;
        --ok: #4bb85f;
        --ok-soft: #16281a;
        --info: #5a9dfb;
        --info-soft: #16202e;
        --danger: #e05a50;
        --danger-soft: #2c1a18;
        --sidebar: #0e0f11;
        --sidebar-2: #1a1c1f;
        --sidebar-text: #e9eaec;
        --sidebar-muted: #7d838c;
        --input-bg: #0f1013;
    --note-bg: #7a6f33;
    --note-line: #8d8140;
    --note-text: #fbf6e4;

        --focus-bg: #2b2e34;
        --ok-line: #2a4a33;
        --ok-text: #7fc79b;
        --ok-tint: #17241c;
        --ok-tint-line: #274031;
        --bad-tint: #2a1917;
        --bad-line: #4a2b27;
        --bad-text: #e79b91;
        --warn-tint: #2a2313;
        --warn-text-c: #d9b168;
        --warncard-tint: #2a1a16;
        --warncard-line: #4d2f28;
        --warncard-text: #eda392;
        --info-tint: #16202e;
        --info-text-c: #8ab6f5;
        --deload: #6d79a6;
        --deload-tint: #1b1f2e;
        --deload-line: #333a52;
        --deload-text: #a8b2d8;
        --zone-mv: #26282c;
        --zone-mev: #33291a;
        --zone-good: #1a2b21;
        --error-tint: #3a3116;
        --sum-empty: #2b2e34;
    }
}

/* The muscle colours are data, not CSS - fifteen values chosen to read on white. Several are dark
   enough to sink into a dark card, so they are lifted where they are used as text or a dot rather
   than being duplicated as a second set of fifteen. */
/* The muscle chip on dark, measured off RP's own app rather than guessed at.

   Sampling their ABS chip: the fill is the muscle's hue at S 36% L 28% - a dark, quiet tint - while
   the border and the three bars are both that colour at full strength (S 75% L 58%, which is simply
   the colour itself), and the label is white.

   So it is not the solid fill I tried first. It is the same shape as the light chip - tint, coloured
   border, coloured bars - tipped toward black instead of toward white, with the text going white
   because it can no longer be the colour.

   The color-mix line is a fallback: relative colour syntax is widely supported now but a chip with
   no background at all would be a bad way to find out otherwise. Browsers that understand the
   second declaration use it and ignore the first. */
:root[data-theme="dark"] .mtag {
    background: color-mix(in srgb, var(--c) 34%, #000);
    background: hsl(from var(--c) h 36% 28%);
    border-color: var(--c);
    color: #fff;
}
:root[data-theme="dark"] .mtag .bars b { background: var(--c); }

/* The fifteen muscle colours were chosen to read on white, so as a dot on a dark card several of
   them sink. Lifted where they are used rather than duplicated as a second set to keep in step. */
:root[data-theme="dark"] .vol-label .dot { filter: brightness(1.3) saturate(.95); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .mtag {
        background: color-mix(in srgb, var(--c) 34%, #000);
        background: hsl(from var(--c) h 36% 28%);
        border-color: var(--c);
        color: #fff;
    }
    :root:not([data-theme="light"]) .mtag .bars b { background: var(--c); }
    :root:not([data-theme="light"]) .vol-label .dot { filter: brightness(1.3) saturate(.95); }
}
