/* Tennis Performance System, Level 2 · the course app's look: CENTRE COURT, IN FARSI (Amir, 2026-10-13: "Im ok with your
   recommendations start", after the direction board claude.ai/artifact/92KNKRwtzBvvReRTu3TifC).
   The training app's look (program.html, "Centre Court"; Content/APP-UI-KIT.md, §9 for Farsi) adapted to Farsi and right to left:
   calm paper, rows with hairlines and no boxes, ONE green thing per screen (a cover, where the screen has a picture), clay only
   where it asks the reader to look, green buttons. The colour set is program.html's, declared once, on body.
   Farsi rules: Vazirmatn only; no capitals and no letter-spacing; no text under 12 px; Persian digits; NO middle dot "·" next
   to a Persian digit (in Vazirmatn it is the Persian zero "۰": «۱۶ هفته · ۴ بلوک» reads «۴۰ بلوک»), so the shell draws the
   dot as .sep, a short bar, and eyebrows use «،». Logical properties (inline-start/end) everywhere, so RTL needs no mirrored
   rules; the few things that are handed (the pictures, the lights in the greens, the go chevron) say so where they are set.
   No yellow, gold, ochre or amber, and no emoji drawn by the shell (they paint yellow on most phones).
   The sheet is in sections: 0 font · 1 tokens · 2 base · 3 THE SHARED PARTS (the cover and the paper header, the eyebrow,
   section titles, rows, the numeral, door rows, shelves, folds, buttons, the content blocks, the tab bar) · then one section
   per screen group: DOORS (Start, Setup, Guide, the locked page, sign in, the tour) · TRAINING (Programme, Week, Session,
   Exercises) · STEP, LEARN AND TESTS. A screen's own rule goes in its section; a part two groups use goes in section 3. */

/* ── 0. Vazirmatn, self-hosted (v33.0.3, SIL Open Font License: fonts/OFL.txt). One variable file covers every weight, and
   the text never waits on Google Fonts, which may not load from Iran. ── */
@font-face {
  font-family: Vazirmatn;
  src: url("fonts/Vazirmatn-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ── 1. Tokens. The type scale (not colours) on :root; every colour on body, program.html's one set, light only (the course
   has no dark mode). Farsi runs about one step larger than the Latin scale and never under 12 px. ── */
:root {
  --tabs-h: 64px;
  --fs-label: 13px;    /* eyebrows, captions, section titles' codes, meta lines */
  --fs-small: 14px;    /* a row's second line, a helper sentence */
  --fs-body: 16px;     /* reading text, lessons */
  --fs-lead: 18px;     /* a row's title, a button */
  --fs-title: 22px;    /* a number in the scoreboard, a heading inside a page */
  --fs-head: 28px;     /* an inner page's title, a shelf's title */
  --fs-display: 36px;  /* a tab screen's title */
}
body {
  --g: 20px;
  --paper: #FAF7F2; --sand: #F1ECE3; --row: #FFFFFF; --hair: #E4DDD1; --box: #D8D1C5;
  --ink: #1A1A1A; --grey: #5C5C5C; --ring: #8A8378;
  --fill: #0E4A36; --green-ink: #0E4A36; --mint: #6DBE95;
  --clay: #C7552F; --clay-ink: #B5461F; --clay-big: #C7552F; --clay-on-green: #E06B43;
  --tint: rgba(14,74,54,.08); --clay-tint: rgba(199,85,47,.08);
  /* The greens, MIRRORED for right to left: each light sits where the picture is, on the LEFT (program.html's sit right). */
  --hero: radial-gradient(125% 90% at 0% 0%, #1B7254 0%, #0E4A36 46%, #082D20 100%);
  --btn: radial-gradient(120% 120% at 100% 0%, #1B6A4E 0%, #0E4A36 55%, #0B3E2D 100%);
  --tile-on-green: radial-gradient(120% 150% at 100% 0%, #24855F 0%, #16603F 52%, #0E4A36 100%);
  --bar: radial-gradient(160% 260% at 0% 0%, #17664B 0%, #0E4A36 45%, #0A3829 100%);
  --hero-end: #06241A; --hero-end-a: rgba(6,36,26,.55);
  /* The two drawn chevrons, masks in the element's colour: ⌄ opens a fold; the go chevron points LEFT (forward in RTL). */
  --chev-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E");
  --chev-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 6l-6 6 6 6'/%3E%3C/svg%3E");
  /* The older names, aliases of the set above, so a rule not yet moved to the new names keeps working. New rules use the new names. */
  --green: var(--fill); --green-2: #14684c; --green-dim: var(--tint); --green-mid: rgba(14,74,54,.22);
  --clay-dim: var(--clay-tint); --card: var(--sand); --line: var(--box); --muted: var(--grey); --white: var(--row);
  --red: var(--clay-ink); --ochre: var(--fill);   /* no red and no gold: the fault is clay, the old ochre is green */
  --radius: 12px;
}
@media (max-width: 359px) { body { --g: 16px; } }

/* ── 2. Base ── */
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: Vazirmatn, Tahoma, "Segoe UI", system-ui, sans-serif;
  background: var(--paper);
  color: var(--ink);
  font-size: var(--fs-body);
  line-height: 1.85;
  padding-bottom: calc(var(--tabs-h) + env(safe-area-inset-bottom) + 12px);
}
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
img, iframe { max-width: 100%; }
bdi { unicode-bidi: isolate; }
[hidden] { display: none !important; }
.num { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2px solid var(--green-ink); outline-offset: 2px; }
#app { max-width: 560px; margin: 0 auto; }
.loading { padding: 80px 20px; text-align: center; color: var(--grey); }

/* The local modes' bar (?local=1, ?content=…), never shown to a buyer. */
.sample-bar { background: var(--ink); color: #fff; text-align: center; font-size: var(--fs-label); font-weight: 700; padding: 4px 10px; }
html:not(.is-local) .sample-bar { display: none; }

/* The demo's bar (html.is-demo only): it asks for something, so it is clay, the one clay band (a banner that asks). */
.demo-bar { display: none; }
html.is-demo .demo-bar { display: flex; justify-content: center; align-items: center; gap: 0 12px; flex-wrap: wrap;
  background: var(--clay); color: #fff; font-size: var(--fs-small); font-weight: 700; padding: 2px 12px; line-height: 1.6; }
.demo-bar a { display: inline-flex; align-items: center; min-height: 40px; color: #fff; font-weight: 900; text-decoration: underline; text-underline-offset: 4px; }

/* ══ 3. THE SHARED PARTS ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* 3.1 The separator. Never a middle dot next to a Persian digit: SEP in app.js draws this short bar instead, in the text's
   own colour, so it works on the paper and on the green. */
.sep { display: inline-block; width: 1px; height: .85em; margin: 0 .6em; vertical-align: -.1em; background: currentColor; opacity: .35; }

/* 3.2 The picture layer (artLayer() in app.js). A picture that fails takes its layer away and the green stays. */
/* NO z-index on .ph: a z-index makes it a stacking context, and the picture's luminosity blend then sees an empty backdrop and
   draws the court in its own orange instead of graded into the green (found by the Doors build, 2026-10-13). The cover's and the
   shelf's other children carry z-index 2, so they still sit above it. */
.ph { position: absolute; inset: 0; overflow: hidden; }
.ph img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .5s cubic-bezier(.16,1,.3,1); }
.ph img.in { opacity: 1; }
.ph::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 30%, var(--hero-end-a) 78%, var(--hero-end) 100%); }

/* 3.3 The screen's head: banner() draws ONE of two. A picture earns a COVER (.is-cover): the green, the picture graded into it
   (luminosity at .7, masked so it shows at the LEFT, where every course picture keeps its subject), a scrim down to the
   cover's last colour, the eyebrow in mint, the title in white at the right. No picture: the PAPER HEADER (.is-paper), the
   eyebrow and a big title on the paper. A tab screen's title is display size; an inner page's (it has a back button) is head size. */
.banner { position: relative; }
.banner .kicker { position: relative; }
.banner h1 { position: relative; text-wrap: balance; }
.banner .sub, .banner .meta { position: relative; }

.banner.is-paper { padding: 22px var(--g) 10px; }
.banner.is-paper.has-back { padding-top: 70px; }
.banner.is-paper h1 { margin-top: 6px; font: 900 var(--fs-display)/1.25 Vazirmatn, sans-serif; color: var(--ink); }
.banner.is-paper.has-back h1 { font-size: var(--fs-head); line-height: 1.32; }
.banner.is-paper .sub { margin-top: 6px; font-size: var(--fs-body); line-height: 1.75; color: var(--grey); }
.banner.is-paper .meta { margin-top: 10px; font-size: var(--fs-small); font-weight: 600; color: var(--grey); }

.banner.is-cover { isolation: isolate; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 236px; padding: 76px var(--g) 22px; background: var(--hero); color: #fff; }
.banner.is-cover.is-tall { min-height: clamp(440px, 64vh, 560px); }
.banner.is-cover .ph img.in { opacity: .7; mix-blend-mode: luminosity; }
.banner.is-cover .ph img { -webkit-mask-image: linear-gradient(270deg, transparent 0%, rgba(0,0,0,.2) 28%, #000 70%);
  mask-image: linear-gradient(270deg, transparent 0%, rgba(0,0,0,.2) 28%, #000 70%); }
.banner.is-cover > :not(.ph) { z-index: 2; }
.banner.is-cover .kicker { color: var(--mint); }
.banner.is-cover h1 { margin-top: 8px; font: 900 clamp(26px, 8vw, 32px)/1.3 Vazirmatn, sans-serif; color: #fff; }
.banner.is-cover .sub { margin-top: 8px; font-size: var(--fs-body); line-height: 1.75; color: rgba(255,255,255,.84); }
.banner.is-cover .meta { margin-top: 10px; font-size: var(--fs-small); font-weight: 600; line-height: 1.6; color: rgba(255,255,255,.74); }

/* Its buttons: back at the start (right), the version gear and the guide's ؟ at the end (left). 44 px to hit. Glass on the
   green, sand circles on the paper. */
.back, .gear, .bhelp { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; text-decoration: none; }
.back { position: absolute; top: 10px; inset-inline-start: 10px; z-index: 5; }
.bnav { position: absolute; top: 10px; inset-inline-end: 10px; z-index: 5; display: flex; gap: 8px; }
.back svg, .gear svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.bhelp { font-size: 20px; font-weight: 900; line-height: 1; }
.is-cover .back, .is-cover .gear, .is-cover .bhelp { color: #fff; background: rgba(0,0,0,.22); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.is-paper .back, .is-paper .gear, .is-paper .bhelp { color: var(--green-ink); background: var(--sand); }
.is-paper .back { top: 14px; inset-inline-start: var(--g); }
.is-paper .bnav { top: 14px; inset-inline-end: var(--g); }
.back:active, .gear:active, .bhelp:active { transform: scale(.92); }
.is-paper:not(.has-back) .kicker { margin-inline-end: 104px; }   /* clear of the two round buttons */

/* 3.4 The eyebrow: a dot and plain Farsi, bold, no capitals, no letter-spacing (the dot, weight and colour carry it). */
.kicker, .eb { display: flex; align-items: center; gap: 8px; font-size: var(--fs-label); font-weight: 700; line-height: 1.5; color: var(--green-ink); }
.kicker::before, .eb::before { content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* 3.5 The page under a head, its section titles (green, a hairline to the end edge; .sec-code, a slot code such as P1, sits
   quiet past the line) and the plain grey line. */
.section { padding: 8px var(--g) 4px; }
.sec, .h2 { display: flex; align-items: center; gap: 12px; margin: 26px 0 4px; font-size: 15px; font-weight: 800; line-height: 1.5; color: var(--green-ink); }
.sec::after, .h2::after { content: ''; flex: 1; height: 1px; background: var(--hair); }
.sec .sec-code { order: 2; font-size: 12px; font-weight: 600; color: var(--ring); }
.lead { color: var(--grey); font-size: 15px; line-height: 1.8; margin-bottom: 10px; }
.grid2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
.empty { text-align: center; color: var(--grey); padding: 24px 10px; }

/* 3.6 The numeral (P24): a big outlined number in Persian digits, the training app's exercise number. Solid when the thing is
   done or open; grey when locked. Phones without text-stroke get the solid number. */
.pnum { display: block; font-size: 32px; font-weight: 900; line-height: 1; text-align: center; font-variant-numeric: tabular-nums;
  color: transparent; -webkit-text-stroke: 1.5px var(--green-ink); paint-order: stroke fill; }
.pnum.solid { color: var(--green-ink); }
.pnum.off { -webkit-text-stroke-color: var(--ring); }
.pnum.off.solid { color: var(--ring); }
.pnum.sm { font-size: 26px; }
@supports not (-webkit-text-stroke: 1px black) { .pnum { color: var(--green-ink); } .pnum.off { color: var(--ring); } }

/* 3.7 Rows on the paper (.list-row): a hairline between rows, no box, no white. An optional numeral at the start (.has-num),
   the title and its grey line, and at the end the go chevron (.lr-go, drawn) or a lock. */
.list-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 12px; min-height: 64px; padding: 12px 0;
  color: inherit; text-decoration: none; overflow-wrap: anywhere; }
.list-row.has-num { grid-template-columns: 44px minmax(0, 1fr) auto; }
.list-row + .list-row { border-top: 1px solid var(--hair); }
.list-row:active { background: rgba(14,74,54,.05); }
.list-row .lr-body { min-width: 0; }
.list-row .lr-body br { display: none; }
.list-row .lr-title { display: block; font-size: var(--fs-lead); font-weight: 700; line-height: 1.5; }
.list-row .lr-sub { display: block; margin-top: 2px; font-size: var(--fs-small); line-height: 1.65; color: var(--grey); }
.lr-go { display: block; flex: none; width: 20px; height: 20px; font-size: 0; background: var(--ring);
  -webkit-mask: var(--chev-go) center / 20px no-repeat; mask: var(--chev-go) center / 20px no-repeat; }
.list-row.locked .lr-title { color: var(--grey); }
.list-row.locked .pnum { -webkit-text-stroke-color: var(--ring); }

/* 3.8 The lock (LOCK in app.js), drawn, never the 🔒 emoji. */
.lock { display: inline-flex; vertical-align: -.12em; margin-inline-start: 6px; color: var(--ring); }
.lock svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* 3.9 Door rows (.door): what takes you somewhere. White, rounded 12, a green line icon, a green label over the value, the go chevron. */
.door { display: flex; align-items: center; gap: 14px; min-height: 64px; margin: 0 0 10px; padding: 12px 16px 12px 14px;
  border: 1px solid var(--hair); border-radius: 12px; background: var(--row); color: var(--ink); text-decoration: none; text-align: start; width: 100%; }
.door:active { background: var(--sand); }
.door .d-ic { flex: none; display: inline-flex; width: 22px; height: 22px; color: var(--green-ink); }
.door .d-ic svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.door .d-b { flex: 1; min-width: 0; display: grid; gap: 2px; }
.door .d-l { font-size: var(--fs-label); font-weight: 700; line-height: 1.4; color: var(--green-ink); }
.door .d-v { font-size: 17px; font-weight: 700; line-height: 1.45; }
.door .d-s { font-size: var(--fs-small); line-height: 1.6; color: var(--grey); }

/* 3.10 Shelves (.band): a short photo band over a group of rows, the training app's Library shelves. The eyebrow in mint, the
   title in white; the picture at the left, masked, as on a cover. */
.band { position: relative; isolation: isolate; overflow: hidden; display: block; margin: 28px 0 6px; min-height: 104px; border-radius: 14px;
  background: var(--hero); color: #fff; text-decoration: none; }
.band .ph img.in { opacity: .7; mix-blend-mode: luminosity; }
.band .ph img { -webkit-mask-image: linear-gradient(270deg, transparent 10%, rgba(0,0,0,.35) 40%, #000 80%);
  mask-image: linear-gradient(270deg, transparent 10%, rgba(0,0,0,.35) 40%, #000 80%); }
.band .ph::after { background: linear-gradient(180deg, transparent 20%, var(--hero-end-a) 100%); }
.band .b-cap { position: relative; z-index: 2; padding: 20px 18px 16px; }
.band .eb { color: var(--mint); }
.band .b-t { margin-top: 4px; font-size: var(--fs-head); font-weight: 900; line-height: 1.3; }

/* 3.11 Folds (acc() in app.js): a row on the paper that opens in place, with the drawn ⌄. A fold that asks the reader to look
   (.clay: safety, the under-16 rules for an under-16) carries the clay dot after its title. */
.acc { overflow: hidden; }
.acc + .acc { border-top: 1px solid var(--hair); }
.acc-head { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) 24px; align-items: center; column-gap: 12px; min-height: 60px;
  padding: 12px 0; text-align: start; font-size: 17px; font-weight: 700; line-height: 1.5; color: var(--ink); }
.acc.clay .acc-head > span:first-child::after { content: ''; display: inline-block; width: 7px; height: 7px; margin-inline-start: 8px;
  border-radius: 50%; background: var(--clay); vertical-align: .15em; }
.chev { display: block; width: 18px; height: 18px; justify-self: end; font-size: 0; background: var(--ring); transition: transform .2s;
  -webkit-mask: var(--chev-down) center / 18px no-repeat; mask: var(--chev-down) center / 18px no-repeat; }
.acc.open .chev { transform: rotate(180deg); }
.acc-body { display: none; padding: 0 0 16px; }
.acc.open .acc-body { display: block; }
.acc-body .grid2 { margin-top: 12px; }

/* 3.12 Buttons. Green, always (a buy button too: .btn.clay draws green); the outlined twin for the second choice. On a cover
   the primary is the lighter green with a light ring. */
.btn { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 52px; padding: 12px 16px;
  border: 0; border-radius: 10px; font-size: var(--fs-lead); font-weight: 800; line-height: 1.3; text-decoration: none; text-align: center; }
.btn.primary, .btn.clay { background: var(--btn); color: #fff; box-shadow: 0 10px 22px -12px rgba(14,74,54,.6); }
.btn.ghost { background: transparent; border: 1.5px solid var(--box); color: var(--ink); }
.btn:active { transform: scale(.98); }
.btn[disabled] { opacity: .4; cursor: default; }
.is-cover .btn.primary, .cov-go { background: var(--tile-on-green); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.22), 0 10px 22px -10px rgba(0,0,0,.6); }
/* the go triangle after a cover button's words: mint, pointing LEFT (forward in RTL); drawn, so it never turns into an emoji */
.go-tri { flex: none; width: 0; height: 0; border-style: solid; border-width: 6px 9px 6px 0; border-color: transparent var(--mint) transparent transparent; }
.link-btn { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; color: var(--green-ink); font-size: 15px; font-weight: 800; text-decoration: none; }
.link-btn::after { content: ''; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: var(--chev-go) center / 16px no-repeat; mask: var(--chev-go) center / 16px no-repeat; }

/* 3.13 Pills (few left: tags on an exercise page) and the pick-one controls. */
.pill { display: inline-flex; align-items: center; gap: 4px; padding: 2px 12px; border-radius: 999px; background: var(--sand); color: var(--ink);
  font-size: var(--fs-label); font-weight: 700; line-height: 1.8; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pill.green { background: var(--tint); color: var(--green-ink); }
.pill.clay { background: var(--clay-tint); color: var(--clay-ink); }
.pill.light { background: rgba(255,255,255,.14); color: #fff; }
a.pill { min-height: 44px; padding: 0 16px; text-decoration: none; font-size: var(--fs-small); }   /* a pill that is a link (the version, on Programme) is 44 px to hit */
.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 8px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip { flex: none; min-height: 44px; padding: 0 16px; border-radius: 999px; background: var(--sand); color: var(--grey); font-size: 15px; font-weight: 700; }
.chip.on { background: var(--btn); color: #fff; }
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; padding: 4px; border-radius: 12px; background: var(--sand); }
.seg button { min-height: 44px; border-radius: 9px; font-size: 15px; font-weight: 800; color: var(--grey); }
.seg button.on { background: var(--btn); color: #fff; }
.search { width: 100%; min-height: 48px; padding: 10px 14px; border: 1px solid var(--box); border-radius: 12px; background: var(--row);
  font-size: var(--fs-field); color: var(--ink); }
.search:focus { outline: none; border-color: var(--green-ink); box-shadow: 0 0 0 3px var(--tint); }

/* 3.14 Plain cards (few left: a note, a "this asks you" banner, a panel such as the calculator). White, rounded, a hairline, no
   shadow. .clay and .warn carry the clay stripe at the start edge (a banner that asks); .green is a quiet sand note. */
.card { background: var(--row); border: 1px solid var(--hair); border-radius: 12px; padding: 16px; margin-bottom: 12px; overflow-wrap: anywhere; }
.card h3 { font-size: var(--fs-lead); font-weight: 800; line-height: 1.5; margin-bottom: 6px; }
.card p { font-size: 15px; }
.card.clay, .card.warn { border-inline-start: 4px solid var(--clay); }
.card.green { background: var(--sand); border-color: transparent; }

/* 3.15 The reading blocks every screen shares: labels, lists, numbered steps (outlined numerals), cues (the fault in clay), the
   note (Amir's line, behind the clay quote mark), the easier/harder pair, the callout. */
.label { margin: 18px 0 6px; font-size: var(--fs-label); font-weight: 800; line-height: 1.4; color: var(--green-ink); }
ul.list { padding-inline-start: 20px; }
ul.list li { margin: 4px 0; font-size: 15px; }
ul.list li::marker { color: var(--green-ink); }
ol.steps { list-style: none; counter-reset: s; }
ol.steps li { counter-increment: s; display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 8px; padding: 5px 0; font-size: 15px; line-height: 1.8; }
ol.steps li::before { content: counter(s, persian); font-size: 19px; font-weight: 900; line-height: 1.5; text-align: center;
  color: transparent; -webkit-text-stroke: 1px var(--green-ink); }
@supports not (-webkit-text-stroke: 1px black) { ol.steps li::before { color: var(--green-ink); } }
.cue { display: grid; grid-template-columns: 3px minmax(0, 1fr); gap: 12px; padding: 8px 0; font-size: 15px; line-height: 1.75; }
.cue::before { content: ''; border-radius: 2px; background: var(--fill); }
.cue.bad::before { background: var(--clay); }
.note { position: relative; margin-top: 14px; padding-inline-start: 30px; font-size: 15px; font-weight: 500; line-height: 1.8; }
.note::before { content: '\201D'; position: absolute; inset-inline-start: 0; top: -6px; font: 900 40px/1 Georgia, serif; color: var(--clay); }
.alt { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; margin-top: 4px; }
.alt div { padding: 10px 12px; border: 1px solid var(--hair); border-radius: 12px; background: var(--row); font-size: var(--fs-small); line-height: 1.7; }
.alt div b { display: block; margin-bottom: 2px; font-size: 12px; font-weight: 800; color: var(--green-ink); }
.callout { margin: 10px 0; padding: 10px 14px; border-inline-start: 3px solid var(--fill); border-radius: 0 10px 10px 0; background: var(--sand);
  font-size: 15px; font-weight: 700; }
.ex-alt { display: block; font-size: var(--fs-small); font-weight: 600; color: var(--grey); line-height: 1.5; }

/* 3.16 The scoreboard (.stats from statsGrid()): the numbers of an exercise as values over captions, hairlines between the
   cells, no box. The markup is caption then value; the column turns them over. */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 12px; border-block: 1px solid var(--hair); }
.stat { display: flex; flex-direction: column-reverse; justify-content: flex-end; padding: 8px 2px; text-align: center; }
.stat + .stat { border-inline-start: 1px solid var(--hair); }
.stat span { display: block; font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--grey); }
.stat b { display: block; font-size: var(--fs-title); font-weight: 800; line-height: 1.35; font-variant-numeric: tabular-nums; }

/* 3.17 The video and its YouTube bar (videoBlock()): ONE unit (Amir, 2026-10-05). The bar sits OUTSIDE .video, because the
   iframe fills that box and would cover a bar inside it, which is exactly when the embed has failed. The mark is YouTube's own
   red so it never reads as the green ▶. The ▶ points right in every language (a player's play is not mirrored). */
.video { position: relative; height: 190px; overflow: hidden; background: #0a0a0c; display: flex; align-items: center; justify-content: center; }
.video::before { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(135deg, #15151a 0 14px, #0a0a0c 14px 28px); }
.video .play { position: relative; z-index: 2; width: 62px; height: 62px; border-radius: 50%; background: var(--btn); color: transparent; font-size: 0;
  box-shadow: 0 4px 18px rgba(0,0,0,.35); }
.video .play::before { content: ''; position: absolute; top: 50%; left: 50%; margin: -10px 0 0 -6px; border-style: solid; border-width: 10px 0 10px 16px;
  border-color: transparent transparent transparent #fff; }
.video .vnote { position: absolute; z-index: 2; bottom: 10px; inset-inline: 12px; color: rgba(255,255,255,.66); font-size: 12px; text-align: center; }
.video.playing iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; z-index: 3; }
.video.short { height: auto; aspect-ratio: 9 / 16; width: min(100%, 300px); margin-inline: auto; }
.vunit { margin-top: 16px; border-radius: 12px; overflow: hidden; background: #0a0a0c; }
.vunit .video { margin-top: 0; border-radius: 0; }
.vunit.short { width: min(100%, 300px); margin-inline: auto; }
.vunit.short .video.short { width: 100%; margin: 0; }
.vyt { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 14px; background: #111114;
  border-top: 1px solid rgba(255,255,255,0.1); color: rgba(255,255,255,0.92); text-decoration: none; font-size: var(--fs-small); font-weight: 700; }
.vyt svg:first-child { flex: none; width: 18px; height: 13px; }
.vyt svg:last-child { flex: none; width: 11px; height: 11px; margin-inline-start: auto; transform: scaleX(-1); }   /* the external-link arrow mirrors in RTL */
.vyt:active { background: #1b1b20; }
.vyt:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* 3.18 The warm-up's tick list (warmRows(), on the session page and in step mode): the number IS the tick, as on the training
   app's day (P24): an outlined numeral that turns solid green when ticked. Ticks are never saved. */
.wlist { margin-top: 4px; }
.wrow { display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: center; column-gap: 10px; min-height: 52px; padding: 4px 0; }
.wrow + .wrow { border-top: 1px solid var(--hair); }
.wchk { display: grid; place-items: center; width: 44px; height: 44px; font-size: 24px; font-weight: 900; line-height: 1;
  color: transparent; -webkit-text-stroke: 1.3px var(--green-ink); }
.wrow.done .wchk { color: var(--green-ink); }
@supports not (-webkit-text-stroke: 1px black) { .wchk { color: var(--ring); } .wrow.done .wchk { color: var(--green-ink); } }
.wname { display: block; min-width: 0; font-size: 16px; font-weight: 700; line-height: 1.5; text-decoration: none; }
a.wname { padding-block: 10px; margin-block: -10px; }   /* a warm-up name that links to its exercise: 44 px to hit, the row unchanged */
.wrow .wdose { display: block; font-size: var(--fs-small); font-weight: 500; color: var(--grey); }
.wrow.done .wname { color: var(--grey); }

/* 3.19 The tab bar: the paper, a hairline, the line icons; the open tab green with its tint pill. */
.tabs { position: fixed; bottom: 0; inset-inline: 0; z-index: 20; display: flex; justify-content: center;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom)); background: var(--paper); border-top: 1px solid var(--hair); }
.tabs a { flex: 1; max-width: 112px; min-height: 52px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-decoration: none;
  color: var(--grey); font-size: 12px; font-weight: 700; line-height: 1.4; padding: 2px 0; }
.tabs .ti { width: 52px; height: 30px; border-radius: 99px; display: flex; align-items: center; justify-content: center; }
.tabs svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tabs a.active { color: var(--green-ink); }
.tabs a.active .ti { background: var(--tint); }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }


/* ══ DOORS: Start, Setup, the Guide, the locked page, sign in, the tour ═══════════════════════════════════════════════════
   (viewStart, demoIntro, versionLine, setupControls, viewSetup, accountBlock, buyActions, viewLocked, demoFailed, showMessage,
   viewGuide, gRow, index.html's sign-in screen, the tour's card.) Centre Court in Farsi: the picture under a cover, the paper
   under everything else, rows with hairlines, one green button, clay only where it asks the reader to look. Everything here
   is built from the shared parts (section 3); only what no other screen needs is written below. */


/* ── Sign in: program.html's Centre Court sign-in, set in Vazirmatn. The window behind the card is the cover's last colour,
   the card is the paper, the hero is the cover green with the picture over it under a scrim. Right to left, except the two
   fields (a Latin username and password), whose reveal button therefore stays at the physical right. ── */
.signin-screen { display: none; position: fixed; inset: 0; z-index: 900; overflow-y: auto; background: var(--hero-end); }
.signin-screen.visible { display: block; }
.signin-card { display: flex; flex-direction: column; width: 100%; max-width: 460px; min-height: 100%; margin: 0 auto; background: var(--paper); }
/* The copy is pushed down by margin-top:auto inside a padded column, never anchored with `bottom`: a short phone makes a short hero. */
.si-hero { position: relative; flex: 0 0 auto; overflow: hidden; display: flex; flex-direction: column; height: clamp(310px, 44vh, 400px);
  padding: calc(env(safe-area-inset-top, 0px) + 36px) 26px 52px; background: var(--hero); }
.si-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .55s cubic-bezier(.16,1,.3,1); }
.si-hero-img.in { opacity: 1; }
.si-hero-scrim { position: absolute; inset: 0; background: var(--hero-end);
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.96) 6%, rgba(0,0,0,.4) 56%, rgba(0,0,0,.52));
          mask-image: linear-gradient(to top, rgba(0,0,0,.96) 6%, rgba(0,0,0,.4) 56%, rgba(0,0,0,.52)); }
.si-hero-copy { position: relative; z-index: 2; margin-top: auto; }
.signin-mark { display: block; width: 52px; height: 52px; margin: 0 0 14px; border-radius: 13px; box-shadow: 0 8px 24px rgba(0,0,0,.34); }
.si-eyebrow { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: var(--fs-label); font-weight: 700; line-height: 1.5; color: var(--mint); }
.si-eyebrow::before { content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.signin-title { margin: 0; font: 900 clamp(27px, 8.2vw, 33px)/1.3 Vazirmatn, Tahoma, sans-serif; color: #fff; text-wrap: balance; }
.signin-title em { font-style: normal; color: var(--clay-on-green); }   /* the brand word: clay on the green */
.si-mantra { margin: 10px 0 0; font-size: 16px; font-weight: 400; line-height: 1.7; color: rgba(255,255,255,.84); }
.si-sheet { position: relative; z-index: 2; flex: 1 1 auto; display: flex; flex-direction: column; margin-top: -30px; padding: 30px 26px 26px;
  border-radius: 16px 16px 0 0; background: var(--paper); }
.signin-f { display: block; margin-bottom: 15px; }
.signin-f > span { display: block; margin-bottom: 7px; font-size: var(--fs-small); font-weight: 700; line-height: 1.5; color: var(--grey); }
/* 16 px keeps iOS from zooming the page when a field takes focus. */
.signin-f input { display: block; width: 100%; min-height: 48px; padding: 0 14px; border: 1px solid var(--box); border-radius: 12px; background: var(--row); color: var(--ink);
  font: 500 16px/1.2 Vazirmatn, Tahoma, sans-serif; outline: none; -webkit-appearance: none; appearance: none; transition: border-color .35s cubic-bezier(.16,1,.3,1); }
.signin-f input:focus { border-color: var(--green-ink); box-shadow: 0 0 0 1px var(--green-ink); }
.signin-f input:-webkit-autofill { -webkit-box-shadow: 0 0 0 100px var(--row) inset; -webkit-text-fill-color: var(--ink); caret-color: var(--ink); }
.signin-f .si-wrap { position: relative; }
.signin-f .si-wrap input { padding-right: 52px; }   /* physical: the field is left-to-right, so its end is the right */
.si-eye { position: absolute; top: 0; right: 0; display: flex; align-items: center; justify-content: center; width: 48px; height: 100%; padding: 0; border: 0; background: none;
  color: var(--grey); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.si-eye:focus-visible { outline: 2px solid var(--green-ink); outline-offset: -4px; border-radius: 0 12px 12px 0; }
.si-eye svg { display: block; width: 20px; height: 20px; }
.si-eye .si-eye-slash { display: none; }
.si-eye.on { color: var(--green-ink); }
.si-eye.on .si-eye-slash { display: block; }
/* The one primary button, green like every other (it was clay). */
.signin-go { display: block; width: 100%; min-height: 52px; margin-top: 6px; padding: 12px 16px; border: 0; border-radius: 10px; background: var(--btn); color: #fff;
  font: 800 var(--fs-lead)/1.3 Vazirmatn, Tahoma, sans-serif; cursor: pointer; box-shadow: 0 10px 22px -12px rgba(14,74,54,.6); transition: transform .35s cubic-bezier(.16,1,.3,1); }
.signin-go:active { transform: translateY(1px); }
.signin-go:focus-visible { outline: 2px solid var(--green-ink); outline-offset: 2px; }
.signin-go[disabled] { opacity: .6; cursor: default; box-shadow: none; }
/* The error is a banner that asks: a white row, a 4 px clay stripe at the start edge, the words in ink. */
.signin-err { margin-top: 13px; padding: 12px 14px; border: 1px solid var(--hair); border-inline-start: 4px solid var(--clay); border-radius: 10px; background: var(--row);
  font-size: 15px; line-height: 1.75; color: var(--ink); text-wrap: pretty; }
.signin-help { margin: 16px 0 0; font-size: var(--fs-small); line-height: 1.7; text-align: center; color: var(--grey); }
.signin-help + .signin-help { margin-top: 8px; }
.signin-foot { margin: auto 0 0; padding-top: 22px; text-align: center; font-size: 12px; font-weight: 700; line-height: 1.5; color: var(--grey); }

/* ── Start ── the cover is banner() (the tall one, section 3.3); its one green button is the cover's, bigger. ── */
.btn.big { min-height: 56px; margin-top: 22px; }
.intro { margin: 6px 0 16px; font-size: var(--fs-body); line-height: 1.85; color: var(--ink); }
.acc-p { margin: 0 0 8px; font-size: 15px; line-height: 1.8; }
.more { margin-top: 18px; }

/* ── Setup and the version picker: a label line over the switch ── */
.setup-row .lbl { margin: 0 0 8px; font-size: var(--fs-small); font-weight: 700; line-height: 1.5; color: var(--grey); }
.setup-go { margin-top: 18px; }
.acct { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 8px 0 12px; }
.acct .who { flex: 1 1 170px; min-width: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--grey); }
.acct .who b { color: var(--ink); }
.acct .btn { flex: none; width: auto; min-width: 110px; }
/* versionLine()'s pill is a link: the pill stays small, its hit area grows to 44 px with nothing in the layout changing. */
a.pill { position: relative; text-decoration: none; }
a.pill::after { content: ''; position: absolute; inset: -9px -6px; }

/* ── The buy actions (under a locked item, on Setup, in the guide, when the demo fails) ── */
.demo-actions { display: grid; gap: 10px; margin-top: 14px; }
.demo-actions .lead { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 6px; margin: 2px 0 0; text-align: center; font-size: var(--fs-small); }

/* ── The guide screen (#/guide): the map the tour leaves behind. Every row is a real link where there is somewhere to go, so
   reading where something lives and going there are one tap; a row with nothing to open has no chevron. ── */
.guide-row { grid-template-columns: 22px minmax(0, 1fr) auto; column-gap: 14px; align-items: start; padding: 14px 0; }
.guide-row .g-ic { display: flex; width: 22px; height: 22px; margin-top: 6px; color: var(--green-ink); }
.guide-row .g-ic svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.guide-row .lr-go { align-self: center; }
div.guide-row:active { background: none; }

/* ── The guided tour (راهنمای تصویری) ───────────────────────────────────
   A clay ring around a real control, a card beside it saying what that control does, and the rest of the screen dimmed. Built
   the way habits.html's tour is, with the differences this app forces:
     · Z-INDEX 800: above the tab bar (20) and above step-by-step mode (100), because the tour walks INTO step mode and rings
       its buttons. Below the sign-in screen (900): nobody is toured before they are let in.
     · The dimmer is FOUR PANES with a real hole, never one lid with a transparent window. A step marked `act` is finished by
       actually doing the thing: tapping the green button really does open the session.
     · The layer lives outside #view, which every route replaces wholesale.
     · RTL needs no mirrored rules: the card is centred and the geometry is in viewport coordinates. Only the arrows are
       handed (→ back, ← next), matching the app's own .back button and .lr-go rows.
   The tour is "look here", so the ring and the card's top edge stay clay; the card itself is Centre Court's: radius 16, a
   19 px title, a grey 15 px body with the bold in ink, a green next and an outlined back. ── */
.tour { position: fixed; inset: 0; z-index: 800; pointer-events: none; }
.tour[hidden] { display: none !important; }
.tourmask, .tourblock { position: fixed; pointer-events: auto; background: rgba(8,38,27,0.66); }
.tourblock { background: none; }
.tour.opening .tourmask { animation: tourFade .22s ease; }
@keyframes tourFade { from { opacity: 0; } to { opacity: 1; } }
.tourring {
  position: fixed; pointer-events: none; border: 3px solid var(--clay);
  border-radius: 14px; animation: tourPulse 1.7s ease-in-out infinite;
}
@keyframes tourPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(199,85,47,0.55); }
  50%      { box-shadow: 0 0 0 9px rgba(199,85,47,0); }
}
.tourcard {
  position: fixed; pointer-events: auto; background: var(--row);
  border-radius: 16px; border-top: 4px solid var(--clay);
  box-shadow: 0 18px 44px rgba(8,38,27,0.34);
  padding: 16px 18px 12px; display: flex; flex-direction: column; gap: 10px;
  animation: tourRise .22s ease;
  /* Bounded, so the ring always has somewhere to be. On a short phone an unbounded card is over half the viewport and no
     placement leaves the thing it is describing visible. The prose scrolls; title and buttons never move. */
  max-height: 58vh;
}
@keyframes tourRise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
.tourcard .tourbody { overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
.tourcard .tourbody::-webkit-scrollbar { width: 0; }
.tourcard .tourtop { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.tourcard h4 { font-size: 19px; font-weight: 900; line-height: 1.45; min-width: 0; }
.tourcard .tourn { font-size: 13px; font-weight: 800; color: var(--grey); flex: none; }
.tourcard p { font-size: 15px; line-height: 1.8; color: var(--grey); }
.tourcard p b { color: var(--ink); font-weight: 800; }
.tourcard .tourhint { color: var(--clay-ink); }
.tourcard .tournav { display: flex; gap: 8px; align-items: stretch; margin-top: 2px; }
.tourcard .tournav .btn { flex: 1; min-height: 48px; padding: 10px 14px; }
.tourcard .tournav .tourback { flex: none; width: 52px; padding: 0; font-size: 17px; font-weight: 800; }
/* 44 px to hit, taking no room: the margins pull the card's padding in. */
.tourskip { align-self: flex-start; display: inline-flex; align-items: center; min-height: 44px; margin: -4px 0 -8px; padding: 0 4px; font-size: 13px; font-weight: 700; color: var(--grey); }
/* The pointing finger: a plain triangle off the card's edge, clay when the card hangs under its target (the clay edge), the card's white when it sits above. */
.tourcard .tourtip { position: absolute; width: 0; height: 0; }
.tourcard .tourtip.up   { top: -9px;    border-inline: 9px solid transparent; border-bottom: 9px solid var(--clay); }
.tourcard .tourtip.down { bottom: -9px; border-inline: 9px solid transparent; border-top: 9px solid var(--row); }


/* ══ TRAINING: Programme, Week, Session, Exercises ════════════════════════════════════════════════════════════════════════
   (viewProgramme, sessionCard, viewWeek, viewSession, exRow, exFacts, warmCard, viewTestDay, viewExercises, exListHtml,
   viewExercise.) Centre Court's rows and numeral (section 3) do the work; this section holds only what is special to these
   screens: the week tiles, the exercise row that opens in place, the reading lines. No shared part is overridden here. */

/* ── Programme: each block is a picture band (.band, 3.10), its goal as a grey line, and four week tiles. The numeral inside a
   tile is the shared .pnum.sm: solid when the week is open, outlined grey when it is locked. The block's last week is its test
   week and says «آزمون» in green. A tile is a link and at least 68 px tall. ── */
.bc-goal { margin-top: 10px; font-size: var(--fs-small); line-height: 1.75; color: var(--grey); }
.weeks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.week { display: grid; place-items: center; align-content: center; min-height: 68px; padding: 6px 0 4px; border: 1px solid var(--hair);
  border-radius: 12px; background: var(--row); color: inherit; text-decoration: none; }
a.week:active { background: var(--sand); }
.week .wl { font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--grey); }
.week .wl.test { font-weight: 800; color: var(--green-ink); }
.week.locked { background: transparent; }
.week.soon { background: transparent; opacity: .45; }
.block-card + .lead { margin-top: 24px; }

/* ── Week: the week's note, the session rows (.list-row, 3.7), the test day's stopwatch where a numeral would be ── */
.section > .note:first-child { margin-top: 20px; }
.lr-ic { display: grid; place-items: center; width: 44px; height: 44px; color: var(--green-ink); }
.lr-ic svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.acc + .list-row { border-top: 1px solid var(--hair); }
.acc-body .fact + .list { margin-top: 6px; }
.list-row.soon { opacity: .55; }
.list-row > .lock { margin: 0; }
.lead.closing { margin-top: 18px; }

/* ── Session: the one green button lives inside the cover now, so its wrapper is plain ── */
.cta-bar { margin-top: 18px; }

/* ── Exercise rows: a paper row, no box and no stripe, a hairline between neighbours. The button is a grid: the numeral in a 44 px
   column at the start, the body, the ⌄ at the end (turned over when open, the numeral then solid). The warm-up row has no numeral.
   The dose line steps aside once the row is open, because the scoreboard inside says the same numbers larger. ── */
.ex { overflow-wrap: anywhere; }
.ex + .ex { border-top: 1px solid var(--hair); }
.ex-main { display: grid; grid-template-columns: 44px minmax(0, 1fr) 24px; align-items: center; column-gap: 12px; width: 100%; min-height: 64px;
  padding: 12px 0; text-align: start; }
.ex-main:active { background: rgba(14,74,54,.05); }
.ex.warm .ex-main { grid-template-columns: minmax(0, 1fr) 24px; }
.ex .pnum { white-space: nowrap; overflow-wrap: normal; }
.ex-body { display: block; min-width: 0; }
.ex-name { display: block; font-size: var(--fs-lead); font-weight: 700; line-height: 1.5; }
.ex-dose { display: block; margin-top: 3px; font-size: 15px; font-weight: 500; line-height: 1.6; }
.ex-dose b { font-weight: 800; }
.ex-sub { display: block; margin-top: 2px; font-size: var(--fs-small); line-height: 1.65; color: var(--grey); }
.ex.open .pnum { color: var(--green-ink); }
.ex.open .chev { transform: rotate(180deg); }
.ex.open .ex-dose { display: none; }
.ex-detail { display: none; padding: 0 0 18px; }
.ex.open .ex-detail { display: block; }
.ex-links { display: flex; flex-wrap: wrap; column-gap: 22px; margin-top: 10px; }

/* ── What an exercise says (exFacts): reading lines under the .label titles ── */
.fact { font-size: 15px; line-height: 1.85; }
.fact.quiet { margin-top: 4px; font-size: var(--fs-small); color: var(--grey); }

/* ── Exercises: the search, the chips, the list ── */
.search + .chips { margin-top: 10px; }
#exlist { margin-top: 4px; }


/* ══ STEP, LEARN AND TESTS: step-by-step mode, Learn and a lesson, Tests and a test (the 1RM calculator, the Yo-Yo player) ══
   (renderStep, renderWarmStep, viewLearn, viewLesson, viewTests, testDayBody, viewTest, ormCalc, paintOrm, yoyoCard, the yy*
   functions.) Centre Court in Farsi: Learn and Tests are section 3's rows, numerals and shelves; a lesson and a test are prose on
   the paper under a cover; step mode is the training app's Guided look. A rule here that changes a shared part says "(override)"
   and is scoped to its screen. */

/* ── Step by step: the training app's Guided look ──
   A slim green bar (where you are, the ✕ at the end, a thin progress line along its foot), then the paper: the group as an
   eyebrow, the name, the numbers as the scoreboard, the sets as numerals, the coach's note and cues, the video. In the foot, one
   green button and the two outlined ones. The rest screen and the warm-up step share one ring. */
.step { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; background: var(--paper); }
.step-top { flex: none; padding-top: env(safe-area-inset-top); background: var(--bar); color: #fff; }
.step-top .row { display: flex; align-items: center; gap: 10px; min-height: 60px; padding: 8px 10px; padding-inline-start: var(--g); }
.step-top .where { flex: 1; min-width: 0; font-size: var(--fs-small); font-weight: 700; line-height: 1.5; color: #fff; }
.step-top .where .sep { opacity: .55; }
.step-top .x { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; color: #fff; font-size: 18px; line-height: 1;
  background: rgba(0,0,0,.22); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.step-top .x:active { transform: scale(.92); }
.bar { height: 3px; background: rgba(255,255,255,.18); }
.bar i { display: block; height: 100%; background: var(--mint); border-start-end-radius: 3px; border-end-end-radius: 3px; transition: width .3s; }

.step-body { flex: 1; min-height: 0; overflow-y: auto; width: 100%; max-width: 560px; margin: 0 auto; padding: 22px var(--g) 24px; }
.step-name { margin-top: 6px; font-size: var(--fs-head); font-weight: 900; line-height: 1.3; text-wrap: balance; }
.step-alt .ex-alt { margin-top: 4px; font-size: var(--fs-body); }
.step-body .stats { margin-top: 18px; }
.step-body .note { margin-top: 20px; }
.step-body .vunit { margin-top: 20px; }

/* The sets as numerals (P24's way): done = solid green, now = a green disc with a white numeral, still to come = outlined. */
.set-dots { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 20px; }
.set-dots i { display: grid; place-items: center; min-width: 40px; height: 40px; border-radius: 50%; font-style: normal; font-size: 24px; font-weight: 900;
  line-height: 1; font-variant-numeric: tabular-nums; color: transparent; -webkit-text-stroke: 1.3px var(--green-ink); }
.set-dots i.done { color: var(--green-ink); }
.set-dots i.now { background: var(--btn); color: #fff; -webkit-text-stroke: 0; box-shadow: 0 6px 14px -8px rgba(14,74,54,.7); }
@supports not (-webkit-text-stroke: 1px black) { .set-dots i { color: var(--ring); } .set-dots i.done { color: var(--green-ink); } .set-dots i.now { color: #fff; } }
.set-label { margin-top: 8px; font-size: var(--fs-lead); font-weight: 800; line-height: 1.5; }

/* The foot: the paper again, a hairline over it, the content held to the page width. */
.step-foot { flex: none; display: grid; gap: 10px; padding: 12px max(var(--g), calc((100% - 560px) / 2)) calc(14px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--hair); background: var(--paper); }
.step-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.step-nav .btn { min-height: 48px; font-size: 16px; }

/* The rest screen and the warm-up step: the ring green on the paper, the time in 56 px. */
.rest { padding: 10px 0 0; text-align: center; }
.rest-label { font-size: var(--fs-lead); font-weight: 800; color: var(--grey); }
.ring { position: relative; width: min(232px, 64vw); aspect-ratio: 1; margin: 12px auto 14px; }
.ring svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 10; }
.ring .track { stroke: var(--hair); }
.ring .prog { stroke: var(--fill); stroke-linecap: round; transition: stroke-dashoffset .25s linear; }
.ring .time { position: absolute; inset: 0; display: grid; place-items: center; font-size: 56px; font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums; }
@media (max-width: 359px) { .ring .time { font-size: 48px; } }   /* the ring is 64vw here: 10:00 in 56 px touches its edge */
.rest-actions { display: flex; justify-content: center; gap: 10px; }
.rest-actions .chip { padding: 0 22px; }
.rest-next { margin-top: 20px; font-size: var(--fs-small); line-height: 1.7; color: var(--grey); }

/* The end of the session: a green band in the cover treatment under the bar (override: the cover keeps its room for a back button
   at the top, and there is none here), then the sentence. */
.step .banner.is-cover.done-cover { flex: none; min-height: 236px; padding-top: 40px; }
.done-line { font-size: 17px; line-height: 1.95; }

/* ── Learn and Tests: the rows, numerals and shelves are section 3's; here the first shelf's room and a test's badge ── */
.section > .band:first-child { margin-top: 14px; }
.list-row .lr-sub b { font-weight: 700; color: var(--ink); }
.list-row .lr-sub.clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }   /* a long summary is a teaser here: the page has all of it */

/* ── A lesson and a test: prose on the paper ── */
.prose h3 { margin: 32px 0 8px; font-size: 20px; font-weight: 800; line-height: 1.5; color: var(--ink); }
.prose > h3:first-child { margin-top: 18px; }
.prose p { margin: 8px 0; font-size: 16px; line-height: 1.95; }
.prose p.lead { font-size: 15px; line-height: 1.8; }
.prose ul.list { margin: 8px 0; }
.prose ul.list li, .prose ol.steps li { font-size: 16px; line-height: 1.9; }   /* (override) section 3 sets lists at 15 px; here they read with the paragraphs */
.prose .callout { margin: 16px 0; border-radius: 10px; font-size: 16px; line-height: 1.8; }   /* (override) section 3's corners are handed; here all four are round */
.prose .card { margin: 16px 0; }
.prose .card h3 { margin: 0 0 6px; font-size: var(--fs-lead); }
.prose .card p { margin: 0; font-size: 15px; line-height: 1.85; }
.prose .acc { margin-top: 4px; }

/* The two tables, the RM guide and the results sheet: white, hairlines, a sand header; they scroll sideways inside their own box. */
.table-wrap { margin-top: 10px; overflow-x: auto; border: 1px solid var(--hair); border-radius: 12px; background: var(--row); -webkit-overflow-scrolling: touch; }
table.sheet, table.rmg { width: 100%; border-collapse: collapse; font-size: 14px; }
table.sheet { min-width: 420px; }
table.sheet th, table.sheet td, table.rmg th, table.rmg td { padding: 10px 12px; border-bottom: 1px solid var(--hair); text-align: start; vertical-align: top; line-height: 1.7; }
table.sheet th + th, table.sheet td + td, table.rmg th + th, table.rmg td + td { border-inline-start: 1px solid var(--hair); }
table.sheet tr:last-child td, table.rmg tr:last-child td { border-bottom: 0; }
table.sheet th, table.rmg th { background: var(--sand); font-weight: 800; color: var(--ink); }
table.sheet th, table.sheet td { text-align: center; vertical-align: middle; }
table.sheet th:first-child, table.sheet td:first-child { text-align: start; white-space: nowrap; }
table.sheet td { height: 48px; }
table.sheet td:first-child { font-weight: 700; }
table.rmg td:nth-child(2) { white-space: nowrap; font-weight: 800; color: var(--green-ink); }
.print-btn { margin-top: 14px; }

/* ── The Ceiling (سقف) calculator: one white panel, three boxes, the estimate large in green ── */
.orm-inputs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.orm-field { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 76px; padding: 8px 4px;
  border: 1.5px solid var(--box); border-radius: 12px; background: var(--paper); }
.orm-field:focus-within { border-color: var(--green-ink); box-shadow: 0 0 0 3px var(--tint); }
.orm-field.wide { margin-top: 14px; }
.orm-field input { width: 100%; min-width: 0; min-height: 44px; border: 0; outline: none; background: transparent; direction: ltr; text-align: center; font: inherit; font-size: 22px; font-weight: 800; color: var(--green-ink); }
.orm-field span { font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--grey); }
.orm-out { padding: 16px 0 2px; text-align: center; }
.orm-out b { display: block; font-size: 38px; font-weight: 900; line-height: 1.15; color: var(--green-ink); }
.orm-out i { font-style: normal; font-size: var(--fs-label); color: var(--grey); }
.orm-grade { margin-top: 4px; text-align: center; font-size: var(--fs-small); font-weight: 800; }
.orm-grade:empty { display: none; }
.orm-grade em { font-style: normal; font-weight: 500; color: var(--grey); }
.orm-grade.g1 { color: var(--green-ink); }
.orm-grade.g2, .orm-grade.g3 { color: var(--grey); }
.orm-from { margin-top: 8px; text-align: center; font-size: var(--fs-small); line-height: 1.75; }
.orm-ratio { margin-top: 8px; text-align: center; font-size: var(--fs-small); font-weight: 700; line-height: 1.7; }
.orm-ratio:empty { display: none; }
.orm-note { margin-top: 10px; text-align: center; font-size: var(--fs-label); color: var(--grey); }

/* ── The Yo-Yo IR1: the card on the test page, then the full-screen player (the three greens are the phases of a run) ── */
.yy-card .btn { margin-top: 14px; }
.yoyo { position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column; overflow-y: auto; background: var(--fill); color: #fff; transition: background .3s; }
.yoyo[hidden] { display: none; }
.yoyo[data-phase="rest"], .yoyo[data-phase="count"] { background: #2F6B57; }
.yoyo[data-phase="back"] { background: #0A3829; }
.yy-top { display: flex; justify-content: flex-end; padding: calc(10px + env(safe-area-inset-top)) 10px 0; }
.yy-x { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; font-size: 18px; line-height: 1; }
.yy-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 16px var(--g) 32px; text-align: center; }
.yy-level { font-size: var(--fs-lead); font-weight: 800; line-height: 1.5; }
.yy-speed { font-size: var(--fs-small); opacity: .85; }
.yy-left { font-size: 96px; font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums; }
.yy-phase { font-size: 22px; font-weight: 800; line-height: 1.5; }
.yy-dist-l { margin-top: 12px; font-size: var(--fs-label); opacity: .8; }
.yy-dist { font-size: 30px; font-weight: 900; }
.yy-hint, .yy-note { max-width: 420px; font-size: 15px; line-height: 1.8; opacity: .9; }
.yy-adj { display: flex; align-items: center; gap: 14px; }
.yy-adj button { min-width: 64px; min-height: 48px; padding: 0 14px; border-radius: 12px; background: rgba(255,255,255,.16); color: #fff; font-weight: 800; }
.yy-big { font-size: 56px; font-weight: 900; line-height: 1.1; }
.yy-big small { font-size: var(--fs-lead); font-weight: 700; }
.yy-vo2 { font-size: 22px; font-weight: 800; color: var(--mint); }
.yy-unit { margin-top: -6px; font-size: 12px; opacity: .8; }
.yoyo .btn { width: 100%; max-width: 360px; }
.yoyo .btn.primary { background: var(--row); color: var(--green-ink); box-shadow: none; }   /* (override) the green button on this green screen is white */
.yoyo .btn.primary .go-tri { border-color: transparent var(--fill) transparent transparent; }
.yoyo .btn.ghost { background: rgba(255,255,255,.16); color: #fff; border-color: transparent; }
.yoyo .btn.stop { margin-top: 18px; background: var(--clay); color: #fff; }
