/* ═══════════════════ Role palette ═══════════════════
   A role says **what the color is for**, not its shade: --surface means "card background",
   so it flips with the theme, and --on-accent means "text on a saturated color", so it does not.

   Mixing the two was the bug: a single #fff served both roles in 39 places, and replacing it
   with one variable would have blotted out nine badges that only show in the dark theme on a
   phone.

   **Zero hard-coded colors outside these two blocks.** A new element written with roles
   inherits both themes with no extra line; a single hard-coded color opens a light patch in the
   dark theme that nobody notices until they are at the gym.

   Contrast is measured, not estimated: node specs/006-dark-theme/contrast-check.mjs
   checks 21 pairs per theme and exits with 1 on any failure. */
:root{
  color-scheme: light;

  /* Surfaces */
  --bg:#E4E6E9; --surface:#FFFFFF; --surface-2:#F7F8F9;
  --line:#C9CDD3;            /* decorative divider — no minimum contrast */
  --line-strong:#767E88;     /* interactive component border — ≥3:1 required */

  /* Text */
  --text:#14171B; --text-2:#5C646E;

  /* Brand block — dark in both themes, and darker than its surroundings in both */
  --brand-surface:#14171B; --brand-surface-2:#222831;
  --on-brand:#FFFFFF; --brand-muted:#B4BBC3;
  --brand-chip:#1B1F25; --brand-chip-line:#39404A;

  /* The primary button is a role separate from the brand block even though they match in the
     light theme: the brand block becomes **darker** than the page in the dark theme, and a
     button darker than the card it sits on reads as a hole, not a button (measured: 1.38:1).

     The unified rule: **the primary button is the inverse of the page** — black on white in
     the light theme, white on black in the dark one. One rule gives maximum contrast in both
     themes, and nobody misses the primary action on a phone screen in a brightly lit gym. */
  --btn:#14171B; --on-btn:#FFFFFF; --btn-hover:#2A3038;

  /* The accent color. --on-accent flips **the other way**: the red becomes lighter in the
     dark theme, so white text on it gives 2.1:1 — an unreadable badge.
     Text follows the color it sits on, not the theme. */
  --accent:#C8102E; --accent-hover:#8E1220; --on-accent:#FFFFFF;
  --accent-line:#E8B4B4;

  /* States. The two values below are **corrected**: they were #12855A and #B07A00
     and failed 4.5:1 (4.18 and 3.73) — two bugs that predate this feature. */
  --ok:#0E6E4A; --warn:#946600; --info:#0B57A4;
  --ok-bg:#EAF6F0; --warn-bg:#FBF6EA; --err-bg:#FBEBEB; --info-bg:#EEF3FA;
  --ok-line:#A8D5C0;

  /* Shadows and scrims */
  --shadow:rgba(20,23,27,.10);
  --scrim:rgba(20,23,27,.82);
  --focus-glow:rgba(200,16,46,.13);

  /* Theme-independent on purpose: the video background is black in any player, and the scrim
     over the image is dark in both themes — so its text is white in both. A color follows what
     it sits on, not what surrounds it. */
  --video-bg:#000000;
  --on-scrim:#FFFFFF;

  /* Video frame background before the thumbnail loads. A role separate from
     --brand-surface-2 despite their closeness: it was #2A3038 here and #222831 on nav bar
     hover, and merging them really did change the light theme — breaking the "light stays as
     it was" promise. Two close values do not make one role. */
  --media-bg:#2A3038;
}

/* ═══ Dark theme — the default ═══
   Set on the <html> tag by the server before any byte of content, so there is no moment when
   the browser paints with the wrong color: the flash is prevented **structurally**, not deferred
   to a script. And color-scheme makes inputs, the date picker and scrollbars follow the theme
   from the browser itself — without it the picker opens as a white panel over a dark page. */
:root[data-theme="dark"]{
  color-scheme: dark;

  --bg:#0F1215; --surface:#181C21; --surface-2:#20252B;
  --line:#333A43; --line-strong:#626C77;

  --text:#E8EBEE; --text-2:#9BA5B0;

  /* Black, darker than the page background: the bar was darker than its surroundings and
     stays darker */
  --brand-surface:#000000; --brand-surface-2:#14181D;
  --on-brand:#FFFFFF; --brand-muted:#8C959F;
  --brand-chip:#1E242B; --brand-chip-line:#39424C;
  --btn:#E8EBEE; --on-btn:#0F1215; --btn-hover:#FFFFFF;
  --media-bg:#14181D;

  --accent:#FF4D6A; --accent-hover:#FF7085; --on-accent:#1A0509;
  --accent-line:#6B2430;

  --ok:#3FD79A; --warn:#F0B429; --info:#63A9F5;
  --ok-bg:#10261D; --warn-bg:#2A2110; --err-bg:#2B1215; --info-bg:#121E2E;
  --ok-line:#1F4A38;

  --shadow:rgba(0,0,0,.45);
  --scrim:rgba(0,0,0,.72);
  --focus-glow:rgba(255,77,106,.22);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--text);
  font-family:'IBM Plex Sans Arabic',system-ui,sans-serif;font-size:16px;line-height:1.7;
  -webkit-font-smoothing:antialiased;overflow-wrap:anywhere}
.wrap{max-width:860px;margin:0 auto;padding:0 16px}
a{color:inherit}
.num,.mono{font-family:'IBM Plex Mono',monospace;font-variant-numeric:tabular-nums}
/* Arabic text containing digits: the digits are tabular and the font stays Arabic. Forcing the
   monospace font on Arabic spaces its letters apart, so the word for "chest" reads as separate
   letters instead of one joined word. */
.numin{font-variant-numeric:tabular-nums}

.topbar{background:var(--brand-surface);color:var(--on-brand);position:sticky;top:0;z-index:30;border-bottom:4px solid var(--accent)}
.bar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 16px;flex-wrap:wrap}
.brand{font-family:'Alexandria',sans-serif;font-weight:800;font-size:19px;text-decoration:none;color:var(--on-brand);white-space:nowrap}
.brand span{color:var(--accent);margin-inline-start:5px}
.topbar nav{display:flex;gap:4px;flex-wrap:wrap}
.topbar nav a{text-decoration:none;color:var(--brand-muted);font-size:14px;font-weight:500;
  padding:6px 12px;border-radius:7px;transition:background .15s,color .15s}
.topbar nav a:hover{background:var(--brand-surface-2);color:var(--on-brand)}
.topbar nav a.on{background:var(--accent);color:var(--on-accent);font-weight:600}
.topbar nav a.out{color:var(--brand-muted)}
.topbar nav a:focus-visible{outline:2px solid var(--on-brand);outline-offset:2px}
/* Signed-in account badge. The green dot says "you are signed in as this identity" without an
   extra word, and the name is truncated with an ellipsis instead of pushing the nav bar onto a
   second line. */
.topbar nav .who{display:inline-flex;align-items:center;align-self:center;gap:6px;
  font-size:12.5px;font-weight:600;color:var(--on-brand);padding:5px 11px;
  border:1px solid var(--brand-chip-line);border-radius:999px;background:var(--brand-chip);
  max-width:11ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.topbar nav .who::before{content:"";flex:0 0 auto;width:6px;height:6px;
  border-radius:50%;background:var(--ok)}
@media(max-width:400px){
  .topbar nav .who{max-width:8ch;padding:4px 9px;font-size:12px}
}

h1{font-family:'Alexandria',sans-serif;font-weight:800;font-size:clamp(23px,5.5vw,32px);margin:26px 0 6px;line-height:1.2}
h2{font-family:'Alexandria',sans-serif;font-weight:700;font-size:19px;margin:28px 0 12px}
.sub{color:var(--text-2);font-size:14.5px;margin:0 0 18px}

.card{background:var(--surface);border:1px solid var(--line);border-radius:13px;padding:17px;margin-bottom:14px}
.card h3{font-family:'Alexandria',sans-serif;font-size:16px;margin:0 0 8px;font-weight:700}

.coach{background:var(--brand-surface);color:var(--on-brand);border:0;border-radius:13px;padding:20px;margin-bottom:16px}
.coach .kicker{font-family:'IBM Plex Mono',monospace;font-size:11px;letter-spacing:.18em;
  color:var(--brand-muted);text-transform:uppercase;margin:0 0 8px}
.coach h2{font-family:'Alexandria',sans-serif;font-size:clamp(21px,5vw,27px);margin:0 0 8px;color:var(--on-brand)}
.coach p{margin:0;color:var(--brand-muted);font-size:15px}
.coach .cta{display:inline-flex;align-items:center;gap:8px;margin-top:15px;background:var(--accent);
  color:var(--on-accent);text-decoration:none;font-weight:600;font-size:15px;padding:11px 22px;border-radius:9px}
.coach .cta:hover{opacity:.9}

.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:11px;overflow:hidden;margin-bottom:18px}
.stat{background:var(--surface);padding:13px 14px}
.stat b{display:block;font-family:'Alexandria',sans-serif;font-size:22px;font-weight:700;line-height:1.15}
.stat span{font-size:12.5px;color:var(--text-2)}

.exlist{display:grid;gap:11px;margin:0;padding:0;list-style:none}
.ex{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px}
.ex .top{display:flex;justify-content:space-between;gap:12px;align-items:baseline;flex-wrap:wrap}
.ex .name{font-family:'Alexandria',sans-serif;font-weight:700;font-size:16px}
.ex .target{font-family:'IBM Plex Mono',monospace;font-size:13px;font-weight:600;
  background:var(--brand-surface);color:var(--on-brand);border-radius:6px;padding:3px 9px;white-space:nowrap}
.ex .advice{margin:9px 0 0;font-size:14px;padding:9px 12px;border-radius:8px;
  background:var(--surface-2);border-inline-start:3px solid var(--text-2)}
.ex .advice.up{border-inline-start-color:var(--ok);background:var(--ok-bg)}
.ex .advice.keep{border-inline-start-color:var(--warn);background:var(--warn-bg)}
.ex .advice.new{border-inline-start-color:var(--info);background:var(--info-bg)}
.ex .muscles{font-size:12.5px;color:var(--text-2);margin-top:5px}

label{display:block;font-size:13.5px;font-weight:600;margin-bottom:5px}
input,select,textarea{width:100%;font-family:inherit;font-size:15px;padding:10px 12px;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--text)}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
.row{display:grid;gap:12px;margin-bottom:14px}
.row.two{grid-template-columns:1fr 1fr}
button,.btn{font-family:'IBM Plex Sans Arabic',sans-serif;font-size:15px;font-weight:600;cursor:pointer;
  background:var(--btn);color:var(--on-btn);border:1px solid var(--btn);border-radius:9px;
  padding:11px 22px;text-decoration:none;display:inline-block}
button:hover,.btn:hover{opacity:.88}
button.ghost,.btn.ghost{background:var(--surface);color:var(--text-2);border-color:var(--line)}
button.ghost:hover{color:var(--text);border-color:var(--text)}
button:focus-visible,.btn:focus-visible{outline:3px solid var(--accent);outline-offset:2px}

.sets{display:grid;gap:8px;margin-bottom:12px}
.setrow{display:grid;grid-template-columns:38px 1fr 1fr auto;gap:8px;align-items:center}
.setrow .no{font-family:'IBM Plex Mono',monospace;font-size:13px;color:var(--text-2);text-align:center}
/* min-width:0 is required: a grid item defaults to min-content, and the number input has an
   intrinsic width that refuses to shrink, pushing the page into horizontal scrolling at 360px. */
.setrow input{padding:9px 10px;min-width:0}
.hint{font-size:12.5px;color:var(--text-2);margin:4px 0 0}

.tablewrap{overflow-x:auto;background:var(--surface);border:1px solid var(--line);border-radius:12px}
table{width:100%;border-collapse:collapse;font-size:14px;min-width:420px}
th,td{padding:10px 13px;text-align:start;border-bottom:1px solid var(--line)}
th{background:var(--surface-2);font-weight:600;font-size:13px;color:var(--text-2);white-space:nowrap}
tr:last-child td{border-bottom:0}
td.n{font-family:'IBM Plex Mono',monospace;font-variant-numeric:tabular-nums;white-space:nowrap}

.pill{display:inline-block;font-size:12px;font-weight:600;padding:2px 10px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2)}
.pill.day{background:var(--brand-surface);color:var(--on-brand);border-color:var(--brand-surface)}

.msg{padding:12px 15px;border-radius:10px;margin-bottom:16px;font-size:14.5px}
.msg.ok{background:var(--ok-bg);border:1px solid var(--ok-line);color:var(--ok)}
.msg.err{background:var(--err-bg);border:1px solid var(--accent-line);color:var(--accent-hover)}
.empty{text-align:center;color:var(--text-2);padding:34px 16px;font-size:15px}

.loginpage{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.loginbox{background:var(--surface);border:1px solid var(--line);border-radius:15px;padding:30px 26px;width:100%;max-width:370px}
.loginbox h1{margin:0 0 4px;font-size:25px;text-align:center}
.loginbox .sub{text-align:center;margin-bottom:22px}
.loginbox button{width:100%;margin-top:6px}
.loginbox .row{margin-bottom:13px}
/* 026: the visitor count under the form — one short line that wraps at 360px */
.loginbox .visits{margin:12px 0 0;font-size:13px}

.foot{margin-top:44px;padding:22px 0 32px;border-top:1px solid var(--line);
  color:var(--text-2);font-size:12.5px;text-align:center}
.foot-note{margin:10px 0 0;font-size:12px;color:var(--text-2)}

/* ── Powered by badge ── */
.powered{display:inline-flex;align-items:center;gap:9px;direction:ltr;vertical-align:middle}
.pw-mark{width:15px;height:15px;flex:0 0 auto;border-radius:50%;
  border:3.5px solid var(--accent);background:transparent;
  box-shadow:inset 0 0 0 1px var(--shadow), 0 1px 0 var(--shadow)}
.pw-txt{display:flex;flex-direction:column;align-items:flex-start;gap:2px;line-height:1}
.pw-label{font-family:'IBM Plex Mono',monospace;font-size:8.5px;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:var(--text-2)}
.pw-name{font-family:'Alexandria',sans-serif;font-size:13px;font-weight:800;
  letter-spacing:.03em;color:var(--text)}
.pw-slot{margin-top:20px;padding-top:16px;border-top:1px solid var(--line);text-align:center}

.vid{position:relative;width:100%;aspect-ratio:9/16;max-width:270px;margin:12px auto 0;
  border-radius:10px;overflow:hidden;background:linear-gradient(160deg,var(--media-bg),var(--brand-surface));cursor:pointer}
.vid img{width:100%;height:100%;object-fit:cover;display:block}
.vid video,.vid iframe{width:100%;height:100%;border:0;display:block;background:var(--video-bg)}
.vid .play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.vid .play span{background:var(--scrim);color:var(--on-scrim);border-radius:999px;padding:9px 18px;font-size:13.5px;font-weight:600}
.vtabs{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:9px}
/* width:auto overrides the button{width:100%} rule in the phone range. A tab is not an action
   button but a choice tag, and its full width was turning seven tabs into seven lines and 232px
   that pushed the logging form off the screen. */
.vtab{font-size:12px;padding:4px 11px;border-radius:999px;background:var(--surface-2);
  border:1px solid var(--line);color:var(--text-2);cursor:pointer;
  width:auto;max-width:100%}
.vtabs .vtab{width:auto}

/* Equipment section divider (feature 011).
   `flex-basis:100%` breaks the line before each section, so the structure shows without a
   second bar — which keeps the 360px width free of horizontal scrolling (Principle VI).
   No hard-coded color: it all comes from the theme palette, so it works in light and dark. */
.vsec{flex-basis:100%;text-align:center;font-size:11px;letter-spacing:.02em;
  color:var(--text-2);margin:5px 0 1px;text-transform:none}
.vsec:first-child{margin-top:0}
.vtab[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--on-accent);font-weight:600}
.vfoot{display:flex;gap:8px;justify-content:center;margin-top:9px;flex-wrap:wrap}
.vfoot a,.vfoot button{font-size:13px;padding:8px 15px}

/* ═══ Schedule page — training mode ═══ */
.daytabs{justify-content:flex-start;margin-bottom:12px}

/* The "Your turn today" mark: a dot inside the tab, not a badge above it, so the bar neither
   grows taller nor breaks onto an extra line at 360px. */
.vtab.today{border-color:var(--accent)}
.todaydot{margin-inline-start:4px;color:var(--accent);font-weight:700;line-height:1}
/* On the selected tab the background turns red, so the dot flips to white to stay visible */
.vtab[aria-pressed="true"] .todaydot{color:var(--on-accent)}

/* The "why this day" line — shown only when the day is derived automatically */
.daywhy{font-size:13px;color:var(--text-2);margin:-4px 0 12px;line-height:1.6;
  border-inline-start:3px solid var(--accent);padding-inline-start:9px}
.trainbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:9px 14px;margin-bottom:14px}
.trainbar .prog{font-size:14px;color:var(--text-2)}
.trainbar .prog b{color:var(--text);font-size:17px}
.trainbar .viewbtn{font-size:13px;padding:8px 14px;white-space:nowrap}

.excols{display:grid;gap:12px;margin-top:10px}
.excol{min-width:0}
/* Your last weights: framed with a dashed line so they read as a "reference", not "advice" —
   the coach's advice above them is colored, and the visual separation keeps the number from
   being confused with the recommendation. */
.lastline{background:var(--surface-2);border:1px dashed var(--line);border-radius:8px;
  padding:8px 11px;margin:8px 0 0;font-size:13px;line-height:1.6}
.lastline strong{color:var(--text-2);font-weight:600}
.ex .advice.edit{border-inline-start-color:var(--accent);background:var(--err-bg)}
.ex.editing{border-color:var(--accent);box-shadow:0 0 0 2px var(--focus-glow)}
/* ── The toggle that reveals the logging fields ──
   A details element, not a script: folding and unfolding is native browser behavior, so the
   "logging works without JavaScript" promise still holds. And the four fields, folded by
   default, let the card be read before it is filled in. */
.logbox{margin-top:11px}
.logbtn{display:block;cursor:pointer;list-style:none;text-align:center;
  font-family:'IBM Plex Sans Arabic',sans-serif;font-size:15px;font-weight:600;
  background:var(--btn);color:var(--on-btn);border:1px solid var(--btn);border-radius:9px;
  padding:11px 22px;user-select:none}
.logbtn::-webkit-details-marker{display:none}   /* Safari draws a triangle without this */
.logbtn::marker{content:''}
.logbtn:hover{opacity:.88}
.logbtn:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
/* When open it turns into a secondary button: the primary button is now "Save" below the
   fields, and two dark buttons side by side make the user press the wrong one. */
.logbox[open] .logbtn{background:var(--surface);color:var(--text-2);border-color:var(--line);
  font-size:13.5px;padding:8px 16px;margin-bottom:10px}
.logbox[open] .logbtn::after{content:' ▲'}
.logbox:not([open]) .logbtn::after{content:' ▼'}

.exform{margin-top:0}
.exform .sets{margin-bottom:10px}
.exform button{width:100%}
.exform .hint{text-align:center}
.how{margin-top:11px}
.how summary{cursor:pointer;font-weight:600;font-size:14px}
.how ol{font-size:14px;padding-inline-start:20px;margin:9px 0 0}
.how .hint{margin-top:8px}
.swipe{display:none;gap:8px;justify-content:space-between;margin-top:11px}
.swipe .btn{font-size:13px;padding:7px 14px;width:auto}

.donebox{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:12px 15px;margin:16px 0 40px}
.donebox summary{cursor:pointer;font-family:'Alexandria',sans-serif;font-weight:700;font-size:15px}
.donelist{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:9px}
.donelist li{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  border-top:1px solid var(--line);padding-top:9px}
.donelist .dinfo{min-width:0}
.donelist .dname{display:block;font-weight:600;font-size:14px}
.donelist .dsets{font-size:12.5px;color:var(--text-2)}
.donelist .btn{font-size:12.5px;padding:6px 13px;width:auto}
.done-all{background:var(--ok-bg);border-color:var(--ok-line);color:var(--ok);font-size:15px}

/* ═══ Videos: the "near" tag and the entry to ordering ═══ */
.nearmark{display:inline-block;margin-inline-start:5px;font-size:9.5px;font-weight:700;
  padding:1px 6px;border-radius:999px;background:var(--warn);color:var(--on-accent);vertical-align:middle}
.vtab[aria-pressed="true"] .nearmark{background:var(--on-accent);color:var(--accent)}
.curatelink{display:block;text-align:center;margin-top:9px;font-size:12.5px;font-weight:600;
  color:var(--text-2);text-decoration:none;padding:5px}
.curatelink:hover{color:var(--text);text-decoration:underline}

/* ═══ Video ordering screen ═══ */
.vlist{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:8px}
.vrow{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--line);
  border-radius:11px;padding:10px 12px}
.vrow:target{border-color:var(--accent);box-shadow:0 0 0 2px var(--focus-glow)}
.vnum{flex:0 0 auto;width:26px;text-align:center;font-size:14px;font-weight:700;color:var(--text-2)}
.vinfo{flex:1 1 auto;min-width:0}
.vlabel{display:block;font-weight:600;font-size:14.5px;line-height:1.45}
.vkind{font-size:11.5px;color:var(--text-2)}
.vacts{flex:0 0 auto;display:flex;gap:5px;align-items:center}
.actf{margin:0}
/* Enough touch area for a single finger at the gym — no 18px buttons */
.vacts button{width:38px;height:38px;padding:0;font-size:15px;line-height:1;text-align:center}
.vacts .hidebtn{color:var(--accent);border-color:var(--accent-line)}
.vacts .hidebtn:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.actspace{width:38px;height:38px;flex:0 0 auto}
.vlist.muted .vrow{background:var(--surface-2);opacity:.75}
.vfootnav{display:flex;gap:10px;flex-wrap:wrap;margin:20px 0 40px}
.vfootnav .btn,.vfootnav button{width:auto}
.resetf{margin:0}
@media (max-width:600px){
  .vacts button,.actspace{width:34px;height:34px}
  .vfootnav{flex-direction:column}
  .vfootnav .btn,.vfootnav button,.resetf{width:100%;text-align:center}
}

/* ── Wide mode ──
   The horizontal scrolling here is inside the strip container only; the page body stays free
   of horizontal scrolling (Principle VI). Finger swiping works without a script, and the
   anchors are an alternative for those who do not swipe. */
.sched.wide .exlist{display:flex;gap:12px;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;padding-bottom:6px}
.sched.wide .exlist>.ex{flex:0 0 100%;scroll-snap-align:center}
.sched.wide .swipe{display:flex}
@media (min-width:901px){
  /* Wide screen: two cards side by side — the "one per screen" limit is phone-only (FR-022) */
  .sched.wide .exlist>.ex{flex-basis:calc(50% - 6px)}
}
/* The compaction below is conditioned on a short screen, not a narrow one. Measurement proved
   both conditions necessary: on a 360×640 portrait phone in wide mode, the width rule alone
   produced four 32px-wide cells — a layout that cannot be used at all.
   A height of 520px separates "a phone lying on its side" from everything else. */
@media (max-width:900px) and (max-height:520px){
  /* Phone in landscape: the height is only about 360px. Measuring at 740×360 showed that the
     first layout pushed the log button off the screen — and that button is the whole point of
     the mode. So everything not needed during the workout is hidden, and the logging column is
     compacted so the button stays visible without scrolling.
     dvh, not vh — the browser's moving toolbar makes vh lie on a phone. */
  /* The ordering entry point disappears here: the contract requires that curation tools not
     crowd the training path, and ordering happens once every few months, not while you lie
     between two sets. */
  .sched.wide h1,.sched.wide .daywarm,.sched.wide>h2,.sched.wide>.sub,
  .sched.wide .daytabs,.sched.wide .daywhy,.sched.wide .how,.sched.wide .muscles,
  .sched.wide .curatelink,
  .sched.wide .exform .hint,.sched.wide .setrow .pill{display:none}
  .sched.wide .trainbar{padding:6px 12px;margin-bottom:8px}
  .sched.wide .trainbar .prog{font-size:12.5px}
  .sched.wide .trainbar .prog b{font-size:15px}
  .sched.wide .trainbar .viewbtn{font-size:12px;padding:6px 12px}
  .sched.wide .exlist>.ex{max-height:calc(100dvh - 118px);overflow-y:auto;padding:8px 12px}
  .sched.wide .excols{grid-template-columns:1fr 1fr;align-items:start;gap:10px;margin-top:5px}
  /* Only the video column scrolls internally. The logging column must stay fully in view —
     it is the reason this mode exists. */
  .sched.wide .excol:first-child{max-height:calc(100dvh - 205px);overflow-y:auto}
  /* The video is square, not portrait: at 9/16 its height alone would exceed the screen */
  .sched.wide .vid{max-width:112px;aspect-ratio:1;margin-top:2px}
  .sched.wide .vtabs{margin-top:4px;gap:4px}
  .sched.wide .vtab{font-size:10.5px;padding:2px 7px}
  .sched.wide .vfoot{margin-top:4px;gap:4px}
  .sched.wide .vfoot a,.sched.wide .vfoot button{font-size:11px;padding:4px 8px}
  /* The coach's advice is hidden here, not because it is redundant but because the number
     matters more at this moment: the "Last time" line stays, and it decides how much you load. */
  .sched.wide .advice{display:none}
  .sched.wide .lastline{margin:0;padding:5px 9px;font-size:11.5px;line-height:1.45}
  /* The toggle adds height, and a landscape phone has none to spare: measuring at 740×360
     showed the save button 41px below the screen. So the toggle is compacted when open, and
     the "Last time" line is hidden then — you read it before opening, and the fields deserve
     the space more. */
  .sched.wide .logbox{margin-top:6px}
  .sched.wide .logbtn{padding:6px 12px;font-size:12.5px}
  .sched.wide .logbox[open] .logbtn{padding:3px 10px;font-size:11px;margin-bottom:5px}
  .sched.wide .excol:has(.logbox[open]) .lastline{display:none}
  .sched.wide .exform{margin-top:0}
  .sched.wide .exform .sets{grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:6px}
  /* The four sets side by side, not stacked: a landscape phone is wide with no height, and
     four stacked rows alone eat 147px out of 242. */
  .sched.wide .setrow{grid-template-columns:1fr;grid-template-rows:auto auto auto;gap:3px;
    background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:4px 5px}
  .sched.wide .setrow .no{font-size:10.5px;line-height:1.3}
  .sched.wide .setrow input{padding:4px 6px;font-size:13px;text-align:center}
  .sched.wide .exform button{padding:7px 14px;font-size:13.5px}
  /* The previous/next buttons move to the title line instead of the bottom of the card: the
     bottom falls off a 360px-tall screen, and navigation must be visible, not hunted for by
     scrolling — and that is where the thumb already sits with the phone propped up. */
  .sched.wide .exlist>.ex{display:grid;grid-template-columns:1fr auto;
    grid-template-areas:"hd nav" "body body";align-content:start;column-gap:8px}
  .sched.wide .exlist>.ex>.top{grid-area:hd;min-width:0}
  .sched.wide .exlist>.ex>.excols{grid-area:body}
  .sched.wide .swipe{grid-area:nav;margin:0;align-self:center;gap:5px}
  .sched.wide .swipe .btn{font-size:12px;padding:4px 10px}
  .sched.wide .swipe span:empty{display:none}
}

@media (max-width:600px){
  body{font-size:15px}
  .trainbar{padding:9px 12px}
  .trainbar .viewbtn{width:auto}
  .bar{padding:10px 14px}
  .brand{font-size:17px}
  .topbar nav a{font-size:13px;padding:5px 9px}
  .row.two{grid-template-columns:1fr}
  .setrow{grid-template-columns:32px 1fr 1fr auto;gap:6px}
  .card{padding:14px}
  button,.btn{width:100%;text-align:center}
  .vfoot a,.vfoot button{width:auto}
}

/* ═══ Wrong-video report — on the exercise card ═══
   Below the video footer, not inside it: the footer is the hot playback path during training,
   and reporting happens once every few months. Both are small and muted so they do not crowd
   "Watch the form". */
.vflags{display:flex;gap:6px;justify-content:center;flex-wrap:wrap;margin-top:7px}
.reportf,.hidef{margin:0;display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:center}
/* 34px tall, not 28: pressed with one thumb at the gym with the phone in one hand.
   Smaller than the playback buttons above them because they are secondary, but not so small
   that they cause mistakes. */
.vflags button{font-size:12px;padding:8px 13px;width:auto;color:var(--text-2);
  border-color:var(--line);background:transparent;line-height:1.45;min-height:34px}
.vflags .reportbtn:hover{color:var(--warn);border-color:var(--warn)}
/* Hide is red and report is gray **at rest**, not only on hover: a phone has no hover at all,
   and two actions done with one finger must look different before the touch, not after —
   otherwise a hide tap lands where a report was meant. */
.vflags .hidebtn{color:var(--accent);border-color:var(--accent-line)}
.vflags .hidebtn:hover{color:var(--on-accent);background:var(--accent);border-color:var(--accent)}
.whybox{margin:0}
.whybox>summary{font-size:12px;color:var(--text-2);cursor:pointer;padding:8px 11px;
  list-style:none;border-radius:7px;min-height:34px;display:flex;align-items:center}
.whybox>summary::-webkit-details-marker{display:none}
.whybox>summary:hover{color:var(--text);background:var(--surface-2)}
.whybox[open]>summary{color:var(--text);font-weight:600}
.whybox input{width:100%;margin-top:6px;font-size:13px;padding:8px 10px;
  border:1px solid var(--line);border-radius:8px;font-family:inherit}
.whybox input:focus{outline:2px solid var(--warn);outline-offset:1px;border-color:var(--warn)}
.reportedmark{display:inline-block;margin-inline-start:5px;font-size:9.5px;font-weight:700;
  padding:1px 6px;border-radius:999px;background:var(--info);color:var(--on-accent);vertical-align:middle}
.vtab[aria-pressed="true"] .reportedmark{background:var(--on-accent);color:var(--accent)}

/* Report counter badge in the nav bar */
.topbar nav .badge{display:inline-block;margin-inline-start:6px;min-width:18px;padding:0 5px;
  font-family:'IBM Plex Mono',monospace;font-size:11px;font-weight:600;line-height:18px;
  text-align:center;border-radius:999px;background:var(--accent);color:var(--on-accent)}
.topbar nav a.on .badge{background:var(--on-accent);color:var(--accent)}

/* ═══ Admin report inbox ═══ */
.rlist{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:10px}
.rrow{display:flex;align-items:flex-start;gap:12px;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;padding:13px 14px;flex-wrap:wrap}
.rinfo{flex:1 1 240px;min-width:0}
.rex{display:block;font-family:'Alexandria',sans-serif;font-weight:700;font-size:15px;line-height:1.4}
.rday{font-family:'IBM Plex Sans Arabic',sans-serif;font-weight:500;font-size:12px;
  color:var(--text-2);margin-inline-start:6px}
.rvid{display:block;font-size:13.5px;color:var(--text);margin-top:3px;line-height:1.6}
.rid{font-size:11.5px;color:var(--text-2);margin-inline-start:6px}
.rgone{display:inline-block;margin-top:5px;font-size:11.5px;font-weight:600;
  padding:2px 9px;border-radius:999px;background:var(--warn);color:var(--on-accent)}
.rmeta{display:block;font-size:12.5px;color:var(--text-2);margin-top:6px}
.rwhy{margin:7px 0 0;font-size:13px;color:var(--text);background:var(--surface-2);
  border-inline-start:3px solid var(--line);border-radius:7px;padding:7px 10px}
.racts{flex:0 0 auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.racts button,.racts .btn{width:auto;font-size:12.5px;padding:7px 13px}
.racts .hidebtn{color:var(--accent);border-color:var(--accent-line)}
.racts .hidebtn:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.rlist.muted .rrow{background:var(--surface-2);opacity:.8}
.pill.hidden{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.pill.dismissed{background:var(--ok);color:var(--on-accent);border-color:var(--ok)}

/* 360px: the buttons drop to a full line instead of pushing the page into horizontal scrolling */
@media (max-width:600px){
  .rrow{flex-direction:column;gap:9px}
  /* flex-basis is measured along the main axis: in a column direction it is **height**, not
     width, so 240px was forcing vertical space between the report text and its buttons. */
  .rinfo{flex:1 1 auto}
  .racts{width:100%}
  .racts form{flex:1 1 auto}
  .racts button,.racts .btn{width:100%;text-align:center}
  .vflags button{font-size:11px;padding:5px 9px}
}


/* ═══ Theme switcher ═══
   In the nav bar between the account badge and the logout link: near the session identity,
   not the navigation links, because it is a display preference, not a destination. And the
   touch target is 32px — pressed with one thumb like the rest of the bar. */
.themef{margin:0;display:flex;align-items:center}
.themebtn{width:32px;height:32px;padding:0;font-size:14px;line-height:1;
  display:flex;align-items:center;justify-content:center;
  background:transparent;color:var(--brand-muted);
  border:1px solid var(--brand-chip-line);border-radius:999px;cursor:pointer}
.themebtn:hover{background:var(--brand-surface-2);color:var(--on-brand)}
.themebtn:focus-visible{outline:2px solid var(--on-brand);outline-offset:2px}
/* The login page has no nav bar, so the switcher stands alone in its corner */
.loginthemes{position:absolute;top:16px;inset-inline-end:16px;
  display:flex;gap:8px;align-items:center}
.loginthemes .themebtn{border-color:var(--line);color:var(--text-2)}
.loginthemes .themebtn:hover{background:var(--surface-2);color:var(--text)}
@media (max-width:600px){
  .themebtn{width:30px;height:30px;font-size:13px}
}

/* ═══ Language switcher ═══
   Next to the theme switcher and shaped the same, so the two read as a pair, not two strangers.
   It differs in one thing: its content is **text**, not a symbol — "EN" is two letters and the
   Arabic label one — so its width has a fixed minimum with horizontal padding instead of a
   strict square, otherwise "EN" would be squeezed against its edges.
   And no hard-coded color here: the same roles the theme switcher uses (FR-028). */
.langf{margin:0;display:flex;align-items:center}
.langbtn{min-width:32px;height:32px;padding:0 7px;line-height:1;
  font-size:12px;font-weight:700;letter-spacing:.4px;
  display:flex;align-items:center;justify-content:center;
  background:transparent;color:var(--brand-muted);
  border:1px solid var(--brand-chip-line);border-radius:999px;cursor:pointer}
.langbtn:hover{background:var(--brand-surface-2);color:var(--on-brand)}
.langbtn:focus-visible{outline:2px solid var(--on-brand);outline-offset:2px}
.loginthemes .langbtn{border-color:var(--line);color:var(--text-2)}
.loginthemes .langbtn:hover{background:var(--surface-2);color:var(--text)}
@media (max-width:600px){
  .langbtn{min-width:30px;height:30px;padding:0 6px;font-size:11px}
}

/* ═══ Untranslated content tag ═══
   Shown next to Arabic text on an English page. Small and muted because it is **a declared
   state, not a bug**: a blank would lie, a raw key would confuse, and the tag tells the truth
   with the least noise. And it does not crowd the text: an inline block with tiny padding and
   a light border. */
.artag{display:inline-block;margin-inline-start:5px;padding:0 4px;
  font-size:10px;font-weight:700;line-height:1.5;letter-spacing:.3px;
  color:var(--text-2);background:var(--surface-2);
  border:1px solid var(--line);border-radius:4px;
  vertical-align:baseline;white-space:nowrap;cursor:help}

/* ═══ Schools page ═══ */
.schoolist{list-style:none;margin:0 0 24px;padding:0;display:grid;gap:12px}
.schoolcard{background:var(--surface);border:1px solid var(--line);
  border-radius:13px;padding:16px}
/* The user's school: a text tag **and a colored border together**, not color alone — so the
   distinction reaches screen readers and people who cannot tell colors apart. */
.schoolcard.mine{border-color:var(--accent);box-shadow:0 0 0 2px var(--focus-glow)}
.schtop{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.schname{font-family:'Alexandria',sans-serif;font-weight:700;font-size:17px;line-height:1.35}
.lv{font-size:11.5px;font-weight:700;padding:2px 10px;border-radius:999px;
  color:var(--on-accent);white-space:nowrap}
.lv.lv1{background:var(--ok)} .lv.lv2{background:var(--info)} .lv.lv3{background:var(--accent)}
.minetag{font-size:11.5px;font-weight:600;padding:2px 10px;border-radius:999px;
  background:var(--surface-2);color:var(--text-2);border:1px solid var(--line)}
.schwhy{margin:0 0 6px;font-size:14.5px;font-weight:600;color:var(--text)}
.schabout{margin:0 0 8px;font-size:13.5px;color:var(--text-2);line-height:1.65}
.schnote{margin:0 0 8px;font-size:12.5px;color:var(--text-2)}
.schgoal,.schcycle{margin:0 0 8px;font-size:12px;font-weight:700}
.schgoal{color:var(--info)}
.schcycle{color:var(--warn)}

/* Weekly volume: wrapping chips, not a table.
   Thirteen muscles in one row break 360px, and `flex-wrap` drops them line after line with no
   horizontal scrolling, however many there are. */
.schvol{display:flex;flex-wrap:wrap;gap:5px;margin:0 0 10px}
.vol{font-size:11.5px;padding:2px 8px;border-radius:999px;
  background:var(--surface-2);color:var(--text-2);border:1px solid var(--line);
  white-space:nowrap}
.schvolall{margin:0 0 10px}
.schvolall summary{font-size:12px;color:var(--text-2);cursor:pointer;
  padding:4px 0;list-style-position:inside}
.schvolall summary:hover{color:var(--text)}
.schvolall .schvol{margin-top:8px}
.schacts{display:flex;gap:8px;flex-wrap:wrap}
.schacts .btn,.schacts button{width:auto;font-size:13.5px;padding:9px 16px}
.pickf{margin:0}
.pill.sch{background:var(--surface-2);color:var(--text-2);border-color:var(--line);
  margin-inline-start:8px}
/* Section row inside the school program table */
.secrow td{background:var(--surface-2);font-weight:700;font-size:13px;
  color:var(--text-2);padding-top:9px}

/* ═══ Muscle section heading in the schedule ═══
   Separates a muscle's exercises from the ones before, so the trainee knows what they are
   targeting now. The line extending on both sides makes the break visible without a heavy
   background crowding the cards. */
.sechead{display:flex;align-items:center;gap:12px;margin:6px 2px 0;list-style:none}
.sechead::before,.sechead::after{content:"";flex:1 1 auto;height:1px;background:var(--line)}
.sechead span{flex:0 0 auto;font-family:'Alexandria',sans-serif;font-weight:700;
  font-size:13px;color:var(--text-2);letter-spacing:.02em}
@media (max-width:600px){
  .schacts .btn,.schacts button{width:100%;text-align:center}
  .schacts form{flex:1 1 100%}
  .sechead{gap:8px}
}

/* ═══ Print ═══
   The log is printed on white paper. A dark theme in print wastes ink and comes out
   unreadable, so the palette is forced to light whatever theme is shown on screen. */
@media print{
  :root, :root[data-theme="dark"]{
    color-scheme: light;
    --bg:#FFFFFF; --surface:#FFFFFF; --surface-2:#FFFFFF;
    --line:#999999; --line-strong:#666666;
    --text:#000000; --text-2:#333333;
    --brand-surface:#FFFFFF; --brand-surface-2:#FFFFFF;
    --on-brand:#000000; --brand-muted:#333333;
    --accent:#000000; --on-accent:#FFFFFF;
    --ok:#000000; --warn:#000000; --info:#000000;
    --ok-bg:#FFFFFF; --warn-bg:#FFFFFF; --err-bg:#FFFFFF; --info-bg:#FFFFFF;
    --shadow:transparent; --focus-glow:transparent;
  }
  .topbar, .foot, .themef, .langf, .swipe, .vwrap, .logbox, .vflags{display:none!important}
  .card, .ex, .rrow, .vrow{break-inside:avoid}
}

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