/* DEAD CSS SWEEP - 12 Sep 2026 (audit round 3). Rules removed only when every
   class in the selector appears NOWHERE in any JS file or index.html, as a
   plain substring - a deliberately stricter test than the class extractor,
   because a class can also be applied from a template literal the extractor
   does not see. Most of what went was debris from features already removed:
   the old hero image and greeting, the goal cards, the first journey bar, the
   pre-pillar home blocks, and Live Mode's styling. */
/* DARK MODE REMOVED - 12 Sep 2026, his call: he deleted the feature because he
   never used it. applyTheme() hard-sets data-theme="light" and no toggle
   exists anywhere, so every [data-theme="dark"] rule was unreachable by
   construction. Removed rather than left in place: otherwise the next person
   to add a colour inherits an obligation to maintain a dark variant that can
   never render. If dark mode returns it starts from the current palette. */

/* 26 Aug 2026, his call: Hebrew text should render in Rubik, everywhere. This
   is scoped to Hebrew ONLY on purpose - a mixed line like "Back Squat 4x6"
   is the norm throughout this app (exercise names, app text, and his own
   settings are English by design; only the conversation and the surrounding
   chrome are Hebrew), and he asked for the Hebrew half of that to change, not
   the English half.
   unicode-range is what makes one font-family do that without touching a
   single one of the thousands of font-family:inherit / var(--sans) rules
   below: for Hebrew codepoints (and the punctuation/currency Google ships in
   its own Hebrew subset) the browser uses this file; for everything else -
   Latin letters, digits, symbols - it declares no coverage and the browser
   falls straight through to the next font in --sans, unchanged. The same
   character-by-character switch already happens invisibly for emoji and
   symbols today; this just adds one more rule to it.
   Self-hosting the URL Google's own CSS API serves for the Hebrew subset
   (fetched and verified directly, not guessed) skips the extra request their
   font.googleapis.com stylesheet would otherwise cost, and 300..900 is a
   variable range so it covers every odd weight already used in this file
   (650, 750, 850...) without picking individual static cuts. */
@font-face{
  font-family:'Rubik';
  font-style:normal;
  font-weight:300 900;
  font-display:swap;
  src:url(https://fonts.gstatic.com/s/rubik/v31/iJWKBXyIfDnIV7nDrXyw023e1Ik.woff2) format('woff2');
  unicode-range:U+0307-0308,U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F;
}
/* ============================================================
   DESIGN TOKENS
   Deep midnight-navy base, deep-blue primary, mint-green success.
   Numeric data uses a tabular monospace stack (instrument panel).
   ============================================================ */
:root{
  /* Palette — bright / light theme */
  --bg:            #F1F4FA;   /* app background (soft light blue-gray) */
  --bg-glow:       #E4ECFB;   /* subtle radial glow near top */
  --surface:       #FFFFFF;   /* card surface */
  --surface-2:     #EEF2FA;   /* nested / elevated surface */
  --hairline:      rgba(40,70,150,.12);
  --hairline-str:  rgba(40,70,150,.20);

  /* DEEP NAVY, GRADIENT, SLIGHTLY RAISED - 28 Aug 2026, his direction: every
     blue in the app becomes a deep navy gradient with a little dimension.
     Retuning the tokens rather than repainting 39 rules keeps the whole app in
     step, and it repays an accessibility debt on the way: --blue-soft carries
     42 pieces of TEXT and sat at 4.42:1 on white, under the 4.5:1 floor for
     normal-size copy. The navy reads 8.17:1. --blue goes 5.18 -> 11.55.
     The 3D is one inset highlight along the top edge, one inset shade along
     the bottom, and a short drop shadow - a raised key, not a bevel. Pressing
     flattens it, which is where the tactility actually comes from. */
  --blue:          #1B347A;   /* primary accent (deep navy) */
  --blue-soft:     #2A4A9E;   /* lighter navy - text, borders */
  --blue-hi:       #35529E;   /* gradient top */
  --blue-lo:       #14245C;   /* gradient bottom */
  --blue-grad:     linear-gradient(180deg,var(--blue-hi) 0%,var(--blue-lo) 100%);
  --blue-3d:       inset 0 1px 0 rgba(255,255,255,.16),
                   inset 0 -1px 0 rgba(0,0,0,.24),
                   0 2px 5px rgba(16,32,80,.28);
  --blue-3d-press: inset 0 1px 0 rgba(255,255,255,.06),
                   0 1px 2px rgba(16,32,80,.22);
  --blue-dim:      rgba(27,52,122,.10);

  /* ORANGE-GOLD - 29 Aug 2026, his direction: the palette is white, black,
     deep navy and orange-gold. Navy is the app's ACTION colour (send, save,
     confirm); gold is its INVITATION colour - the things offered rather than
     committed to. Keeping those two jobs apart is what stops a four-colour
     palette turning into decoration.
     Gold carries DARK text, never white: a gold bright enough to read as gold
     tops out around 3.6:1 against white, under the floor, while the app's own
     near-black reads 5.73:1 even on the deepest stop of this gradient. That is
     the honest way round for this hue, and it is also the crisper one. */
  /* Retuned 29 Aug 2026 against his reference: the first pass came out MUSTARD.
     Two causes, and the second mattered more than the hue.
     1. #F0B247 -> #D18A22 sits at ~35 degrees hue with the value pulled well
        down - that is a brown-orange. The reference gold is up near 45 degrees
        and close to full brightness: yellow that has gold in it, not orange
        that has been darkened.
     2. The bottom inset was rgba(120,70,0,.26) - a BROWN shade laid over the
        deepest part of the gradient, which is exactly where mustard is made.
        Depth on a luminous colour has to come from the colour going purer, not
        dirtier, so the shade is now a low-opacity warm amber and the drop
        shadow carries the weight instead.
     The brightness pays for the text too. He disliked the dark ink, and it was
     a muddy brown-black (#2B1A05) chosen because the old gold could not carry
     anything lighter - it only cleared 5.88:1. This gold reads 10.63:1 against
     the app's own near-black, so the ink is simply the app's text colour: the
     same black used everywhere else, which is what makes it look deliberate
     rather than tinted. */
  --gold-hi:       #FFE07A;   /* gradient top - luminous */
  --gold-lo:       #FFC93C;   /* gradient bottom */
  --gold:          #FFC93C;
  /* THE INK ON GOLD - settled 29 Aug 2026, third attempt, and the first two
     were both wrong for reasons worth keeping.
     White (1.5:1) was unreadable, exactly as measured. But black was ALSO
     rejected, and not on any number - it read cheap. The answer came out of
     his own reference: the ink on that yellow panel is not black, it is deep
     forest green. A dark drawn FROM the palette, not a neutral dropped on top.
     Black beside gold is a contrast; navy beside gold is a pair - the warm and
     the cool of one scheme, which is why one looks designed and the other looks
     defaulted. Same navy the buttons are made of, so the two accents are
     visibly the same family seen from two sides.
     9.52:1 at the deepest stop of the gradient - sharp in gym light and in
     sun, which is where white failed him. */
  --gold-ink:      #14245C;
  --gold-deep:     #96530C;   /* gold as TEXT on pale surfaces - 5.29:1 */
  --gold-dim:      rgba(255,201,60,.18);
  --gold-grad:     linear-gradient(180deg,var(--gold-hi) 0%,var(--gold-lo) 100%);
  --gold-3d:       inset 0 1px 0 rgba(255,255,255,.55),
                   inset 0 -1px 0 rgba(214,145,16,.40),
                   0 2px 6px rgba(190,130,20,.30);
  --gold-3d-press: inset 0 1px 0 rgba(255,255,255,.22),
                   0 1px 2px rgba(190,130,20,.24);
  --green:         #12B98A;   /* success / completion (mint, deepened for light bg) */
  --green-soft:    #096B50;  /* was #0E9E76 - 3.40:1 on white, 3.02:1 on the pale
    green pill it usually sits in, both well under 4.5:1. This is the token for
    green TEXT: COMPLETED tags, set labels, the rest-timer's ready state, volume
    readouts. --green itself is untouched at #12B98A because that one is a FILL -
    checkmarks, meters, dots - where the threshold is 3:1 and the colour is part
    of how the app looks. Darkening only the text token fixes the legibility
    without repainting the product. Now 6.50:1 on white and 5.26:1 on the pill. */
  --green-dim:     rgba(18,185,138,.13);

  --text:          #18202F;   /* primary text (near-black navy) */
  --text-2:        #55617C;   /* secondary text */
  --text-3:        #657088;   /* was #6B7690 - 4.13:1 on the page, under the 4.5:1 floor.
    136 rules set text under 18px in this colour: session meta, table headers,
    set labels, placeholders, readouts. A 3% darkening is invisible as a design
    change and is the difference between legible and nearly legible for anyone
    over about forty reading a phone in a gym. This is the single highest-value
    change in the pass, precisely because it is the least visible. */   /* muted / captions — darkened 12 Aug 2026: the
                                  previous #8A93AB read at ~3.07:1 on white,
                                  below the 4.5:1 a normal-size caption needs,
                                  and this text sits under bright gym lighting
                                  more than most apps ever will */

  /* soft elevation shadow for cards on a light background */
  --shadow: 0 1px 2px rgba(20,40,100,.05), 0 12px 34px -22px rgba(20,40,100,.30);

  /* Type */
  --sans: 'Rubik', -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Inter, Roboto, system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", "SFMono-Regular", "Menlo", "Roboto Mono", "Courier New", monospace;

  /* Rhythm */
  --r-lg: 26px;   /* card radius */
  --r-md: 16px;
  --r-sm: 11px;
  --pad: 26px;
  --gap: 18px;
  --maxw: 660px;

  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}

/* ============================================================ RESET */
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;overflow-x:hidden;overscroll-behavior-x:none}
body{overscroll-behavior-x:none;max-width:100vw}
body{
  font-family:var(--sans);
  color:var(--text);
  background:var(--bg);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  min-height:100vh;
  overflow-x:hidden;
  padding-bottom:120px;
}
/* Ambient top glow — quiet atmosphere, not decoration overload */
body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(1100px 520px at 50% -140px, var(--bg-glow), transparent 70%),
    radial-gradient(700px 500px at 90% 0%, rgba(53,214,164,.05), transparent 60%);
}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,textarea{font-family:inherit;color:inherit}
::selection{background:var(--blue);color:#fff}

.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ============================================================
   STICKY HEADER  — Week / session titles + progress ring
   ============================================================ */
.header{
  position:sticky;top:0;z-index:40;
  background:rgba(255,255,255,.80);
  backdrop-filter:blur(18px) saturate(140%);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--hairline);
}
.header-inner{
  max-width:var(--maxw);margin:0 auto;
  padding:16px 22px calc(16px + env(safe-area-inset-bottom,0));
  padding-top:calc(16px + env(safe-area-inset-top,0));
  display:flex;align-items:center;gap:18px;
}
.header-text{flex:1;min-width:0}
.eyebrow{
  font-size:15.18px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--blue-soft);font-weight:600;
}
.session-title{
  font-size:clamp(24.84px,6.35vw,31.74px);font-weight:700;letter-spacing:-.02em;
  margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.session-meta{
  font-size:17.25px;color:var(--text-3);margin-top:3px;
  display:flex;gap:8px;align-items:center;flex-wrap:wrap;
}
.session-meta .mono{color:var(--text-2)}
.dot-sep{width:3px;height:3px;border-radius:50%;background:var(--text-3);opacity:.6}

/* Progress ring (signature element) */
.ring-wrap{position:relative;width:64px;height:64px;flex:none}
.ring-wrap svg{transform:rotate(-90deg);display:block}
.ring-track{stroke:var(--hairline-str)}
.ring-prog{
  stroke:url(#ringGrad);stroke-linecap:round;
  transition:stroke-dashoffset .7s var(--ease-out);
}
.ring-pct{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:20.7px;font-weight:600;letter-spacing:-.02em;
}
.ring-pct small{font-size:12.42px;opacity:.6;margin-left:1px}

/* ============================================================ LAYOUT */
/* The top padding was a flat 26px, so on a notched phone the greeting started
   under the clock rather than below it. */
main{max-width:var(--maxw);margin:0 auto;
  padding:calc(26px + env(safe-area-inset-top,0px)) 22px 40px}
.mantra{
  text-align:center;color:var(--text-3);font-size:17.94px;letter-spacing:.01em;
  margin:2px 0 26px;
}
.mantra b{color:var(--text-2);font-weight:600}

/* ============================================================
   SECTION CARDS
   ============================================================ */
.card{
  background:linear-gradient(180deg,var(--surface),#F7F9FE);
  border:1px solid var(--hairline);
  border-radius:var(--r-lg);
  margin-bottom:var(--gap);
  overflow:hidden;
  box-shadow:var(--shadow);
  transition:border-color .4s var(--ease), box-shadow .4s var(--ease), transform .4s var(--ease);
}
.card.done{
  border-color:var(--green-dim);
  box-shadow:0 0 0 1px var(--green-dim), 0 18px 40px -28px rgba(53,214,164,.5);
}
/* Header row */
.card-head{
  display:flex;align-items:flex-start;gap:15px;
  padding:var(--pad);cursor:pointer;user-select:none;
}
.idx{
  font-family:var(--mono);font-size:16.56px;color:var(--text-3);
  padding-top:4px;letter-spacing:.02em;flex:none;width:22px;
}
.card.done .idx{color:var(--green)}
.head-body{flex:1;min-width:0}
.card-title{
  font-size:24.84px;font-weight:650;letter-spacing:-.015em;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
}
.card-sub{color:var(--text-2);font-size:18.63px;margin-top:5px;line-height:1.5}
.tag{
  font-family:var(--mono);font-size:14.49px;letter-spacing:.04em;
  color:var(--blue-soft);background:var(--blue-dim);
  padding:3px 8px;border-radius:100px;font-weight:600;white-space:nowrap;
}
.card.done .tag{color:var(--green-soft);background:var(--green-dim)}
.done-pill{
  display:none;font-family:var(--mono);font-size:14.49px;letter-spacing:.05em;
  color:var(--green-soft);background:var(--green-dim);
  padding:3px 9px;border-radius:100px;font-weight:600;
}
.card.done .done-pill{display:inline-block}

/* Chevron for expand state on completed cards */
.chev{
  flex:none;width:26px;height:26px;border-radius:50%;
  display:grid;place-items:center;color:var(--text-3);
  transition:transform .4s var(--ease), opacity .3s;
  opacity:0;
}
.card.done .chev{opacity:1}
.card.collapsed .chev{transform:rotate(180deg)}
.chev svg{width:13px;height:13px}

/* Collapsible body */
.card-body{
  overflow:hidden;
  transition:max-height .55s var(--ease-out), opacity .4s var(--ease), padding .4s var(--ease);
  max-height:2600px;opacity:1;
}
.card.collapsed .card-body{max-height:0 !important;opacity:0;padding-top:0;padding-bottom:0}
.body-inner{padding:0 var(--pad) var(--pad)}

/* ============================================================
   CUSTOM CHECK CIRCLE  (used everywhere)
   ============================================================ */
.check{
  flex:none;width:26px;height:26px;border-radius:50%;
  border:2px solid var(--hairline-str);
  background:var(--surface-2);
  display:grid;place-items:center;position:relative;
  transition:border-color .25s var(--ease), background .25s var(--ease), transform .18s var(--ease);
}
.check:hover{border-color:var(--blue-soft)}
.check:active{transform:scale(.88)}
.check svg{width:13px;height:13px;stroke:#04140e;stroke-width:3.4;
  stroke-linecap:round;stroke-linejoin:round;fill:none;
  stroke-dasharray:20;stroke-dashoffset:20;
  transition:stroke-dashoffset .3s var(--ease-out) .05s;}
.check[data-done="true"]{
  background:var(--green);border-color:var(--green);
}
.check[data-done="true"] svg{stroke-dashoffset:0}
.check[data-done="true"]::after{
  content:"";position:absolute;inset:-6px;border-radius:50%;
  border:2px solid var(--green);opacity:0;
  animation:ripple .5s var(--ease-out);
}
@keyframes ripple{from{opacity:.6;transform:scale(.6)}to{opacity:0;transform:scale(1.25)}}
/* header check is bigger + primary blue when unchecked */
.check.lg{width:30px;height:30px;border-color:var(--hairline-str)}
.check.lg:hover{border-color:var(--green-soft)}

/* focus ring for keyboard */
.check:focus-visible,.timer-btn:focus-visible,.big-btn:focus-visible,
.video-btn:focus-visible,.scale-dot:focus-visible,.sec-toggle:focus-visible{
  outline:2px solid var(--blue-soft);outline-offset:3px;border-radius:8px;
}

/* ============================================================
   EXERCISE ROWS
   ============================================================ */
.ex{
  display:flex;align-items:center;gap:14px;
  padding:15px 0;border-top:1px solid var(--hairline);
}
.ex:first-child{border-top:none}
.ex-name{font-size:20.7px;font-weight:550;letter-spacing:-.01em;transition:color .3s,opacity .3s}
.ex-detail{font-family:var(--mono);font-size:16.56px;color:var(--text-3);margin-top:2px;letter-spacing:.02em}
.ex .check[data-done="true"] ~ .ex-main .ex-name,
.ex.is-done .ex-name{color:var(--text-2)}

/* notes field under mobility items */
.note{
  width:100%;margin-top:10px;background:var(--surface-2);
  border:1px solid var(--hairline);border-radius:var(--r-sm);
  padding:9px 12px;font-size:17.94px;color:var(--text);resize:none;
  transition:border-color .25s;line-height:1.45;
}
.note::placeholder{color:var(--text-3)}
.note:focus{outline:none;border-color:var(--blue)}
.ex-col{flex:1;min-width:0}   /* variant for stacked (notes) rows */

/* ============================================================
   TIMER
   ============================================================ */
.timer{
  display:flex;flex-direction:column;align-items:center;gap:20px;
  padding:8px 0 6px;
}
.timer-face{
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:clamp(71.76px,20.7vw,93.84px);font-weight:600;letter-spacing:-.03em;
  line-height:1;position:relative;
}
.timer-face.running{color:var(--blue-soft)}
.timer-face.finished{color:var(--green)}
.timer-bar{
  width:100%;height:5px;border-radius:100px;background:var(--hairline);overflow:hidden;
}
.timer-bar span{
  display:block;height:100%;width:0%;border-radius:100px;
  background:linear-gradient(90deg,var(--blue),var(--green));
  transition:width 1s linear;
}
.timer-ctrls{display:flex;gap:12px}
.timer-btn{
  padding:11px 22px;border-radius:100px;font-size:19.32px;font-weight:600;
  background:var(--surface-2);border:1px solid var(--hairline-str);
  color:var(--text);transition:all .2s var(--ease);letter-spacing:.01em;
}
.timer-btn:hover{border-color:var(--blue-soft);background:var(--surface-2)}
.timer-btn:active{transform:scale(.95)}
.timer-btn.primary{background:var(--blue-grad);box-shadow:var(--blue-3d);border-color:var(--blue);color:#fff}
.timer-btn.primary:hover{background:var(--blue-soft)}
.timer-done-row{
  display:flex;align-items:center;gap:12px;justify-content:center;
  margin-top:4px;font-size:19.32px;color:var(--text-2);
}

/* ============================================================
   MAIN LIFT — the special section
   ============================================================ */
.card.mainlift{
  background:
    linear-gradient(180deg, rgba(62,107,255,.06), transparent 40%),
    linear-gradient(180deg,var(--surface),#F7F9FE);
}
.card.mainlift:not(.done){
  border-color:var(--hairline-str);
  box-shadow:0 0 0 1px rgba(62,107,255,.10), 0 30px 70px -50px rgba(62,107,255,.9);
}
.goal{
  background:var(--blue-dim);border:1px solid rgba(62,107,255,.22);
  border-radius:var(--r-md);padding:16px 18px;margin-bottom:22px;
  display:flex;gap:13px;align-items:flex-start;
}
.goal .flag{font-size:23.46px;line-height:1.2}
.goal-label{font-size:15.18px;letter-spacing:.14em;text-transform:uppercase;color:var(--blue-soft);font-weight:600}
.goal-text{font-size:22.08px;font-weight:600;margin-top:3px;letter-spacing:-.01em}
.goal-note{font-family:var(--mono);font-size:16.56px;color:var(--text-2);margin-top:6px}

/* logging table */
table.log{width:100%;border-collapse:collapse;min-width:400px}
.log th{
  font-family:var(--mono);font-size:14.49px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-3);font-weight:600;text-align:left;padding:0 8px 12px;
}
.log th.c,.log td.c{text-align:center}
.log td{padding:6px 8px;border-top:1px solid var(--hairline)}
.log tr.warm td:first-child{color:var(--text-3)}
td.c .check{margin:0 auto}
tr.set-done .set-label{color:var(--green-soft)}

/* live readouts */
.readouts{
  display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:22px 0;
}
.readout{
  background:var(--surface-2);border:1px solid var(--hairline);
  border-radius:var(--r-md);padding:15px 17px;
}
.readout .k{font-size:15.18px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);font-weight:600}
.readout .v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:37.26px;font-weight:600;letter-spacing:-.02em;margin-top:5px}
.readout .v small{font-size:17.94px;color:var(--text-3);font-weight:500;margin-left:3px}
.readout.rpe .v{color:var(--blue-soft)}
.readout.vol .v{color:var(--green-soft)}

/* technical focus */
.cues{margin:14px 0 4px}
/* General cues, compressed: one flowing line, separated by dots, no ticks and no
   rules. Five of them cost about 40px instead of 240. */
.cue-gen{font-size:13.8px;line-height:1.65;color:var(--text-3);margin-top:11px;
  padding-top:10px;border-top:1px solid var(--hairline)}
.cue-gen-l{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;
  font-weight:700;color:var(--text-3);margin-inline-end:8px}
.cue-gen-i:not(:last-child)::after{content:' \00b7 ';opacity:.5}
.cue-lbl{font-family:var(--mono);font-size:12.07px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-3);font-weight:700;margin:12px 0 6px}
.cue-lbl:first-child{margin-top:0}
.cue-lbl.mine{color:var(--blue)}
.focus-list{display:flex;flex-direction:column}
.focus-item{
  display:flex;align-items:center;gap:13px;padding:12px 0;
  border-top:1px solid var(--hairline);cursor:pointer;
}
.focus-item.static{cursor:default}
.focus-item .fbullet{flex:none;width:23px;height:23px;border-radius:50%;background:var(--blue-dim);
  display:grid;place-items:center}
.focus-item .fbullet svg{width:12px;height:12px;stroke:var(--blue);stroke-width:3;fill:none;
  stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0}
.focus-item .check{width:23px;height:23px}
.focus-item span{font-size:20.01px;transition:color .3s}
.focus-item.is-done span{color:var(--text-2)}

/* big complete button */
.big-btn{
  width:100%;margin-top:24px;padding:18px;border-radius:var(--r-md);
  font-size:22.08px;font-weight:700;letter-spacing:.01em;
  background:linear-gradient(135deg,var(--green),#28b98c);color:#04140e;
  transition:transform .18s var(--ease), filter .2s, box-shadow .3s;
  box-shadow:0 16px 40px -18px var(--green);
}
.big-btn:hover{filter:brightness(1.05)}
.big-btn:active{transform:scale(.98)}
.big-btn.ready{animation:pulse-ready 2s var(--ease) infinite}
.big-btn.is-done{
  background:var(--green-dim);color:var(--green-soft);box-shadow:none;
  border:1px solid var(--green-dim);
}
@keyframes pulse-ready{
  0%,100%{box-shadow:0 16px 40px -18px var(--green)}
  50%{box-shadow:0 16px 48px -14px var(--green)}
}

/* ---- Coach-in-pocket: REST PANEL ---- */
@keyframes rest-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}





.rest-len{
  padding:5px 11px;border-radius:100px;font-family:var(--mono);font-size:16.56px;
  background:transparent;border:1px solid var(--hairline);color:var(--text-3);transition:all .18s;
}
.rest-len.on{background:var(--blue-dim);border-color:rgba(62,107,255,.3);color:var(--blue-soft)}

/* Bigger, glanceable set labels + highlight the set you're on now */
.log td{padding:8px}

/* Calm "current section" focus cue (subtle, no clutter) */
.card.current:not(.done):not(.mainlift){
  border-color:rgba(62,107,255,.22);
  box-shadow:0 0 0 1px rgba(62,107,255,.10), 0 24px 60px -46px rgba(62,107,255,.9);
}
.card.current .idx::after{content:"";display:block;width:6px;height:6px;border-radius:50%;
  background:var(--blue);margin:7px auto 0;box-shadow:0 0 8px var(--blue);animation:nowpulse 2.4s var(--ease) infinite}
@keyframes nowpulse{0%,100%{opacity:.5}50%{opacity:1}}

/* --- Feature 2: now / next line under the header --- */
.nowline{max-width:var(--maxw);margin:0 auto 14px;display:flex;align-items:center;gap:10px;
  font-size:17.94px;color:var(--text-2);flex-wrap:wrap}
.nowline .lab{font-family:var(--mono);font-size:13.8px;letter-spacing:.08em;color:var(--blue-soft);
  background:var(--blue-dim);border:1px solid rgba(62,107,255,.25);padding:3px 8px;border-radius:100px;font-weight:600}
.nowline b{color:var(--text);font-weight:650}
.nowline .nxt{color:var(--text-3);font-size:17.25px}
.nowline.empty .lab{color:var(--green-soft);background:var(--green-dim);border-color:rgba(53,214,164,.3)}

/* --- Feature 2: focus mode — collapsed cards are a slim, tappable line --- */
.card.collapsed .chev{opacity:1}
.card.collapsed:not(.done) .card-head{opacity:.72}
.card.collapsed:not(.done):hover .card-head{opacity:1}

/* --- Feature 3: reveal-on-demand mobility note --- */
.mob-note-toggle{margin-top:6px;font-family:var(--mono);font-size:15.18px;color:var(--text-3);
  background:none;border:none;padding:2px 0;cursor:pointer;opacity:.7;transition:opacity .2s,color .2s}
.mob-note-toggle:hover{opacity:1;color:var(--blue-soft)}

.sc-last{color:#4c6fff;font-weight:600;margin-inline-start:6px}
/* --- Feature 3: RPE reveal toggle --- */
.rpe-toggle .on{color:var(--blue-soft)}

/* --- Feature 4: small per-exercise Rest button on accessory cards --- */

/* ============================================================
   ACCESSORY GRID
   ============================================================ */
.acc{
  border-top:1px solid var(--hairline);padding:16px 0;
}
.acc:first-child{border-top:none}
.acc-head{display:flex;align-items:center;gap:13px;margin-bottom:13px}
.acc-name{flex:1;font-size:20.7px;font-weight:600;letter-spacing:-.01em}
.acc-namewrap{flex:1;min-width:0}
.acc-namewrap .acc-name{flex:none}
/* A held exercise: the prescription as written, and one button that counts it
   down. No weight, no sets, no reps - there is nothing to enter. */
.acc-presc{font-family:var(--mono);font-size:13.8px;color:var(--text-3);margin-top:3px;letter-spacing:.02em}
.acc-hold{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.acc-hold-p{font-family:var(--mono);font-size:14.95px;color:var(--text-2)}
.acc-hold-b{margin-inline-start:auto;border:1px solid var(--blue-soft,#9db6f0);background:transparent;
  color:var(--blue);border-radius:11px;padding:9px 14px;font-family:inherit;font-size:14.95px;
  font-weight:700;cursor:pointer;white-space:nowrap}
.acc-hold-b:active{transform:scale(.97)}
.acc-detail{font-family:var(--mono);font-size:14.49px;color:var(--text-3);margin-top:3px;letter-spacing:.01em;line-height:1.35}
.acc-fields{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;padding-left:39px}
.field label{
  display:block;font-family:var(--mono);font-size:13.8px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3);margin-bottom:5px;font-weight:600;
}
.field input{
  width:100%;background:var(--surface-2);border:1px solid var(--hairline);
  border-radius:9px;padding:9px 10px;font-family:var(--mono);
  font-variant-numeric:tabular-nums;font-size:20.7px;text-align:center;
  transition:border-color .2s,background .2s;
}
.field input:focus{outline:none;border-color:var(--blue);background:#FFFFFF}
.field input::placeholder{color:var(--text-3)}

/* ============================================================
   VIDEO + NOTES CARDS
   ============================================================ */
.plain-card{
  background:linear-gradient(180deg,var(--surface),#F7F9FE);
  border:1px solid var(--hairline);border-radius:var(--r-lg);
  padding:var(--pad);margin-bottom:var(--gap);box-shadow:var(--shadow);
}
.video-card{display:flex;align-items:center;gap:16px}
.video-card.done{border-color:var(--green-dim);box-shadow:0 0 0 1px var(--green-dim)}
.video-emoji{font-size:35.88px;flex:none}
.video-body{flex:1}
.video-body .t{font-size:20.7px;font-weight:600}
.video-body .s{font-size:17.25px;color:var(--text-3);margin-top:3px}
.video-btn{
  flex:none;padding:11px 20px;border-radius:100px;font-size:19.32px;font-weight:600;
  background:var(--surface-2);border:1px solid var(--hairline-str);
  transition:all .2s var(--ease);white-space:nowrap;
}
.video-btn:hover{border-color:var(--green-soft)}
.video-btn:active{transform:scale(.95)}
.video-btn.done{background:var(--green-dim);border-color:var(--green-dim);color:var(--green-soft)}

.notes-title{font-size:23.46px;font-weight:650;letter-spacing:-.015em;margin-bottom:4px}
.notes-box{
  width:100%;min-height:120px;background:var(--surface-2);
  border:1px solid var(--hairline);border-radius:var(--r-md);
  padding:14px;font-size:19.32px;line-height:1.6;resize:vertical;transition:border-color .2s;
}
.notes-box:focus{outline:none;border-color:var(--blue)}
.notes-box::placeholder{color:var(--text-3)}

.scales{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:20px}
@media(max-width:460px){.scales{grid-template-columns:1fr}}
.scale .sk{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:9px}
.scale .sk .lbl{font-size:16.56px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);font-weight:600}
.scale .sk .num{font-family:var(--mono);font-size:30.36px;font-weight:600;color:var(--blue-soft)}
.scale-dots{display:flex;gap:5px}
.scale-dot{
  flex:1;height:26px;border-radius:7px;background:var(--surface-2);
  border:1px solid var(--hairline);transition:all .18s var(--ease);
}
.scale-dot:hover{border-color:var(--blue-soft)}
.scale-dot.on{background:linear-gradient(180deg,var(--blue),#2d52d8);border-color:transparent}

/* ============================================================
   FINISH OVERLAY
   ============================================================ */
.finish{
  /* The tab bar sits at z-index 200 and was drawing straight over the bottom of
     this card - which is where the two buttons are. It is a modal; it goes on
     top. The card already scrolls internally, so the only real fault was the
     stacking order and a bottom edge that ignored the home indicator. */
  position:fixed;inset:0;z-index:260;
  background:rgba(18,26,44,.5);backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;
  opacity:0;visibility:hidden;transition:opacity .3s var(--ease);
  padding:20px 16px calc(20px + env(safe-area-inset-bottom,0px));
}
.finish.show{opacity:1;visibility:visible}
body.finish-open{overflow:hidden;touch-action:none}
.finish-inner{
  position:relative;background:var(--surface);border:1px solid var(--hairline-str);
  max-width:400px;width:100%;max-height:88vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;touch-action:pan-y;
  border-radius:24px;padding:30px 22px 22px;text-align:center;
  box-shadow:0 30px 80px -20px rgba(20,30,60,.55);
  transform:translateY(20px) scale(.97);opacity:0;
  transition:transform .4s var(--ease-out), opacity .3s var(--ease);
}
.finish.show .finish-inner{transform:none;opacity:1}
.finish-close{position:absolute;top:12px;right:12px;width:34px;height:34px;border-radius:50%;border:none;
  background:var(--surface-2);color:var(--text-3);font-size:19.55px;line-height:1;cursor:pointer;display:grid;place-items:center;z-index:3}
.finish-close:active{transform:scale(.92)}
.check-badge{
  width:74px;height:74px;margin:4px auto 18px;border-radius:50%;
  background:var(--green-dim);border:2px solid var(--green);
  display:grid;place-items:center;box-shadow:0 0 44px -12px var(--green);
}
.check-badge svg{width:34px;height:34px;stroke:var(--green);stroke-width:3.5;
  fill:none;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:60;stroke-dashoffset:60;}
.finish.show .check-badge svg{animation:draw .7s var(--ease-out) .5s forwards}
@keyframes draw{to{stroke-dashoffset:0}}
.finish h1{font-size:31.05px;font-weight:750;letter-spacing:-.03em}
.finish .lead{color:var(--green-soft);font-weight:600;margin-top:5px;font-size:17.82px}
.finish .msg{color:var(--text-2);font-size:16.67px;line-height:1.55;margin-top:11px;max-width:320px;margin-inline:auto}
/* THE FINISH SCREEN, GIVEN A HIERARCHY.

   Six identical tiles in a 2x3 grid gave "Not reached: 0" the same weight as the
   work itself, and the eye had nowhere to land. Sessions where nothing was missed
   spent a third of the panel saying so.

   So one number leads - how much of the core work was completed, which is the
   only figure that answers "did I do the session" - and the rest sit under it as
   a quiet row. Anything that is zero and means nothing is not shown at all.

   Spacing is one scale rather than six margins picked separately. */
.finish-inner{--fin-gap:18px}
.check-badge{width:64px;height:64px;margin:0 auto var(--fin-gap)}
.check-badge svg{width:30px;height:30px}
#finishTitle{font-size:28.75px;letter-spacing:-.025em;margin:0}
.finish-inner .lead{font-size:17.25px;font-weight:700;margin:6px 0 0}
.finish-inner .msg{font-size:15.52px;line-height:1.6;color:var(--text-3);
  margin:8px auto 0;max-width:31ch}

/* The headline figure. */
.fin-hero{margin:var(--fin-gap) 0 0;padding:16px 18px;border-radius:16px;
  background:linear-gradient(160deg,var(--surface-2),transparent);
  border:1px solid var(--hairline);display:flex;align-items:center;gap:14px;text-align:start}
.fin-hero-v{font-size:39.1px;font-weight:850;letter-spacing:-.03em;line-height:1}
.fin-hero-v small{font-size:17.25px;font-weight:700;opacity:.45;margin-inline-start:2px}
.fin-hero-t{flex:1}
.fin-hero-k{font-size:12.07px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-3)}
.fin-hero-s{font-size:14.37px;color:var(--text-2);margin-top:2px;line-height:1.4}

/* Everything else, as one quiet strip. */
.finish-stats{display:flex;flex-wrap:wrap;gap:0;margin:var(--fin-gap) 0 0;
  border-top:1px solid var(--hairline);padding-top:12px}
.fstat{flex:1 1 0;min-width:74px;background:none;border:0;padding:0 6px;text-align:center;
  border-inline-start:1px solid var(--hairline)}
.fstat:first-child{border-inline-start:0}
.fstat .k{font-size:10.92px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-3)}
.fstat .v{font-size:19.55px;font-weight:800;letter-spacing:-.02em;margin-top:3px}
.fstat .v small{font-size:12.07px;font-weight:700;opacity:.45;margin-inline-start:1px}

.big-btn{margin-top:calc(var(--fin-gap) + 6px);padding:16px;font-size:19.55px}
.dl-btn{margin-top:9px;padding:14px 16px;font-size:17.82px}
.notreached-note{margin:var(--fin-gap) 0 0;font-size:14.37px;line-height:1.55}

/* Films taken during a session, shown back at the end of it. The readings were
   being written to the movement log from the first day and nothing ever read
   them out, so ten clips of a deload could be analysed well and then be
   unreachable. This is the screen that was missing. */
.ff{margin:18px 0 4px;text-align:right}
.ff-h{font-size:13.8px;letter-spacing:.09em;text-transform:uppercase;opacity:.55;
      margin-bottom:10px;font-weight:700}
.ff-row{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.09);
        border-radius:14px;padding:11px 13px;margin-bottom:8px}
.ff-top{display:flex;align-items:baseline;gap:8px;justify-content:space-between}
.ff-mv{font-weight:700;font-size:16.67px}
.ff-t{font-size:13.22px;opacity:.5;font-variant-numeric:tabular-nums}
.ff-v{font-size:14.95px;opacity:.9;margin-top:4px;line-height:1.45}
.ff-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:7px}
.ff-tag{font-size:12.65px;padding:2px 8px;border-radius:999px;
        background:rgba(255,255,255,.09)}
.ff-tag.bad{background:rgba(255,138,128,.16)}
.ff-tag.good{background:rgba(129,230,170,.15)}

.fstat{
  background:var(--surface-2);border:1px solid var(--hairline);
  border-radius:var(--r-md);padding:13px;
}
.fstat .k{font-size:12.65px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-3);font-weight:600}
.fstat .v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:27.6px;font-weight:600;margin-top:5px;letter-spacing:-.02em}
.fstat .v small{font-size:14.95px;color:var(--text-3);margin-left:3px}
.finish .big-btn{margin-top:8px}
canvas#confetti{position:fixed;inset:0;z-index:70;pointer-events:none}

/* tiny "session complete" re-open badge once finished + dismissed */
.reopen{
  position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:45;
  background:var(--green-dim);border:1px solid var(--green-dim);color:var(--green-soft);
  padding:11px 20px;border-radius:100px;font-size:18.63px;font-weight:600;
  box-shadow:0 12px 30px -12px rgba(0,0,0,.7);display:none;align-items:center;gap:8px;
  backdrop-filter:blur(10px);
}
.reopen.show{display:inline-flex}

/* ============================================================
   STICKY REST STOPWATCH (bottom-left)
   ============================================================ */
/* The launch skeleton. Sized from the real thing - the hero's 1672/941 frame and
   the card rhythm underneath it - so the page does not jump when the real
   content lands on top of it. */
.sk{background:var(--surface-2);border-radius:18px;position:relative;overflow:hidden;
  margin:0 0 var(--home-gap,12px)}
.sk-hero{aspect-ratio:1672/941;border-radius:18px}
.sk-row{height:52px;border-radius:14px}
.sk-card{height:132px}
.sk-short{height:84px}
.sk::after{content:'';position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);
  animation:skShine 1.35s ease-in-out infinite}
@keyframes skShine{ to{ transform:translateX(100%) } }
@media(prefers-reduced-motion:reduce){ .sk::after{animation:none} }
.stopwatch{
  position:fixed;z-index:46;
  left:calc(16px + env(safe-area-inset-left,0));
  bottom:calc(20px + env(safe-area-inset-bottom,0));
}
.sw-face{
  position:relative;width:76px;height:76px;border-radius:50%;
  background:var(--surface);border:1px solid var(--hairline-str);
  box-shadow:0 10px 30px -10px rgba(20,40,100,.35), 0 2px 6px rgba(20,40,100,.10);
  display:grid;place-items:center;transition:transform .18s var(--ease), box-shadow .3s;
}
.sw-face:active{transform:scale(.94)}
.stopwatch.running .sw-face,.stopwatch.done .sw-face{transform:scale(1.32)}
.stopwatch.running .sw-face:active,.stopwatch.done .sw-face:active{transform:scale(1.24)}
.sw-ring{position:absolute;inset:0;width:76px;height:76px;transform:rotate(-90deg)}
.sw-track{stroke:var(--hairline)}
.sw-prog{stroke:var(--blue);transition:stroke-dashoffset .95s linear, stroke .3s}
.sw-icon{width:26px;height:26px;color:var(--blue);display:block}
.sw-text{position:absolute;font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-weight:700;font-size:25.3px;color:var(--text);letter-spacing:-.02em;display:none;direction:ltr}
/* idle: show icon; running/done: show number */
.stopwatch.running .sw-icon,.stopwatch.done .sw-icon{display:none}
.stopwatch.running .sw-text,.stopwatch.done .sw-text{display:block}
.stopwatch.running .sw-face{border-color:rgba(46,91,255,.5)}
.stopwatch.paused .sw-prog{stroke:var(--text-3)}
.stopwatch.done .sw-face{background:var(--green);border-color:var(--green);box-shadow:0 0 0 6px var(--green-dim),0 10px 30px -8px var(--green)}
.stopwatch.done .sw-prog{stroke:#ffffff}
.stopwatch.done .sw-text{color:#04140e}
.stopwatch.done .sw-face{animation:swpulse 1s var(--ease) 2}
@keyframes swpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
/* small resting label under the idle circle */
.stopwatch:not(.running):not(.done) .sw-text{display:block;position:static;font-size:12.65px;color:var(--text-3);font-family:var(--sans);font-weight:600;margin-top:0}
.stopwatch:not(.running):not(.done) .sw-icon{margin-bottom:-2px}
/* popover replaced by a clean bottom sheet */
.sw-backdrop{position:fixed;inset:0;z-index:58;background:rgba(20,30,60,.32);
  backdrop-filter:blur(2px);opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility .3s}
.sw-backdrop.show{opacity:1;visibility:visible}
.sw-sheet{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  max-width:var(--maxw);margin:0 auto;
  background:var(--surface);border:1px solid var(--hairline-str);border-bottom:none;
  border-radius:24px 24px 0 0;
  padding:12px 20px calc(26px + env(safe-area-inset-bottom,0));
  box-shadow:0 -18px 50px -20px rgba(20,40,100,.4);
  transform:translateY(110%);transition:transform .38s var(--ease-out);
  text-align:center;
}
.sw-sheet.open{transform:none}
.sw-grip{width:40px;height:4px;border-radius:100px;background:var(--hairline-str);margin:0 auto 14px}
.sw-sheet-head{display:flex;justify-content:space-between;align-items:center;
  font-family:var(--mono);font-size:13.8px;letter-spacing:.05em;color:var(--blue-soft);font-weight:600;margin-bottom:6px}
.sw-sheet.done .sw-sheet-head{color:var(--green-soft)}
.sw-sheet-head .nxt{color:var(--text-3)}
.sw-sheet-face{font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:clamp(66.7px,19.55vw,96.6px);font-weight:600;letter-spacing:-.03em;line-height:1;color:var(--blue-soft);direction:ltr}
.sw-sheet.done .sw-sheet-face{color:var(--green-soft)}
.sw-sheet-bar{width:100%;height:6px;border-radius:100px;background:var(--surface-2);overflow:hidden;margin:16px 0 4px}
.sw-sheet-bar span{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--blue),var(--green));transition:width .95s linear}
.sw-sheet-cue{font-size:17.25px;color:var(--text-2);min-height:22px;margin:12px 0 18px}
.sw-sheet.done .sw-sheet-cue{color:var(--green-soft);font-weight:600}
.sw-sheet-ctrls{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;margin-bottom:14px}
.sw-c{padding:15px 8px;border-radius:14px;font-size:17.25px;font-weight:650;
  background:var(--surface-2);border:1px solid var(--hairline-str);color:var(--text);transition:all .16s var(--ease)}
.sw-c:active{transform:scale(.95)}
.sw-c.go{background:var(--green);border-color:var(--green);color:#04140e}
.sw-sheet.done .sw-sheet-ctrls{grid-template-columns:1fr}
.sw-sheet.done .hide-on-done{display:none}
.sw-sheet-lens{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}
.sw-sheet-lens .lbl{font-family:var(--mono);font-size:12.65px;letter-spacing:.06em;color:var(--text-3);text-transform:uppercase;font-weight:600}
.sw-sheet.done .sw-sheet-lens{display:none}

/* footer hint (keyboard shortcuts) */
.hint kbd{
  font-family:var(--mono);font-size:15.18px;background:var(--surface-2);
  border:1px solid var(--hairline-str);border-radius:6px;padding:2px 7px;color:var(--text-2);
}

/* reset link */
/* download / share workout buttons */
.dl-row{display:flex;gap:12px;margin-top:24px;flex-wrap:wrap}
.dl-btn{
  flex:1;min-width:190px;padding:15px 18px;border-radius:var(--r-md);
  font-size:20.7px;font-weight:650;letter-spacing:.01em;
  background:var(--blue-dim);border:1px solid rgba(62,107,255,.30);color:var(--blue-soft);
  display:flex;align-items:center;justify-content:center;gap:9px;
  transition:background .2s var(--ease),border-color .2s var(--ease),transform .16s var(--ease);
}
.dl-btn:hover{background:rgba(62,107,255,.20);border-color:var(--blue-soft)}
.dl-btn:active{transform:scale(.98)}
.dl-btn:focus-visible{outline:2px solid var(--blue-soft);outline-offset:3px}
.dl-btn svg{width:17px;height:17px;flex:none}
.dl-btn.share{background:var(--green-dim);border-color:rgba(53,214,164,.30);color:var(--green-soft)}
.dl-btn.share:hover{background:rgba(53,214,164,.20);border-color:var(--green-soft)}
.dl-btn.ghost{background:transparent;border-color:var(--hairline-str);color:var(--text-2);margin-top:12px}
.dl-btn.ghost:hover{border-color:var(--blue-soft);color:var(--blue-soft);background:var(--blue-dim)}

.reset-link{
  display:block;width:max-content;max-width:100%;margin:26px auto 6px;
  padding:11px 22px;border-radius:12px;text-align:center;cursor:pointer;
  background:rgba(225,72,72,.08);border:1px solid rgba(225,72,72,.25);
  color:#d64545;font-size:16.1px;font-weight:650;text-decoration:none;transition:all .18s;
}
.reset-link:hover{background:rgba(225,72,72,.13)}
.reset-link:active{transform:scale(.98)}
.reset-link.armed{background:#d64545;border-color:#d64545;color:#fff}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important;transition-duration:.08s !important}
}
@media(min-width:520px){.acc-fields{grid-template-columns:100px 90px 90px 1fr;align-items:end}}
#modeChip{display:none}
#modeChip + .dot-sep{display:none}

/* ============================ DARK THEME ============================ */
/* theme toggle (top-right) */
.theme-tog{display:none}
body.on-home .theme-tog{position:fixed;top:calc(env(safe-area-inset-top,0px) + 9px);right:10px;z-index:210;
  width:38px;height:38px;border-radius:50%;display:grid;place-items:center;cursor:pointer;
  background:var(--surface);border:1px solid var(--hairline-str);color:var(--text-2);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:var(--shadow);transition:transform .12s,color .2s}
.theme-tog:active{transform:scale(.9)}
.theme-tog svg{width:19px;height:19px}
.theme-tog .moon{display:none}

/* refresh. 12 Aug 2026: this used to float permanently over the Home screen -
   a cache-bypass tool ("it exists to prove what is live", per the original
   note below) that both athletes saw always, with no explanation of what it
   was for. It now lives once, in Profile, next to the version number it's
   actually about. */
.refresh-tog{display:inline-flex;align-items:center;gap:6px}
.refresh-tog svg{width:15px;height:15px}
.refresh-tog.spin svg{animation:refspin .8s linear infinite}
@keyframes refspin{to{transform:rotate(360deg)}}

/* ===== Timer Center ===== */
.tc-tabs{display:flex;gap:5px;background:var(--surface-2);border-radius:12px;padding:4px;margin:4px 0 12px}
.tc-tabs button{flex:1;border:none;background:none;color:var(--text-3);font-size:14.37px;font-weight:700;padding:8px 4px;border-radius:9px;cursor:pointer;font-family:inherit}
.tc-tabs button.on{background:var(--surface);color:var(--text);box-shadow:0 1px 3px rgba(0,0,0,.12)}
.tc-panel{display:none}
.tc-panel.on{display:block}
.tc-start{width:100%;margin-top:10px;padding:12px;border:1px solid var(--hairline-str);border-radius:12px;background:var(--surface-2);color:var(--text);font-weight:650;font-size:16.1px;cursor:pointer;font-family:inherit}
.tc-presets{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin-bottom:10px}
.tc-presets button{padding:11px 4px;border:1px solid var(--hairline-str);border-radius:11px;background:var(--surface);color:var(--text);font-weight:700;font-size:16.1px;font-family:var(--mono);cursor:pointer}
.tc-presets button:active{transform:scale(.96)}
.tc-emom{grid-template-columns:repeat(3,1fr)}
.tc-emom button{font-family:inherit;font-size:14.37px}
.tc-adj{display:flex;align-items:center;justify-content:center;gap:16px;margin-bottom:12px}
.tc-adj button{width:64px;padding:9px 0;border:1px solid var(--hairline-str);border-radius:10px;background:var(--surface);color:var(--text);font-weight:650;cursor:pointer;font-family:inherit}
.tc-adj-lbl{font-family:var(--mono);font-size:25.3px;font-weight:800;color:var(--text);min-width:76px;text-align:center}
.tc-fields{display:flex;gap:8px;margin-bottom:10px}
.tc-fields label{flex:1;display:flex;flex-direction:column;gap:4px;font-size:12.65px;font-weight:700;color:var(--text-3);text-transform:uppercase;letter-spacing:.04em}
.tc-fields input{width:100%;box-sizing:border-box;text-align:center;font-family:var(--mono);font-size:23px;font-weight:800;color:var(--text);background:var(--surface-2);border:1px solid var(--hairline-str);border-radius:10px;padding:9px 4px}
.tc-fields input:focus{outline:none;border-color:var(--blue)}
.tc-fields span{font-size:11.5px;color:var(--text-3);text-align:center;font-weight:600}
.tc-run{display:flex;gap:8px;margin-top:4px}
.tc-run .tc-go{flex:2;padding:13px;border:none;border-radius:12px;background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff;font-weight:750;font-size:17.25px;cursor:pointer;font-family:inherit}
.tc-run .tc-c{flex:1;padding:13px;border:1px solid var(--hairline-str);border-radius:12px;background:var(--surface);color:var(--text);font-weight:650;cursor:pointer;font-family:inherit}
.tc-run button:active{transform:scale(.97)}
.tc-sound{width:100%;margin-top:12px;padding:9px;border:none;border-radius:10px;background:none;color:var(--text-3);font-size:14.37px;font-weight:650;cursor:pointer;font-family:inherit}

.plainlist{display:flex;flex-direction:column;margin:2px 0 2px;min-width:0}
.plainlist.is-interval{margin-top:14px}
.interval-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;margin:0 0 6px}
.interval-stat{min-width:0;padding:9px 5px 8px;border:1px solid var(--hairline);border-radius:11px;background:var(--surface-2);text-align:center}
.interval-stat b{display:block;color:var(--text);font-family:var(--mono);font-size:16.1px;line-height:1.2;overflow-wrap:anywhere}
.interval-stat span{display:block;margin-top:3px;color:var(--text-3);font-size:10.35px;font-weight:750;letter-spacing:.07em;text-transform:uppercase}
.pl-row{display:grid;grid-template-columns:minmax(118px,.42fr) minmax(0,1fr);align-items:start;gap:14px;padding:12px 0;border-bottom:1px solid var(--hairline);min-width:0}
.pl-row:last-child{border-bottom:none}
.pl-name{min-width:0;font-size:17.82px;font-weight:650;color:var(--text);line-height:1.35;overflow-wrap:anywhere}
.pl-detail{min-width:0;font-size:14.95px;color:var(--text-3);text-align:left;font-family:var(--mono);white-space:normal;overflow-wrap:anywhere;line-height:1.48}
/* 2 Sep 2026 - the coach's own prescription, on the card at last. `note` was
   sitting on five live sections and drawn by nothing at all;
   sectionPrescriptionHTML puts it here. pre-line because a coach writes these
   as several short lines, not one paragraph. */
.sec-brief{margin:2px 0 6px;padding:12px 14px;border:1px solid var(--hairline);border-radius:12px;background:var(--surface-2);color:var(--text-2);font-size:15.5px;line-height:1.55;white-space:pre-line;overflow-wrap:anywhere}
.pl-side{min-width:0;display:flex;flex-direction:column;gap:4px}
.pl-cue{font-family:var(--sans);opacity:.92}
.tc-preset-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:52px;box-sizing:border-box;margin-top:14px;padding:13px 12px;border:none;border-radius:14px;background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff;font-weight:750;font-size:17.25px;line-height:1.25;text-align:center;white-space:normal;cursor:pointer;font-family:inherit;box-shadow:0 6px 18px -8px var(--blue)}
.tc-preset-btn:active{transform:scale(.98)}
@media(max-width:520px){
  .pl-row{grid-template-columns:minmax(0,1fr);gap:4px;padding:13px 0}
  .pl-name{font-size:17.25px}
  .pl-detail{font-size:14.95px;line-height:1.5}
}

/* exercise demo videos */
.lift-vidrow{display:flex;align-items:center;gap:4px;font-size:14.37px;color:var(--text-3);margin:0 0 12px}
.vid-btn{border:none;background:none;cursor:pointer;font-size:17.25px;line-height:1;padding:2px 4px;margin-inline-start:6px;opacity:.85;vertical-align:middle;filter:grayscale(.1)}
.vid-btn:active{transform:scale(.9)}
/* 11 Aug 2026: the mobility flow sheet sits at 1200 and the demo video opened
   BEHIND it - a working button with an invisible result. The demo is always the
   topmost thing when open: you asked to see it, so you see it. */
.vid-modal{position:fixed;inset:0;z-index:1300;display:none;align-items:center;justify-content:center;padding:18px}
.vid-modal.show{display:flex}
.vid-backdrop{position:absolute;inset:0;background:rgba(6,10,18,.72);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.vid-card{position:relative;width:min(380px,92vw);background:var(--surface);border:1px solid var(--hairline-str);border-radius:18px;box-shadow:0 24px 60px -18px rgba(0,0,0,.6);overflow:hidden}
.vid-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:13px 15px}
.vid-title{font-size:17.25px;font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vid-x{border:none;background:var(--surface-2);color:var(--text-2);width:30px;height:30px;border-radius:50%;font-size:17.25px;cursor:pointer;flex:none}
.vid-body{padding:0 15px}
.vid-frame{position:relative;width:100%;padding-top:56.25%;border-radius:12px;overflow:hidden;background:#000}
.vid-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.vid-loading{padding:34px 12px;text-align:center;color:var(--text-2);font-size:16.1px;line-height:1.5}

body.kb-open .tabbar{transform:translate3d(0,120%,0)}
/* The in-workout coach is a modal conversation over the session. See the note
   in .wc-panel: with the keyboard up the bar was landing across the middle of
   it. The panel's own X is the way out. */
body.wc-open .tabbar{transform:translate3d(0,120%,0);pointer-events:none}
/* Nothing pins the top any more. Pinning it was the second wrong answer to the
   clipping: it made overflow impossible by making the sheet full-height, which
   turned one greeting into a screen of white. The sheet is bottom-anchored and
   sized from the MEASURED viewport instead - see .wc-panel. */
/* The coach view stops short of the bottom by exactly the tab bar's measured
   height (--bar-h, about 42px since 15 Aug). With the keyboard up the bar
   slides away, so that reserved strip would otherwise become an empty band
   between the composer and the keyboard. */
/* Keyboard up: the tab bar slid away, so reclaim its strip - the full small
   viewport, which already excludes the keyboard. */
body.kb-open #viewCoach.on{height:100svh}
/* While the keyboard is up the document is cut to the visual viewport by js/19
   (html/body inline height) so iOS has no room left to pan; the body must not
   re-stretch itself to the screen through inset:0. */
body.kb-open.on-coach{inset:auto;top:0;left:0;right:0;bottom:auto;overflow:hidden}
@supports not (height:100svh){ body.kb-open #viewCoach.on{height:100vh} }
body.on-coach{position:fixed;inset:0;width:100%;overflow:hidden}
/* 15 Aug 2026, and the same day it was reverted. Hiding the bar in a
   conversation did give the thread its 56px back, but I wrote that "the coach
   header keeps its own way back" without checking, and it does not: the header
   has an avatar, a name and four action buttons, and no exit. He opened the
   chat and had no way out of it. That is worse than any amount of space.
   The bar is slim now (42px) and the header has a real back arrow, so the
   trade the hiding was making no longer needs making. */
body./* The switch was hidden here on purpose once, to keep the chat clean. But
   the coach screen is where most time is spent, so it was the one place you
   could not change the theme. It stays, tucked out of the way. */
body.on-coach #themeTog{display:grid;top:calc(env(safe-area-inset-top,0px) + 62px);opacity:.75}
body.on-coach #themeTog:hover{opacity:1}
/* The watch card. One figure line worth looking at, everything else quiet. */
.wx{padding:2px 0 0}
.wx-plan{font-size:15.52px;line-height:1.55;color:var(--text-2);margin-bottom:12px}
.wx-got{border-radius:14px;padding:13px 14px;margin-bottom:11px;
  background:linear-gradient(150deg,rgba(46,160,110,.13),rgba(60,120,220,.10));
  border:1px solid var(--hairline-str)}
.wx-meta{font-size:13.22px;color:var(--text-2);margin-top:4px;direction:ltr}
.wx-empty{font-size:14.37px;line-height:1.5;color:var(--text-3);border:1px dashed var(--hairline-str);
  border-radius:14px;padding:13px 14px;margin-bottom:11px}
.wx-sync{width:100%;border:0;border-radius:14px;padding:14px;background:var(--blue);color:#fff;
  font-family:inherit;font-size:17.25px;font-weight:700;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:9px}
.wx-sync:active{transform:scale(.985)}
.wx-sync[disabled]{opacity:.55;cursor:default}
.wx-run{font-size:20.7px;line-height:1}
.wx-note{font-size:12.65px;color:var(--text-3);text-align:center;margin-top:9px;line-height:1.45}
/* A goal the coach is offering. It sits under the reply that proposed it, in
   English because that is the record, and it does nothing until he taps. Styled
   as a quiet card, not an alert: this is an offer, and declining it is normal. */
/* 25 Aug 2026. The goal proposal card, styled as a sibling of the plan's - same
   weight, same place, because it is the same kind of decision. */
.gp-card{max-width:840px;margin:0 auto 8px;border:1px solid rgba(56,102,255,.28);
  background:var(--blue-dim);border-radius:16px;padding:13px 15px 12px}
.gp-top{display:flex;align-items:center;gap:8px;justify-content:space-between;margin-bottom:6px}
.gp-badge{font-size:11.5px;font-weight:750;letter-spacing:.04em;color:var(--blue);
  background:rgba(56,102,255,.12);border-radius:999px;padding:3px 9px;white-space:nowrap}
.gp-badge.rm{color:#b4442f;background:rgba(214,92,66,.13)}
.gp-when{font-size:12.07px;color:var(--text-3);font-variant-numeric:tabular-nums}
.gp-title{font-size:17.2px;font-weight:750;letter-spacing:-.01em;line-height:1.32}
.gp-d{font-size:14.37px;color:var(--text-2);line-height:1.5;margin-top:5px}
/* 25 Aug 2026, his call: the card was longer than the screen, and a card he has
   to scroll to read is a card he approves without reading. Three lines of the
   commitment, and everything else - how it is judged, what it replaces, why -
   behind one tap. The decision needs the gist; the detail needs to be reachable,
   not present. */
.gp-d.clamp{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.gp-more{margin-top:7px;border:0;background:none;padding:0;font-family:inherit;
  font-size:13.22px;font-weight:700;color:var(--blue)}
.gp-rest{margin-top:2px}
.gp-m{font-size:13.22px;color:var(--text-3);line-height:1.45;margin-top:6px}
.gp-m b{color:var(--text-2)}
.gp-old{font-size:13.22px;color:#b4442f;line-height:1.45;margin-top:6px}
.gp-why{font-size:13.22px;color:var(--text-2);font-style:italic;line-height:1.45;margin-top:7px}
.gp-actions{display:flex;gap:8px;margin-top:11px}
.gp-btn{flex:1;border:0;border-radius:12px;padding:12px 8px;font-size:15.5px;font-weight:750;
  font-family:inherit}
.gp-ok{background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff}
.gp-no{background:var(--surface);color:var(--text-2);flex:0 0 auto;padding:12px 18px}
.gp-btn:active{transform:scale(.98)}
.gp-err{font-size:13.22px;color:#b4442f;margin-top:8px}
.gcard{border:1px solid var(--hairline-str);border-radius:15px;padding:14px 15px;margin:9px 0 2px;
  background:linear-gradient(155deg,rgba(60,120,220,.09),rgba(46,160,110,.07));direction:ltr;text-align:left}
.gcard-m{font-size:13.22px;line-height:1.5;color:var(--text-3);margin-top:7px}
.gcard-set{flex:1;border:0;border-radius:11px;padding:11px;background:var(--blue);color:#fff;
  font-family:inherit;font-size:16.1px;font-weight:700;cursor:pointer}
.gcard-set:active{transform:scale(.985)}
.gcard-set[disabled]{opacity:.5;cursor:default}
/* The chip that offers to word a goal, when the coach settled one in words and
   did not put a card on it. It appears under that reply only, never in general. */
.gchip{display:inline-flex;align-items:center;gap:7px;margin-top:9px;
  border:1px solid var(--hairline-str);background:var(--surface);color:var(--blue);
  border-radius:100px;padding:8px 14px;font-family:inherit;font-size:14.95px;font-weight:600;cursor:pointer}
.gchip:active{transform:scale(.97)}
.gchip[disabled]{opacity:.6;cursor:default}
/* The options the coach offers instead of deciding for him (<<PICK>>). They sit
   under the bubble they belong to, wrap onto as many rows as they need, and
   stay on screen after he taps - greyed, with his choice marked - because a
   decision that vanishes reads as a decision that was never made. */
.pickrow{display:flex;flex-wrap:wrap;gap:7px;margin-top:9px}
.pchip{border:1px solid var(--hairline-str);background:var(--surface);color:var(--blue);
  border-radius:100px;padding:8px 14px;font-family:inherit;font-size:14.95px;font-weight:600;
  cursor:pointer;max-width:100%;text-align:center;line-height:1.25}
.pchip:active{transform:scale(.97)}
.pickrow.picked .pchip{opacity:.5;cursor:default}
.pickrow.picked .pchip.chosen{opacity:1;background:var(--blue);color:#fff;border-color:var(--blue)}
.gcard.done{opacity:.72}
.gcard.done .gcard-row{display:none}
.gcard-ok{font-size:14.37px;font-weight:600;color:var(--green-soft,#2ea06e);margin-top:11px}
.tz-toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom,0px) + 72px);transform:translateX(-50%) translateY(20px);background:var(--text);color:var(--bg);padding:11px 18px;border-radius:999px;font-size:16.1px;font-weight:650;box-shadow:0 10px 28px -10px rgba(0,0,0,.55);opacity:0;pointer-events:none;transition:opacity .25s ease,transform .25s ease;z-index:400;max-width:90vw;text-align:center}
/* 9 Aug 2026. "Plan updated" stayed on screen. Hiding depended on a setTimeout
   stored on the element, and a timer that never fires - a throttled tab, a
   second call racing the first - left the toast up with nothing to take it down.
   A CSS animation cannot be forgotten: it fades in, waits, and fades out on its
   own, even if no JavaScript ever runs again. The timeout below is now only
   housekeeping. */
.tz-toast.show{animation:tzToastLife 2.9s ease forwards}
@keyframes tzToastLife{
  0%{opacity:0;transform:translateX(-50%) translateY(20px)}
  9%{opacity:1;transform:translateX(-50%) translateY(0)}
  82%{opacity:1;transform:translateX(-50%) translateY(0)}
  100%{opacity:0;transform:translateX(-50%) translateY(8px)}
}
.tz-toast.err{background:#c0392b;color:#fff}
body.bg-lock{overflow:hidden !important;touch-action:none}
.vid-sound{display:block;margin:12px auto 4px;padding:10px 18px;border:none;border-radius:999px;background:var(--surface-2);color:var(--text);font-size:16.1px;font-weight:700;cursor:pointer}
.vid-sound.on{background:var(--blue-dim);color:var(--blue-soft)}
.coach-switch{flex:none;display:flex;gap:7px;padding:9px 12px;border-bottom:1px solid var(--hairline);background:var(--surface);overflow-x:auto;-webkit-overflow-scrolling:touch}
.cs-chip{flex:none;display:flex;align-items:center;gap:5px;padding:7px 13px;border-radius:999px;border:1px solid var(--hairline);background:var(--bg);color:var(--text-2);font-size:14.95px;font-weight:650;cursor:pointer;white-space:nowrap}
.cs-chip.on{background:var(--blue);border-color:var(--blue);color:#fff;box-shadow:0 3px 10px -4px var(--blue)}
.cs-chip span{font-size:17.25px}
/* The search indicator. Deliberately not shaped like a message: it is the app
   working, and a chat bubble would say the coach was talking. */
.sch{display:inline-flex;align-items:center;gap:10px;margin:4px 0 8px;
  padding:9px 16px;border-radius:999px;color:#3b4a86;font-size:14.95px;font-weight:700;
  background:linear-gradient(110deg,#eef2ff 30%,#dfe7ff 45%,#eef2ff 60%);
  background-size:220% 100%;animation:schShimmer 1.6s linear infinite;
  border:1px solid #dbe3ff;box-shadow:0 2px 10px rgba(59,74,134,.08)}
@keyframes schShimmer{to{background-position:-220% 0}}
.sch-orb{position:relative;width:20px;height:20px;flex:none}
.sch-orb::before{content:'';position:absolute;inset:5px;border-radius:50%;
  background:#4f6ef7;box-shadow:0 0 10px rgba(79,110,247,.65);
  animation:schCore 1.2s ease-in-out infinite}
@keyframes schCore{50%{transform:scale(.72);opacity:.7}}
.sch-orb i{position:absolute;inset:0;border-radius:50%;
  border:1.5px solid transparent;border-top-color:#4f6ef7;opacity:.85;
  animation:schOrbit 1.1s linear infinite}
.sch-orb i:nth-child(2){inset:-4px;border-top-color:#8aa0ff;opacity:.5;
  animation-duration:1.7s;animation-direction:reverse}
.sch-orb i:nth-child(3){inset:-8px;border-top-color:#c3cfff;opacity:.35;
  animation-duration:2.4s}
@keyframes schOrbit{to{transform:rotate(360deg)}}
@keyframes schDot{30%{transform:translateY(-3px)}}
.sch-out{opacity:0;transform:translateY(-4px);transition:all .25s}
/* While the search runs and no words exist yet, the reply bubble itself hides -
   the half-open empty bubble under the chip was the whole complaint. */
.msg-hollow{display:none !important}
to{opacity:1;transform:none}}

/* Controls for questions. Sized for a thumb between sets, not for a desk. */
.ex.is-ask .ex-detail{margin-bottom:8px}
.ansscale{display:flex;gap:5px;flex-wrap:wrap;margin:2px 0 4px}
.ansdot{min-width:38px;height:38px;padding:0 6px;border-radius:10px;cursor:pointer;
  font:inherit;font-size:16.1px;font-weight:600;color:var(--text-2);
  background:var(--surface);border:1px solid var(--hairline-str)}
.ansdot:hover{border-color:var(--blue)}
.ansdot.on{background:var(--blue);border-color:var(--blue);color:#fff}
.ansends{display:flex;justify-content:space-between;font-size:13.22px;color:var(--text-3);margin-bottom:4px}
.anspills{display:flex;gap:7px;flex-wrap:wrap;margin:2px 0 6px}
.anspill{padding:9px 16px;border-radius:20px;cursor:pointer;font:inherit;font-size:16.1px;
  color:var(--text-2);background:var(--surface);border:1px solid var(--hairline-str)}
.anspill:hover{border-color:var(--blue)}
.anspill.on{background:var(--blue);border-color:var(--blue);color:#fff;font-weight:600}
.ansnum,.anstext{width:100%;font:inherit;font-size:17.25px;color:var(--text);background:var(--surface);
  border:1px solid var(--hairline-str);border-radius:10px;padding:9px 12px;margin:2px 0 6px}
.ansnum{max-width:130px}
.anstext{resize:vertical;line-height:1.5}
.ansnum:focus,.anstext:focus{outline:none;border-color:var(--blue)}

.wkcard{background:var(--card);border:1px solid var(--blue);border-radius:16px;
  margin:0 0 16px;box-shadow:0 6px 22px rgba(76,111,255,.10);overflow:hidden}
.wkcard-sum{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;padding:15px 18px}
.wkcard-sum::-webkit-details-marker{display:none}
.wkcard-c{margin-inline-start:auto;font-size:14.95px;color:var(--text-2)}
.wkcard-chev{font-size:25.3px;line-height:1;color:var(--text-3);transform:rotate(90deg);
  transition:transform .18s ease}
.wkcard[open] .wkcard-chev{transform:rotate(-90deg)}
.wkcard-body{padding:0 18px 16px}
.wkcard.done{border-color:var(--hairline-str);color:var(--text-2);font-size:16.67px;
  box-shadow:none;padding:15px 18px;display:block}
.wkcard-h{font-size:18.97px;font-weight:700}
.wknote{background:var(--blue-dim,#eef2ff);border-radius:13px;padding:13px 15px;margin-bottom:14px}
.wknote.wait{color:var(--text-3);font-size:14.37px;font-style:italic}
.wknote-h{font-family:var(--mono);font-size:12.07px;letter-spacing:.12em;text-transform:uppercase;
  font-weight:700;color:var(--blue);margin-bottom:8px}
.wknote-p{font-size:14.95px;line-height:1.6;color:var(--text)}
.wknote-p+.wknote-p{margin-top:10px}
.wkcard-s{font-size:15.52px;color:var(--text-2);margin-bottom:14px;line-height:1.5}
.wkq{padding:10px 0;border-top:1px solid var(--hairline)}
.wkq-n{font-size:17.25px;font-weight:600;margin-bottom:2px}
.wkq-d{font-size:14.37px;color:var(--text-3);margin-bottom:8px}
.wksend{width:100%;margin-top:14px;background:var(--blue);color:#fff;border:none;border-radius:12px;
  padding:14px;font:inherit;font-size:17.82px;font-weight:700;cursor:pointer}
.cs-fold{border:1px solid var(--hairline-str);border-radius:12px;background:var(--surface);overflow:hidden}
.cs-sum{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;padding:13px 14px}
.cs-sum::-webkit-details-marker{display:none}
.cs-sum-t{font-size:17.25px;font-weight:600}
.cs-sum-v{margin-inline-start:auto;font-size:14.95px;color:var(--text-2);text-align:end;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:52%}
.cs-chev{font-size:24.15px;line-height:1;color:var(--text-3);transform:rotate(90deg);transition:transform .18s ease}
.cs-fold[open] .cs-chev{transform:rotate(-90deg)}
.cs-fold .cs-wrap{padding:2px 14px 12px}
.cb-txt.streaming{white-space:pre-wrap}
.coach-input button.coach-attach{flex:none;width:44px;height:44px;border-radius:50%;background:#eaf0ff;color:#3b6cff;border:1px solid #c5d4ff;display:grid;place-items:center;cursor:pointer;font-size:24.15px;transition:transform .12s}
.coach-attach:active{transform:scale(.92)}
/* THE STATUS BAR STRIP - 14 Aug 2026.
   With viewport-fit=cover the page runs under the clock and the battery, and
   this morning a workout card scrolled up behind them: white card, white status
   text, nothing readable. iOS gives no strip of its own, so the app has to
   provide one. A blurred wash the exact height of the inset, above everything
   and untouchable, so the time stays readable whatever scrolls beneath it.
   Zero height on a device without an inset, so desktop and Android are
   unaffected. */
.statusveil{
  position:fixed; top:0; left:0; right:0; z-index:400; pointer-events:none;
  height:env(safe-area-inset-top,0px);
  background:rgba(241,244,250,.72);
  -webkit-backdrop-filter:saturate(180%) blur(14px);
  backdrop-filter:saturate(180%) blur(14px);
}

/* CAPACITOR IOS LAYOUT - 19 Aug 2026.
   The native WKWebView already starts below the iPhone status area. Adding the
   web safe-area to the coach header again leaves a blank strip above the chat.
   Browsers and the installed PWA keep the original inset; only the native shell
   receives this correction. */
html.project40-native-ios .coach-hdr{padding-top:12px}
html.project40-native-ios .statusveil{display:none}

/* KEYBOARD FOCUS - 14 Aug 2026.
   Eleven rules in this file set outline:none on :focus and only eight put a
   replacement back, so on a Mac the focus ring simply vanished inside notes
   fields, timer inputs, the coach composer and the score inputs - tab into one
   and there is no way to tell where you are. :focus-visible only shows for
   keyboard and assistive navigation, so this costs a mouse user nothing.
   Declared last and broadly on purpose: a later narrow rule can still override
   it, but nothing can now silently leave a control with no focus state at all. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible{
  outline:2px solid var(--blue);
  outline-offset:2px;
  border-radius:6px;
}
/* Inside the dark live-workout screens the blue ring disappears into the
   background, so it goes light there. */
.modescreen :where(a,button,input,textarea,select,[tabindex]):focus-visible,
.live :where(a,button,input,textarea,select,[tabindex]):focus-visible{
  outline-color:#EAF0FA;
}
/* The headline used to carry "average of 4 areas with data", which was the least
   useful sentence on the home screen and was rightly removed. This replaces it
   with the one that earns the room: which week's standard the number is measured
   against, and what is holding it down. */
.sc-why-big{margin-top:7px;font-size:12.8px;line-height:1.45;opacity:.82}
/* The section heading is quiet on purpose. It is a signpost, not a title - the
   coach's sentences are the content and anything competing with them for weight
   makes the card look like a form again. */
.wks{margin-top:13px}
.wks:first-of-type{margin-top:4px}
.wks-h{font-size:11.4px;font-weight:800;letter-spacing:.075em;text-transform:uppercase;
  color:var(--blue);opacity:.85;margin-bottom:4px}
.wks-b{font-size:15.2px;line-height:1.58;color:var(--text)}
.wknote-err{color:var(--text-2);font-style:normal}
.wknote-retry{margin-inline-start:8px;padding:5px 11px;border-radius:9px;
  border:1px solid var(--hairline-str);background:var(--surface);color:var(--blue);
  font:inherit;font-size:13.5px;font-weight:600;cursor:pointer}
.wknote-retry:disabled{opacity:.5;cursor:default}
/* A hard ceiling rather than a promise to keep the strings short. Two lines on
   the cards, one on the headline: whatever anyone writes into a `why` later, the
   four cards cannot push each other off the fold again. */
.sc-why{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sc-why-big{-webkit-line-clamp:1}
/* The + and the sheet it opens. The wrapper is the positioning context so the
   menu rises from the button rather than from the bar, and the bar itself is not
   allowed to clip it. */
.ca-wrap{position:relative;flex:none;display:flex}
.coach-input .ca-wrap>button#coachPlus{width:44px;height:44px;border-radius:50%;background:#eaf0ff;color:#3b6cff;border:1px solid #c5d4ff}
.ca-plus{width:22px;height:22px;transition:transform .18s ease}
.ca-wrap.open .ca-plus{transform:rotate(45deg)}
.ca-menu{position:absolute;bottom:54px;left:0;z-index:9;min-width:212px;
  background:var(--surface);border:1px solid var(--hairline-str);border-radius:14px;
  box-shadow:0 12px 34px rgba(16,24,48,.18);padding:6px;
  display:none;flex-direction:column;gap:2px}
.ca-wrap.open .ca-menu{display:flex}
.coach-input .ca-menu button.ca-item{width:100%;height:auto;min-height:44px;border-radius:10px;
  background:transparent;color:var(--text);border:none;
  display:flex;align-items:center;justify-content:flex-start;gap:11px;
  padding:9px 11px;font-family:inherit;font-size:15.5px;text-align:left;cursor:pointer}
.coach-input .ca-menu button.ca-item:hover{background:var(--blue-dim)}
.coach-input .ca-menu button.ca-item:active{transform:none;background:var(--blue-dim)}
.ca-ico{font-size:19px;line-height:1;width:22px;text-align:center;flex:none}
.ca-lbl{flex:1;min-width:0}
.coach-preview{padding:0 2px 8px;display:flex;flex-wrap:wrap;gap:8px}
.cp-wrap{position:relative;display:inline-block}
.cp-wrap img{max-height:88px;border-radius:12px;display:block;border:1px solid var(--hairline)}
.cp-x{position:absolute;top:-7px;inset-inline-end:-7px;width:22px;height:22px;border-radius:50%;background:var(--text);color:var(--bg);border:none;font-size:12.65px;cursor:pointer;display:grid;place-items:center}
/* a clip he sent, sitting in the conversation like a photo does */
.cb-vid{max-width:220px;max-height:240px;border-radius:12px;margin-bottom:6px;display:block;background:#000;object-fit:cover}
/* past conversations */
/* touch-action:none on the body stops the drag being handed to the document;
   the sheet's own list re-enables it for itself, so the content still scrolls. */
body.sheet-open{overflow:hidden;touch-action:none}
body.sheet-open .ch-body{touch-action:pan-y}
.ch-back{position:fixed;inset:0;z-index:360;background:rgba(12,20,38,.42);opacity:0;pointer-events:none;transition:opacity .18s ease}
.ch-back.show{opacity:1;pointer-events:auto}
.ch-panel{position:fixed;z-index:370;left:0;right:0;bottom:0;background:var(--surface);
  border-radius:22px 22px 0 0;box-shadow:0 -10px 40px rgba(16,28,54,.22);
  display:flex;flex-direction:column;max-height:min(78vh,640px);
  transform:translateY(102%);transition:transform .24s cubic-bezier(.32,.72,0,1);
  padding-bottom:env(safe-area-inset-bottom,0px)}
.ch-panel.show{transform:translateY(0)}
.ch-grab{width:38px;height:4px;border-radius:99px;background:rgba(120,140,180,.32);margin:9px auto 4px;flex:none}
.ch-hdr{display:flex;align-items:center;gap:10px;padding:6px 18px 12px;border-bottom:1px solid var(--hairline);flex:none}
.ch-hdr b{font-size:17.82px}
.ch-hdr .ch-x{margin-inline-start:auto;border:0;background:rgba(120,140,180,.12);color:var(--text-2);
  width:30px;height:30px;border-radius:50%;font-size:19.55px;cursor:pointer;flex:none}
.ch-body{flex:1;overflow-y:auto;padding:8px 14px 16px;-webkit-overflow-scrolling:touch}
.ch-row{display:flex;align-items:center;gap:12px;width:100%;text-align:right;background:transparent;
  border:0;border-bottom:1px solid var(--hairline);padding:13px 6px;cursor:pointer;font-family:inherit}
.ch-row:active{background:rgba(120,140,180,.07)}
.ch-row .ch-d{font-size:16.67px;font-weight:650;color:var(--text)}
.ch-row .ch-s{font-size:13.8px;color:var(--text-2);margin-top:2px}
.ch-row .ch-n{margin-inline-start:auto;font-size:13.8px;color:var(--text-2);flex:none}
.ch-empty{padding:26px 12px;text-align:center;color:var(--text-2);font-size:16.1px;line-height:1.6}
.ch-note{padding:10px 14px;font-size:14.37px;color:var(--text-2);text-align:center}
.nut-del{border:0;background:rgba(220,80,80,.10);color:#c2453f;border-radius:10px;padding:7px 12px;
  font-family:inherit;font-size:14.95px;font-weight:600;cursor:pointer;margin-inline-start:auto;flex:none}
.nut-del:active{background:rgba(220,80,80,.18)}
.nfav-row{position:relative}
.nfav-row .nfav{width:100%}
/* 28 Aug 2026, his words: the right-side buttons were ugly. They were: a text
   glyph pencil pinned 7px from the TOP of a two-line row - so it hung above
   centre, crowding the plus - and a "+" character faked into a circle with a
   line-height. Both are drawn now: real icons, both vertically centred, the
   pencil a quiet ghost circle, the plus a proper filled disc that becomes the
   confirm pill (see .armed below). */
.nfav-head{position:relative}
.nfav-row.has-pen .nfav-main{margin-inline-end:36px}
.nfav-pen{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:52px;
  width:32px;height:32px;border:0;background:none;color:var(--text-3);cursor:pointer;
  border-radius:50%;display:flex;align-items:center;justify-content:center;padding:0}
.nfav-pen svg{width:15px;height:15px;display:block}
.nfav-pen:active{background:var(--surface)}
/* 28 Aug 2026, his eye: the widened Log pill slides under the pencil. While a
   row is armed the pencil yields - fades out, takes no taps - and returns the
   moment the pill does, on the same class the arming flow already toggles. */
.nfav-pen{transition:opacity .16s ease}
.nfav.armed ~ .nfav-pen{opacity:0;pointer-events:none}
.nfav-edit{margin:6px 0 2px;padding:10px 12px;background:var(--surface);
  border:1px solid var(--hairline);border-radius:14px}
.nfe-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.nfe-name{margin-bottom:8px}
/* .nfe-f input sets the tabular mono for the four figures and is declared after
   this block, so an equal-specificity selector here loses. Doubling the class
   wins it back without moving the rule and without !important. */
.nfe-f.nfe-name input{text-align:start;font-family:inherit;font-size:14.5px;font-weight:600}
.nfe-f{display:flex;flex-direction:column;gap:3px;font-size:10.6px;
  text-transform:uppercase;letter-spacing:.06em;color:var(--text-3);font-weight:700}
.nfe-f input{width:100%;padding:8px;border:1px solid var(--hairline);border-radius:10px;
  background:var(--surface-2);color:var(--text);font-family:var(--mono);font-size:15px;
  text-align:center}
.nfe-act{display:flex;gap:8px;margin-top:10px}
.nfe-save{flex:1;padding:9px;border:0;border-radius:11px;background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff;
  font-family:inherit;font-size:14px;font-weight:700;cursor:pointer}
.nfe-del{padding:9px 12px;border:1px solid var(--hairline);border-radius:11px;
  background:none;color:var(--text-2);font-family:inherit;font-size:13px;cursor:pointer}
.mw-way .nfav-t{font-weight:750}
.mw-way .nfav-add{background:transparent;color:var(--text-3);font-size:24px;line-height:26px}
.nfav-list{display:flex;flex-direction:column;gap:6px;padding:2px 6px 10px}
.nfav{display:flex;align-items:center;gap:10px;width:100%;text-align:start;
  background:var(--surface-2);border:1px solid var(--hairline);border-radius:14px;
  padding:10px 12px;cursor:pointer;font-family:inherit;color:var(--text);
  transition:transform .12s ease,opacity .15s ease}
.nfav:active{transform:scale(.985)}
.nfav.busy{opacity:.5;pointer-events:none}
.nfav-main{flex:1;min-width:0}
.nfav-t{font-size:14.6px;font-weight:700;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nfav-s{font-size:12.07px;color:var(--text-2);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The press. Every raised navy control drops to the flat shadow and settles a
   hair - one rule, so nothing can be raised without also being pressable. */
.timer-btn.primary:active,.tc-run .tc-go:active,.tc-preset-btn:active,.gp-ok:active,
.hero .cta:active,.pp-approve:active,.coach-input button:active,.nfe-save:active{
  box-shadow:var(--blue-3d-press);transform:translateY(1px)}
@media (prefers-reduced-motion:reduce){
  .timer-btn.primary:active,.tc-run .tc-go:active,.tc-preset-btn:active,.gp-ok:active,
  .hero .cta:active,.pp-approve:active,.coach-input button:active,.nfe-save:active{
    transform:none}
}
.nfav-add{flex:none;min-width:32px;height:32px;border-radius:16px;background:var(--blue-grad);box-shadow:var(--blue-3d);
  color:#fff;display:flex;align-items:center;justify-content:center;padding:0;
  font-size:19px;font-weight:700;
  transition:min-width .16s ease,background .16s ease}
.nfav-add svg{width:15px;height:15px;display:block}
.nfav-add .nfa-txt{display:none;font-size:12.5px;font-weight:750;letter-spacing:.02em;padding:0 12px}
/* TWO TAPS TO LOG - 28 Aug 2026, his request, to stop mis-tap meals.
   First tap arms the row: the plus widens into a green "Log" pill and nothing
   is written. Only a second tap on the same row logs it. Four seconds of
   silence, or arming another row, stands it down. */
.nfav.armed{border-color:var(--green)}
.nfav.armed .nfav-add{min-width:72px;
  /* Deep green, not the mint --green. The label is 12.5px, so white on it needs
     4.5:1, and --green #12B98A gives 2.52 - the "Log" word he taps was the
     least legible text in the panel. This gradient reads 4.99 at its lightest
     point. Same construction as the navy: it is the confirm twin of it. */
  background:linear-gradient(180deg,#0A7F5E 0%,#04533C 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.20),
             inset 0 -1px 0 rgba(0,0,0,.22),
             0 2px 5px rgba(4,83,60,.30)}
.nfav.armed:active .nfav-add{box-shadow:inset 0 1px 0 rgba(255,255,255,.08),
             0 1px 2px rgba(4,83,60,.22)}
.nfav.armed .nfav-add svg{display:none}
.nfav.armed .nfav-add .nfa-txt{display:block}
.nut-sum{padding:14px 6px 6px;font-size:16.67px;text-align:right}
/* history folders */
.ht{margin:0}
.ht>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;
  font-family:inherit;text-align:left;direction:ltr;padding:11px 4px;
  border-bottom:1px solid var(--hairline)}
.ht-n{margin-inline-start:auto}
.ht>summary::-webkit-details-marker{display:none}
.ht>summary::before{content:'▸';font-size:12.65px;color:var(--text-2);transition:transform .15s ease;flex:none}
.ht[open]>summary::before{transform:rotate(90deg)}
.ht-cap{font-size:10.92px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-2);
  background:rgba(120,140,180,.12);border-radius:5px;padding:2px 6px;flex:none}
.ht-n{margin-inline-start:auto;font-size:13.22px;color:var(--text-2);
  background:rgba(120,140,180,.12);border-radius:99px;padding:2px 8px;flex:none}
.ht.y>summary{font-size:17.25px;font-weight:700}
.ht.q>summary{font-size:16.1px;font-weight:650}
.ht.b>summary{font-size:15.52px;font-weight:600}
.ht.w>summary{font-size:15.52px;font-weight:600}
.ht.q{padding-inline-start:8px}
.ht,.ht>summary{direction:ltr}
.ht.b{padding-inline-start:8px}
.ht.w{padding-inline-start:8px}
/* planned days sit in the same tree as finished ones and must not compete with
   them: no tap affordance, lighter ink, no border emphasis. */
.hrow.planned{opacity:.62;cursor:default}
.hrow.planned.missed .hr-r{color:var(--warn,#c2410c)}
.hrow.planned .hr-r b{font-weight:600}
.cp-vidph{width:54px;height:54px;border-radius:10px;background:#000;display:flex;align-items:center;justify-content:center;font-size:25.3px}
.cp-badge{position:absolute;inset-inline-start:3px;bottom:3px;font-size:12.65px;background:rgba(0,0,0,.55);border-radius:6px;padding:1px 4px;line-height:1.4}
.coach-hdr-clear.ch-btn svg{width:19px;height:19px}
/* ===== the way in =====
   Signing out used to leave the last athlete's week on screen. Whoever opens
   the app next should see a door, not somebody else's training. */
.lp{min-height:100dvh;min-height:100vh;width:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:34px 26px;
  box-sizing:border-box;
  background:
    radial-gradient(120% 80% at 50% -10%, #23345f 0%, transparent 60%),
    radial-gradient(90% 60% at 50% 110%, #1a2444 0%, transparent 55%),
    #0B1120;
  color:#fff;overflow:auto}
.lp-mark{width:min(190px,46vw);height:auto;margin-bottom:26px;
  filter:drop-shadow(0 12px 34px rgba(212,175,110,.28))}
/* THE BOOT SPLASH, 26 Aug 2026 - same identity as .lp above (dark navy,
   the gold mark and wordmark, the gold rule), reduced to a smaller, calmer
   moment since this one holds for a fixed few seconds rather than until he
   acts. #bootSplash sits fixed above everything (z-index 9999) and is
   removed from the DOM once its JS-driven fade-out finishes. */
#bootSplash{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  background:
    radial-gradient(120% 80% at 50% -10%, #23345f 0%, transparent 60%),
    radial-gradient(90% 60% at 50% 110%, #1a2444 0%, transparent 55%),
    #0B1120;
  opacity:1;transition:opacity .5s ease;pointer-events:none}
#bootSplash.out{opacity:0}
.bs-mark{width:min(162px,39vw);height:auto;margin-bottom:24px;
  filter:drop-shadow(0 15px 42px rgba(212,175,110,.26));
  opacity:0;transform:scale(.92);animation:bsIn .6s cubic-bezier(.22,1,.36,1) .05s forwards}
.bs-word{font-size:clamp(32.78px,9.9vw,43.1px);font-weight:800;letter-spacing:.14em;line-height:1;
  background:linear-gradient(180deg,#F3E4C4 0%,#D8B36A 55%,#B98F45 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  opacity:0;transform:translateY(6px);animation:bsIn .55s cubic-bezier(.22,1,.36,1) .22s forwards}
.bs-rule{display:flex;align-items:center;gap:15px;margin:18px 0 0;width:min(330px,87vw);
  opacity:0;animation:bsFade .5s ease .42s forwards}
.bs-rule i{flex:1;height:1.5px;background:linear-gradient(90deg,transparent,rgba(216,179,106,.5),transparent)}
.bs-rule span{font-size:15.52px;letter-spacing:.26em;color:#D8B36A;font-weight:700;white-space:nowrap}
.bs-dots{display:flex;gap:9px;margin-top:45px;opacity:0;animation:bsFade .5s ease .6s forwards}
.bs-dots i{width:7.5px;height:7.5px;border-radius:50%;background:#D8B36A;opacity:.35;
  animation:bsDot 1.1s ease-in-out infinite}
.bs-dots i:nth-child(2){animation-delay:.15s}
.bs-dots i:nth-child(3){animation-delay:.3s}
@keyframes bsIn{ to{ opacity:1; transform:none } }
@keyframes bsFade{ to{ opacity:1 } }
@keyframes bsDot{ 0%,80%,100%{ opacity:.35; transform:scale(1) } 40%{ opacity:1; transform:scale(1.35) } }
@media(prefers-reduced-motion:reduce){
  #bootSplash{transition:opacity .2s linear}
  .bs-mark,.bs-word,.bs-rule,.bs-dots{animation:none;opacity:1;transform:none}
  .bs-dots i{animation:none;opacity:.7}
}
.lp-word{font-size:clamp(34.5px,10.35vw,48.3px);font-weight:800;letter-spacing:.14em;line-height:1;
  background:linear-gradient(180deg,#F3E4C4 0%,#D8B36A 55%,#B98F45 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.lp-rule{display:flex;align-items:center;gap:12px;margin:14px 0 0;width:min(300px,72vw)}
.lp-rule i{flex:1;height:1px;background:linear-gradient(90deg,transparent,rgba(216,179,106,.55),transparent)}
.lp-rule span{font-size:12.07px;letter-spacing:.28em;color:#D8B36A;font-weight:700;white-space:nowrap}
.lp-title{font-size:clamp(21.85px,6.21vw,26.45px);font-weight:700;line-height:1.35;margin-top:30px;
  color:#EAF0FF}
.lp-sub{font-size:16.67px;line-height:1.65;color:rgba(234,240,255,.62);margin-top:10px;max-width:30ch}
.lp-btn{margin-top:34px;width:min(340px,88vw);border:0;border-radius:16px;padding:16px;cursor:pointer;
  background:#fff;color:#12203c;font-family:inherit;font-size:17.82px;font-weight:700;
  display:flex;align-items:center;justify-content:center;gap:10px;
  box-shadow:0 10px 30px rgba(0,0,0,.35)}
.lp-btn:active{transform:scale(.985)}
.lp-foot{margin-top:20px;color:rgba(234,240,255,.38);font-size:13.22px;line-height:1.6;max-width:32ch}
body.signed-out .tabbar,
body.signed-out .refresh-tog,
body.signed-out .theme-tog{display:none !important}
/* ===== the picture, whole ===== */
/* The artwork has its own rounded corners and a transparent edge, so the
   container adds neither radius nor a shadow that would cut across them. */
/* Reserve the picture's space before it loads. Without a known ratio the box
   is zero-height on first paint and then snaps open, which is the jump you see
   every time the home screen is rebuilt - and it is rebuilt on every week
   change. */
/* The greeting sits ON the hero now. The hero is already a title card, so a
   separate greeting row above it made two headers where one was wanted. The
   scrim is not decoration - it is what keeps white type legible over whatever
   part of the photograph is behind it, in either theme. */
@media(min-width:900px){
  /* On a laptop the artwork is wider than it is tall, so at full width it filled
     the screen and pushed everything worth reading below the fold. */
}

/* the week line that replaced the big header */
/* On a phone the title and the three buttons could not share a row, so the
   buttons were squeezed until "This week" broke across two lines. They get
   their own row instead of fighting for the same one. */
.wk-title-sm{font-size:18.4px;font-weight:750;line-height:1.25}
.wk-line .wk-sub{font-size:13.8px;color:var(--text-2);margin-top:3px}
.wk-line .wk-nav{display:flex;gap:6px;margin-top:10px}
.wk-line .wk-btn{padding:7px 14px;font-size:14.37px;white-space:nowrap;flex:1}
@media(min-width:640px){
  .wk-line .wk-nav{margin-inline-start:auto;margin-top:0}
  .wk-line .wk-btn{flex:none}
}

/* ===== the two corner buttons, one per corner =====
   They were both pinned top-right and sat on top of each other. */
/* Back on the right. It only moved left because the profile avatar was there,
   and the avatar has since moved into the tab bar. */
.theme-tog{right:10px !important; left:auto !important}
body.on-coach #themeTog{right:10px !important; left:auto !important}

@media(min-width:900px){
  .theme-tog{right:calc(var(--shell-right) + 12px) !important; left:auto !important}
}
/* ===== profile ===== */

/* 25 Aug 2026. The profile hero, on the same grammar as the Journey one -
   same gradient, radius and shadow - so the two screens read as one app. The
   avatar sits ON the gradient, which is why it needs a light ring rather than
   the hairline border used against a white card. */
.pf-hero{border-radius:20px;padding:18px 18px 14px;margin:2px 0 4px;
  background:linear-gradient(135deg,#152249 0%,#2f4bb0 55%,#3b6cff 100%);color:#fff;
  box-shadow:0 12px 34px rgba(59,108,255,.28);position:relative;overflow:hidden}
.pfh-top{display:flex;align-items:center;gap:14px}
.pfh-ava{flex:none;width:64px;height:64px;border-radius:50%;overflow:hidden;
  background:rgba(255,255,255,.16);border:2px solid rgba(255,255,255,.34);
  display:flex;align-items:center;justify-content:center;
  font-size:25.3px;font-weight:850;color:#fff;cursor:pointer}
.pfh-ava img{width:100%;height:100%;object-fit:cover;display:block}
.pfh-ava:active{transform:scale(.96)}
.pfh-id{min-width:0;flex:1}
.pfh-name{font-size:24.15px;font-weight:850;letter-spacing:-.02em;line-height:1.12;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfh-where{font-size:12.65px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  opacity:.8;margin-top:4px}
.pfh-mail{font-size:13.22px;opacity:.72;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfh-aim{font-size:14.37px;line-height:1.5;opacity:.94;margin-top:13px;
  padding-top:12px;border-top:1px solid rgba(255,255,255,.18)}
.pfh-stats{display:flex;gap:8px;margin-top:14px}
.pfh-stat{flex:1;min-width:0;background:rgba(255,255,255,.13);border-radius:13px;
  padding:9px 8px 8px;text-align:center}
.pfh-sv{font-size:19.55px;font-weight:850;letter-spacing:-.02em;line-height:1.1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pfh-sk{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  opacity:.72;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pfh-hint{font-size:12.07px;opacity:.62;margin-top:11px;text-align:center}
.pf-sec{font-size:12.07px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-2);
  margin:16px 4px 7px;font-weight:700}
.pf-list{background:var(--bg);border:1px solid var(--hairline);border-radius:14px;overflow:hidden}
.pf-item{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--hairline);
  font-size:16.1px}
.pf-item:last-child{border-bottom:0}
.pf-k{color:var(--text-2);font-size:14.95px}
.pf-v{margin-inline-start:auto;font-weight:650;text-align:end}

.pf-note{font-size:12.65px;color:var(--text-3);margin:7px 2px 0;line-height:1.5}
/* The Journey screen reads left to right in one language. It was inheriting the
   app's right-to-left direction and holding a mix of Hebrew and English, which
   left punctuation on the wrong side of half the lines. */
/* Hierarchy from type and space, not from borders. When every block is a card,
   nothing is emphasised - so only the bottleneck, the gate and the day's move
   carry weight. */
#viewHistory .home-wrap{direction:ltr;text-align:left}
/* The voice note. Dark, because it is the one thing on this screen that speaks. */
/* THE VOICE NOTE, ON THE HOME SCREEN.

   It moved here from the Journey screen because this is where he actually looks,
   and it replaced Daily Focus because the two were the same idea at different
   lengths - one read, one heard, and the heard one wins on a morning.

   Dark, so it does not read as another card. This is the only thing on the screen
   that speaks. */
.vb{position:relative;overflow:hidden;
  background:radial-gradient(120% 140% at 12% 0%, #1c2947 0%, #0d1424 62%);
  border-radius:18px;padding:15px 16px 13px;color:#fff;
  direction:ltr;text-align:left;
  box-shadow:0 1px 2px rgba(8,14,30,.22), 0 16px 36px -26px rgba(8,14,30,.75)}
/* The learning screen. Reads as a shelf of lessons, not a dashboard. */
.ln-head{padding:14px 2px 8px;direction:ltr;text-align:left}
.ln-h1{font-size:21.85px;font-weight:850;letter-spacing:-.03em;line-height:1.15}
.ln-h2{font-size:13.22px;color:var(--text-3);margin-top:3px}
.ln-load{font-size:14.95px;color:var(--text-3);padding:26px 2px;direction:ltr;text-align:left}

/* 10 Aug 2026. Three lesson cards were 826px - 92% of the screen - so Journey
   opened on a wall of players and the build below was a scroll away. Same
   information, less furniture. */
.ln{background:var(--surface);border:1px solid var(--hairline);border-radius:14px;
  padding:11px 13px 10px;margin:0 0 8px;direction:ltr;text-align:left;
  transition:border-color .16s ease,box-shadow .16s ease}
/* Playing is marked on the card, not only on its button - on a screen with three
   players the eye needs to find the live one without hunting. */
.ln.on{border-color:var(--blue);box-shadow:0 10px 30px -22px rgba(46,91,255,.55)}
.ln-top{display:flex;align-items:center;gap:8px}
.ln-who{font-size:11.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-3)}
.ln-done{margin-inline-start:auto;font-size:10.92px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:#0f9d58;background:rgba(15,157,88,.1);
  padding:3px 7px;border-radius:6px}
/* A lesson that is missing. Quiet, not an alarm - it is a gap to fill, and the
   button is the whole point of showing it. */
/* The archive. One quiet line until he wants it, and the same cards inside. */
.ln-arch{border:1px solid var(--hairline);border-radius:17px;background:var(--surface);
  overflow:hidden;margin:4px 0 12px}
.ln-arch>summary{list-style:none;cursor:pointer;padding:14px 16px;display:flex;align-items:center;gap:9px}
.ln-arch>summary::-webkit-details-marker{display:none}
.ln-arch>summary::before{content:'\25b8';font-size:12.65px;color:var(--text-3);transition:transform .15s ease;flex:none}
.ln-arch[open]>summary::before{transform:rotate(90deg)}
.ln-arch-t{flex:1;font-size:16.67px;font-weight:700;color:var(--text)}
.ln-arch-n{font-size:13.22px;font-weight:700;color:var(--text-2);background:var(--hairline);
  border-radius:100px;padding:3px 9px}
.ln-arch-b{padding:0 16px 14px;font-size:14.37px;color:var(--text-3)}
.ln-day{border-top:1px solid var(--hairline)}
.ln-day>summary{list-style:none;cursor:pointer;padding:12px 16px;display:flex;align-items:center;gap:9px}
.ln-day>summary::-webkit-details-marker{display:none}
.ln-day-t{flex:1;font-size:15.52px;font-weight:600;color:var(--text);direction:ltr;text-align:left}
.ln-day-n{font-size:12.65px;color:var(--text-3);flex:none}
.ln-day>.ln{margin:0 12px 11px}
.flow-sheet{position:fixed;inset:0;background:rgba(20,26,43,.45);z-index:1200;display:flex;align-items:flex-end;justify-content:center}
/* contain, so hitting the end of this scroller does not scroll the page behind
   it - that chaining was the other half of why the backdrop kept moving. */
.flow-card{background:var(--bg,#f4f6fb);border-radius:22px 22px 0 0;width:100%;max-width:520px;
  max-height:86vh;overflow:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  padding:20px 18px 26px;position:relative}
.flow-sheet{overscroll-behavior:contain}
.flow-x{position:absolute;top:10px;right:14px;border:0;background:var(--surface,#fff);border-radius:50%;width:32px;height:32px;font-size:21.85px;color:var(--text-2)}
.flow-h{font-size:21.85px;font-weight:750;letter-spacing:-.015em}
.flow-why{font-size:14.37px;color:var(--text-2);font-style:italic;margin:6px 0 12px;line-height:1.5}
/* 25 Aug 2026. The picker sheet - shown before any single flow, so a bottleneck
   he already has cached opens on a tap rather than a rewrite. Cards match the
   weight of .flow-step below them; the recommended one gets the same blue the
   app already uses for "this is the one" elsewhere (.flow-step.on, .flow-tgt.on). */
#fmList{margin-top:4px}
.fm-card{background:var(--surface,#fff);border-radius:16px;padding:14px 15px;margin-top:9px;
  border:1.5px solid transparent;cursor:pointer}
.fm-card:active{transform:scale(.98)}
.fm-card.busy{opacity:.55;pointer-events:none}
.fm-card.rec{border-color:var(--blue,#3b5bfd)}
.fm-badge{display:inline-block;font-size:11.5px;font-weight:750;letter-spacing:.05em;
  color:var(--blue,#3b5bfd);background:rgba(59,91,253,.1);border-radius:999px;
  padding:3px 9px;margin-bottom:7px}
.fm-t{font-size:16.67px;font-weight:750;letter-spacing:-.01em}
.fm-done{font-size:13.22px;font-weight:650;color:var(--green,#1fa06a)}
.fm-d{font-size:13.22px;color:var(--text-3);line-height:1.45;margin-top:3px}
.fm-m{font-family:var(--mono);font-size:12.65px;color:var(--text-2);margin-top:7px}
.fm-skel{height:78px;border-radius:16px;margin-top:9px;background:var(--surface-2,#eef1f8);
  position:relative;overflow:hidden}
.fm-skel::after{content:'';position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.6),transparent);
  animation:fmShine 1.3s ease-in-out infinite}
@keyframes fmShine{ to{ transform:translateX(100%) } }
@media(prefers-reduced-motion:reduce){ .fm-skel::after{animation:none} }
.flow-step{background:var(--surface,#fff);border-radius:15px;padding:13px 15px;margin-top:9px;display:grid;grid-template-columns:1fr auto;gap:2px 12px;align-items:center;cursor:pointer;border:1.5px solid transparent}
.flow-step.on{border-color:var(--blue,#3b5bfd)}
.flow-n{font-size:16.67px;font-weight:650}
.flow-c{font-size:13.22px;color:var(--text-3);grid-column:1;line-height:1.45}
.flow-t{grid-column:2;grid-row:1/span 2;font-family:var(--mono);font-size:18.4px;font-weight:750;color:var(--blue,#3b5bfd)}
/* Gold, like every other "press this" in the app - 31 Aug 2026. It was the
   old bright green, which was both off-palette and, at 18px white on #1fa06a,
   the least legible large text on the screen. */
.flow-start{width:100%;margin:14px 0 8px;border:0;border-radius:14px;padding:15px;
  background:var(--gold-grad);color:var(--gold-ink);box-shadow:var(--gold-3d);
  font-size:18.4px;font-weight:800;letter-spacing:-.01em;font-family:inherit}
.flow-start:active{box-shadow:var(--gold-3d-press);transform:translateY(1px)}
.flow-focus{background:var(--surface,#fff);border-radius:18px;padding:26px 18px;margin:14px 0 6px;text-align:center}
.flow-focus.rest{background:linear-gradient(160deg,#eaf0ff,#dbe4ff)}
.ff-k{font-family:var(--mono);font-size:12.07px;letter-spacing:.14em;font-weight:700;color:var(--text-3)}
.ff-n{font-size:24.15px;font-weight:750;letter-spacing:-.02em;margin-top:6px}
.ff-t{font-family:var(--mono);font-size:64.4px;font-weight:750;line-height:1.1;color:var(--blue,#3b5bfd);margin:8px 0 4px}
.ff-c{font-size:14.37px;color:var(--text-2);line-height:1.5}
/* 24 Aug 2026 - the flow became a circuit he can drive.
   Transport controls, a round counter, and the target chips. Pause is wider
   than the rest because it is the one he reaches for mid-position, often
   without looking. */
.flow-tgts{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 4px}
.flow-tgt{border:1.5px solid var(--hairline);background:var(--surface,#fff);color:var(--text-2);
  border-radius:999px;padding:7px 12px;font-size:13.22px;font-weight:600;line-height:1}
.flow-tgt.on{border-color:var(--blue,#3b5bfd);color:var(--blue,#3b5bfd);background:rgba(59,91,253,.07)}
.flow-tgt:disabled{opacity:.5}
.flow-round{display:inline-block;font-family:var(--mono);font-size:12.07px;letter-spacing:.12em;
  font-weight:700;color:var(--text-3);margin-bottom:2px}
.flow-ctl{display:flex;align-items:center;justify-content:center;gap:18px;margin:12px 0 4px}
.flow-cb{border:0;border-radius:50%;width:52px;height:52px;padding:0;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--surface,#fff);color:var(--text-2);line-height:1;
  box-shadow:0 1px 3px rgba(20,26,43,.08)}
/* THE CONTROLS - 31 Aug 2026, his call: they looked dated. They were flat white
   tiles carrying grey system glyphs (\u23ee \u23ed \u21ba as text), which is the
   one place in the app still doing that after the icon pass. Same construction
   as every other key now: gradient, an inset highlight on the top edge, a short
   drop shadow, and a press that flattens it. Navy for transport, gold for the
   one that starts and stops - it is the control he reaches for mid-flow, and
   gold is this app's word for "the thing to press". */
.flow-cb{background:linear-gradient(180deg,#FFFFFF 0%,#EEF2FA 100%);
  border:1px solid var(--hairline,#e3e8f3);color:var(--blue,#1B347A);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 1px 2px rgba(20,36,92,.10),
             0 6px 14px -10px rgba(20,36,92,.45)}
.flow-cb svg{width:20px;height:20px;display:block}
.flow-cb.main{width:70px;height:70px;background:var(--gold-grad);color:var(--gold-ink);
  border-color:rgba(214,145,16,.5);box-shadow:var(--gold-3d)}
.flow-cb.main svg{width:27px;height:27px}
/* Play reads left-heavy inside a circle; a hair of offset centres it the way
   the eye expects. Pause is symmetrical and needs none. */
.flow-cb.main.paused svg{margin-inline-start:3px}
.flow-cb.main.paused{background:var(--blue-grad);color:#fff;
  border-color:transparent;box-shadow:var(--blue-3d)}
.flow-cb:active{transform:translateY(1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6),0 1px 2px rgba(20,36,92,.14)}
.flow-cb.main:active{box-shadow:var(--gold-3d-press)}
.flow-cb.main.paused:active{box-shadow:var(--blue-3d-press)}
.flow-note{font-size:12.65px;color:var(--text-3);text-align:center;margin-top:8px}
.pr-row{display:flex;align-items:baseline;gap:10px;padding:9px 16px;border-top:1px solid var(--hairline);direction:ltr;text-align:left}
.pr-name{flex:1;font-size:14.95px;font-weight:600;color:var(--text)}
.pr-val{font-family:var(--mono);font-size:14.95px;font-weight:700;color:var(--blue)}
.pr-latest{font-family:var(--sans);font-size:12.07px;font-weight:600;color:var(--text-3)}
.pr-date{font-size:12.07px;color:var(--text-3)}
.ln-miss{background:var(--surface);border:1px dashed var(--hairline-str);border-radius:17px;
  padding:14px 16px;margin:0 0 11px;direction:ltr;text-align:left}
.ln-miss-t{font-size:16.1px;font-weight:700;color:var(--text)}
.ln-miss-s{font-size:13.8px;color:var(--text-3);margin-top:4px;line-height:1.5}
.ln-miss-b{margin-top:11px;width:100%;border:0;border-radius:12px;padding:11px;
  background:var(--blue);color:#fff;font-family:inherit;font-size:15.52px;font-weight:700;cursor:pointer}
.ln-miss-b[disabled]{opacity:.55;cursor:default}
.ln-topic,.ln-why,.ln-script{text-align:start;unicode-bidi:plaintext}
.ln-topic{font-size:17.25px;font-weight:800;letter-spacing:-.02em;line-height:1.25;margin-top:4px}
.ln-why{font-size:13.22px;line-height:1.45;color:var(--text-2);margin-top:3px}

.ln-row{display:flex;align-items:center;gap:8px;margin-top:9px}
.ln-play{flex:none;width:32px;height:32px;border-radius:50%;border:0;cursor:pointer;
  background:var(--blue);color:#fff;display:grid;place-items:center;
  transition:transform .12s ease}
.ln-play:active{transform:scale(.9)}
.ln-play:disabled{opacity:.3}
.ln-play.on{background:var(--text);color:var(--surface)}
.ln-bar{flex:1;height:3px;border-radius:99px;background:var(--hairline);overflow:hidden}
.ln-bar i{display:block;height:100%;width:0;border-radius:99px;background:var(--blue);
  transition:width .2s linear}
.ln-len{flex:none;font-size:12.65px;color:var(--text-3);font-variant-numeric:tabular-nums}
.ln-txt{flex:none;background:var(--surface-2);border:0;border-radius:8px;padding:6px 11px;
  cursor:pointer;font-family:inherit;font-size:12.65px;font-weight:750;color:var(--text-2)}

.ln-tools{display:flex;align-items:center;gap:14px;margin-top:7px}
.ln:not(.on):not(.open) .ln-sp,.ln:not(.on):not(.open) [data-lndl]{display:none}
.ln-sp{flex:none;background:none;border:0;padding:0;cursor:pointer;font-family:inherit;
  font-size:12.65px;font-weight:800;color:var(--text-3);font-variant-numeric:tabular-nums}
.ln-sp.fast{background:var(--blue-dim);color:var(--blue-soft)}
.ln-tool{flex:none;background:none;border:0;padding:0;cursor:pointer;font-family:inherit;
  font-size:12.65px;font-weight:750;color:var(--text-3)}
.ln-tool:active{transform:scale(.95)}
.ln-tool:disabled{opacity:.5}
/* Continuing with the coach is the one action here that starts something, so it
   carries colour while saving and reading stay quiet. */
.ln-tool.talk{margin-inline-start:auto;background:none;color:var(--blue);font-weight:800}
.ln-script{font-size:15.52px;line-height:1.78;color:var(--text-2);margin-top:14px;
  padding-top:13px;border-top:1px solid var(--hairline)}
.ln-src{font-size:12.07px;color:var(--text-3);margin-top:11px;font-style:italic}
.ln-warn{font-size:12.65px;color:var(--text-3);margin-top:10px}
/* The current week is no longer opened for him, so it is marked instead - a
   small dot on its summary. Enough to find it in a closed list, not enough to
   compete with the labels. */
.ht.w.now>summary{font-weight:750}
.ht.w.now>summary .ht-cap::after{content:'';display:inline-block;width:5px;height:5px;
  border-radius:50%;background:var(--blue);margin-inline-start:6px;vertical-align:middle}
/* 25 Aug 2026. Built on .hero-vision's grammar - the same gradient, radius and
   shadow already used for the vision card on home - so the Journey opens like a
   part of this app rather than a second idea. */
.js-hero{max-width:var(--maxw);margin:2px auto 16px;border-radius:20px;padding:20px 20px 16px;
  background:linear-gradient(135deg,#152249 0%,#2f4bb0 55%,#3b6cff 100%);color:#fff;
  box-shadow:0 12px 34px rgba(59,108,255,.28);position:relative;overflow:hidden}
.js-kick{font-size:12.07px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  opacity:.78;margin-bottom:7px}
.js-title{font-size:26.45px;font-weight:850;line-height:1.14;letter-spacing:-.02em}
.js-where{font-size:14.37px;opacity:.85;margin-top:5px;font-weight:650}
.js-stats{display:flex;gap:8px;margin-top:16px}
.js-stat{flex:1;min-width:0;background:rgba(255,255,255,.13);border-radius:13px;
  padding:9px 8px 8px;text-align:center}
.js-sv{font-size:19.55px;font-weight:850;letter-spacing:-.02em;line-height:1.1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.js-sk{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  opacity:.72;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.js-build{font-size:12.07px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-3);margin:34px 2px 10px}
.jp{background:linear-gradient(135deg,var(--blue) 0%,#5b46d6 100%);color:#fff;
  border-radius:18px;padding:15px 17px 14px;margin:0 0 11px;direction:ltr;text-align:left}
.jr-card.key{border-color:var(--blue);box-shadow:0 1px 2px rgba(46,91,255,.10), 0 10px 28px -20px rgba(46,91,255,.45)}
.jr-card.thin{border-style:dashed;box-shadow:none}

/* Headings sit above the body text in size, not below it. */

.jw{background:linear-gradient(180deg,var(--surface-2),transparent);
  border:1px solid var(--hairline);border-radius:14px;padding:11px 12px}
.jw-d.up{color:#0f9d58}
.jw-d.down{color:#d0342c}
.jr-ref.due{background:var(--blue-dim);color:var(--blue-soft)}
/* Headings inside a card. mdLite had no concept of them, so a model asked for
   '## Behind you' produced exactly that on screen. */
/* Built from the home screen's own surfaces and hairlines rather than a new
   visual language. One card, not four competing ones: the three lanes are rows
   inside it, because they are one instruction seen from three sides. */
.df{background:var(--surface);border:1px solid var(--hairline);border-radius:16px;
  padding:14px 15px 12px;direction:ltr;text-align:left;position:relative}
/* Closed, the three titles sit in one row and read as one instruction. Open, they
   stack so each can carry its paragraph. */



/* ONE vertical rhythm for the whole screen.

   Every block on home had picked its own margin, so the gaps between sections
   were all slightly different and the page read as a pile rather than a layout.
   A single variable now owns the spacing, and each section simply obeys it. */
/* 15 Aug 2026. The screen was built at 22px margins and 12px between every
   card, which on a 390px phone spends a fifth of the width and most of the
   scroll on nothing. 16 and 10 keep the cards clearly separate objects while
   giving the content back the room. */
:root{--home-gap:10px}
/* One rhythm, and it has to outrank what each card brought with it. Every
   block on this screen had picked its own margin, so the gaps were all
   slightly different and the page read as a pile rather than a layout.
   Collapsing them here is the whole reason the spacing now looks deliberate. */
.home-wrap > *{margin-top:0 !important;margin-bottom:var(--home-gap) !important}
.home-wrap > *:last-child{margin-bottom:0 !important}
/* Empty holders must not leave a gap where nothing is shown. */
.home-wrap > *:empty{display:none}
.home-wrap > [hidden]{display:none !important}

.qk{display:grid;grid-template-columns:1fr 1fr;gap:var(--home-gap)}
/* Stacked icon over label made each button 68px tall for two words. Side by
   side they are 46px, read as one line, and the pair stops dominating the top
   of the screen. */
/* Two quiet tints rather than two more white cards: they read as actions, and
   they do not compete with the score card or the session card above them. */

/* The score card, tightened. It was 74px of chrome for one number. */
.sc-btn{cursor:pointer;position:relative;transition:transform .12s ease}
.sc-btn:active{transform:scale(.988)}
.sc-btn::after{content:'';position:absolute;right:15px;bottom:14px;width:6px;height:6px;
  border-right:2px solid rgba(255,255,255,.45);border-bottom:2px solid rgba(255,255,255,.45);
  transform:rotate(45deg);transition:transform .18s ease}
.sc-btn.open::after{transform:rotate(-135deg)}
.sc-btn .sc-overall{margin:0}
.sc-hold{height:66px;border-radius:16px;background:var(--surface-2);opacity:.5}
/* The profile as a screen, not a sheet.
   It was a bottom panel over a dimmed home screen, which made it look like a modal
   interruption rather than a place in the app. There is no reason it should not own
   the whole screen the way every other view does. */
.ch-panel.pf-full{border-radius:0;bottom:0;top:0;max-height:none;height:100%;
  box-shadow:none;transform:translateY(100%)}
.ch-panel.pf-full.show{transform:translateY(0)}
/* And with no sheet behind it, there is nothing to dim. */
.ch-back.pf-none{background:transparent}
.pf-full .ch-h{padding-top:calc(12px + env(safe-area-inset-top,0px))}
.pf-full .ch-grab{display:none}   /* nothing to drag any more */

/* The profile picture. */
/* the paywall + intake card */
#cgate{position:fixed;inset:0;z-index:910;background:linear-gradient(165deg,#0b0b10,#15151d);
  display:grid;place-items:center;padding:22px;overflow:auto}
.cg-card{max-width:430px;width:100%;color:#f2efe9}
.cg-h{font-size:26.45px;font-weight:800;margin:20px 0 18px;text-align:center}
.cg-l{display:block;font-size:13.8px;font-weight:700;color:#bcb7ad;margin-bottom:6px}
.cg-sel{width:100%;padding:12px;border-radius:10px;background:#15151d;color:#f2efe9;
  border:1px solid #23232e;font-family:inherit;font-size:17.25px}
.cg-note{font-size:13.22px;color:#807d75;margin:8px 0 16px}
.cg-chk{display:flex;gap:10px;align-items:flex-start;text-align:left;font-size:13.22px;
  line-height:1.6;color:#bcb7ad;margin:0 0 14px;cursor:pointer}
.cg-chk input{margin-top:3px;flex:none;width:16px;height:16px}
.cg-chk a{color:#e4bd77}
.pw-disc{text-align:left;font-size:13.22px;line-height:1.65;color:#bcb7ad;
  background:#101017;border:1px solid #23232e;border-radius:10px;padding:12px 14px;margin:16px 0 12px}
.pw-disc b{color:#e4bd77}
.pw-chk{margin-bottom:4px}
#paywall{position:fixed;inset:0;z-index:900;background:linear-gradient(165deg,#0b0b10,#15151d);
  display:grid;place-items:center;padding:22px}
.pw-card{max-width:400px;width:100%;text-align:center;color:#f2efe9}
.pw-logo{font-weight:800;font-size:25.3px;letter-spacing:.16em}
.pw-logo b{color:#d4a24e}
.pw-h{font-size:29.9px;font-weight:800;letter-spacing:-.01em;margin:22px 0 10px}
.pw-p{font-size:16.67px;line-height:1.65;color:#bcb7ad}
.pw-price{margin:22px 0 6px;font-size:17.25px;color:#bcb7ad}
.pw-price b{font-size:34.5px;color:#e4bd77;font-weight:800}
.pw-btn{width:100%;margin-top:14px;background:#d4a24e;color:#151007;border:0;border-radius:12px;
  padding:15px;font-family:inherit;font-size:18.4px;font-weight:800;cursor:pointer}
.pw-btn:disabled{opacity:.6}
.pw-fine{font-size:13.22px;color:#807d75;margin-top:10px}
.pw-out{background:none;border:0;color:#807d75;font-family:inherit;font-size:13.8px;
  margin-top:26px;cursor:pointer;text-decoration:underline}
.intake-card{margin:14px;padding:20px;border-radius:16px;background:var(--surface);
  border:1px solid var(--hairline);text-align:center}
.ic-h{font-size:19.55px;font-weight:800}
.ic-p{font-size:14.95px;color:var(--text-2);line-height:1.65;margin:10px 0 14px}
.ic-btn{background:var(--blue);color:#fff;border:0;border-radius:10px;padding:11px 20px;
  font-family:inherit;font-size:16.1px;font-weight:800;cursor:pointer}
/* ===== LIVE MODE - the workout as a sequence of single moments ===== */
#liveView{position:fixed;inset:0;z-index:950;display:none;flex-direction:column;
  background:radial-gradient(120% 90% at 50% 0%, #101a33 0%, #0a0f1e 55%, #070a14 100%);
  color:#eef1f8;padding:calc(env(safe-area-inset-top) + 14px) 20px calc(env(safe-area-inset-bottom) + 18px)}
#liveView.on{display:flex}
@keyframes lvpulse{50%{opacity:.35}}
#liveBtn{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(env(safe-area-inset-bottom) + 86px);
  z-index:60;display:none;align-items:center;gap:8px;padding:12px 22px;border:0;border-radius:999px;
  background:#0f172a;color:#fff;font-family:inherit;font-size:16.1px;font-weight:800;letter-spacing:.08em;
  box-shadow:0 10px 26px rgba(2,6,23,.45);cursor:pointer}
/* the me-bubble, final word: gradient that actually targets .cb-txt (the real
   class - .cb-b never existed), and room to breathe on a wide screen. Late in
   the sheet + !important so nothing upstream wins. */
/* 9 Aug 2026 - width deliberately NOT set here any more. My bubble had its own
   ladder (88% on .cb, min(920px,94%) on the text) while the coach's came from
   .cb and .cb .cb-txt. Two sets of rules for one thing, and mine broke the line
   early. Both sides share the same rules now: widen .cb and both follow. */
.cb.me .cb-txt{background:linear-gradient(135deg,#4f7dff 0%,#2b4fe0 55%,#5b4fe8 100%) !important;
  border-color:transparent !important;color:#fff;
  box-shadow:0 6px 20px rgba(43,79,224,.28)}
/* Desktop: the whole coach column was capped at var(--maxw) - fine for reading a
   feed, cramped for a conversation on a Mac. On wide screens the chat breathes. */
@media (min-width:1100px){
}
/* ===== stage v5: one picture behind the whole app, both themes.
   Phone: full screen. Laptop: confined to the measured shell column, so the
   margins stay plain and the column reads as a window with the artwork inside
   it rather than wallpaper stretched over the desk.
   Blur is DESKTOP ONLY. backdrop-filter on every bubble, over a fixed
   background, is what made the chat stall for seconds on iOS. ===== */
#silk{position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:url('chat-bg.webp') center/cover no-repeat}
@media (min-width:900px){
  #silk{left:var(--shell-left,0px); right:var(--shell-right,0px)}
}
/* nothing between the picture and the content may paint over it. v3 listed
   .coach-wrap, which does not exist in the DOM, and missed #appShell - the
   desktop column, which paints var(--surface) from 900px up. */
#appShell, #viewCoach.on, #viewHome, #viewHistory, #viewTraining,
.coach-msgs{background:transparent !important}
/* header, coach chips, composer and tab bar sit on the picture instead of
   cutting it into slabs */
.coach-hdr, .coach-switch, .coach-bar{background:rgba(255,255,255,.72) !important}
.tabbar{background:rgba(255,255,255,.78) !important}
/* coach bubbles: translucent everywhere, frosted only where it is free */
.cb.coach .cb-txt{background:rgba(255,255,255,.80) !important;
  border:1px solid rgba(255,255,255,.9) !important;
  box-shadow:0 8px 26px rgba(30,50,120,.10)}
/* The coach's bubble sat at #1E263E against a #0E1420 page - technically a
   different colour, visually the same slab. Lifted well clear of the
   background, given a real edge and a soft blue cast so a long answer reads as
   something set on the page rather than a hole in it. */
@media (min-width:900px){
  .coach-hdr, .coach-switch, .coach-bar{
    background:rgba(255,255,255,.62) !important;
    -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
  .cb.coach .cb-txt{background:rgba(255,255,255,.58) !important;
    -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
}
/* the three coach chips carry the same gradient as his own bubbles */
.cs-chip{background:rgba(255,255,255,.62)}
.cs-chip.on{background:linear-gradient(135deg,#3b6df6 0%,#2b4fe0 55%,#4f46e5 100%);
  border-color:transparent;color:#fff;box-shadow:0 6px 18px rgba(43,79,224,.28)}
/* Profile was a sheet that slid up over everything, tab bar included, with a
   drag handle and a close cross - a modal wearing a screen's clothes. It is a
   screen now: inside the column, under the tab bar, no animation, no exit. */
.ch-panel.pf-full{position:fixed;z-index:6;top:0;bottom:var(--bar-h,56px);
  left:var(--shell-left,0px);right:var(--shell-right,0px);
  height:auto;max-height:none;border-radius:0;box-shadow:none;
  background:transparent;transform:none;transition:none;
  padding-bottom:0;display:none}
.ch-panel.pf-full.show{display:flex;transform:none}
.ch-panel.pf-full .ch-hdr{background:transparent}
.ch-panel.pf-full .ch-x{display:none}
.ch-panel.pf-full .ch-body{flex:1;min-height:0;overflow-y:auto}


.pf-note{font-size:13.22px;color:var(--text-3);line-height:1.5;margin:-4px 2px 10px}
.cs-wrap{display:flex;flex-direction:column;gap:15px;padding:4px 2px 2px}
.cs-row{display:flex;flex-direction:column;gap:5px}
.cs-t{font-size:15.52px;font-weight:700;color:var(--text)}
.cs-ends{display:flex;justify-content:space-between;font-size:12.07px;color:var(--text-3);font-weight:600}
.cs-sl{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:99px;
  background:var(--hairline-str);outline:none;margin:2px 0}
.cs-sl::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;border-radius:50%;
  background:linear-gradient(135deg,#3b6df6 0%,#2b4fe0 55%,#4f46e5 100%);
  box-shadow:0 3px 10px rgba(43,79,224,.35);cursor:pointer;border:2px solid #fff}
.cs-sl::-moz-range-thumb{width:22px;height:22px;border-radius:50%;border:2px solid #fff;
  background:#2b4fe0;box-shadow:0 3px 10px rgba(43,79,224,.35);cursor:pointer}

#pfBack{display:none !important}
.gl-wrap{direction:ltr;text-align:left}
.gl-sec{margin:0 0 14px;border:1px solid var(--hairline);border-radius:15px;
  background:var(--surface);overflow:hidden}
.gl-sec>summary{list-style:none;cursor:pointer;padding:13px 15px;display:flex;align-items:center;gap:9px}
.gl-sec>summary::-webkit-details-marker{display:none}
.gl-sec>summary::before{content:'\25b8';font-size:12.65px;color:var(--text-3);transition:transform .15s ease;flex:none}
.gl-sec[open]>summary::before{transform:rotate(90deg)}
.gl-sec>summary .gl-h{flex:1}
.gl-n{font-size:13.22px;font-weight:700;color:var(--text-2);background:var(--hairline);
  border-radius:100px;padding:3px 9px;flex:none}
.gl-sec>.gl-sub,.gl-sec>.gl-none{padding-inline:15px}
.gl-sec>.gl-add{margin-inline:15px;width:calc(100% - 30px)}
.gl-sec>.gl{margin-inline:15px}
/* Same fold as the goals, reused for the daily targets - he reads them when
   something changes, not every time he opens the screen. */
/* 10 Aug 2026. The three folds read as one list rather than three floating
   cards: no gaps between them, one outer border, and rounding only at the two
   ends. #pfGoals is a plain div holding the two goal sections, so the rules reach
   through it. */
.fold-stack{border:1px solid var(--hairline-str);border-radius:15px;overflow:hidden;
  background:var(--surface);margin:0 0 20px}
.fold-stack .gl-sec{margin:0;border:0;border-radius:0;background:transparent}
.fold-stack #pfGoals>.gl-wrap>.gl-sec+.gl-sec,
.fold-stack>.gl-sec{border-top:1px solid var(--hairline)}
.fold-stack #pfGoals>.gl-wrap>.gl-sec:first-child{border-top:0}
.pf-fold{margin:0}
.pf-fold>.pf-list{margin:0 15px 14px;border-radius:12px;overflow:hidden}
.pf-fold>summary .gl-h{font-size:16.1px}
.gl-sec>.gl:last-of-type{margin-bottom:4px}
.gl-h{font-size:17.25px;font-weight:800;letter-spacing:-.01em}
.gl-sub{font-size:13.22px;color:var(--text-3);margin:2px 0 11px;line-height:1.45}
.gl{background:var(--surface);border:1px solid var(--hairline);border-radius:14px;
  padding:13px 14px;margin:0 0 9px}
/* A proposal is visibly not yet a goal - dashed until a coach has agreed to it. */
.gl.pend{border-style:dashed;background:transparent}
.gl-t{font-size:16.67px;font-weight:750;line-height:1.35;letter-spacing:-.01em}
.gl-d{font-size:14.37px;line-height:1.55;color:var(--text-2);margin-top:5px}
.gl-m{font-size:13.22px;line-height:1.5;color:var(--text-3);margin-top:7px}
.gl-m span{display:block;font-size:10.35px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3);margin-bottom:2px}
.gl-f{display:flex;align-items:center;gap:8px;margin-top:10px}
.gl-st{font-size:10.92px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;
  color:#b26a00;background:rgba(178,106,0,.1);padding:3px 7px;border-radius:6px}
.gl-by{font-size:12.07px;color:var(--text-3)}
.gl-x{margin-inline-start:auto;background:var(--surface-2);border:0;border-radius:8px;
  padding:6px 11px;cursor:pointer;font-family:inherit;font-size:12.65px;font-weight:750;
  color:var(--text-2)}
.gl-add{width:100%;background:none;border:1px dashed var(--hairline-str);border-radius:12px;
  padding:11px;cursor:pointer;font-family:inherit;font-size:14.37px;font-weight:700;
  color:var(--blue-soft);margin-top:2px}
.gl-none{font-size:14.37px;color:var(--text-3);padding:4px 2px 10px}
.gl-load{font-size:14.37px;color:var(--text-3);padding:14px 2px}
/* The leading goal reads as the one the others serve, rather than as the first item
   in a list. Everything below it is tightened, because the section was taking most
   of the sheet for what is mostly reference. */
.gl.lead{border-color:var(--blue);background:linear-gradient(160deg,var(--blue-dim),transparent)}
.gl-lead{font-size:10.35px;font-weight:800;letter-spacing:.11em;text-transform:uppercase;
  color:var(--blue-soft);margin-bottom:6px}
.gl.lead .gl-t{font-size:18.4px}
.gl-w{background:none;border:0;padding:6px 8px;cursor:pointer;font-family:inherit;
  font-size:12.65px;font-weight:700;color:var(--text-3);text-decoration:underline}
/* Armed: the second tap is destructive, so it stops being a quiet link. */
.gl-w[data-goalrm]{text-decoration:none}
.gl-w[data-goalrm]:not(:only-child){margin-inline-start:auto}
.gl-f .gl-w[data-goalrm]{color:var(--text-3)}
.gl-f .gl-w[data-goalrm].armed,
.gl-f .gl-w[data-goalrm]:focus{color:#c62828;font-weight:800}
/* Detail and measure collapse to two lines each: he reads the goal, not the essay,
   and the full text is a tap away in the conversation. */
.gl-d,.gl-m{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
.gl.lead .gl-d{-webkit-line-clamp:3}
.gl-sec{margin:0 0 16px}
.gl{padding:12px 13px;margin:0 0 8px}
.hc-card{background:#fff5f5;border:1px solid #f3c6c6;border-radius:16px;
  padding:13px 15px;margin:10px 0;direction:ltr;text-align:left}
.hc-h{font-size:14.95px;font-weight:800;color:#a32a21;margin-bottom:8px}
.hc-row{font-size:13.8px;line-height:1.5;padding:4px 0;border-top:1px solid #f6dcdc;
  display:flex;flex-direction:column;gap:1px}
.hc-row:first-of-type{border-top:0}
.hc-row b{color:#7d211a}
.hc-row span{color:#9a5c56}
.hc-n{font-size:12.07px;color:#a98a86;margin-top:8px;line-height:1.45}
.mc-card{background:var(--surface);border:1px solid var(--hairline-str);border-radius:16px;
  padding:13px 15px;margin:10px 0;text-align:right}
.mc-top{display:flex;align-items:baseline;gap:10px}
.mc-t{font-weight:750;font-size:16.67px}
.mc-n{margin-inline-start:auto;font-weight:800;font-size:19.55px}
.mc-s{font-size:13.22px;color:var(--text-3);margin-top:4px;line-height:1.45}
.mc-x{margin-top:10px;border:0;border-radius:10px;padding:7px 14px;cursor:pointer;
  font-family:inherit;font-size:14.37px;font-weight:650;background:var(--blue-dim);color:var(--blue-soft)}
.pf-v.muted{color:var(--text-2);font-weight:500}
.pf-tag{display:inline-flex;align-items:center;gap:5px;background:rgba(120,140,180,.12);
  border-radius:999px;padding:4px 10px;font-size:14.37px;font-weight:650;margin:0 0 6px 6px}
/* Upload Program. Touched a handful of times a year, so it is one folded line
   until it is wanted, and it lives behind the owner's email. */
.pf-adm{border:1px solid var(--hairline-str);border-radius:13px;overflow:hidden;margin-bottom:14px;background:var(--surface)}
.pf-adm>summary{list-style:none;cursor:pointer;padding:13px 14px;font-size:16.1px;font-weight:600;
  display:flex;align-items:center;gap:9px}
.pf-adm>summary::-webkit-details-marker{display:none}
.pf-adm>summary::before{content:'\25b8';font-size:12.65px;color:var(--text-2);transition:transform .15s ease}
.pf-adm[open]>summary::before{transform:rotate(90deg)}
.up-body{padding:0 14px 14px;display:flex;flex-direction:column;gap:11px}
.up-who{display:flex;gap:8px}
.up-chip{flex:1;padding:9px;border-radius:11px;border:1px solid var(--hairline-str);background:transparent;
  color:var(--text);font-size:15.52px;font-weight:600;font-family:inherit;cursor:pointer}
.up-chip.on{background:var(--blue);color:#fff;border-color:transparent}
.up-pick{display:block;text-align:center;padding:13px;border-radius:11px;cursor:pointer;
  border:1.5px dashed var(--hairline-str);color:var(--text-2);font-size:15.52px}
.up-pre{font-size:14.37px;line-height:1.6;border-radius:11px;padding:11px 12px;
  background:rgba(120,140,180,.09);direction:ltr;text-align:left;white-space:pre-wrap;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;max-height:290px;overflow:auto}
.up-bad{background:rgba(220,80,80,.10);color:#c2453f}
.up-go{width:100%;border:0;background:var(--blue);color:#fff;border-radius:13px;padding:13px;
  font-size:16.67px;font-weight:700;font-family:inherit;cursor:pointer}
.up-go[disabled]{opacity:.4;cursor:default}
.pf-out{width:100%;border:0;background:rgba(220,80,80,.10);color:#c2453f;border-radius:13px;
  padding:12px;font-family:inherit;font-size:16.67px;font-weight:650;cursor:pointer;margin-top:18px}

/* ===== athlete scores ===== */
/* HOME-ONLY TRIMS. Scoped to .home-wrap so the Journey screen - which shares
   every one of these classes and has different work to do - is untouched. */
.home-wrap .ln{margin:0}
/* --- today's lesson, compact (home) --------------------------------------- */
.lnm{padding:0;overflow:hidden}
.lnm-row{display:flex;align-items:center;gap:11px;padding:9px 11px 9px 10px}
.lnm-play{flex:none;width:34px;height:34px;border-radius:50%;border:0;cursor:pointer;
  display:grid;place-items:center;background:var(--blue);color:#fff;
  transition:transform .12s ease,opacity .12s ease}
.lnm-play:active{transform:scale(.92)}
.lnm-play:disabled{opacity:.4;cursor:default}
.lnm-mid{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  background:none;border:0;padding:0;cursor:pointer;font-family:inherit;text-align:left}
.lnm-eyebrow{font-size:9.9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* One line, clipped. The whole point of the row is that its height is fixed;
   a two-line title would put it straight back where it came from. */
.lnm-t{font-size:14.6px;font-weight:750;letter-spacing:-.015em;line-height:1.25;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.lnm-len{flex:none;font-size:12.07px;color:var(--text-3);font-variant-numeric:tabular-nums}
.lnm-chev{flex:none;width:22px;height:22px;border:0;background:none;padding:0;cursor:pointer;
  position:relative}
.lnm-chev::after{content:'';position:absolute;left:6px;top:7px;width:7px;height:7px;
  border-right:2px solid var(--text-3);border-bottom:2px solid var(--text-3);
  transform:rotate(45deg);transition:transform .18s ease}
.lnm.open .lnm-chev::after{transform:rotate(-135deg);top:10px}
/* The row is the progress bar. */
.lnm-prog{height:2px;background:transparent}
.lnm-prog i{display:block;height:100%;width:0;background:var(--blue);
  transition:width .2s linear}
.lnm.on .lnm-prog{background:var(--hairline)}
/* --- the tool strip ------------------------------------------------------- */
.lnm-bar{display:flex;align-items:center;gap:4px;padding:6px 8px 7px;
  border-top:1px solid var(--hairline)}
.lnm-gap{flex:1}
.lnm-sp{flex:none;min-width:34px;height:30px;padding:0 8px;border:0;border-radius:9px;
  background:var(--surface-2);color:var(--text-2);cursor:pointer;font-family:inherit;
  font-size:12.07px;font-weight:800;font-variant-numeric:tabular-nums}
.lnm-sp.fast{background:rgba(46,91,255,.12);color:var(--blue)}
.lnm-ic{flex:none;position:relative;width:32px;height:30px;border:0;border-radius:9px;
  background:none;color:var(--text-2);cursor:pointer;display:grid;place-items:center;
  transition:background .14s ease,transform .12s ease}
.lnm-ic svg{width:21px;height:21px}
.lnm-ic:active{transform:scale(.9);background:var(--surface-2)}
/* The 15 is svg <text> now (see lnCardMini), so there is nothing to position. */
.lnm-ic svg text{font-family:inherit;font-variant-numeric:tabular-nums}

/* --- the lesson, opened --------------------------------------------------- */
/* It used to be the escaped script in one blob at the card's own size and full
   width. Given a measure, a rhythm and a quieter colour it reads like an
   article instead of a dump. */
.lnm-body{padding:12px 15px 15px;border-top:1px solid var(--hairline)}
.lnm-lede{margin:0 0 12px;font-size:14.2px;line-height:1.5;font-weight:650;
  color:var(--text);max-width:62ch}
/* A four-minute lesson is well over a screen of text. Left unbounded it turned
   home into an endless page with everything below it - the scores, the session,
   the week - pushed out of reach behind it. It scrolls within the card instead,
   so the lesson can be read in place and the screen keeps its shape. The fade
   at the bottom edge is the signal that there is more, without a scrollbar. */
.lnm-script{font-size:14.6px;line-height:1.62;color:var(--text-2);max-width:66ch;
  max-height:44vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding-bottom:6px;
  -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 26px),transparent);
  mask-image:linear-gradient(180deg,#000 calc(100% - 26px),transparent)}
/* Once it is scrolled to the end there is nothing more to hint at, and the fade
   would just be dimming the last line. */
.lnm-script.at-end{-webkit-mask-image:none;mask-image:none}
.lnm-script p{margin:0 0 13px}
.lnm-script p:last-child{margin-bottom:0}
.lnm-script p.first{color:var(--text)}
.lnm-body .ln-src{margin-top:13px;padding-top:11px;border-top:1px solid var(--hairline)}
.lnm .ln-warn{padding:0 12px 9px}
@media (prefers-reduced-motion:reduce){
  .lnm-chev::after,.lnm-prog i,.lnm-play{transition:none}
}
.home-wrap .ln-tools{margin-top:5px}
.home-wrap .ln-row{margin-top:7px}
/* The four mini scores lost their small print (it moved behind a tap), so the
   space that line used to occupy goes with it. */
.home-wrap .sc{padding:11px 13px 11px}
.sc-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:9px;margin-bottom:8px}
/* THE FOUR PILLARS, AS LINES - 29 Aug 2026. Two columns of rows tucked under
   the Athlete Score they add up to, separated from it by a single rule. Grey
   by default; gold only on the one that moved, because a screen where four
   numbers all shout is a screen where none of them do. */
.sc-rows{display:grid;grid-template-columns:1fr 1fr;gap:13px 18px;
  margin:-4px 0 10px;padding:13px 15px 14px;
  background:var(--surface);border:1px solid var(--hairline);
  border-top:0;border-radius:0 0 16px 16px}
.scr{cursor:pointer;-webkit-tap-highlight-color:transparent;min-width:0}
.scr-k{display:flex;align-items:baseline;gap:6px;font-size:12.6px;font-weight:750;
  color:var(--text-2);letter-spacing:-.01em}
.scr-v{margin-inline-start:auto;font-size:15px;font-weight:850;letter-spacing:-.02em;color:var(--text)}
.scr-d{font-size:10.6px;font-weight:850;color:var(--text-3)}
.scr-b{height:3px;border-radius:99px;background:#E1E7F2;margin-top:6px;overflow:hidden}
.scr-b i{display:block;height:100%;border-radius:99px;background:#93A2C2;
  transition:width .5s cubic-bezier(.22,.9,.3,1)}
.scr.moved .scr-v,.scr.moved .scr-d{color:var(--gold-deep)}
.scr.moved .scr-b i{background:linear-gradient(90deg,var(--gold-hi),var(--gold-lo))}
.scr.na .scr-v{color:var(--text-3)}
.scr .sc-whyline{margin-top:7px;font-size:11.8px;line-height:1.45;color:var(--text-3)}
.scr:active{opacity:.65}
/* The score card sits flush on its rows so the two read as one object. The
   home rhythm rule sets margin-bottom on every direct child with !important,
   which would open a 10px seam right through the middle of that object - so
   the only place that rule is overruled is here, and only while open. */
.sc-btn.open .sc-overall{border-radius:16px 16px 0 0;margin-bottom:0}
.home-wrap > .sc-btn.open{margin-bottom:0 !important}

/* THE MORNING VITALS - 29 Aug 2026. Four dials on one row: recovery, sleep,
   strain, fuel. Small on purpose - this is a glance, not a dashboard, and the
   session above it must stay the loudest thing on the screen. Navy ring by
   default; gold when a figure wants looking at, which is the same rule the
   score rows follow, so "gold means notice this" holds across the page. */
.vitals{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;
  background:var(--surface);border:1px solid var(--hairline);
  border-radius:16px;padding:14px 7px 12px}
.vt{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0}
.vt-r{width:54px;height:54px;display:block;flex:none;
  filter:drop-shadow(0 1px 1.5px rgba(20,36,92,.16))}
/* The track is thinner than the arc and set back - the value should sit ON the
   groove, not fill it edge to edge. That single relationship is most of the
   difference between a progress ring and a coloured circle. */
/* Four arcs, outside in: calories, protein, carbs, fat. Tints of the two house
   colours, not four new hues - the quadruple ring has to read as one object. */
.vt-r circle.a1,.vt-r circle.a2,.vt-r circle.a3,.vt-r circle.a4,
.vt-r circle.ok,.vt-r circle.warn-a{
  fill:none;stroke-width:4.4;stroke-linecap:round;
  transition:stroke-dasharray .7s cubic-bezier(.22,.9,.3,1)}
/* Inside the quadruple ring the four bands run close together, so they stay
   thinner - at 4.4 they would touch and the whole thing would read as a blob. */
.vt-r.quad circle{stroke-width:3.1}
.vt-r.quad .vt-bg{stroke-width:2.2}
.vt-r circle.a1{stroke:url(#ringNavy)}
.vt-r circle.a2{stroke:url(#ringGold)}
.vt-r circle.a3{stroke:url(#ringMid)}
.vt-r circle.a4{stroke:url(#ringPale)}
.vt-r circle.ok{stroke:url(#ringGreen)}
.vt-r circle.warn-a{stroke:url(#ringGold)}
.vt-v{font-size:14.5px;font-weight:850;letter-spacing:-.02em;line-height:1;white-space:nowrap}
.vt-v i{font-style:normal;font-size:10.5px;font-weight:800;color:var(--text-3);margin-inline-start:1px}
.vt.warn .vt-v{color:var(--gold-deep)}
/* A target reached reads in the same green as every other confirmation in the
   app, and only on the number - the label stays quiet so a met goal is a note,
   not a celebration that outshouts the things still needing attention. */
.vt.hit .vt-v{color:#0A7F5E}

/* THE FOUR-YEAR TRACK. Deliberately thin: it is the slowest-moving thing on the
   screen and must never compete with today. Ticks at each year so 2% reads as
   "the start of four years" rather than "almost nothing". */
.jbar{background:var(--surface);border:1px solid var(--hairline);
  border-radius:16px;padding:12px 15px 13px}
.jb-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.jb-k{font-size:10.4px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--gold-deep)}
.jb-n{font-family:var(--mono);font-size:11.4px;font-weight:750;color:var(--text-3)}
.jb-track{position:relative;height:7px;border-radius:99px;background:#E4E9F4;margin:10px 0 9px}
.jb-fill{position:absolute;inset-inline-start:0;top:0;height:100%;border-radius:99px;
  background:var(--blue-grad);transition:width .7s cubic-bezier(.22,.9,.3,1)}
.jb-t{position:absolute;top:-2px;width:1px;height:11px;background:#C6CFE0;transform:translateX(-.5px)}
.jb-dot{position:absolute;top:50%;width:11px;height:11px;border-radius:50%;
  background:var(--gold-lo);border:2px solid var(--surface);
  transform:translate(-50%,-50%);box-shadow:0 1px 3px rgba(20,36,92,.3)}
.jb-f{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  font-size:11.6px;font-weight:700;color:var(--text-3)}
.jb-f span:first-child{color:var(--text-2);font-weight:750}

/* The finished day. Quiet by design - it is a receipt, not an instruction. */
.done-card{width:100%;display:flex;align-items:center;gap:12px;text-align:start;
  background:var(--surface);border:1px solid var(--hairline);border-radius:18px;
  padding:13px 15px;font-family:inherit;cursor:pointer;color:var(--text)}
.done-card:active{transform:scale(.99)}
.dn-ic{flex:none;width:32px;height:32px;border-radius:50%;background:var(--gold-dim);
  display:flex;align-items:center;justify-content:center;color:var(--gold-deep)}
.dn-ic svg{width:16px;height:16px}
.dn-tx{min-width:0;flex:1}
.dn-k{font-size:10.6px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--gold-deep)}
.dn-t{font-size:15px;font-weight:750;line-height:1.3;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.dn-go{flex:none;color:var(--text-3)}
.dn-go svg{width:16px;height:16px;display:block}

/* 4 - THREE BEATS ON THE DAY'S BUTTON. It waits 1.1s so it is not competing
   with the rings drawing in, beats three times, and stops. A control that
   pulses forever is a control being ignored: after the second morning the eye
   filters it out and all that is left is a screen that will not sit still.
   The pulse is a shadow, never a transform - a button that changes size is a
   button that moves under his thumb. */
/* A BREATH, NOT A BLINK - 30 Aug 2026. First attempt was a short flash inside a
   long pause, on the theory that a brief signal resists becoming wallpaper. He
   read it as fast and hard, and he is right about what he asked for: breathing
   is slow, symmetrical and never arrives at an edge. So the glow swells over
   most of two seconds and recedes over the other two, on a sine curve - no
   sharp end to the movement in either direction - and it is softer and wider
   than the flash was, because a breath is felt rather than noticed.
   Four seconds a cycle: roughly a resting breath, which is the point. */
@keyframes tzBeat{
  0%,100%{box-shadow:var(--gold-3d),0 0 0 0 rgba(255,201,60,0)}
  50%    {box-shadow:var(--gold-3d),0 0 0 9px rgba(255,201,60,.20)}
}
.start-card .sc-go{animation:tzBeat 4s cubic-bezier(.45,0,.55,1) 1.2s infinite both}

/* 5 - the sweep of light along the four-year track is GONE. He called it
   strange and he was right: a glint travelling across a progress bar suggests
   something is loading, and nothing was. The track is honest without it. */
@media (prefers-reduced-motion:reduce){
  .start-card .sc-go{animation:none}
}

/* The section word, inside the card - 30 Aug 2026, his call. It was a
   full-width rule above each card, which spent a whole row of height on one
   word. It now rides the eyebrow line that was already there - heavier than
   the text it leads, with a gold bullet doing the separating. No new space. */
.crd-sec{font-weight:900;letter-spacing:.14em}
.crd-sec::after{content:'\00a0\00b7\00a0';font-weight:700;color:var(--gold-lo)}
.start-card .crd-sec::after{color:var(--gold-hi)}
.lnm-eyebrow .crd-sec{color:var(--gold-deep)}

/* The greeting that replaced the photograph: one line, his name and the date. */
.home-top{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px;margin:2px 3px 13px}
/* 18px, not 20.5: at 390px "Welcome back, Tzvika" and the date could not both
   fit and his name was the half that got the ellipsis. */
.home-hi{font-size:18px;font-weight:800;letter-spacing:-.02em;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.home-dt{flex:none;font-size:12.2px;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3)}
.sc{background:var(--surface);border:1px solid var(--hairline);border-radius:16px;padding:11px 13px 12px;position:relative}
.sc-top{display:flex;align-items:baseline;gap:6px}
.sc-num{font-size:31.05px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.sc-max{font-size:13.8px;color:var(--text-2);font-weight:600}
.sc-na{font-size:21.85px;font-weight:700;color:var(--text-2);letter-spacing:.02em}
.sc-name{font-size:14.37px;font-weight:650;margin-top:6px;display:flex;align-items:center;gap:5px}
.sc-why{font-size:12.65px;color:var(--text-2);margin-top:5px;line-height:1.45}
.sc-trend{position:absolute;top:12px;inset-inline-end:13px;font-size:13.22px;font-weight:700}
.sc-trend.up{color:#2fb972}.sc-trend.down{color:#d9534f}.sc-trend.flat{color:var(--text-2)}
.sc-meter{height:4px;border-radius:99px;background:rgba(120,140,180,.16);margin-top:9px;overflow:hidden}
.sc-meter i{display:block;height:100%;border-radius:99px;background:var(--blue);transition:width .5s ease}
.sc.na .sc-meter i{background:rgba(120,140,180,.3)}
/* ============================================================
   GOLD ON THE DARK GROUNDS - 29 Aug 2026, his note: too much deep navy.
   He is right, and the reason is structural rather than a matter of degree.
   Navy was doing two jobs at once: the colour of every ACTION and also the
   colour of every large SURFACE - score card, profile header, journey header,
   session card. On a light screen that reads as an accent; four dark slabs in
   a row and it reads as the whole app.
   Split by ground rather than sprinkling gold at random:
     on a LIGHT ground, navy leads - send, save, confirm
     on a NAVY ground, gold leads  - the figure, the label, the way forward
   Nothing new is invented: the gold lands on what already mattered most inside
   each dark card - the number he opened it to read, and the control he opened
   it to press.
   ============================================================ */
.js-kick,.pf-kick,.wr-kick{color:var(--gold-hi);opacity:1}
.js-sv,.pf-sv{color:var(--gold-hi)}
.sc-overall .sc-num{color:var(--gold-hi)}

.sc-overall{grid-column:1 / -1;background:linear-gradient(135deg,#1d2f6b,#3b6cff);color:#fff;border:0;
  padding:12px 15px 13px}
.sc-overall .sc-head{display:flex;align-items:baseline;gap:9px}
.sc-overall .sc-sp{flex:1}
.sc-overall .sc-trend{position:static}
.sc-overall .sc-name{margin-top:0}
.sc-overall .sc-meter{margin-top:8px}
.sc-overall .sc-max,.sc-overall .sc-why{color:rgba(255,255,255,.72)}
.sc-overall .sc-meter{background:rgba(255,255,255,.22)}
.sc-overall .sc-meter i{background:#fff}
.sc-overall .sc-trend.flat{color:rgba(255,255,255,.7)}
.ev-item{display:flex;gap:9px;align-items:flex-start;padding:7px 0;font-size:15.52px;line-height:1.5}
.ev-ic{flex:none;width:20px;text-align:center}
.ev-item b{font-weight:700}
/* ===== weekly review ===== */
.wr-hero{background:linear-gradient(135deg,#1d2f6b,#3b6cff);color:#fff;border-radius:20px;
  padding:20px 18px;margin-bottom:14px}
.wr-kicker{font-size:12.07px;letter-spacing:.12em;text-transform:uppercase;opacity:.72;font-weight:700}
.wr-title{font-size:24.15px;font-weight:800;margin-top:5px;line-height:1.25}
.wr-sub{font-size:14.95px;opacity:.85;margin-top:6px;line-height:1.5}
.wr-l{font-size:13.22px;color:var(--text-2);margin-top:3px;line-height:1.35}

.wr-bars{display:flex;align-items:flex-end;gap:5px;height:52px;margin-top:10px}
.wr-bar{flex:1;background:var(--blue-dim,rgba(59,108,255,.16));border-radius:4px 4px 2px 2px;min-height:3px;
  position:relative}
.wr-bar.hit{background:var(--blue)}
.wr-bar span{position:absolute;bottom:-16px;inset-inline-start:0;right:0;text-align:center;
  font-size:10.35px;color:var(--text-2)}
.wr-block{background:var(--surface);border:1px solid var(--hairline);border-radius:15px;
  padding:14px 15px;margin-bottom:12px}
.wr-h{font-size:15.52px;font-weight:700;margin-bottom:8px;display:flex;align-items:center;gap:7px}
.wr-li{font-size:15.52px;line-height:1.6;color:var(--text);padding:4px 0 4px 0;display:flex;gap:8px}
.wr-li b{font-weight:700}
.wr-li .wr-ic{flex:none}
.wr-empty{color:var(--text-2);font-size:14.95px;line-height:1.6}
.cb-img{width:220px;height:220px;object-fit:cover;border-radius:12px;margin-bottom:6px;display:block;
  background:var(--surface-2)}   /* fixed box: nothing reflows when a photo finishes loading */
/* The attachment card. Sized like a document row, not like a message: it should
   read as something ENCLOSED with the message rather than as more of it. Sits on
   his own bubble, so the surface is a translucent lift off the navy rather than
   a colour of its own. */
.cb-att{align-self:flex-end;max-width:100%;margin:2px 0 6px;border-radius:14px;
  overflow:hidden;background:var(--surface);border:1px solid var(--hairline);
  box-shadow:0 1px 2px rgba(20,36,92,.06),0 6px 18px -14px rgba(20,36,92,.5)}
.cb.coach .cb-att{align-self:flex-start}
.cb-att-head{display:flex;align-items:center;gap:10px;width:100%;
  padding:10px 12px;border:0;background:none;cursor:pointer;
  font-family:inherit;text-align:start;color:var(--text)}
.cb-att-head:active{background:var(--surface-2)}
.cb-att-ico{font-size:19px;line-height:1;flex:none}
.cb-att-txt{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
.cb-att-kind{font-size:10.6px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--gold-deep)}
.cb-att-name{font-size:14px;font-weight:650;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical}
.cb-att-n{flex:none;font-family:var(--mono);font-size:11.5px;font-weight:700;
  color:var(--text-3);padding-inline-start:4px}
.cb-att-n::after{content:' w'}
.cb-att-head::before{content:'';order:9;flex:none;width:7px;height:7px;
  border-right:2px solid var(--text-3);border-bottom:2px solid var(--text-3);
  transform:rotate(45deg);margin-top:-3px;transition:transform .18s ease}
.cb-att.open .cb-att-head::before{transform:rotate(-135deg);margin-top:2px}
.cb-att-body{padding:0 12px 11px;font-size:13.5px;line-height:1.55;
  color:var(--text-2);max-height:340px;overflow:auto;
  border-top:1px solid var(--hairline);margin-top:2px;padding-top:10px}
.cb-att-body .mdli{margin:0 0 2px}
@media (prefers-reduced-motion:reduce){ .cb-att-head::before{transition:none} }
.cb-imgnote{font-size:13.8px;color:var(--text-3);margin-bottom:4px}
/* ===== the coach, inside the session =====
   Mirrors the rest timer: same size, same height off the floor, opposite
   corner. It grows out of its own circle rather than sliding in from nowhere,
   so it reads as the bubble opening rather than a panel arriving. */
/* The rest timer and the coach are the same object in two roles, so they are
   built from the same numbers instead of one being measured against the other.
   The old version copied the wrapper's height - caption included - and also
   picked up the timer's scale-up while running, so it was never the same size
   twice. */
.wc-fab{position:fixed;z-index:46;
  right:calc(16px + env(safe-area-inset-right,0));
  bottom:calc(20px + env(safe-area-inset-bottom,0));
  width:76px;height:76px;border-radius:50%;padding:0;cursor:pointer;
  border:1px solid var(--hairline-str);
  display:grid;place-items:center;background:var(--surface);
  box-shadow:0 10px 30px -10px rgba(20,40,100,.35), 0 2px 6px rgba(20,40,100,.10);
  transition:transform .18s cubic-bezier(.34,1.4,.5,1),opacity .16s ease}
.wc-fab .wc-ico{font-size:29.9px;line-height:1}
.wc-fab .wc-lab{position:absolute;bottom:9px;font-size:10.92px;font-weight:700;letter-spacing:.04em;color:var(--text-2)}
.wc-fab:active{transform:scale(.93)}
.wc-fab.hidden{transform:scale(.4);opacity:0;pointer-events:none}
.wc-fab .wc-dot{position:absolute;top:9px;inset-inline-end:9px;width:9px;height:9px;border-radius:50%;
  background:var(--green,#2fb972);box-shadow:0 0 0 3px var(--surface)}

/* THE SCRIM DID NOT REACH THE BOTTOM - 25 Aug 2026.
   He photographed it twice: the blur ends in a hard horizontal line and below it
   the workout page is sharp and bright. inset:0 pins this to the LAYOUT
   viewport, and with the keyboard up on iOS the layout viewport and the visible
   area are not the same rectangle - Safari shifts one inside the other, and
   which way it shifts is not something I could work out from here. I tried
   twice.
   So stop computing the edge. The scrim now extends 200vh past every side. It
   costs nothing - it is one painted layer with no content - and it cannot fail
   to cover, whatever the browser does with the viewport under a keyboard. The
   rounded card above it is what he sees; this only has to be everywhere. */
.wc-scrim{position:fixed;left:-100vw;right:-100vw;top:-200vh;bottom:-200vh;
  z-index:47;background:rgba(12,20,38,.34);
  -webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);
  opacity:0;pointer-events:none;transition:opacity .2s ease}
/* With the session frozen behind it, a swipe in the conversation stays in the
   conversation instead of scrolling the workout underneath. */
body.wc-open{overflow:hidden;touch-action:none}
.wc-scrim.show{opacity:1;pointer-events:auto}

.wc-panel{position:fixed;z-index:48;
position:fixed;z-index:48;
  /* THE IN-WORKOUT COACH, REBUILT AS A SHEET - 17 Aug 2026.

     Three attempts failed here and they all failed for one reason I had wrong:
     this app's viewport meta asks the browser to shrink the page when the
     keyboard opens (interactive-widget=resizes-content), and IOS SAFARI DOES NOT
     IMPLEMENT IT. On his iPhone the layout viewport stays full height and the
     keyboard simply covers the bottom of it. So 100vh, 100dvh and every
     max-height built from them were all reporting a screen that was not there:
     the panel kept full-screen height, its top ran off the display, and when I
     pinned the top as well the result was a full-height sheet with one greeting
     in it - the white void he photographed.

     CSS cannot see the keyboard on iOS. So JS measures visualViewport and
     publishes two numbers - --wc-kb (keyboard height) and --wc-vvh (the height
     actually visible) - and the geometry here is built from those. See
     wcViewportTrack.

     Shape: a sheet at the bottom, above the keyboard, as tall as its content up
     to the room available. Short conversation, short sheet. Long one, capped and
     scrolling inside. */
  left:max(8px, env(safe-area-inset-left,0px));
  right:max(8px, env(safe-area-inset-right,0px));
  /* THE SHEET LAGGED BEHIND THE KEYBOARD - 25 Aug 2026, his report:
     "it does not sit fixed, something peeks out at the bottom".
     Two causes, both here.
     1. bottom and max-height were in the transition below. iOS fires a stream of
        visualViewport resize events across the keyboard animation, and each one
        restarted a fresh 220ms ease - so the sheet was permanently chasing the
        keyboard and never arrived, and the workout page showed through the strip
        it had not covered yet. Geometry driven by a measurement must not be
        animated; it has to be where the measurement says, this frame.
     2. The 10px breathing gap is right when the sheet rests above the tab bar
        and wrong when it sits on a keyboard - there it is just a slot for the
        page behind to peek through. --wc-pad is set to 0 while the keyboard is
        up so the sheet meets the keyboard with nothing between them. */
  bottom:calc(var(--wc-kb, 0px) + var(--wc-pad, max(10px, env(safe-area-inset-bottom,0px))));
  width:auto;max-width:520px;margin-inline:auto;
  height:auto;
  max-height:calc(var(--wc-vvh, 100dvh) - 78px);
  background:var(--surface);border:1px solid var(--hairline);
  border-radius:24px;
  box-shadow:0 24px 60px -16px rgba(16,28,54,.42), 0 2px 10px rgba(16,28,54,.10);
  display:flex;flex-direction:column;overflow:hidden;
  transform-origin:bottom center;
  transform:translateY(14px) scale(.98);opacity:0;pointer-events:none;
  transition:transform .28s cubic-bezier(.22,1.1,.36,1),opacity .18s ease}
.wc-panel.show{transform:none;opacity:1;pointer-events:auto}
@media(prefers-reduced-motion:reduce){ .wc-panel{transition:opacity .15s ease} }

.wc-head{display:flex;align-items:center;gap:10px;padding:13px 15px 11px;
  border-bottom:1px solid var(--hairline);flex:none}
.wc-head b{font-size:16.67px;display:block;line-height:1.25}
.wc-where{font-size:13.22px;color:var(--text-2);margin-top:2px;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wc-x{margin-inline-start:auto;border:0;background:rgba(120,140,180,.12);color:var(--text-2);
  width:29px;height:29px;border-radius:50%;font-size:19.55px;line-height:1;cursor:pointer;flex:none}
/* flex:0 1 auto, not flex:1 - with flex:1 the list stretched to fill whatever
   height the sheet had, which is how a two-line greeting became a white void.
   Now the list is as tall as its messages and the sheet follows it. */
.wc-msgs{flex:0 1 auto;overflow-y:auto;overscroll-behavior:contain;
  padding:13px 15px;display:flex;flex-direction:column;gap:9px;
  -webkit-overflow-scrolling:touch;min-height:60px}
.wc-b{max-width:88%;padding:9px 12px;border-radius:15px;font-size:16.67px;line-height:1.55;
  white-space:pre-wrap;overflow-wrap:break-word;word-break:normal}
.wc-b.me{align-self:flex-start;background:var(--blue);color:#fff;border-bottom-left-radius:5px}
.wc-b.co{align-self:flex-end;background:rgba(120,140,180,.12);color:var(--text);border-bottom-right-radius:5px}
.wc-b.sys{align-self:center;background:transparent;color:var(--text-2);font-size:14.37px;text-align:center;max-width:100%}
/* 26 Aug 2026: the plan-proposal card already has its own complete chrome
   (border, background, padding - see .pp-card). Wrapping it in the normal
   .wc-b bubble background/padding/radius would box it twice. This wrapper
   exists only so it sits in the message flow and scrolls with everything
   else; it contributes no chrome of its own. */
.wc-b.wc-pp{background:none;padding:0;max-width:100%;border-radius:0;align-self:stretch}
.wc-b.wc-pp .pp-card{max-width:100%;margin:0}
/* One row, the way a messenger does it.

   The two-row version was worse. The icons ended up as three solid blue squares
   floating in their own band, because `.wc-in button` paints every button in the
   panel blue and outranks `.wc-att` on specificity - so my quiet strip was never
   quiet. And splitting the composer left an empty band under it.

   Back to one row, but built to fit: borderless icons at the start, the field
   taking whatever is left, and a round send button. The rule that was fighting
   me is now scoped to the send button alone, so nothing paints over the icons. */
.wc-in{display:flex;align-items:center;gap:6px;
  padding:9px 11px calc(11px + env(safe-area-inset-bottom,0px));
  border-top:1px solid var(--hairline);flex:none}

/* Scoped, so it stops repainting the icon buttons. */
.wc-in .wc-go{border:0;background:var(--blue);color:#fff;border-radius:50%;
  width:38px;height:38px;flex:none;display:grid;place-items:center;cursor:pointer;
  transition:transform .12s ease,opacity .12s ease}
.wc-in .wc-go:active{transform:scale(.92)}
.wc-in .wc-go:disabled{opacity:.35}
.wc-in .wc-go svg{transform:scaleX(-1)}

/* Plain glyphs, no chrome. They are tools, not decisions - so they sit at the
   edge and take no visual weight until one of them is live. */
.wc-in .wc-att{flex:none;width:31px;height:31px;padding:0;border:0;border-radius:10px;
  background:transparent;color:inherit;font-size:18.4px;line-height:1;cursor:pointer;
  display:grid;place-items:center;opacity:.62;
  transition:opacity .12s ease,transform .12s ease,background .12s ease}
.wc-in .wc-att:active{transform:scale(.9)}
.wc-in .wc-att:disabled{opacity:.28}
.wc-in .wc-att.live{opacity:1;background:var(--blue);color:#fff}
.wc-in .wc-att.hear{box-shadow:0 0 0 3px rgba(59,108,255,.22)}
.wc-in .wc-att.talk{opacity:.7}

.wc-in textarea{flex:1;min-width:0;resize:none;border:1px solid var(--hairline);
  border-radius:19px;padding:9px 14px;font-family:inherit;font-size:18.4px;line-height:1.4;
  max-height:84px;background:var(--bg);color:var(--text)}
.wc-in textarea:focus{outline:none;border-color:var(--blue)}
/* The blanket `.wc-in button` rule lived here and painted every button in the
   composer solid blue, including the three icons. Send is styled by .wc-go and
   the icons by .wc-att; nothing needs a catch-all. */
.wc-in button:disabled{opacity:.4}

/* ===== the in-session coach gets the same surface as the full chat =====
   It is the same conversation in a smaller window, so it should not look like
   a different product: the artwork behind it, glass for what the coach says,
   the gradient for what he says. Blur is desktop-only here too - this panel
   is open mid-workout, which is the worst possible moment to cost frames. */
.wc-panel{background:url('chat-bg.webp') center/cover no-repeat, var(--surface)}
.wc-head, .wc-in{background:rgba(255,255,255,.72)}
.wc-b.me{background:linear-gradient(135deg,#3b6df6 0%,#2b4fe0 55%,#4f46e5 100%);
  box-shadow:0 5px 14px rgba(43,79,224,.24)}
.wc-b.co{background:rgba(255,255,255,.82);border:1px solid rgba(255,255,255,.9);
  box-shadow:0 5px 16px rgba(30,50,120,.10)}
/* the running commentary is not speech - it stays a whisper on the artwork */
.wc-b.sys{background:transparent;text-shadow:0 1px 2px rgba(255,255,255,.5)}
/* the send button matches his own bubble, the way it does in the full chat */
.wc-in .wc-go{background:linear-gradient(135deg,#3b6df6 0%,#2b4fe0 55%,#4f46e5 100%);
  box-shadow:0 4px 12px rgba(43,79,224,.28)}
/* the field stays near-solid: this one has to be readable with a barbell in
   the other hand, and translucency is the first thing to cost that */
.wc-in textarea{background:rgba(255,255,255,.92)}
@media (min-width:900px){
  .wc-head, .wc-in{background:rgba(255,255,255,.62);
    -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
  .wc-b.co{background:rgba(255,255,255,.6);
    -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
}
/* The animation was only ever defined on .cb-txt.typing - the main chat's own
   class - so the bubble inherited none of it and rendered three invisible,
   unstyled spans. Written out here rather than borrowed, so it cannot go quiet
   again if the other chat is restyled. */
.wc-b.typing{display:flex;gap:5px;align-items:center;padding:13px 15px;min-width:0}
.wc-b.typing span{width:7px;height:7px;border-radius:50%;background:var(--text-3);
  animation:blink 1.2s infinite both}
.wc-b.typing span:nth-child(2){animation-delay:.2s}
.wc-b.typing span:nth-child(3){animation-delay:.4s}

@media(min-width:900px){
  body{font-size:18.4px}
/* ===== v5.3 · email sign-in + in-workout coach ===== */



  .cb-txt{font-size:17.07px;line-height:1.6}
  .coach-input textarea{font-size:17.07px}
  .cb-img{max-width:300px;max-height:320px}
  .coach-msgs{max-width:840px;margin-inline:auto;width:100%}
  .coach-hdr,.coach-switch,.coach-input,.coach-foot{max-width:840px;margin-inline:auto}
}

/* ===== v2 additions (time-budget, circuits, 2-row set cards, tiers) ===== */
.modescreen{position:fixed;inset:0;z-index:90;background:radial-gradient(900px 700px at 50% 15%,#ffffff,#e9eef8);
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:0 20px;opacity:0;visibility:hidden;transition:opacity .35s var(--ease),visibility .35s;overflow-y:auto;-webkit-overflow-scrolling:touch}
.modescreen.show{opacity:1;visibility:visible}
.mode-inner{max-width:460px;width:100%;text-align:center;margin:auto;padding:26px 0 120px}

/* 9 Aug 2026. THE READINESS CHECK IS A SHEET, NOT A SCREEN.
   It used to take the whole display, which made an optional thirty-second
   check-in feel like a gate he had to pass to reach his own workout - and with
   a long session title the heading alone ran to three lines. It is the same
   questions in a card he can dismiss: the day stays visible and blurred behind
   it, and both the backdrop and a small x take him back.
   Built on the .sw-sheet pattern already used for the rest timer, so it moves
   and reads like the rest of the app rather than like a second idea. */
/* Above the tab bar (z-index 200), not under it. At 90 the nav sat on top of the
   sheet and ate the Begin button - the one control the card exists for. A sheet
   that covers the whole screen is also the honest shape: while it is open there
   is nowhere else to go except back. */
.modescreen.asSheet{background:rgba(20,30,60,.34);backdrop-filter:blur(7px) saturate(115%);
  -webkit-backdrop-filter:blur(7px) saturate(115%);
  z-index:210;display:block;padding:0;overflow:hidden;overscroll-behavior:contain}
.modescreen.asSheet .mode-inner{
  position:fixed;left:0;right:0;bottom:0;max-width:var(--maxw);margin:0 auto;
  background:var(--surface);border:1px solid var(--hairline-str);border-bottom:none;
  border-radius:24px 24px 0 0;
  padding:12px 20px calc(26px + env(safe-area-inset-bottom,0));
  box-shadow:0 -18px 50px -20px rgba(20,40,100,.4);
  max-height:86vh;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  transform:translateY(110%);transition:transform .38s var(--ease-out);
  text-align:center}
.modescreen.asSheet.show .mode-inner{transform:none}
.modescreen.asSheet .mode-grip{width:40px;height:4px;border-radius:100px;
  background:var(--hairline-str);margin:0 auto 4px}
.mode-x{position:absolute;top:10px;inset-inline-end:12px;width:30px;height:30px;border:0;
  border-radius:50%;background:var(--hairline);color:var(--text-2);font-size:19.55px;line-height:1;
  font-family:inherit;cursor:pointer;display:grid;place-items:center}
.mode-x:active{transform:scale(.93)}
/* One line for what this is, one quiet line for which session. The session
   title was the heading, and a good title makes a bad heading. */
.modescreen.asSheet #readyTitle{font-size:25.3px;margin:8px 0 0}
.modescreen.asSheet #readyDay{font-size:14.95px;color:var(--text-2);margin:3px 0 0;line-height:1.4}
.modescreen.asSheet #readySub{font-size:14.37px;color:var(--text-3);margin:8px 0 0}
.why-line{display:block;font-size:15.52px;line-height:1.55;color:var(--text-2);font-style:italic}
.modescreen.asSheet .mode-energy{margin-top:14px;padding-top:14px}
.mode-inner h1{font-size:29.9px;font-weight:750;letter-spacing:-.02em;margin-bottom:6px}
.mode-inner p{color:var(--text-2);font-size:17.25px;margin-bottom:24px}
.mode-opt.sel{border-color:var(--blue);background:var(--blue-dim);box-shadow:inset 0 0 0 1px var(--blue)}
.mode-opt.sel .mo-t::after{content:' ✓';color:var(--blue)}
.big-btn:disabled{opacity:.45;cursor:not-allowed;filter:grayscale(.3)}
.mode-energy{margin-top:18px;padding-top:18px;border-top:1px solid var(--hairline)}
.mode-energy .lbl{font-size:14.95px;color:var(--text-2);font-weight:600;margin-bottom:10px}

.dual{max-width:var(--maxw);margin:0 auto 14px;display:flex;gap:14px}
.dual .d{flex:1}
.dual .dh{display:flex;justify-content:space-between;font-family:var(--mono);font-size:12.07px;font-weight:600;color:var(--text-3);margin-bottom:5px;text-transform:uppercase;letter-spacing:.05em}
.dual .dh b{color:var(--text)}
.dual .track{height:7px;border-radius:100px;background:var(--surface-2);overflow:hidden}
.dual .fillc{height:100%;background:linear-gradient(90deg,var(--blue),var(--green));border-radius:100px;transition:width .5s var(--ease)}
.dual .fillo{height:100%;background:var(--text-3);opacity:.5;border-radius:100px;transition:width .5s var(--ease)}

/* tier badges + de-emphasis */
.tierbadge.core{color:var(--blue-soft);background:var(--blue-dim)}
.tierbadge.recommended{color:var(--text-2);background:var(--surface-2)}
.tierbadge.optional{color:var(--text-3);background:var(--surface-2)}
.card.opt .card-title{color:var(--text-2)}
.card.opt{opacity:.94}
.skipped-pill{display:none;font-family:var(--mono);font-size:12.07px;color:var(--amber-soft,#c98a2e);background:var(--amber-dim,rgba(224,164,74,.15));padding:3px 9px;border-radius:100px;font-weight:600}
.card.skipped .skipped-pill{display:inline-block}
.card.skipped .card-title{color:var(--text-3);text-decoration:line-through;text-decoration-color:rgba(150,150,150,.4)}
.skip-btn{display:block;margin:16px auto 2px;color:var(--text-3);font-size:14.37px;background:none;border:none;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.skip-btn:hover{color:var(--amber-soft,#c98a2e)}

/* circuit */
.circuit-head{display:flex;align-items:center;gap:12px;margin-bottom:4px}
.round-pill{font-family:var(--mono);font-size:13.8px;font-weight:700;color:var(--blue-soft);background:var(--blue-dim);border:1px solid rgba(46,91,255,.22);padding:5px 12px;border-radius:100px}
.round-note{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--text-3);letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:46%}
.round-dots{display:flex;gap:6px;margin-left:auto}
.round-dot{width:9px;height:9px;border-radius:50%;background:var(--surface-2);border:1px solid var(--hairline-str)}
.round-dot.on{background:var(--green);border-color:var(--green)}
.round-dot.cur{background:var(--blue);border-color:var(--blue)}
.cues{margin-top:6px;padding-inline-start:2px}
.cues li{font-size:14.37px;color:var(--text-3);line-height:1.5;list-style:none;position:relative;padding-inline-start:14px}
.cues li::before{content:'·';position:absolute;inset-inline-start:2px;color:var(--blue-soft)}

/* 2-row set cards (no horizontal scroll) */
.setcards{display:flex;flex-direction:column;gap:10px;margin:6px 0 4px}
.setcard{border:1px solid var(--hairline);border-radius:14px;padding:12px 13px;background:var(--surface);transition:border-color .25s,background .25s}
.setcard.warm{background:var(--surface-2)}
.setcard.set-done{border-color:var(--green-dim);box-shadow:inset 0 0 0 1px var(--green-dim)}
.sc-r1,.sc-r2{display:grid;grid-template-columns:1.25fr 1fr 1fr;gap:9px;align-items:end}
.sc-r2{margin-top:10px;align-items:center}
.sc-set{font-size:18.4px;font-weight:700;letter-spacing:-.01em;line-height:1.15}
.sc-set small{display:block;font-family:var(--mono);font-size:12.65px;color:var(--text-3);font-weight:500;margin-top:2px}
.setcard.warm .sc-set{color:var(--text-2)}
.setcard.set-done .sc-set{color:var(--green-soft)}
.sc-f label{display:block;font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;color:var(--text-3);font-weight:600;margin-bottom:4px;text-transform:uppercase}
.sc-f input{width:100%;background:var(--surface-2);border:1px solid var(--hairline-str);border-radius:10px;
  padding:12px 8px;font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:19.55px;text-align:center;direction:ltr;color:var(--text)}
.setcard.warm .sc-f input{background:var(--surface)}
.sc-f input:focus{outline:none;border-color:var(--blue);background:var(--surface-2)}
.sc-f input::placeholder{color:var(--text-3)}
.sc-rest{display:flex;align-items:center;justify-content:center;gap:5px;font-family:var(--mono);font-size:14.95px;font-weight:600;
  color:var(--blue-soft);background:var(--blue-dim);border:1px solid rgba(46,91,255,.2);border-radius:10px;padding:12px 6px;cursor:pointer;transition:all .16s}
.sc-rest:active{transform:scale(.95)}
.sc-rest svg{width:13px;height:13px}
/* 2 Sep 2026: film the last working set straight from the set card. Same shape
   as the rest button beside it, so the row still reads as one control strip. */
.sc-film{display:flex;align-items:center;justify-content:center;font-size:16px;line-height:1;
  background:var(--surface-2);border:1px solid var(--hairline);border-radius:10px;padding:12px 6px;cursor:pointer;transition:all .16s}
.sc-film:active{transform:scale(.95)}
.sc-done{display:flex;align-items:center;justify-content:center;gap:6px;border-radius:10px;padding:12px 6px;font-size:16.1px;font-weight:700;
  background:var(--surface-2);border:1px solid var(--hairline-str);color:var(--text);cursor:pointer;transition:all .16s}
.sc-done:active{transform:scale(.95)}
.setcard.set-done .sc-done{background:var(--green);border-color:var(--green);color:#04140e}
.set-split{font-family:var(--mono);font-size:12.07px;letter-spacing:.06em;color:var(--text-3);text-transform:uppercase;font-weight:700;margin:14px 0 2px}

/* readouts triple */
.readouts.three{grid-template-columns:1fr 1fr 1fr}
@media(max-width:440px){.readouts.three{grid-template-columns:1fr 1fr}.readouts.three .r3{grid-column:1/-1}}

/* summary subjective */
.subj-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px 18px;margin-top:8px}
.qlabel{font-size:15.52px;color:var(--text-2);font-weight:600;margin-bottom:9px}
.skills-rules{font-size:14.37px;color:var(--text-3);background:var(--surface-2);border:1px solid var(--hairline);border-radius:12px;padding:11px 13px;line-height:1.5}
.cond-summary{margin-top:12px;font-size:14.95px;color:var(--text-2);background:var(--blue-dim);border:1px solid rgba(46,91,255,.2);border-radius:12px;padding:11px 13px;line-height:1.5}
.cond-summary b{color:var(--blue-soft)}
.skills-rules + .qlabel{margin-top:14px}
.variant-row{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 12px}
.vchip{padding:8px 12px;border-radius:100px;font-size:14.95px;font-weight:600;background:var(--surface-2);border:1px solid var(--hairline-str);color:var(--text-2);cursor:pointer;transition:all .16s}
/* 13 Sep 2026, his call on the box-led version picker: "it is hard to see
   which one I chose - the colours are too close to each other." The chosen
   chip is now solid blue with white text, so the answer reads at a glance
   from arm's length with a phone on the floor, and the unchosen ones go
   quieter to widen the gap from both sides. */
.vchip{background:var(--surface-2);border-color:var(--hairline);color:var(--text-3)}
.vchip.on{background:var(--blue);border-color:var(--blue);color:#fff;font-weight:650;
  box-shadow:0 1px 2px rgba(20,40,100,.10),0 6px 16px -10px rgba(46,91,255,.6)}
[data-skill]{width:100%;background:var(--surface-2);border:1px solid var(--hairline-str);border-radius:10px;padding:11px 12px;font-size:17.25px;color:var(--text)}
[data-skill]:focus{outline:none;border-color:var(--blue);background:var(--surface-2)}
@media(max-width:460px){.subj-grid{grid-template-columns:1fr}}
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip{padding:9px 13px;border-radius:100px;font-size:14.95px;font-weight:550;background:var(--surface-2);border:1px solid var(--hairline-str);color:var(--text-2);cursor:pointer;transition:all .16s}
.chip:hover{border-color:var(--blue-soft)}
.chip.on{background:var(--blue-dim);border-color:rgba(46,91,255,.35);color:var(--blue-soft)}
.review-item{display:flex;align-items:center;gap:11px;padding:11px 12px;background:var(--surface-2);border:1px solid var(--hairline);border-radius:12px;font-size:16.1px}
.review-item .rtier{margin-inline-start:auto;font-family:var(--mono);font-size:11.5px;color:var(--text-3)}
.finish-why{margin:14px 0 4px}
.finish-why .fw-t{font-size:14.95px;color:var(--text-2);font-weight:600;margin-bottom:9px}
.notreached-note{font-size:14.37px;color:var(--text-3);margin-top:8px;line-height:1.5}

/* ===== v1.2.1: nav shell + home + history ===== */
.view{display:none}
.view.on{display:block}
/* 26 Aug 2026, his call: the bottom of every screen was loose. This reserved
   82px, which was measured against the OLD 56px tab bar - the bar was slimmed
   to ~42px on 15 Aug and this number was never re-measured, leaving about 35px
   of dead space under the last element on every screen.
   The real bar is 47px at its tallest (the ACTIVE tab is the tall one: 13px
   padding + 21px icon + 2px gap + its 10.6px label; inactive tabs are 34px and
   the min-height floor is 42px). 54px gives that a clean 7px of breathing room
   without the gap reading as a mistake. env(safe-area-inset-bottom) is added on
   top, as before, and is what actually clears the home indicator - the two were
   never doing the same job, which is why the old margin could be this large
   without anyone noticing it was wrong. */
body{padding-bottom:calc(54px + var(--tabpad))}
/* The explanation, in the card. Sized so opening one does not shove the grid
   around more than the line itself needs. */
.sc-whyline{margin-top:9px;padding-top:9px;border-top:1px solid var(--hairline);
  font-size:12.65px;line-height:1.45;color:var(--text-2);
  animation:scWhyIn .16s ease}
@keyframes scWhyIn{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.sc-tap.why-open{box-shadow:0 6px 18px -8px rgba(20,40,100,.28)}
/* A prompt card: the instruction gets normal prose treatment instead of the
   monospaced prescription face, because it is a sentence, not a load. */
.ex.is-prompt .ex-detail{font-family:inherit;font-size:14.6px;line-height:1.5;color:var(--text-2)}
.blk-err{font-size:12.65px;color:var(--text-3);background:var(--surface-2);
  border:1px dashed var(--hairline);border-radius:12px;padding:9px 12px;margin:0 0 var(--home-gap)}
.sc-tap{cursor:pointer;-webkit-tap-highlight-color:transparent;transition:transform .12s ease}
.sc-tap:active{transform:scale(.975)}
/* The .scwhy-* dialog was deleted on 18 Aug: the score explanation opens inside
   its own card now (see scWhyShow / .sc-whyline). Nothing emitted these. */
/* 26 Aug 2026, his call: the gap under the icons. That space was the FULL
   home-indicator inset (34px on this phone) used as padding, which is more than
   the indicator needs to stay clear and read as a large empty band under the
   row. Trimmed to the inset minus 18px, floored at 6px so a phone without an
   indicator still gets a little air rather than none.
   Kept in one variable because four separate rules depend on this number -
   the bar's own padding, body's reserved space, and the two floating controls.
   Last time these drifted apart, floating buttons ended up adrift above a bar
   that had been resized months earlier. */
:root{ --tabpad: max(6px, calc(env(safe-area-inset-bottom, 0px) - 18px)); }
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:200;display:flex;
  background:rgba(255,255,255,.96);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-top:1px solid var(--hairline);
  padding-bottom:var(--tabpad);transform:translateZ(0);-webkit-transform:translateZ(0)}
/* 15 Aug 2026, his call: the bar was 56px on every screen - an icon, a word
   under it, and generous padding, four times over. Naming all four tabs is
   redundant once you are standing on one: the ACTIVE tab keeps its label, the
   other three are icons. About 42px, and where he is reads louder than before
   because the word is now unique to the current tab rather than shared by all
   of them. aria-label on every button carries the name for a screen reader, so
   nothing is lost to accessibility by hiding it visually. */
.tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  padding:7px 0 6px;color:var(--text-3);font-size:10.6px;font-weight:700;letter-spacing:.01em;background:none;border:none;cursor:pointer;transition:color .18s}
.tab svg{width:21px;height:21px}
.tab-l{display:none;line-height:1}
.tab.on .tab-l{color:var(--gold-deep)}
/* Without this the row jumps 12px taller the moment a tab becomes active. */
.tabbar{min-height:42px;align-items:center}
/* 26 Aug 2026, his call: the current screen's icon in a warm orange gradient.
   Three parts, because an icon and a text label take a gradient in completely
   different ways:
   - the solid colour first, which is both the fallback and what the label
     inherits if background-clip:text is unavailable;
   - the ICON's stroke points at the real SVG gradient defined next to the bar
     (a CSS gradient cannot paint a stroke at all);
   - the LABEL uses background-clip:text, which is the only way text takes a
     gradient, and needs the same colours restated because the two mechanisms
     cannot share one declaration. */
.tab.on{color:var(--gold-deep)}
.tab.on svg{stroke:url(#tabGrad)}
/* 29 Aug 2026. This label was three-stop orange clipped into 10.6px text, and
   gradient text is only as legible as its lightest stop: #FFB24D reads 1.79:1
   on the white bar. The word naming the screen he is standing on was the least
   readable text in the app. One solid gold off the new ramp, 5.93:1. The ICON
   keeps the gradient - a 22px stroke can carry it - retuned to the same ramp so
   the pair belongs to one palette. */
.tab.on .tab-l{
  background:none;-webkit-background-clip:border-box;background-clip:border-box;
  -webkit-text-fill-color:currentColor;color:var(--gold-deep)}
/* 26 Aug 2026: these floated 78/80px up, which cleared the OLD 56px bar with a
   large margin and left them visibly adrift above the slimmed one. 54px matches
   body's reserved space exactly, so a floating control now sits directly on the
   bar it is meant to sit above, with the same 7px of air the content gets. */
.stopwatch, .wc-fab{bottom:calc(54px + var(--tabpad)) !important}
.reopen{bottom:calc(56px + var(--tabpad)) !important}
/* home */
.home-wrap{max-width:var(--maxw);margin:0 auto;padding:14px 16px 8px}
.home-h{font-size:17.25px;font-weight:700;color:var(--text-2);margin:26px 2px 12px;letter-spacing:-.01em}
.hero-img + .home-h{margin-top:6px;margin-bottom:9px}
.home-h:first-child{margin-top:6px}
.hero{background:linear-gradient(155deg,#ffffff,#eef2fb);border:1px solid var(--hairline-str);border-radius:22px;padding:20px;box-shadow:var(--shadow)}
.hero .cat{display:inline-block;font-family:var(--mono);font-size:12.65px;font-weight:700;letter-spacing:.06em;color:var(--blue-soft);background:var(--blue-dim);padding:4px 10px;border-radius:100px}
.hero .day{font-family:var(--mono);font-size:14.37px;color:var(--text-3);margin-top:12px}
.hero .ttl{font-size:26.45px;font-weight:750;letter-spacing:-.02em;margin-top:3px;line-height:1.15}
.hero .focus{font-size:16.1px;color:var(--text-2);margin-top:7px}
.hero .meta{display:flex;gap:16px;margin-top:14px;font-size:14.95px;color:var(--text-3)}
.hero .meta b{color:var(--text);font-weight:650}
.hero .cta{margin-top:18px;width:100%;padding:15px;border-radius:14px;font-size:18.4px;font-weight:700;background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff;border:none;cursor:pointer;transition:transform .16s}
.hero .cta:active{transform:scale(.98)}
.hero .cta.resume{background:var(--green)}
.hero.rest{background:linear-gradient(155deg,#fff,#eef7f2)}
/* week strip */
.wday .wl{font-family:var(--mono);font-size:11.5px;color:var(--text-3);font-weight:600}
.wday.today{border-color:var(--blue);box-shadow:inset 0 0 0 1px var(--blue)}
.wday.today .wl{color:var(--blue-soft)}
.wday.done .wdot{background:var(--green);border-color:var(--green)}
.wday.prog .wdot{background:var(--blue);border-color:var(--blue)}
.wday .wn{font-size:13.8px;font-weight:700;color:var(--text-2)}
/* list rows */
.hrow{display:flex;align-items:center;gap:13px;background:var(--surface);border:1px solid var(--hairline);border-radius:14px;padding:14px;margin-bottom:9px;cursor:pointer;transition:border-color .18s}
.hrow:active{border-color:var(--blue-soft)}
.hrow .hr-cat{width:42px;height:42px;border-radius:12px;display:grid;place-items:center;font-size:23px;background:var(--blue-dim);flex:none}
.hrow .hr-main{flex:1;min-width:0}
.hrow .hr-t{font-size:17.82px;font-weight:700;letter-spacing:-.01em}
.hrow .hr-s{font-family:var(--mono);font-size:13.8px;color:var(--text-3);margin-top:3px}
.hrow .hr-r{text-align:right;font-family:var(--mono);font-size:13.8px;color:var(--text-3);flex:none}
.hrow .hr-r b{display:block;font-size:17.25px;color:var(--text)}
.empty-card{background:var(--surface-2);border:1px dashed var(--hairline-str);border-radius:16px;padding:22px;text-align:center;color:var(--text-3);font-size:16.1px;line-height:1.5}
.wsum .ws{background:var(--surface);border:1px solid var(--hairline);border-radius:14px;padding:14px 12px;text-align:center}
.wsum .ws .v{font-size:27.6px;font-weight:750;letter-spacing:-.02em}
.wsum .ws .k{font-size:12.65px;color:var(--text-3);font-weight:600;margin-top:3px}
/* 26 Aug 2026: 18px above the version line, on top of the (then) 82px of body
   padding below it, is what made the very bottom of the screen read as loose.
   It is a quiet footnote - it needs separating from the content above it, not
   an empty band around it. */
.ver{text-align:center;color:var(--text-3);font-size:12.65px;font-family:var(--mono);margin:12px 0 2px}

/* ===== v2.0: weekly home ===== */
.wk-title{font-size:27.6px;font-weight:780;letter-spacing:-.02em;margin-top:6px;line-height:1.1}
.wk-sub{font-size:14.95px;color:var(--text-3);margin-top:5px}
.wk-nav{display:flex;gap:8px;margin-top:14px}
.wk-btn{flex:1;padding:9px;border-radius:10px;font-size:14.37px;font-weight:650;background:var(--surface);border:1px solid var(--hairline);color:var(--text-2);cursor:pointer}
.wk-btn.cur{background:var(--blue-dim);border-color:rgba(46,91,255,.3);color:var(--blue-soft)}
.wk-btn:disabled{opacity:.4;cursor:not-allowed}
.daylist{display:flex;flex-direction:column;gap:9px}
.daycard{display:flex;align-items:stretch;gap:13px;text-align:left;background:var(--surface);border:1px solid var(--hairline);border-radius:15px;padding:13px 14px;cursor:pointer;transition:border-color .16s,transform .12s;width:100%}
.daycard:active{transform:scale(.995)}
.daycard.today{border-color:var(--blue);box-shadow:inset 0 0 0 1px var(--blue)}
.daycard.done{background:linear-gradient(90deg,var(--green-dim),var(--surface) 60%)}
.daycard.prog{background:linear-gradient(90deg,var(--blue-dim),var(--surface) 60%)}
.dc-l{display:flex;flex-direction:column;align-items:center;justify-content:center;width:42px;flex:none;border-right:1px solid var(--hairline);padding-right:12px}
.dc-dow{font-family:var(--mono);font-size:11.5px;font-weight:700;color:var(--text-3);text-transform:uppercase}
.dc-date{font-size:21.85px;font-weight:750;letter-spacing:-.02em}
.daycard.today .dc-date{color:var(--blue)}
.dc-m{flex:1;min-width:0}
.dc-t{font-size:16.67px;font-weight:700;letter-spacing:-.01em;line-height:1.2}
.dc-s{display:flex;align-items:center;gap:8px;margin-top:7px}
.dc-pill{font-family:var(--mono);font-size:11.5px;font-weight:700;letter-spacing:.03em;padding:3px 8px;border-radius:100px;background:var(--surface-2);color:var(--text-2);text-transform:uppercase}
.dc-dur{font-family:var(--mono);font-size:12.65px;color:var(--text-3)}
.dc-cat{display:flex;align-items:center;font-size:23px;flex:none;opacity:.85}
/* day-info overlay */
#dayInfo .di-inner{text-align:center}
.di-emoji{font-size:50.6px;margin-bottom:8px}
.di-day{font-family:var(--mono);font-size:13.8px;color:var(--text-3);text-transform:uppercase;letter-spacing:.05em}
#dayInfo h2{font-size:26.45px;font-weight:750;letter-spacing:-.02em;margin:4px 0 12px}
#dayInfo p{color:var(--text-2);font-size:17.25px;line-height:1.5;margin-bottom:8px}
#dayInfo .di-focus{color:var(--text-3);font-size:15.52px}
#dayInfo .big-btn{margin-top:18px}

/* ===== v2.1: account / cloud bar ===== */
.acct{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px;background:var(--surface);border:1px solid var(--hairline);border-radius:14px;padding:11px 13px;margin-bottom:16px}
.acct-l{display:flex;align-items:center;gap:10px;min-width:0;flex:1 1 auto}
.acct-t{font-size:15.52px;font-weight:700;letter-spacing:-.01em}
.acct-em{font-size:13.22px;color:var(--text-3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:46vw}
.acct-dot{width:9px;height:9px;border-radius:50%;background:var(--green);flex:none;box-shadow:0 0 0 3px var(--green-dim)}
.acct-dot.off{background:var(--text-3);box-shadow:none}
.acct-btn{flex:none;border:1px solid var(--hairline-str);background:var(--surface-2);color:var(--text-2);font-size:14.37px;font-weight:650;padding:8px 13px;border-radius:10px;cursor:pointer;transition:all .16s;white-space:nowrap}
.acct-btn:active{transform:scale(.97)}
.acct-btn.g{background:#fff;color:#3c4043;border-color:var(--hairline-str);font-weight:600}
.acct.signin{background:linear-gradient(155deg,#fff,#eef2fb);border-color:var(--hairline-str)}
.acct.off{justify-content:flex-start;font-size:14.37px;color:var(--text-3)}
@media(max-width:480px){
  .acct.signin{flex-direction:column;align-items:stretch;text-align:center;gap:12px}
  .acct.signin .acct-l{justify-content:center}
  .acct.signin .acct-btn.g{width:100%;justify-content:center;padding:12px}
  .acct-em{max-width:60vw}
}

/* ===== v2.1.3: history delete + delights ===== */
.hr-re{font-size:12.07px;color:var(--blue-soft);margin-top:3px;font-weight:650;opacity:.85}
/* SESSION SUMMARY - a finished session opens as its own record, never as a
   fresh workout. Built entirely from the history record, so it works for any
   week, including weeks the plan has long since moved past. */
.ssum{text-align:start}
.ssum-head{text-align:center;margin-bottom:14px}
.ssum-emoji{font-size:40px}
.ssum-date{font-size:12.65px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-3);margin-top:8px}
.ssum-head h2{margin:6px 0 0;font-size:24.15px;letter-spacing:-.02em}
.ssum-stats{display:flex;margin:16px 0 4px}
.ssum-note{margin-top:12px;padding:12px 14px;border-radius:14px;background:var(--surface-2);font-size:14px;line-height:1.45}
.ssum-pain{color:#b4562f;font-weight:700;margin-top:12px;font-size:13.5px}
.ssum-plabel{margin-top:14px;font-size:12.07px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}
.ssum-pareto{background:var(--surface,#fff);border:1px solid var(--hairline);border-radius:16px;padding:2px 16px;margin-top:8px}
.ssum-pline{padding:10px 0;border-top:1px solid var(--hairline);font-size:14.5px;line-height:1.4}
.ssum-pline:first-child{border-top:0}
/* Quiet, but present. A session left short is not an error - it is a session
   with something still in it. */
.hr-resume{flex:none;margin-inline-start:8px;height:32px;padding:0 12px;border-radius:9px;
  border:1px solid var(--blue);background:var(--blue-dim);color:var(--blue-soft);
  font-family:inherit;font-size:13.8px;font-weight:750;cursor:pointer;white-space:nowrap;
  transition:transform .12s ease}
.hr-resume:active{transform:scale(.95)}
/* Reads as an action rather than a utility: it is the one thing on this screen
   that produces something new, so it carries colour while Copy stays a ghost. */
.dl-btn.coach-read{background:var(--blue-dim);border:1px solid var(--blue);
  color:var(--blue-soft);font-weight:750}
.dl-btn.coach-read:disabled{opacity:.55}
.dl-btn.coach-read[data-busy]{opacity:.6}
.hr-del{flex:none;margin-inline-start:8px;min-width:38px;height:38px;border-radius:10px;border:1px solid var(--hairline);background:var(--surface-2);font-size:17.25px;line-height:1;cursor:pointer;color:var(--text-3);transition:all .16s}
.hr-del:active{transform:scale(.94)}
.hr-del.armed{background:#d64545;border-color:#d64545;color:#fff;font-size:13.8px;font-weight:700;padding:0 12px}
@keyframes cardIn{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
.daylist .daycard{animation:cardIn .32s var(--ease-out) both}
.daylist .daycard:nth-child(1){animation-delay:.02s}
.daylist .daycard:nth-child(2){animation-delay:.05s}
.daylist .daycard:nth-child(3){animation-delay:.08s}
.daylist .daycard:nth-child(4){animation-delay:.11s}
.daylist .daycard:nth-child(5){animation-delay:.14s}
.daylist .daycard:nth-child(6){animation-delay:.17s}
.daylist .daycard:nth-child(7){animation-delay:.20s}
.hero{animation:cardIn .34s var(--ease-out) both}
@media(prefers-reduced-motion:reduce){ .daylist .daycard,.hero{animation:none} }
.tab{transition:color .18s, transform .1s}
.tab:active{transform:scale(.9)}

/* ===== v2.2: saving transition overlay ===== */
.saving-ov{position:fixed;inset:0;z-index:210;display:flex;align-items:center;justify-content:center;
  background:rgba(241,244,250,.72);backdrop-filter:blur(6px);opacity:0;visibility:hidden;transition:opacity .25s var(--ease),visibility .25s}
.saving-ov.show{opacity:1;visibility:visible}
.saving-card{display:flex;flex-direction:column;align-items:center;gap:16px;background:var(--surface);border:1px solid var(--hairline-str);
  border-radius:22px;padding:30px 40px;box-shadow:0 24px 60px -18px rgba(20,30,60,.5)}
.saving-spin{width:40px;height:40px;border-radius:50%;border:4px solid var(--blue-dim);border-top-color:var(--blue);animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.saving-txt{font-size:17.25px;font-weight:650;color:var(--text-2)}

/* ===== v2.3: AI coach chat ===== */
#viewCoach{overflow-x:hidden;max-width:100%}
/* THE COACH VIEW - 4 Sep 2026. Height is 100svh (the SMALL viewport: the
   screen minus the keyboard, computed by the browser and always correct), so
   the keyboard never pans a fixed element off the top. Header and composer are
   flex head and foot; #coachMsgs is the only flex-1 child, so it is the one
   thing that shrinks when the keyboard opens. The tab-bar strip is subtracted
   only when the keyboard is down; when it is up the bar is translated away and
   the view takes the full small-viewport height. No JS touches these numbers. */
#viewCoach.on{position:fixed;top:0;left:0;right:0;bottom:0;
  height:calc(100svh - var(--bar-h,42px));
  display:flex;flex-direction:column;overflow:hidden;background:var(--bg);z-index:5}
@supports not (height:100svh){ #viewCoach.on{height:calc(100vh - var(--bar-h,42px))} }
.coach-hdr{flex:none;display:flex;align-items:center;gap:13px;padding:calc(env(safe-area-inset-top,0px) + 12px) 16px 12px 16px;border-bottom:1px solid var(--hairline);background:var(--surface)}
.coach-back{flex:none;width:32px;height:32px;margin-inline-start:-6px;border:0;background:none;
  padding:0;cursor:pointer;color:var(--text-2);display:grid;place-items:center;border-radius:50%;
  transition:background .14s ease,transform .12s ease}
.coach-back svg{width:22px;height:22px}
.coach-back:active{transform:scale(.9);background:var(--surface-2)}
.coach-hdr-ava{width:40px;height:40px;border-radius:50%;background:linear-gradient(145deg,var(--blue),var(--green));display:grid;place-items:center;font-size:23px;flex:none;box-shadow:0 3px 10px -3px var(--blue)}
.coach-hdr-meta{flex:1;min-width:0}
.coach-hdr-name{font-size:18.4px;font-weight:750;color:var(--text);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.coach-hdr-sub{font-size:13.22px;color:var(--green-soft);font-weight:600;margin-top:2px;display:flex;align-items:center;gap:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.coach-hdr-sub::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--green);flex:none}
.coach-hdr-clear{flex:none;background:none;border:none;cursor:pointer;color:var(--text-3);padding:8px;border-radius:50%;display:grid;place-items:center}
.coach-hdr-clear svg{width:19px;height:19px}
.coach-hdr-clear:active{background:var(--surface-2)}
.coach-msgs{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;
  /* THE CHAT FROZE AT THE BOTTOM - 25 Aug 2026, his report.
     Drag to the end of the thread and the screen would not come back up for a
     few seconds. Nothing in the JS was holding it: with no overscroll-behavior
     here, hitting the bottom CHAINS the gesture to the page, iOS rubber-bands
     the document, and the touch stays with that outer scroller until the bounce
     settles - which is the pause he felt, and why it always happened at the
     very bottom and nowhere else.
     .wc-msgs, the workout chat, has had `contain` since it was written. This
     one never got it. */
  overscroll-behavior:contain;overscroll-behavior-y:contain;
  display:flex;flex-direction:column;gap:10px;padding:14px 14px 10px;width:100%;box-sizing:border-box}
.cb{display:flex;gap:8px;max-width:85%;min-width:0}
.cb.me .cb-b{background:linear-gradient(135deg,#3b6df6 0%,#2b4fe0 55%,#4f46e5 100%);
  color:#fff;box-shadow:0 6px 18px rgba(43,79,224,.25)}
.cb.me .cb-b{overflow-wrap:break-word;word-break:normal;white-space:pre-wrap}
/* 10 Aug 2026. A resting card is coach, topic, why, and one row: play, bar, time,
   Read. Skipping fifteen seconds is meaningless before it starts, and the speed
   chip and Save are things he touches while listening - so they appear when the
   card is live and stay out of the way when it is not. */
.ln:not(.on) .ln-skip{display:none}
.ln-skip{width:30px;height:30px;border-radius:50%;border:1px solid var(--hairline);
  background:var(--surface);color:var(--text-2);font-size:17.25px;line-height:1;cursor:pointer;
  flex:none;display:inline-flex;align-items:center;justify-content:center;gap:1px}
.ln-skip small{font-size:9.77px;font-weight:800}
.cb.me{align-self:flex-end;flex-direction:row-reverse}
.cb.coach{align-self:flex-start}
.cb-col{display:flex;flex-direction:column;min-width:0}
.cb.me .cb-col{align-items:flex-end}
.cb-time{font-size:11.5px;color:var(--text-3);margin:3px 6px 0;opacity:.75}
/* Shaped after a messaging app rather than a document.

   The single biggest change is width. A bubble that stretches to the edge no
   matter how short its contents reads as a paragraph; one that shrinks to its
   text reads as something somebody said. Everything else here is rhythm. */
.coach-msgs{gap:2px !important;align-items:flex-start}
.coach-intro{align-self:stretch;width:100%}
.cb{max-width:78% !important;align-self:flex-start}
.cb.me{align-self:flex-end}
.cb-txt{border-radius:15px 15px 15px 4px;padding:7px 11px 6px}
.cb.me .cb-txt{border-radius:15px 15px 4px 15px}

/* Runs of messages from the same speaker close up, and the gap goes between
   the runs instead - which is what makes a conversation look like turns.
   Only the last of a run keeps its corner notch and its time. */
.cb.grp{margin-top:0}
.cb:not(.grp){margin-top:11px}
.cb.grp .cb-txt{border-radius:15px 15px 15px 15px}
.cb.grp.me .cb-txt{border-radius:15px 15px 15px 15px}
.cb.midrun .cb-time{display:none}
.cb-time{margin:1px 8px 0 !important;font-size:12.07px}

/* A message that is only emoji is not really text, and rendering it at body
   size makes it look like a typo. */
.cb-txt.emo{background:transparent;border:0;font-size:39.1px;line-height:1.15;padding:2px 6px}

.cb-ava{width:30px;height:30px;border-radius:50%;background:var(--blue-dim);display:grid;place-items:center;font-size:17.25px;flex:none}
.cb-txt{font-size:15.53px;line-height:1.55;max-width:100%;padding:11px 14px;border-radius:16px;background:var(--surface);border:1px solid var(--hairline);color:var(--text);min-width:0;overflow-wrap:break-word;word-break:normal;white-space:normal}
/* 29 Aug 2026. This rule used to end with direction:rtl;text-align:right, and a
   CSS declaration beats the dir attribute on the element - so every English
   message was forced RTL and the pasted lesson arrived with its full stops on
   the wrong side of each line.
   The declarations are DELETED rather than set to unset: direction and
   text-align are both inherited properties, so unset resolves to inherit - the
   parent's direction - which is not the same as letting dir="auto" decide, and
   it flipped his Hebrew to LTR when I tried it. With nothing declared, the
   browser's own [dir=auto] handling applies: first strong character wins, and
   text-align defaults to start, which follows whatever direction that gave. */
.cb-txt code{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word}
.cb-txt pre{white-space:pre-wrap;overflow-x:auto;max-width:100%}
.cb.me .cb-txt{background:var(--blue);border-color:var(--blue);color:#fff;border-bottom-right-radius:5px}
.cb.coach .cb-txt{border-bottom-left-radius:5px}
.cb-txt b{font-weight:750}
/* Structure inside a reply. The coach writes headings and lists; without these it
   renders as one dense slab, which is what he was looking at. */
.cb-txt h4{font-size:16.1px;font-weight:800;letter-spacing:-.01em;line-height:1.6;
  opacity:.95}
/* 10 Aug 2026: the bullet is gone. With a bold lead-in on almost every line it
   made each row read as a line and a half, and he asked for it removed entirely.
   The spacing between rows carries the structure on its own. */
.mdli{margin:0;line-height:1.6}
/* One empty line, the same height as a line of text - so a paragraph break looks
   like a paragraph break and nothing looks like half of one. */
.mdgap{height:1.6em}
.cb-txt h4{margin:0}
.cb-txt h4+.mdli,.cb-txt .mdli+h4{margin-top:0}
.cb-txt i{font-style:italic}
.cb-txt code{font-family:var(--mono);font-size:.9em;background:rgba(0,0,0,.06);padding:1px 5px;border-radius:5px}
.cb.me .cb-txt code{background:rgba(255,255,255,.2)}
.cb-txt.typing{display:flex;gap:4px;align-items:center;padding:14px}
.cb-txt.typing span{width:7px;height:7px;border-radius:50%;background:var(--text-3);animation:blink 1.2s infinite both}
.cb-txt.typing span:nth-child(2){animation-delay:.2s}.cb-txt.typing span:nth-child(3){animation-delay:.4s}
@keyframes blink{0%,80%,100%{opacity:.25}40%{opacity:1}}
.coach-bar{flex:none;background:var(--surface);border-top:1px solid var(--hairline);padding:9px 12px 8px;box-sizing:border-box;width:100%}
.plan-proposals{flex:none;width:100%;max-height:42vh;overflow:auto;padding:0 12px 10px;background:var(--surface);box-sizing:border-box}
.plan-proposals:empty{display:none}
.pp-card.pp-done{border-color:rgba(47,185,114,.42);background:rgba(47,185,114,.10)}
.pp-card.pp-failed{border-color:rgba(226,74,74,.45);background:rgba(226,74,74,.09)}
.pp-badge.pp-bad{color:var(--red,#e24a4a)}
.pp-card.pp-failed .pp-reason{margin-top:6px;font-weight:650;color:var(--red,#e24a4a)}
.pp-card.pp-rejected{border-color:rgba(120,120,130,.35);background:rgba(120,120,130,.08);opacity:.85}
/* A new proposal arriving in a panel he is not looking at is a change he
   cannot consent to. One short pulse when the top card changes. */
.pp-card.pp-new{animation:ppNew 2.4s ease}
@keyframes ppNew{
  0%{box-shadow:0 0 0 0 rgba(56,102,255,.55);transform:translateY(-3px)}
  55%{box-shadow:0 0 0 9px rgba(56,102,255,0)}
  100%{box-shadow:0 0 0 0 rgba(56,102,255,0);transform:none}}
@media (prefers-reduced-motion:reduce){ .pp-card.pp-new{animation:none;border-color:rgba(56,102,255,.7)} }
.pp-card.pp-rejected .pp-badge{color:var(--text-3)}
.pp-card{overflow:hidden;transition:opacity .55s ease,transform .55s ease,max-height .6s ease,margin .6s ease,padding .6s ease}
.pp-card.pp-bye{opacity:0;transform:translateY(-6px) scale(.98);max-height:0 !important;margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;border-width:0}
.pp-badge.pp-ok{color:var(--green,#2fb972)}
.pp-card.pp-done ul{margin:8px 0 0;padding-inline-start:18px;font-size:12.65px;line-height:1.5;color:var(--text-2)}
.pp-parts{margin-top:8px;font-size:12.65px;color:var(--text-2)}
.pp-parts>summary{cursor:pointer;font-weight:650;color:var(--blue);list-style:none}
.pp-parts>summary::-webkit-details-marker{display:none}
.pp-parts ul{margin:7px 0 0;padding-inline-start:18px;line-height:1.5}
.pp-parts li{margin-bottom:3px}
.pp-card{max-width:840px;margin:0 auto 8px;border:1px solid rgba(56,102,255,.28);background:var(--blue-dim);
  border-radius:15px;padding:13px 14px;direction:rtl;text-align:right}
.pp-top{display:flex;align-items:center;gap:8px}.pp-badge{font-size:11px;font-weight:850;letter-spacing:.08em;color:var(--blue);text-transform:uppercase}
.pp-date{margin-inline-start:auto;font-size:12px;color:var(--text-3);direction:ltr}.pp-title{font-size:16px;font-weight:800;line-height:1.4;margin-top:5px;color:var(--text)}
.pp-why{font-size:13px;line-height:1.5;color:var(--text-2);margin-top:4px}.pp-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:11px}
.pp-btn{border:0;border-radius:10px;padding:10px 12px;font-family:inherit;font-size:14px;line-height:1.2;font-weight:750;cursor:pointer}.pp-approve{background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff}
.pp-reject{background:var(--surface);color:var(--text-2);border:1px solid var(--hairline)}.pp-btn:disabled{opacity:.55;cursor:default}
.coach-input{width:100%;display:flex;gap:8px;align-items:flex-end;box-sizing:border-box}
/* max-height was 120px - about four lines. Past that the box stopped growing
   and what he had already typed scrolled out of sight, which reads as the text
   being cut off. 220px is roughly nine lines and still leaves the keyboard room. */
.coach-input textarea{flex:1;min-width:0;resize:none;border:1px solid var(--hairline-str);border-radius:18px;padding:11px 15px;font-size:18.4px;font-family:inherit;background:var(--surface);color:var(--text);max-height:220px;overflow-y:auto;line-height:1.4;box-sizing:border-box}
.coach-input textarea:focus{outline:none;border-color:var(--blue)}
.coach-input button{flex:none;width:44px;height:44px;border-radius:50%;background:var(--blue-grad);box-shadow:var(--blue-3d);color:#fff;border:none;display:grid;place-items:center;cursor:pointer;transition:transform .12s}
.coach-input button:active{transform:scale(.92)}
.coach-input button svg{width:20px;height:20px}
.coach-foot{width:100%;margin:6px 0 0;text-align:center;font-size:12.65px;color:var(--text-3)}
.coach-intro{text-align:center;padding:22px 12px 8px;color:var(--text-2)}
.ci-ava{width:52px;height:52px;border-radius:50%;background:var(--blue-dim);display:grid;place-items:center;font-size:29.9px;margin:0 auto 12px}
.ci-t{font-size:19.55px;font-weight:700;color:var(--text);letter-spacing:-.01em}
.ci-s{font-size:16.1px;line-height:1.5;margin:6px auto 16px;max-width:320px}
/* the badge that marks the first conversation as a goal-setting session */
/* the next session, one tap from opening the app */
.start-card{width:100%;display:flex;align-items:center;gap:14px;margin:0 0 4px;
  padding:14px 16px;border:0;border-radius:18px;cursor:pointer;text-align:start;
  font-family:inherit;color:#fff;
  background:linear-gradient(135deg,#1d2f6b,#3b6cff);
  box-shadow:0 10px 26px -12px rgba(59,108,255,.75)}
.start-card:active{transform:scale(.99)}
.start-card .sc-left{min-width:0;flex:1}
.start-card .sc-when{font-size:12.65px;letter-spacing:.1em;text-transform:uppercase;color:var(--gold-hi);opacity:1;font-weight:700}
.start-card .sc-t{font-size:18.4px;font-weight:750;line-height:1.3;margin-top:5px;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
/* Gold, per the ground rule above: the one control the home screen exists to
   offer. A translucent white pill on blue is a suggestion, not an invitation. */
.start-card .sc-go{flex:none;display:flex;align-items:center;gap:3px;
  background:var(--gold-grad);color:var(--gold-ink);box-shadow:var(--gold-3d);border-radius:999px;padding:9px 14px 9px 16px;
  font-size:15.52px;font-weight:800;white-space:nowrap}
.start-card:active .sc-go{box-shadow:var(--gold-3d-press)}
.start-card .sc-go svg{width:15px;height:15px}
/* ============================================================
   MOVEMENT
   Views appeared and disappeared with display:none, which is a cut, not a
   transition - the screen simply becomes a different screen and the eye has to
   find its place again. A short fade with a few pixels of travel is enough to
   say "this replaced that" rather than "everything just changed".

   Durations are deliberately short. Anything past about 220ms stops reading as
   responsiveness and starts reading as waiting, and this is an app used between
   sets. Everything here also stands down for anyone who has asked their system
   to reduce motion.
   ============================================================ */
.view.on{ animation: viewIn .22s cubic-bezier(.22,.9,.3,1) both }
@keyframes viewIn{
  from{ opacity:0; transform:translate3d(0,8px,0) }
  to  { opacity:1; transform:none }
}
/* A view that owns, or can contain, fixed-position children must never be
   transformed: a transform makes it their containing block, and they collapse
   into whatever box it happens to be. Both of these have been caught doing it -
   the session screen with the coach button, the home screen with the sign-in
   page - so both fade and neither moves. */
#viewTraining.on, #viewHome.on{ animation: viewFade .22s ease both }
@keyframes viewFade{ from{opacity:0} to{opacity:1} }
/* Same rule for the dashboard: the stagger is for the first paint, not for
   every refresh behind it. */
.sc-grid[data-anim="1"] > *{ animation: cardIn .26s cubic-bezier(.22,.9,.3,1) both }
.sc-grid[data-anim="1"] > *:nth-child(1){ animation-delay:.02s }
.sc-grid[data-anim="1"] > *:nth-child(2){ animation-delay:.05s }
.sc-grid[data-anim="1"] > *:nth-child(3){ animation-delay:.08s }
.sc-grid[data-anim="1"] > *:nth-child(4){ animation-delay:.11s }
.sc-grid[data-anim="1"] > *:nth-child(5){ animation-delay:.14s }
.start-card[data-anim="1"]{ animation: cardIn .28s cubic-bezier(.22,.9,.3,1) .16s both }
.wp[data-anim="1"]{ animation: cardIn .28s cubic-bezier(.22,.9,.3,1) .2s both }
@keyframes cardIn{
  from{ opacity:0; transform:translate3d(0,10px,0) scale(.985) }
  to  { opacity:1; transform:none }
}
/* the focus options, as they land */

/* A new message should arrive rather than appear - but only a NEW one. On the
   class itself the animation replayed for every bubble each time the view was
   rebuilt, and the view is rebuilt on load, again after the sync, and again
   when the profile lands. Three flashes of the whole conversation. */
.cb.fresh{ animation: bubbleIn .2s cubic-bezier(.22,.9,.3,1) both }
@keyframes bubbleIn{
  from{ opacity:0; transform:translate3d(0,6px,0) }
  to  { opacity:1; transform:none }
}

/* the panels already slide; give the scrim something to fade with */
.ch-back{ transition: opacity .2s ease }
.ch-panel{ transition: transform .26s cubic-bezier(.22,.9,.3,1) }

/* pressing a tab should feel like pressing something */
.tab{ transition: color .16s ease, transform .12s ease }
.tab:active{ transform: scale(.93) }
.tab.on svg{ animation: tabPop .26s cubic-bezier(.34,1.5,.5,1) both }
@keyframes tabPop{ 0%{transform:scale(.86)} 60%{transform:scale(1.08)} 100%{transform:none} }

/* a tick should confirm itself */
@keyframes tickPop{ 0%{transform:scale(.8)} 60%{transform:scale(1.1)} 100%{transform:none} }

/* the score meters fill rather than snap */
.sc-meter i{ transition: width .55s cubic-bezier(.22,.9,.3,1) }

@media (prefers-reduced-motion: reduce){
  .view.on, .sc-grid[data-anim="1"] > *, .start-card[data-anim="1"], .wp[data-anim="1"],
  .fx-opt, .cb.fresh, .tab.on svg, .fx-d.on{ animation:none !important }
  .sc-meter i, .ch-panel, .ch-back{ transition:none !important }
}

/* ============================================================
   COLOUR AS HIERARCHY
   Everything on the home screen was either bright blue or white, so the one
   thing to press looked the same as the thing to read. Colour now says what
   something is:
     saturated blue  - the single action
     deep navy       - the headline figure
     tinted panel    - a secondary action
     plain surface   - reference, read when you want it
   And each score keeps its own hue, so the dashboard is scannable without
   reading a word.
   ============================================================ */
:root{
  --dom-train: #3B6CFF;
  --dom-food:  #27A567;
  --dom-rest:  #7B61D9;
  --dom-mind:  #D9873A;
}
/* the headline: deep, authoritative, not competing with the button */
.sc-overall{background:linear-gradient(135deg,#101B36 0%,#1B2C58 100%) !important}
.sc-overall .sc-meter{background:rgba(255,255,255,.16)}
/* Gold, per the ground rule: on the darkest card on the home screen the meter
   IS the score. It was pale blue into white - the same family as the card it
   sits on, so it read as texture rather than as a reading. */
.sc-overall .sc-meter i{background:linear-gradient(90deg,var(--gold-hi),var(--gold-lo))}

/* each domain keeps its colour in the meter and the name */
.sc[data-dom]{border-inline-start:3px solid var(--dc,var(--hairline))}
.sc[data-dom] .sc-meter i{background:var(--dc)}
.sc[data-dom="training"] { --dc:var(--dom-train) }
.sc[data-dom="nutrition"]{ --dc:var(--dom-food)  }
.sc[data-dom="recovery"] { --dc:var(--dom-rest)  }
.sc[data-dom="mindset"]  { --dc:var(--dom-mind)  }
.sc.na[data-dom]{border-inline-start-color:var(--hairline)}
.sc.na[data-dom] .sc-meter i{background:rgba(120,140,180,.3)}

/* the one thing to press */
.start-card{box-shadow:0 12px 30px -12px rgba(59,108,255,.85)}

/* a secondary action reads as an invitation, not a headline */
.wp{background:linear-gradient(180deg, rgba(59,108,255,.07), rgba(59,108,255,.03));
  border-color:rgba(59,108,255,.24)}

/* reference material stays quiet */
.wkfold{background:transparent;border-color:var(--hairline)}
.wkfold[open]{background:var(--surface)}
/* ============================================================
   LIVE VOICE
   A full screen, because a spoken conversation is not something you do while
   looking at something else. Dark, so it reads as a different mode - and so
   the room can be dim and the phone can be on the floor.
   ============================================================ */
.vc{position:fixed;inset:0;z-index:600;display:none;flex-direction:column;
  padding:calc(env(safe-area-inset-top,0px) + 14px) 20px calc(env(safe-area-inset-bottom,0px) + 26px);
  background:
    radial-gradient(88% 52% at 50% 104%, rgba(76,125,255,.18) 0%, rgba(76,125,255,0) 62%),
    radial-gradient(70% 44% at 50% -6%, rgba(122,150,255,.13) 0%, rgba(122,150,255,0) 70%),
    linear-gradient(178deg,#0C1526 0%,#060A12 100%);
  background-color:#060A12;color:#EAF0FF;
  -webkit-tap-highlight-color:transparent}
.vc.show{display:flex}

/* Header sits quiet. The coach's name is the only thing that identifies the
   screen, and it should never compete with the ring. */
.vc-top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex:none}
.vc-who{display:flex;align-items:center;gap:9px;font-size:13.8px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(234,240,255,.42)}
.vc-e{font-size:19.55px;letter-spacing:0}
.vc-x{width:36px;height:36px;flex:none;border-radius:50%;border:1px solid rgba(234,240,255,.13);
  background:rgba(234,240,255,.05);color:rgba(234,240,255,.66);font-size:17.25px;line-height:1;
  cursor:pointer;display:grid;place-items:center;transition:background .16s,color .16s}
.vc-x:hover{background:rgba(234,240,255,.1);color:#EAF0FF}

/* Transcript. Bottom-anchored so the newest line is always where the eye
   already is, and masked at the top so older turns dissolve rather than
   colliding with the header. */
.vc-log{flex:1;width:100%;max-width:520px;margin:0 auto;overflow-y:auto;
  display:flex;flex-direction:column;justify-content:flex-end;gap:14px;
  padding:26px 2px 22px;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 52px,#000 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 52px,#000 100%)}
.vc-log::-webkit-scrollbar{display:none}
.vc-t{max-width:90%;animation:vcIn .3s cubic-bezier(.22,.9,.3,1) both}
/* His own words are context; the coach's line is the thing he must catch, so
   the size difference between them is doing real work. */
.vc-t.me{align-self:flex-start;font-size:16.67px;line-height:1.55;
  color:rgba(234,240,255,.44);padding-inline-start:13px;
  border-inline-start:2px solid rgba(234,240,255,.16)}
.vc-note{align-self:center;max-width:94%;margin:0 auto;font-size:13.22px;line-height:1.5;
  letter-spacing:.05em;color:rgba(234,240,255,.42);text-align:center;
  font-variant-numeric:tabular-nums;background:rgba(234,240,255,.045);
  border:1px solid rgba(234,240,255,.08);border-radius:9px;padding:6px 10px;
  word-break:break-word;animation:vcIn .3s cubic-bezier(.22,.9,.3,1) both}
.vc-t.coach{align-self:stretch;font-size:23px;line-height:1.62;font-weight:500;
  color:#EAF0FF;letter-spacing:-.008em}

/* THE BREATH RING - the one thing this screen is remembered by.
   Mental performance coaching is largely breath and attention, so the control
   is not a button that reports a state, it is a ring that breathes with him:
   it swells on his voice while he talks, contracts to a turning arc while the
   coach thinks, and takes long slow breaths while the coach speaks. */
.vc-stage{flex:none;display:flex;flex-direction:column;align-items:center;gap:18px}
.vc-ring{--lvl:0;width:190px;height:190px;padding:0;border:0;background:none;
  cursor:pointer;display:block;position:relative}
.vc-ring svg{width:100%;height:100%;display:block;overflow:visible}
.vc-ring circle{fill:none;transform-box:fill-box;transform-origin:center}

.vc-halo{stroke:#4C7DFF;stroke-width:calc(1px + 30px * var(--lvl));
  opacity:calc(.07 + .34 * var(--lvl));transition:stroke-width .07s linear,opacity .07s linear}
.vc-track{stroke:rgba(234,240,255,.10);stroke-width:1.5}
.vc-arc{stroke:#4C7DFF;stroke-width:2.5;stroke-linecap:round;
  stroke-dasharray:1 999;opacity:0;transition:opacity .2s}
.vc-core{fill:rgba(76,125,255,.10);stroke:rgba(76,125,255,.34);stroke-width:1;
  transform:scale(calc(1 + .22 * var(--lvl)));transition:transform .07s linear}
.vc-dot{fill:#4C7DFF;opacity:.9}

.vc-ring.open .vc-core{fill:rgba(76,125,255,.10)}
.vc-ring.hear .vc-halo{stroke:#7AA2FF}
.vc-ring.hear .vc-core{fill:rgba(122,162,255,.20);stroke:rgba(122,162,255,.55)}

.vc-ring.think .vc-arc{opacity:1;stroke-dasharray:52 400;animation:vcSpin 1.15s linear infinite}
.vc-ring.think .vc-core{fill:rgba(234,240,255,.05);stroke:rgba(234,240,255,.16);transform:scale(.9)}
.vc-ring.think .vc-dot{opacity:0}

.vc-ring.talk .vc-halo{stroke:#42D6A0;stroke-width:14px;opacity:.2;animation:vcBreathe 2.6s ease-in-out infinite}
.vc-ring.talk .vc-core{fill:rgba(66,214,160,.16);stroke:rgba(66,214,160,.5);animation:vcBreathe 2.6s ease-in-out infinite}
.vc-ring.talk .vc-dot{fill:#42D6A0}

.vc-ring.idle .vc-core{fill:rgba(234,240,255,.04);stroke:rgba(234,240,255,.14)}
.vc-ring.idle .vc-dot{fill:rgba(234,240,255,.3)}

/* Status is set like an instrument label, not chat copy: small, tracked, and
   in one fixed place so its meaning is read from the word, never the position. */
.vc-state{font-size:13.22px;font-weight:700;letter-spacing:.19em;text-transform:uppercase;
  color:rgba(234,240,255,.4);min-height:16px;text-align:center;
  transition:color .2s}
.vc-ring.hear ~ .vc-state,.vc-state.hot{color:rgba(122,162,255,.9)}
.vc-hint{font-size:13.8px;color:rgba(234,240,255,.26);text-align:center;min-height:15px;
  letter-spacing:.01em}

@keyframes vcIn{from{opacity:0;transform:translate3d(0,10px,0)}to{opacity:1;transform:none}}
@keyframes vcSpin{to{transform:rotate(360deg)}}
@keyframes vcBreathe{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}

@media (prefers-reduced-motion:reduce){
  .vc-t{animation:none}
  .vc-ring.talk .vc-halo,.vc-ring.talk .vc-core,.vc-ring.think .vc-arc{animation:none}
  .vc-halo,.vc-core{transition:none}
}
}
/* what the coaches know */
.km-add{background:var(--surface);border:1px solid var(--hairline);border-radius:15px;
  padding:13px 14px;margin-bottom:14px}
.km-t{font-size:15.52px;font-weight:700;margin-bottom:8px}
.km-add textarea{width:100%;box-sizing:border-box;border:1px solid var(--hairline);border-radius:11px;
  padding:10px 12px;font-family:inherit;font-size:16.1px;background:var(--bg);color:var(--text);
  resize:none;line-height:1.5}
.km-row{display:flex;gap:8px;margin-top:9px}
/* 16px minimum on a form control or Safari zooms the entire page on focus and
   does not zoom back out - the app appears to break the moment it is touched. */
.km-row select{flex:1;border:1px solid var(--hairline);border-radius:11px;padding:9px 11px;
  font-family:inherit;font-size:14.95px;background:var(--bg);color:var(--text)}
.km-save{flex:none;border:0;border-radius:11px;padding:9px 20px;cursor:pointer;
  font-family:inherit;font-size:15.52px;font-weight:700;background:var(--blue);color:#fff}
.km-save:disabled{opacity:.6}
.km-i{background:var(--bg);border:1px solid var(--hairline);border-radius:13px;
  padding:11px 13px;margin-bottom:8px}
.km-i.mine{border-inline-start:3px solid var(--blue)}
.km-b{font-size:15.52px;line-height:1.6}
.km-m{display:flex;align-items:center;gap:7px;margin-top:8px;flex-wrap:wrap}
.km-s,.km-src,.km-h,.km-you{font-size:12.07px;font-weight:700;border-radius:999px;padding:3px 9px;
  background:rgba(120,140,180,.12);color:var(--text-2)}
.km-you{background:var(--blue-dim,rgba(59,108,255,.14));color:var(--blue)}
.km-x{margin-inline-start:auto;width:26px;height:26px;border-radius:50%;border:1px solid var(--hairline);
  background:transparent;color:var(--text-2);cursor:pointer;font-size:17.25px;line-height:1;
  display:grid;place-items:center;transition:all .16s}
.km-x.armed{background:rgba(220,80,80,.14);border-color:rgba(220,80,80,.45);color:#c2453f}
/* movement history */
.mv-g{margin-bottom:18px}
.mv-h{font-size:17.82px;font-weight:750;display:flex;align-items:baseline;gap:8px}
.mv-kg{font-size:13.8px;font-weight:650;color:var(--text-2)}
.mv-span{font-size:13.22px;color:var(--text-2);margin-top:3px}
.mv-e{background:var(--bg);border:1px solid var(--hairline);border-radius:13px;padding:11px 13px;margin-top:8px}
.mv-d{font-size:12.65px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);font-weight:700}
.mv-v{font-size:15.52px;line-height:1.6;margin-top:5px}
.mv-f{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.mv-tag{font-size:12.65px;font-weight:650;border-radius:999px;padding:3px 9px}
.mv-tag.bad{background:rgba(217,83,79,.12);color:#c2453f}
.mv-tag.good{background:rgba(47,185,114,.14);color:#1f8b53}
/* the week's focus, on the home screen */
.fs{margin:12px 0 4px;display:flex;flex-direction:column;gap:8px}
.fs-d.on{background:var(--blue);border-color:var(--blue)}
.fs-d.fut{opacity:.3;cursor:default}
.fs-d.now:not(.on){border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-dim,rgba(59,108,255,.14))}
/* Saturday planning prompt */
.wp{background:var(--surface);border:1px solid rgba(59,108,255,.30);border-radius:18px;
  padding:15px 16px 14px;margin:14px 0 4px;
  box-shadow:0 6px 20px -14px rgba(40,70,160,.5)}
/* the week, folded */
.wkfold{margin:20px 0 6px;border:1px solid var(--hairline);border-radius:16px;
  background:var(--surface);overflow:hidden}
.wkfold-s{display:flex;align-items:center;gap:12px;padding:14px 15px;cursor:pointer;
  list-style:none;-webkit-tap-highlight-color:transparent}
.wkfold-s::-webkit-details-marker{display:none}
.wkfold-l{min-width:0;flex:1}
.wkfold .wk-title-sm{font-size:16.67px;font-weight:750;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wkfold .wk-sub{font-size:13.22px;color:var(--text-2);margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wkfold-n{flex:none;font-size:14.95px;font-weight:750;color:var(--text-2);
  font-variant-numeric:tabular-nums;background:var(--bg);border-radius:999px;padding:4px 11px}
.wkfold-c{flex:none;width:18px;height:18px;color:var(--text-2);transition:transform .2s}
.wkfold[open] .wkfold-c{transform:rotate(180deg)}
.wkfold[open] .wkfold-s{border-bottom:1px solid var(--hairline)}
.wkfold .wk-nav{display:flex;gap:6px;padding:12px 12px 0}
.wkfold .wk-btn{flex:1;padding:7px 12px;font-size:14.37px;white-space:nowrap}
.wkfold .daylist{padding:12px}
/* the weekly focus */
/* the target in the header, with a dot when the week has no focus yet */
/* two lines is enough for an instruction; past that it stops being a button */
.ch-line{display:flex;align-items:stretch;gap:6px;margin-bottom:6px}
.ch-line .ch-row{flex:1;margin-bottom:0;min-width:0;display:flex;align-items:center}
.ch-txt{min-width:0;flex:1;overflow:hidden}
.ch-txt .ch-d{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ch-txt .ch-s{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px}
.ch-del{flex:none;width:44px;border:1px solid var(--hairline);border-radius:13px;background:var(--bg);
  color:var(--text-2);cursor:pointer;display:grid;place-items:center;transition:all .16s}
.ch-del svg{width:17px;height:17px}
.ch-del.armed{background:rgba(220,80,80,.14);border-color:rgba(220,80,80,.45);color:#c2453f}
.ch-del.armed::after{content:'?';position:absolute;margin-top:-30px;font-size:12.65px;font-weight:800}
.ci-badge{display:inline-block;background:var(--blue);color:#fff;border-radius:999px;padding:5px 13px;font-size:13.22px;font-weight:700;letter-spacing:.02em;margin-bottom:10px}
.ci-chips{display:flex;flex-direction:column;gap:8px;max-width:320px;margin:0 auto}
/* The three opening questions are an INVITATION - the one thing on an empty
   coach screen asking to be touched - so they carry the gold, and the composer's
   send button keeps the navy. Raised on the same construction as the navy keys,
   with a warmer top highlight because gold takes more light before it reads. */
.ci-chip{font-size:16.1px;font-weight:750;color:var(--gold-ink);
  background:var(--gold-grad);border:1px solid rgba(214,145,16,.55);
  border-radius:12px;padding:11px 14px;cursor:pointer;
  box-shadow:var(--gold-3d);
  transition:box-shadow .16s ease,transform .16s ease}
.ci-chip:active{transform:translateY(1px);box-shadow:var(--gold-3d-press)}
@media (prefers-reduced-motion:reduce){ .ci-chip:active{transform:none} }
/* ===== DESKTOP =====
   The column is a real element now, and everything pinned to the window is
   positioned from its measured edges rather than from a guess. */
#appShell{ width:100% }
@media(min-width:900px){
  /* 840 left a third of a laptop screen empty on either side, which read as
     unfinished rather than as a reading column. The column now grows with the
     window in steps, so a 14-inch laptop feels filled and a large monitor still
     keeps a comfortable line length. */
  :root{ --shell:900px; --col:780px; }
  body{ background:
    radial-gradient(1100px 560px at 50% -220px, rgba(59,108,255,.055), transparent 62%),
    var(--bg); }

  #appShell{
    max-width:var(--shell); margin-inline:auto; position:relative;
    background:var(--surface);
    border-inline:1px solid var(--hairline);
    box-shadow:0 0 60px rgba(16,28,54,.07);
    min-height:100vh; }

  #viewHome, #viewHistory, #viewTraining{ padding-inline:14px; }
  .home-wrap, .header-inner{ max-width:100% !important; }

  /* the coach view is pinned to the window, so pin it to the column instead */
  #viewCoach.on{
    left:var(--shell-left) !important;
    right:var(--shell-right) !important; }
  /* Header, chips, messages and composer were each landing on a different
     width, which is what made the screen read as floating fragments rather
     than one conversation. One column, one width, all four. */
  /* The chat uses the whole column. Centring the contents inside a narrower
     reading width left visible margins on both sides that read as unfinished -
     a conversation is not an article, and the bubbles already control line
     length by themselves. */
  .coach-hdr, .coach-switch, .coach-foot{
    max-width:none !important; width:100% !important; margin-inline:0 !important; }
  .coach-msgs{ max-width:none !important; width:100% !important;
    padding-inline:22px !important; }
  .coach-input{ max-width:none !important; padding-inline:18px !important; }
  /* 9 Aug 2026. THIS is what broke every short message into two lines.
     The bubble is already shrink-wrapped to its text, so capping the text at
     88% OF THAT took 12% off whatever it needed - two Hebrew letters got a
     19px content box and wrapped after one. Invisible on a long message (the
     wrap point just moves), glaring on a short one - exactly the symptom.
     Line length on a wide screen is a job for an absolute cap; .cb already
     limits the bubble to 78% of the column. */
  .cb .cb-txt{ max-width:720px; }

  /* every pinned element follows the measured column */
  .tabbar{
    left:var(--shell-left) !important; right:var(--shell-right) !important;
    border-inline:1px solid var(--hairline); }
  /* 13 Sep 2026 - THE COMPOSER SLID OFF THE COLUMN ON DESKTOP, and the cause is
     two correct changes meeting.
     This rule is from when the composer was pinned to the window: it pushed the
     row in from the measured column edges. `.coach-input` is a STATIC element,
     so left/right did nothing at all, and when the composer stopped being
     pinned nobody noticed the rule was still here doing nothing.
     On 12 Sep the scroll-to-latest button needed an anchor, and `.coach-input`
     was given `position:relative` - which is when these two dead offsets woke
     up. A relatively-positioned box honours `left`, so on a 1375px window the
     whole row - plus button, text box and Send - shifted ~240px to the right
     and Send left the screen entirely. Phones were untouched: below 900px this
     block never applies, which is exactly what he reported.
     The offsets go. The anchor stays. */
  .coach-input{ left:auto !important; right:auto !important; }
  .stopwatch{ left:calc(var(--shell-left) + 18px) !important; }
  .wc-fab{   inset-inline-end:auto !important;
             right:calc(var(--shell-right) + 18px) !important; }
  .wc-panel{ inset-inline-end:auto !important;
             right:calc(var(--shell-right) + 18px) !important; }
}
@media(min-width:1300px){ :root{ --shell:1080px; --col:840px; } }
@media(min-width:1700px){ :root{ --shell:1200px; --col:900px; } }

/* PROFESSIONAL COACH CHAT — 19 Aug 2026.
   The visual grammar is deliberately familiar: a compact fixed chrome, short
   message bubbles that hug their contents, related coach thoughts grouped in a
   tight run, and the time inside the final bubble. Project 40 keeps its own
   colour, typography and artwork; only the conversation rhythm is borrowed. */
.coach-msgs{gap:0 !important;align-items:stretch;padding:10px 10px 8px !important;
  scroll-padding-block:12px}
.cb{width:auto;max-width:80% !important;gap:5px;align-items:flex-end;margin:0}
.cb.coach{align-self:flex-start;max-width:88% !important}
.cb.me{align-self:flex-end;max-width:78% !important;flex-direction:row-reverse}
.cb-col{gap:3px;max-width:100%;align-items:flex-start}
.cb.me .cb-col{align-items:flex-end}
.cb:not(.grp){margin-top:11px}
.cb.grp{margin-top:3px}
.cb-ava{width:24px;height:24px;font-size:14px;border:1px solid rgba(255,255,255,.82);
  box-shadow:0 2px 8px rgba(35,58,112,.15);margin-bottom:1px}
.cb.midrun .cb-ava{visibility:hidden}
.cb-txt,.cb-seg{box-sizing:border-box;width:auto;max-width:100%;min-width:46px;
  padding:7px 10px 6px !important;font-size:16px;line-height:1.46 !important;
  border-radius:16px 16px 16px 5px !important;box-shadow:0 2px 10px rgba(28,48,96,.08) !important}
.cb.me .cb-txt{border-radius:16px 16px 5px 16px !important}
.cb.coach .cb-seg:not(.seg-last),
.cb.coach.midrun .cb-seg.seg-last{border-bottom-left-radius:16px !important}
.cb.me.midrun .cb-seg.seg-last{border-bottom-right-radius:16px !important}
.cb-txt .mdli{line-height:1.46}
.cb-txt .mdgap{height:8px}
.cb-meta{float:left;display:inline-flex;align-items:center;gap:2px;margin:5px 0 -1px 9px;
  color:var(--text-3);font-size:10.8px;line-height:1;white-space:nowrap;opacity:.78}
.cb.me .cb-meta{color:rgba(255,255,255,.78)}
.cb-check{font-size:11px;font-weight:800}
.cb-clear{display:block;clear:both;height:0}
.cb-time-media{font-size:10.8px;margin:2px 6px 0;color:var(--text-3);opacity:.78}
.cb-time{font-size:10.8px}
.cb-txt.emo{min-width:0;padding:1px 4px !important;box-shadow:none !important}
.typing-row{margin-top:10px}
.typing-row .cb-txt{min-width:52px}
.coach-bar{padding:7px 8px 6px !important;border-top-color:rgba(126,145,182,.24)}
.coach-input{gap:7px;align-items:flex-end}
.coach-input textarea{min-height:42px;padding:8px 13px;font-size:16.5px;line-height:1.45;
  border-radius:20px;background:rgba(255,255,255,.92)}
.coach-input button,.coach-input button.coach-attach{width:42px;height:42px}
.coach-foot{display:none !important}
.coach-hdr{gap:10px;padding-bottom:9px}
.coach-switch{gap:6px;padding:6px 8px}
.cs-chip{flex:1;justify-content:center;padding:6px 8px;font-size:14px}
.cs-chip span{font-size:16px}

@media(max-width:380px){
  .coach-hdr{gap:7px;padding-inline:10px}
  .coach-hdr-clear{padding:6px}
  .coach-hdr-ava{width:37px;height:37px}
  .coach-hdr-name{font-size:17px}
  .coach-hdr-sub{font-size:12px}
  .cb.coach{max-width:91% !important}
  .cb.me{max-width:82% !important}
}

/* 2 Sep 2026 - the Polar card grew from three lines to everything the watch
   actually sent. A grid, because these are figures to scan, not to read. */
.wx-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;margin-top:10px}
.wx-stat{min-width:0;padding:9px 5px 8px;border:1px solid var(--hairline);border-radius:11px;background:var(--surface-2);text-align:center}
.wx-stat b{display:block;color:var(--text);font-family:var(--mono);font-size:15.5px;line-height:1.2;overflow-wrap:anywhere}
.wx-stat span{display:block;margin-top:3px;color:var(--text-3);font-size:10.35px;font-weight:750;letter-spacing:.06em;text-transform:uppercase}
.wx-benefit{margin-top:9px;padding:8px 11px;border-radius:10px;background:var(--blue-dim);color:var(--blue-soft);font-size:14px;font-weight:650}
.pz{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.pz-row{display:flex;align-items:baseline;gap:5px;padding:5px 9px;border:1px solid var(--hairline);border-radius:9px;background:var(--surface-2)}
.pz-k{font-size:10.5px;font-weight:800;color:var(--text-3);letter-spacing:.05em}
.pz-v{font-family:var(--mono);font-size:13.5px;color:var(--text)}

/* ============ THE FOUR PILLARS ON HOME — 12 Sep 2026 ============ */
/* Every row inside a tile has a FIXED height so all four tiles are identical
   without being stretched: heading 17, figure 31, sub 14, gap 12, then two
   31px buttons with 6 between. A pillar with nothing to report still occupies
   its lines - a blank line costs less than a ragged grid. */
.pillars{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:12px 0 0}
.pl{border-radius:12px;padding:12px;border:0.5px solid transparent}
.pl-h{display:flex;align-items:center;gap:5px;height:17px;line-height:17px;
  font-size:11.5px;font-weight:600;letter-spacing:.01em;white-space:nowrap;overflow:hidden}
.pl-i{width:14px;height:14px;flex:none}
.pl-sc{font-weight:500;opacity:.85}
.pl-big{height:31px;line-height:31px;margin-top:5px;font-size:23px;font-weight:700;letter-spacing:-.01em}
.pl-u{font-size:12px;font-weight:600}
.pl-sub{height:14px;line-height:14px;font-size:10.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pl-acts{margin-top:12px}
.pl-b{display:block;width:100%;height:31px;line-height:31px;padding:0 6px;margin-bottom:6px;
  border:0;border-radius:6px;background:var(--surface);font-family:inherit;font-size:11px;
  font-weight:600;text-align:center;cursor:pointer;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.pl-b:last-child{margin-bottom:0}
.pl-b:active{transform:scale(.98)}
.pl-b.soon{opacity:.62}
/* Colour names a pillar. It is the only thing on this screen that does. */
.pl-tr{background:#FAEEDA}
.pl-tr .pl-h,.pl-tr .pl-sub,.pl-tr .pl-u{color:#854F0B}
.pl-tr .pl-big{color:#412402}
.pl-tr .pl-b{color:#633806}
.pl-nu{background:#EAF3DE}
.pl-nu .pl-h,.pl-nu .pl-sub,.pl-nu .pl-u{color:#3B6D11}
.pl-nu .pl-big{color:#173404}
.pl-nu .pl-b{color:#27500A}
.pl-re{background:#E6F1FB}
.pl-re .pl-h,.pl-re .pl-sub,.pl-re .pl-u{color:#185FA5}
.pl-re .pl-big{color:#042C53}
.pl-re .pl-b{color:#0C447C}
.pl-me{background:#EEEDFE}
.pl-me .pl-h,.pl-me .pl-sub,.pl-me .pl-u{color:#534AB7}
.pl-me .pl-big{color:#26215C}
.pl-me .pl-b{color:#3C3489}
@media (max-width:340px){ .pl-b{font-size:10px} .pl-big{font-size:21px} }

/* ============ THE HERO, CALMED — 10 Sep 2026 ============ */
/* His note: the button at the top is loud next to the four pastel tiles, and
   it is. It was designed in August against a screen that had no other colour
   on it, so a saturated blue gradient with a glowing gold pill and a pulsing
   animation was the only thing competing for the eye and it won by default.
   The screen underneath it changed; this did not.
   Nothing here changes what the control DOES or how big its tap target is -
   it is still the one thing home exists to offer. What goes is the shouting:
   one flat navy instead of a gradient, a coloured shadow replaced by an
   ordinary one, gold reduced from a 3D pill to a flat fill, and the heartbeat
   animation stopped. The tiles' language is flat surfaces and quiet text, so
   the hero speaks it too - louder, but the same language. */
.start-card{
  background:#1E2A4A !important;
  box-shadow:0 1px 2px rgba(16,24,40,.10) !important;
  border-radius:14px !important;
  padding:15px 16px !important;
}
.start-card .sc-when{
  font-size:11px !important;
  letter-spacing:.1em !important;
  font-weight:600 !important;
  color:#F0C46A !important;
}
.start-card .sc-t{
  font-size:17px !important;
  font-weight:600 !important;
  line-height:1.32 !important;
  margin-top:4px !important;
}
.start-card .sc-go{
  background:#F0C46A !important;
  color:#2A2010 !important;
  box-shadow:none !important;
  border-radius:10px !important;
  padding:9px 14px !important;
  font-size:14px !important;
  font-weight:600 !important;
}
/* THE ONE THING THAT MOVES - 10 Sep 2026, his note: the new home reads dead.
   He is right, and it is my doing: yesterday's calming pass killed the beat
   along with the glow, and with the vitals rings and the score gone there was
   nothing left on the screen that changed at all. A still screen reads as a
   screenshot. The beat comes back, quieter than the August one - a 1.5% swell
   rather than a pulse with a shadow behind it - because it is now the ONLY
   movement on the page and no longer has to compete with anything. */
@keyframes tzGoBreathe{
  0%,100%{ transform:scale(1) }
  50%    { transform:scale(1.015) }
}
.start-card .sc-go{
  animation:tzGoBreathe 4.5s cubic-bezier(.45,0,.55,1) 1.4s infinite both !important;
  will-change:transform;
}
@media (prefers-reduced-motion:reduce){
  .start-card .sc-go{ animation:none !important; }
}
.start-card:active .sc-go{ box-shadow:none !important; transform:scale(.97); }
.start-card .sc-go svg{ width:14px; height:14px; }

/* ============ TODAY'S LESSON, AS A BOTTOM SHEET — 10 Sep 2026 ============ */
/* The flow sheet centres a small card, which is right for a four-item picker
   and wrong for a transcript with a toolbar. Same host, different geometry. */
.lesson-sheet{align-items:flex-end !important;padding:0 !important}
.lesson-sheet .flow-card{
  width:100%;max-width:100%;
  /* 40% of the screen, his call. Header and toolbar are fixed; the transcript
     is the only thing that scrolls, so a short sheet costs reading window and
     nothing else. */
  height:40vh;max-height:40vh;min-height:300px;
  border-radius:20px 20px 0 0;
  padding:8px 14px calc(env(safe-area-inset-bottom,0px) + 14px);
  display:flex;flex-direction:column;overflow:hidden;
  animation:lsUp .22s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes lsUp{ from{transform:translateY(14px);opacity:0} to{transform:none;opacity:1} }
.lesson-grip{flex:none;width:38px;height:4px;border-radius:2px;background:var(--hairline-str);
  margin:2px auto 8px}
.lesson-sheet .flow-x{top:10px;right:12px}
.lesson-sheet #lessonBody{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}
/* The card was built to sit inside a page column; inside the sheet it is the
   page, so it drops its own frame rather than drawing a box inside a box. */
/* The card keeps its own surface - stripping it left the text sitting on the
   sheet with nothing holding it, which is the "ugly" he saw. What it drops is
   only the outer margin, so it fills the sheet instead of floating inside it. */
.lesson-sheet .lnm{margin:0 !important;border-radius:12px !important}
.lesson-sheet .lnm-row{position:sticky;top:0;z-index:2;background:var(--surface)}
.lesson-sheet .lnm-script{max-height:none !important}
@media (prefers-reduced-motion:reduce){ .lesson-sheet .flow-card{animation:none} }

/* ============ SCROLL-TO-LATEST, COACH CHAT — 11/12 Sep 2026 ============ */
/* His ask, corrected after the first pass sat centred over the composer: same
   show/hide behaviour as before (hidden at the bottom, appears once he has
   scrolled up - coachSyncScrollBtn still owns that, untouched), but parked
   bottom-right, flush with Send's own edge, floating just above the composer
   row rather than over the message list or the text box.
   Lives inside .coach-input (the flex row that already ends with Send) as a
   position:absolute child - it takes no space in that row's flex flow, so it
   cannot push Send or the textarea, and right:0/bottom:100% lines its right
   edge up with Send's without hand-measuring the composer's padding. */
.coach-input{ position:relative; }
.coach-to-bottom{
  position:absolute; right:0; bottom:100%; margin-bottom:8px;
  width:34px; height:34px; border-radius:50%; border:0;
  background:var(--surface); color:var(--text-secondary);
  box-shadow:0 2px 10px rgba(16,24,40,.14), 0 0 0 0.5px var(--hairline);
  display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; z-index:4;
  transform:translateY(6px);
  transition:opacity .16s ease, transform .16s ease;
}
.coach-to-bottom.show{ opacity:1; pointer-events:auto; transform:translateY(0); }
.coach-to-bottom:active{ transform:translateY(0) scale(.92); }

/* ===== SCROLL-TO-LATEST, IN-WORKOUT COACH PANEL — 12 Sep 2026 (Round 2) ===== */
/* Same control, same rule and same placement as the main chat's: hidden at the
   live edge, floating bottom-right just above Send once he has scrolled up.
   Anchored inside .wc-in (the composer row that already ends with Send) as an
   absolute child, so it takes no space in that flex row and cannot push the
   textarea or the send button. right:0 lines it up with Send's own edge without
   measuring the row's padding. */
.wc-in{ position:relative; }
.wc-to-bottom{
  position:absolute; right:0; bottom:100%; margin-bottom:8px;
  width:32px; height:32px; border-radius:50%; border:0;
  background:var(--surface); color:var(--text-secondary);
  box-shadow:0 2px 10px rgba(16,24,40,.16), 0 0 0 0.5px var(--hairline);
  display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; z-index:5;
  transform:translateY(6px);
  transition:opacity .16s ease, transform .16s ease;
}
.wc-to-bottom.show{ opacity:1; pointer-events:auto; transform:translateY(0); }
.wc-to-bottom:active{ transform:translateY(0) scale(.92); }


/* ===== Box-led workout, modular - 13 Sep 2026 =====
   His words: "sometimes a skill session, sometimes a long endurance piece,
   sometimes a short metcon, sometimes weights." One fixed form described none
   of them. The super-coach lights the modules the box actually ran that day,
   and only those draw. Everything below reuses the card's existing rhythm -
   .vchip for the version picker, .note for inputs - so a module looks like the
   rest of the app rather than a form bolted onto it. */
.bx-mod{margin-top:16px;padding-top:13px;border-top:1px solid var(--hairline)}
.bx-lbl{font-size:12.65px;font-weight:650;letter-spacing:.04em;color:var(--text-2);
  text-transform:uppercase;margin-bottom:8px}
.bx-lbl i{display:none}
.bx-lbl span{font-weight:500;color:var(--text-3);text-transform:none;letter-spacing:0}
.bx-title{font-size:16.1px;font-weight:600;color:var(--text);margin-bottom:10px;line-height:1.4}
.bx-detail{font-size:14.95px;color:var(--text-2);line-height:1.55;margin-bottom:12px}
.bx-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:9px}
.bx-f.wide{grid-column:1/-1}
.bx-f label{display:block;font-size:12.65px;color:var(--text-3);margin-bottom:4px}
.bx-f .note{width:100%}
.bx-bt{display:flex;align-items:center;gap:9px;width:100%;margin-top:4px;padding:10px 12px;
  border:1px solid var(--hairline-str);border-radius:var(--r-sm);background:var(--surface-2);
  font-family:inherit;font-size:14.95px;color:var(--text-2);cursor:pointer;transition:all .16s}
.bx-bt.on{background:var(--amber-dim,rgba(240,180,40,.14));border-color:rgba(200,140,20,.4);color:#7a5206;font-weight:600}
.bx-btn-note{width:100%;margin-top:8px}
.bx-did{font-size:12.65px;color:var(--text-3);margin:15px 0 9px}
.bx-mv{padding:10px 0;border-top:1px solid var(--hairline)}
.bx-mv:first-of-type{border-top:0;padding-top:2px}
.bx-mv-n{font-size:15.5px;font-weight:600;color:var(--text);margin-bottom:7px}
.bx-mv-n span{font-weight:400;color:var(--text-3)}
.bx-mv .variant-row{margin:0}
.bx-mv-load{display:flex;align-items:center;gap:9px}
.bx-mv-load .note{width:86px}
.bx-mv-load span{font-size:14.37px;color:var(--text-2)}


/* ===== The interval player, inside the block - 13 Sep 2026 =====
   It used to open a full-screen sheet that repeated the title, the brief and
   every position the card was already showing. One screen now: read the list,
   press start, the clock appears where the button was. */
.flow-in{margin-top:4px}
.flow-in .flow-focus{margin:10px 0 2px;border:1px solid var(--hairline);box-shadow:none}
.flow-in .flow-start{margin:10px 0 2px}
.round-note-line{font-size:14.37px;color:var(--text-2);margin-bottom:10px;line-height:1.5}
/* The live position, marked in the card's own list. */
.pl-row{transition:background .2s,border-color .2s}
.pl-row.on{background:var(--blue-dim);border-radius:10px;
  box-shadow:inset 3px 0 0 var(--blue)}

/* A position's cue is a glance on the card and a paragraph in the player. */
.pl-detail.clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pl-cue{font-family:var(--mono);font-size:12.65px;color:var(--text-3)}


/* ===== Sheets on desktop - 13 Sep 2026 =====
   Two things were wrong the first time he opened "Log a meal" on the Mac.
   1. THE PAGE BEHIND KEPT SCROLLING. body.sheet-open already sets
      overflow:hidden, and on a phone that is enough. On desktop the scrolling
      box is the documentElement, not the body, so the rule had nothing to hold
      - the darkened home screen slid around under the sheet.
   2. THE SHEET IGNORED THE COLUMN. Every other pinned element - the tab bar,
      the coach view, the composer - is positioned from the measured column
      edges. The sheet was still left:0/right:0, so on a wide window it ran the
      full width of the browser while the app sat in the middle. */
html:has(body.sheet-open), html:has(body.bg-lock){ overflow:hidden }

@media(min-width:900px){
  .ch-panel, .ch-back{
    left:var(--shell-left,0px) !important;
    right:var(--shell-right,0px) !important; }
}


/* The meals list is English text in a panel the app draws left-to-right, but
   .ch-row carries text-align:right for the Hebrew chat-history rows it shares.
   "Protein porridge with peanut butter" sat pushed to the right edge while its
   own macro line ran the full width, so the two lines of one meal did not even
   start in the same place. Scoped to this panel so the chat list is untouched. */
#nutPanel .ch-row, #nutPanel .ch-row .ch-d, #nutPanel .ch-row .ch-s{ text-align:left }
#nutPanel .nut-sum{ text-align:left }

/* A short-term goal with no end date never leaves the coach's focus - it is
   read into every conversation until someone gives it a date. Said on the card
   rather than left for him to work out from its absence. */
.gl-by.warn{color:#9a6a12;background:rgba(240,180,40,.16);
  border:1px solid rgba(200,140,20,.28);border-radius:100px;padding:2px 9px}

/* The four daily targets, editable in place - 13 Sep 2026. */
.tgt-in{width:84px;text-align:end;font-family:var(--mono);font-size:16.1px;font-weight:650;
  color:var(--text);background:var(--surface-2);border:1px solid var(--hairline-str);
  border-radius:9px;padding:6px 9px}
.tgt-in:focus{outline:none;border-color:var(--blue);background:var(--surface-2)}
.tgt-in.bad{border-color:rgba(220,80,80,.65);background:rgba(220,80,80,.07)}
.tgt-u{font-size:13.22px;color:var(--text-3);margin-inline-start:7px}
.tgt-foot .pf-k{font-size:12.65px;color:var(--text-3)}
.tgt-save{border:0;border-radius:11px;padding:8px 18px;font-family:inherit;font-size:14.95px;
  font-weight:650;color:#fff;background:var(--blue-grad);box-shadow:var(--blue-3d);cursor:pointer}
.tgt-save:disabled{opacity:.65}


/* ===== Readiness check - 13 Sep 2026 =====
   Answers, not ticks. Every control here is thumb-sized because this is the
   card he fills standing up, thirty seconds before he starts. */
.rd-item{padding:13px 0;border-top:1px solid var(--hairline)}
.rd-item:first-of-type{border-top:0;padding-top:2px}
.rd-n{font-size:15.5px;font-weight:600;color:var(--text);margin-bottom:3px}
.rd-d{font-size:14.37px;color:var(--text-2);line-height:1.5;margin-bottom:9px}
.rd-row{display:flex;gap:6px}
.rd-chip{flex:1;padding:10px 6px;border-radius:var(--r-sm);border:1px solid var(--hairline-str);
  background:var(--surface-2);font-family:inherit;font-size:14.95px;font-weight:600;
  color:var(--text-3);cursor:pointer;transition:all .16s}
.rd-chip.num{font-family:var(--mono)}
.rd-chip.on{color:#fff;border-color:transparent;
  box-shadow:0 1px 2px rgba(20,40,100,.10),0 6px 16px -10px rgba(46,91,255,.5)}
.rd-chip.on{background:var(--blue)}
.rd-chip.ok.on{background:#1f9d62}
.rd-chip.warn.on{background:#c98a12}
.rd-chip.bad.on{background:#c8483f}
.rd-note,.rd-text{width:100%;margin-top:9px}
.rd-num{display:flex;align-items:center;gap:9px}
.rd-num .note{width:104px}
.rd-num span{font-size:14.37px;color:var(--text-2)}
.rd-foot{font-size:12.65px;color:var(--text-3);margin:14px 0 10px;text-align:center}
