/* ======================================================================
   GymFork home page: the scroll motion (approved mockup, overnight/2026-10-23-site-motion, rounds 1-5; Kade's yes
   2026-10-26). Loaded on the home page only, after site.css.
   Rule: without .mo-on (no JS, or reduced motion) every block shows its finished state in normal flow.
   .mo-on (set by home-boot.js) adds the hero-to-band merge, two pins (the day, the ring) and scroll-driven motion.
   Motion writes only transform / opacity / SVG strokes, plus one background fade (the day turning to night).
   The site's CSP allows no style="" attributes, so every value the mockup set inline lives at the end of this file.
   ====================================================================== */

/* the app's own screen background, so a cropped screenshot sits in its card with no seam */
:root { --app-bg: #F5F5F0; --mo-out: cubic-bezier(0.22, 1, 0.36, 1); --mo-in: cubic-bezier(0.55, 0, 1, 0.45); --mo-reserve: 0px; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --app-bg: #111411; } }
@media (max-width: 59.99rem) { :root { --mo-reserve: 84px; } html { scroll-padding-bottom: 96px; } } /* the phone-only join bar sits here; keyboard focus scrolls clear of it */

/* ---------- shared ---------- */
.mo-h2 { font: 900 var(--text-2xl)/1 var(--font-display); letter-spacing: -0.042em; max-width: 16ch; text-wrap: balance; }
.mo-intro { margin-top: var(--space-md); max-width: 40ch; font-size: var(--text-md); color: var(--color-muted); text-wrap: pretty; }
.mo-track, .mo-stage { position: relative; }
html.mo-on { scroll-behavior: auto; }   /* a Tab from the hero to the ring jumps, it doesn't replay the merge and the day */
.mo-on .mo-stage { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.odo { display: inline-flex; align-items: flex-start; height: 1em; line-height: 1; overflow: hidden; vertical-align: -0.12em; font-variant-numeric: tabular-nums; }
.odo .c { display: flex; flex-direction: column; flex: none; }
.odo .c span, .odo .s { display: block; height: 1em; line-height: 1; flex: none; }
.ticks li, .sec .intro, .mo-cap p, .mo-item p { text-wrap: pretty; }

/* ============ 1 + 2. HERO and ONE APP INSTEAD OF TWO ============ */
.hero h1 .mo-l { overflow: hidden; padding-bottom: 0.1em; margin-bottom: -0.1em; }
.mo-on .hero h1 .mo-l > span { transform: translateY(108%); }
.mo-on .hero .pill, .mo-on .hero .lede, .mo-on .hero #join { opacity: 0; transform: translateY(14px); }
.mo-in .hero h1 .mo-l > span { transform: none; transition: transform 1s var(--mo-out); }
.mo-in .hero h1 .mo-l:nth-child(2) > span { transition-delay: 90ms; }
.mo-in .hero h1 .mo-l:nth-child(3) > span { transition-delay: 180ms; }
.mo-in .hero .pill, .mo-in .hero .lede, .mo-in .hero #join { opacity: 1; transform: none; transition: opacity 700ms var(--mo-out), transform 900ms var(--mo-out); }
.mo-in .hero .lede { transition-delay: 300ms; }
.mo-in .hero #join { transition-delay: 400ms; }
/* arriving from another page's "Join the waitlist" (/#join): the browser scrolls to the form before it rises, so it
   only fades in; rising 14 px after the jump would leave the email field's top edge above the screen */
.mo-on .hero #join:target { transform: none; }

/* two screens side by side at every width (the live site hid one under 640 px and between 960 and 1184 px) */
.screens { gap: 14px; align-items: flex-start; }   /* the live site stretched the first screen 48 px taller than its picture */
.screens .shot { flex: 0 1 290px; min-width: 0; }
.shot { box-shadow: var(--shadow-screen), 0 40px 80px -48px rgb(var(--color-shadow) / 0.32); }
@media (max-width: 39.99rem) {
  .screens { margin-right: 0; justify-content: center; }
  .screens .shot, .screens .shot.offset { display: block; flex: 0 1 min(44vw, 230px); border-radius: 24px; }
  .screens .shot.offset { margin-top: 32px; }
}
@media (min-width: 40rem) and (max-width: 59.99rem) { .screens { justify-content: center; margin-right: 0; } }
/* more room for the two screens beside the headline (they shrank to 256 px at 1440) */
@media (min-width: 74rem) { .hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr); } }

.mo-two .wrap { display: grid; gap: var(--space-xl); align-items: center; }
.mo-one { display: flex; justify-content: center; }
.mo-one .shot { width: min(64vw, 290px); border-color: var(--color-night-rule); }
.mo-two .intro { max-width: 40ch; }
@media (min-width: 60rem) { .mo-two .wrap { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); } }

/* motion: the static screens keep their place (and their alt text) but the moving copies are what you see */
.mo-on .mo-hm { position: relative; }
.mo-on .mo-hm .screens .shot, .mo-on .mo-one .shot { opacity: 0 !important; transform: none !important; transition: none !important; }
.mo-rail { position: absolute; left: 0; right: 0; z-index: 3; pointer-events: none; }
.mo-stick { position: sticky; }
.mo-ph { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; perspective: 2000px; }
.mo-ph .shot { position: relative; margin: 0; width: 100%; height: 100%; }
/* the stacked pair: the back card's screen fades to its own background, so only its edge shows behind the front card */
.mo-veil { position: absolute; inset: 0; z-index: 1; background: var(--app-bg); opacity: 0; pointer-events: none; }
/* phones: while the band rises, its heading fades out over the 28 px just above the screens' top edge (motion.js sets
   --ml, the edge, in the copy's own pixels, and --mf, the fade, which shrinks to 0 once the copy has cleared the edge),
   so no letter is ever cut in open space */
.mo-two-copy[data-mask] {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(var(--ml) - var(--mf, 28px)), transparent var(--ml));
  mask-image: linear-gradient(to bottom, #000 calc(var(--ml) - var(--mf, 28px)), transparent var(--ml));
}
.mo-ph .shot img { height: 100%; object-fit: cover; }
.mo-ph.b { z-index: 1; } .mo-ph.c { z-index: 2; }
.mo-glow { position: absolute; left: 0; top: 0; z-index: 0; transform-origin: 50% 50%; border-radius: 40%; opacity: 0; pointer-events: none; background: radial-gradient(closest-side, rgb(198 214 194 / 0.55), rgb(157 181 154 / 0.18) 60%, transparent); filter: blur(18px); }
/* the turn: every screen shows only its front, so the stacked pair turns over as one and the Today screen is its back */
.mo-tilt { width: 100%; height: 100%; transform-origin: 50% 50%; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
/* load-in: the two hero screens swing in once (the inner figure, so the scroll transform stays free) */
.mo-on .mo-ph:not(.c) .shot { opacity: 0; transform: rotateY(-24deg) rotateX(8deg) translateY(56px) scale(0.94); transform-origin: 50% 60%; }
.mo-in .mo-ph:not(.c) .shot { opacity: 1; transform: none; transition: transform 1.5s var(--mo-out) 250ms, opacity 700ms var(--mo-out) 250ms; }
.mo-in .mo-ph.b .shot { transition-delay: 400ms; }
@media (min-width: 60rem) { .mo-on .mo-two { display: grid; align-content: center; min-height: 100vh; min-height: 100svh; } }
/* phones and tablets: the band starts under the two hero screens and pins for 0.95 screens (round 5: 1.3 before; the
   still hold after the turn was half a screen). Its heading and intro sit on top; the screens hold below them, meet,
   and turn into the Today screen (motion.js). */
@media (max-width: 59.99rem) {
  .mo-on .mo-hm .hero { padding-bottom: 0; }
  .mo-on .mo-hm .screens { height: 0; margin-top: var(--space-lg); top: 22px; }
  .mo-on .mo-two { padding: 0; height: 195vh; height: 195svh; }
  .mo-on .mo-two > .wrap { position: sticky; top: 0; height: 100vh; height: 100svh; display: flex; flex-direction: column; gap: 0; padding-top: 28px; padding-bottom: calc(var(--mo-reserve) + 12px); }
  .mo-on .mo-two-copy { flex: none; }
  .mo-on .mo-two-copy h2 { font-size: clamp(1.875rem, 7.4vw, 2.75rem); max-width: 14ch; }
  .mo-on .mo-two .intro { margin-top: 10px; font-size: var(--text-base); max-width: 38ch; }
  .mo-on .mo-one { flex: 1 1 0; min-height: 0; margin-top: 16px; align-items: flex-end; }
  .mo-on .mo-one .shot { width: auto; max-width: 100%; height: 100%; aspect-ratio: 880 / 1812; }
  .mo-on .mo-one .shot img { width: 100%; height: 100%; object-fit: cover; }
}
@media (max-width: 59.99rem) and (max-height: 720px) {
  .mo-on .mo-two > .wrap { padding-top: 20px; }
  .mo-on .mo-two .intro { margin-top: 8px; font-size: var(--text-sm); }
}

/* ============ 3. A DAY WITH GYMFORK ============ */
.mo-day { background: var(--color-paper); }
.mo-day-grid { padding-block: var(--space-3xl); }
.mo-day-head h2 { font: 900 var(--text-2xl)/1 var(--font-display); letter-spacing: -0.042em; }
.mo-day-head p { margin-top: var(--space-sm); color: var(--color-muted); font-size: var(--text-md); }
.mo-clock, .mo-prog, .mo-dev { display: none; }
.mo-scene { display: grid; gap: var(--space-md) var(--space-2xl); margin-top: var(--space-2xl); align-items: center; }
.mo-time { font: 900 clamp(3rem, 5vw + 1.5rem, 6rem)/1 var(--font-display); letter-spacing: -0.05em; white-space: nowrap; }
.mo-time small, .mo-strip small { font-size: 0.3em; letter-spacing: 0; margin-left: 0.14em; color: var(--color-accent); font-weight: 800; }
.mo-cap h3 { font: 800 var(--text-xl)/1.1 var(--font-display); letter-spacing: -0.03em; }
.mo-cap p { margin-top: var(--space-xs); max-width: 36ch; color: var(--color-muted); font-size: var(--text-md); }
@media (min-width: 60rem) {
  .mo-scene { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); grid-template-areas: "time card" "cap card"; }
  .mo-scene .mo-time { grid-area: time; align-self: end; } .mo-scene .mo-cap { grid-area: cap; align-self: start; } .mo-scene .mo-card { grid-area: card; }
}

/* the cards: each one is a screen of the app on the app's own background (the gym and run cards are real screens) */
.mo-card { position: relative; display: flex; flex-direction: column; gap: 12px; min-height: 0; overflow: hidden; padding: 20px 18px; border-radius: 30px; background: var(--app-bg); border: 1px solid var(--color-rule); box-shadow: var(--shadow-screen), 0 30px 70px -40px rgb(var(--color-shadow) / 0.35); font-size: 0.875rem; line-height: 1.4; font-variant-numeric: tabular-nums; width: 100%; max-width: 420px; justify-self: center; }
.mo-card > * { flex: none; }
.mo-card .s-head { padding-inline: 4px; }
.mo-ttl { font: 900 1.375rem/1 var(--font-display); letter-spacing: -0.035em; }

/* breakfast: the top of the app's Food screen (its ring and range), one action area, then the meal */
.mo-sum { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-radius: 20px; background: var(--color-card); }
.mo-sring { position: relative; width: 76px; height: 76px; flex: none; }
.mo-sring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.mo-sring circle { fill: none; stroke-width: 8; }
.mo-sring .trk { stroke: var(--color-tint-2); }
.mo-sring .arc { stroke: var(--color-accent); stroke-linecap: round; transition: stroke-dasharray 500ms var(--mo-out); }
.mo-sring span { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; line-height: 1; }
.mo-sring b { font: 900 1.125rem/1 var(--font-display); letter-spacing: -0.02em; }
.mo-sring small { margin-top: 2px; color: var(--color-muted); font-size: 0.6875rem; }
.mo-sumr { flex: 1; min-width: 0; }
.mo-sumr small { display: block; color: var(--color-muted); font-size: 0.75rem; }
.mo-sumr b { font: 700 0.9375rem/1.2 var(--font-display); }
.mo-sbars { display: grid; gap: 5px; margin-top: 8px; }
.mo-sbars span { height: 5px; border-radius: 9px; background: var(--color-tint-2); overflow: hidden; }
.mo-sbars i { display: block; height: 100%; border-radius: inherit; transform-origin: left; transform: scaleX(var(--f, 0)); transition: transform 500ms var(--mo-out); }
.mo-sbars span:nth-child(1) i { background: var(--color-protein); } .mo-sbars span:nth-child(2) i { background: var(--color-carb); } .mo-sbars span:nth-child(3) i { background: var(--color-fat); }
.mo-act { position: relative; display: grid; flex: 1 1 124px; min-height: 96px; max-height: 250px; }
.mo-act > * { grid-area: 1 / 1; min-width: 0; }
.mo-scan { position: relative; border-radius: 20px; background: #111311; overflow: hidden; display: grid; place-items: center; }
.mo-scan::before { content: ""; position: absolute; inset: 14px 24%; border-radius: 12px; border: 2px solid rgb(255 255 255 / 0.18); }
.mo-code { display: flex; gap: 3px; height: 40%; max-height: 64px; }
.mo-code i { width: var(--b, 3px); background: #F2F3EE; border-radius: 1px; }
.mo-beam { position: absolute; left: calc(24% + 8px); right: calc(24% + 8px); top: 0; height: 2px; border-radius: 2px; background: #9DB59A; box-shadow: 0 0 14px 2px rgb(157 181 154 / 0.7); opacity: 0; }
.mo-found { position: absolute; left: 50%; bottom: 10px; translate: -50% 0; padding: 6px 11px; border-radius: var(--radius-pill); background: #9DB59A; color: #111311; font: 700 0.8125rem/1 var(--font-display); white-space: nowrap; }
.mo-find, .mo-recent { display: flex; flex-direction: column; justify-content: center; gap: 10px; padding: 14px; border-radius: 20px; background: var(--color-card); }
.mo-field { display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px; border-radius: var(--radius-pill); background: var(--app-bg); border: 1px solid var(--color-rule); font-weight: 500; }
.mo-field svg { width: 16px; height: 16px; color: var(--color-muted); flex: none; }
.mo-caret { width: 1.5px; height: 18px; background: var(--color-accent); margin-left: -6px; }
/* the search panel reads like the app's search: the field on top, the results under it (as many as fit) */
.mo-find { justify-content: flex-start; container-type: size; }
.mo-reslist { display: grid; gap: 6px; }
.mo-res { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 14px; background: var(--app-bg); transition: background-color 200ms var(--mo-out), box-shadow 200ms var(--mo-out); }
.mo-res.tap { box-shadow: inset 0 0 0 1.5px var(--color-accent); }
@container (max-height: 175px) { .mo-res.mo-more:last-child { display: none; } }
@container (max-height: 120px) { .mo-res.mo-more { display: none; } }
.mo-recent { container-type: size; }
@container (max-height: 110px) { .mo-chip.mo-more { display: none; } }
.mo-res b { font-weight: 600; } .mo-res small { display: block; color: var(--color-muted); font-size: 0.75rem; }
.mo-res em { font-style: normal; color: var(--color-muted); }
.mo-recent small { color: var(--color-muted); font-size: 0.75rem; font-weight: 600; }
.mo-recent div { display: flex; flex-wrap: wrap; gap: 8px; }
.mo-chip { padding: 8px 14px; border-radius: var(--radius-pill); background: var(--app-bg); border: 1px solid var(--color-rule); font-weight: 600; transition: background-color 200ms var(--mo-out), color 200ms var(--mo-out), transform 160ms var(--mo-out); }
.mo-chip.tap { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-on-accent); transform: scale(0.96); }
.mo-find, .mo-recent { opacity: 0; }   /* static page: the scan panel shows */
.mo-card .meal { margin-top: 0; padding: 11px 13px; border: 0; border-radius: 18px; background: var(--color-card); }
.mo-card .item { padding: 2px 0; }

/* gym and run: real screens. The screenshot is a plate inside the card: the gym's at the top, the run's at the bottom
   (so its splits stay in view on short phones); the card has the app's background, so no seam shows either way */
.mo-real { padding: 0; gap: 0; }
.mo-real-run { justify-content: flex-end; }
.mo-frame { position: relative; }
.mo-frame img { width: 100%; height: auto; }
.mo-flip { position: absolute; inset: 0; }
.mo-mark, .mo-tap, .mo-km, .mo-route { display: none; }
.mo-real::after { content: ""; position: absolute; inset: auto 0 0 0; height: 0; background: linear-gradient(transparent, var(--app-bg)); pointer-events: none; }
.mo-real-run::after { inset: 0 0 auto 0; background: linear-gradient(var(--app-bg), transparent); opacity: var(--tf, 1); }
.mo-gymc::after { display: none; }
/* gym (round 4): the whole workout screen, from "Squat" down to the app's own "Log set" button.
   fit: scaled to the frame's height and centred (the sides are the app's own background).
   pan (short frames, where the fitted screen would be under 0.66 of the frame's width): full width, and motion.js moves
   the screen inside the frame like a scroll (the `translate` property, so the scene change keeps its own `transform`). */
.mo-on .mo-gymc { align-items: center; }
.mo-on .mo-gymc > .mo-frame { height: 100%; width: auto; max-width: 100%; aspect-ratio: 880 / 1564; }
.mo-on .mo-gymc > .mo-frame img { width: 100%; height: 100%; }
.mo-on .mo-gymc[data-fit="pan"] { justify-content: flex-start; }
.mo-on .mo-gymc[data-fit="pan"] > .mo-frame { width: 100%; height: auto; max-width: none; }
.mo-on .mo-gymc[data-fit="pan"] > .mo-frame img { height: auto; }
.mo-on .mo-real-run > .mo-frame, .mo-on .mo-gymc[data-fit="pan"] > .mo-frame { will-change: transform, translate; }
/* the still page (no motion): the whole screen, at a phone-like width */
html:not(.mo-on) .mo-gymc { max-width: 340px; }

/* evening: the drawn Today card, dark, the same day's numbers as the app's screens above */
.mo-eve { background: var(--color-night-2); border-color: var(--color-night-rule); color: var(--color-on-night); box-shadow: 0 0 0 1px rgb(255 255 255 / 0.06), 0 30px 70px -40px rgb(0 0 0 / 0.5); }
.mo-eve .s-head .meta { color: var(--color-night-muted); }
.mo-eve-ring { position: relative; flex: 0 0 auto; height: 200px; aspect-ratio: 1; margin: 2px auto 0; }
.mo-eve-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.mo-eve-ring circle { fill: none; stroke-width: 16; }
.mo-eve-ring .trk { stroke: var(--color-night-rule); }
.mo-eve-ring .arc { stroke-linecap: round; }
.mo-eve-ring .a0 { stroke: #9DB59A; } .mo-eve-ring .a1 { stroke: var(--color-carb); } .mo-eve-ring .a2 { stroke: var(--color-fat); }
.mo-rc { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; text-align: center; }
.mo-eve-ring .mo-rc b { font: 900 2rem/1 var(--font-display); letter-spacing: -0.03em; }
.mo-eve-ring .mo-rc small { color: var(--color-night-muted); margin-top: 4px; font-size: 0.75rem; line-height: 1.2; }
.mo-eve-ring .mo-rc .mo-inr { margin-top: 2px; color: #C6D6C2; font-weight: 600; }
/* round 5: the ring is a size container, so on the smallest phones (320x568, where the ring is under 130 px) the centre
   text shrinks with it and "in your range" steps out (the caption above says it), instead of running into the arcs */
.mo-eve-ring { container-type: inline-size; }
.mo-on .mo-inr { opacity: 0; transform: translateY(4px); transition: opacity 300ms var(--mo-out), transform 400ms var(--mo-out); }
.mo-on .mo-inr.in { opacity: 1; transform: none; }
.mo-eve-list { list-style: none; }
.mo-eve-list li { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 9px 0; border-top: 1px solid var(--color-night-rule); }
.mo-eve-list li span { color: var(--color-night-muted); }
.mo-eve-list li b { font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.mo-eve-list .tro { width: 16px; height: 16px; color: var(--color-carb); }
/* the week, as the app's Today screen shows it: Monday, Tuesday, Thursday and today done */
.mo-week { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 10px; border-top: 1px solid var(--color-night-rule); }
.mo-week small { color: var(--color-night-muted); font-size: 0.8125rem; }
.mo-wk { display: flex; gap: 5px; }
.mo-wk i { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; border: 1.5px solid #4A524A; font-style: normal; }
.mo-wk b { font: 700 0.6875rem/1 var(--font-body); color: var(--color-night-muted); }
.mo-wk i.on { background: #9DB59A; border-color: #9DB59A; }
.mo-wk i.on b { color: #111311; }
.mo-wk i.now { box-shadow: 0 0 0 2px var(--color-night-2), 0 0 0 3.5px #C6D6C2; }

/* ---- the day, pinned ---- */
.mo-on .mo-day-track { height: 270vh; height: 270svh; }
.mo-on .mo-day-stage { --d-ink: var(--color-ink); --d-muted: var(--color-muted); --d-acc: var(--color-accent); --d-rule: var(--color-tint-2); background: var(--color-paper); color: var(--d-ink); transition: background-color 640ms var(--ease-in-out); }
.mo-on .mo-day-stage[data-night] { --d-ink: var(--color-on-night); --d-muted: var(--color-night-muted); --d-acc: var(--color-accent-night); --d-rule: var(--color-night-rule); background: var(--mo-night, var(--color-night)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --mo-night: #090A09; } }
/* the text colour switches in one step while the text is faded out (no mid-grey on mid-grey) */
.mo-on .mo-day-head, .mo-on .mo-clock, .mo-on .mo-prog, .mo-on .mo-cap { color: var(--d-ink); transition: color 0s linear 230ms; }
.mo-on .mo-day-head p, .mo-on .mo-cap p { color: var(--d-muted); transition: color 0s linear 230ms; }
.mo-on .mo-strip small { color: var(--d-acc); transition: color 0s linear 230ms; }
.mo-on .mo-dip .mo-day-head, .mo-on .mo-dip .mo-clock, .mo-on .mo-dip .mo-prog { animation: mo-dip 620ms linear; }
@keyframes mo-dip { 0% { opacity: 1; } 28%, 60% { opacity: 0; } 100% { opacity: 1; } }

.mo-on .mo-day-grid { display: grid; height: 100%; padding-block: var(--space-xl); grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); grid-template-rows: minmax(0, 1fr) auto auto auto auto minmax(0, 1fr); grid-template-areas: ". card" "head card" "time card" "cap card" "prog card" ". card"; column-gap: var(--space-3xl); }
.mo-on .mo-day-head { grid-area: head; }
.mo-on .mo-day-head h2 { font-size: var(--text-xl); letter-spacing: -0.03em; }
.mo-on .mo-day-head p { margin-top: 6px; font-size: var(--text-base); }
.mo-on .mo-scene { display: contents; }
.mo-on .mo-time { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.mo-on .mo-clock { grid-area: time; display: block; margin-top: var(--space-lg); height: 1.04em; overflow: hidden; font: 900 clamp(3.25rem, 5vw + 1.5rem, 6.5rem)/1 var(--font-display); letter-spacing: -0.05em; white-space: nowrap; }
.mo-strip { display: flex; flex-direction: column; transform: translateY(calc(var(--ci, 0) * -1.04em)); transition: transform 620ms var(--mo-out); }
.mo-strip > span { display: block; height: 1.04em; line-height: 1.04; }
.mo-on .mo-cap { grid-area: cap; margin-top: var(--space-md); }
.mo-on .mo-prog { grid-area: prog; display: block; margin-top: var(--space-xl); max-width: 420px; }
.mo-prog .segs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.mo-prog .segs span { height: 4px; border-radius: 9px; background: var(--d-rule); overflow: hidden; transition: background-color 0s linear 230ms; }
.mo-prog .segs i { display: block; height: 100%; border-radius: inherit; background: var(--d-acc); transform-origin: left; transform: scaleX(0); }
.mo-prog .labs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 8px; font-size: var(--text-xs); font-weight: 500; color: var(--d-muted); transition: color 0s linear 230ms; }
.mo-prog .labs span.on { color: var(--d-ink); font-weight: 650; }

/* one frame for all four scenes: .mo-dev is the phone-sized box (it never moves, fades or resizes); each scene's card
   sits exactly on it with no background of its own, so a scene change only swaps what is on the screen */
.mo-on .mo-dev, .mo-on .mo-card { grid-area: card; justify-self: center; align-self: center; width: min(420px, 100%); max-width: none; height: min(590px, calc(100svh - 2 * var(--space-xl) - 16px)); border-radius: 30px; }
.mo-on .mo-dev { display: block; background: var(--app-bg); border: 1px solid var(--color-rule); box-shadow: var(--shadow-screen), 0 30px 70px -40px rgb(var(--color-shadow) / 0.35); transition: background-color 170ms var(--ease-in-out), border-color 170ms var(--ease-in-out), box-shadow 170ms var(--ease-in-out); }
.mo-on .mo-day-stage[data-night] .mo-dev { background: var(--color-night-2); border-color: var(--color-night-rule); box-shadow: 0 0 0 1px rgb(255 255 255 / 0.06), 0 30px 70px -40px rgb(0 0 0 / 0.6); }
.mo-on .mo-card { background: transparent; border-color: transparent; box-shadow: none; }
/* captions swap with a short stagger so two are never readable at once */
.mo-on .mo-cap { opacity: 0; transform: translateY(12px); transition: opacity 140ms var(--mo-out), transform 140ms var(--mo-out), color 0s linear 230ms; pointer-events: none; }
.mo-on .mo-scene[data-st="past"] .mo-cap { transform: translateY(-10px); }
.mo-on .mo-scene[data-st="on"] .mo-cap { opacity: 1; transform: none; pointer-events: auto; transition: opacity 380ms var(--mo-out) 110ms, transform 520ms var(--mo-out) 110ms, color 0s linear 230ms; }
.mo-on .mo-swap .mo-scene[data-st="on"] .mo-cap { transition-delay: 360ms, 360ms, 230ms; }
/* a scene change: the old screen is gone by 110 ms, the new one starts at 90 ms (both are under 10% at the overlap) */
.mo-on .mo-card { z-index: 1; opacity: 0; pointer-events: none; transition: opacity 110ms linear; }
.mo-on .mo-card > * { transform: translateY(10px); transition: transform 110ms linear; }
.mo-on .mo-scene[data-st="past"] .mo-card > * { transform: translateY(-8px); }
.mo-on .mo-scene[data-st="on"] .mo-card { z-index: 2; opacity: 1; pointer-events: auto; transition: opacity 260ms var(--mo-out) 90ms; }
.mo-on .mo-scene[data-st="on"] .mo-card > * { transform: none; transition: transform 440ms var(--mo-out) 90ms; }
/* into the night (and back): the leaving screen holds 30 ms longer (gone by 140 ms) and the new one starts at 115 ms,
   while the frame turns (170 ms), so the frame is never empty and the two are never both readable */
.mo-on .mo-swap .mo-scene:not([data-st="on"]) .mo-card { transition: opacity 110ms linear 30ms; }
.mo-on .mo-swap .mo-scene[data-st="on"] .mo-card { transition-delay: 115ms; }
.mo-on .mo-swap .mo-scene[data-st="on"] .mo-card > * { transition-delay: 115ms; }

/* motion pieces inside the cards */
.mo-on .mo-found { opacity: 0; scale: 0.8; transition: opacity 250ms var(--mo-out), scale 350ms var(--mo-out); }
.mo-on .mo-found.in { opacity: 1; scale: 1; }
.mo-on .mo-act > * { opacity: 0; transform: translateY(8px); transition: opacity 220ms var(--mo-out), transform 320ms var(--mo-out); }
.mo-on .mo-act > .on { opacity: 1; transform: none; }
.mo-on .mo-reslist { opacity: 0; transform: translateY(6px); transition: opacity 220ms var(--mo-out), transform 300ms var(--mo-out); }
.mo-on .mo-reslist.in { opacity: 1; transform: none; }
.mo-on .mo-caret { animation: mo-blink 900ms steps(1) infinite; }
.mo-on .mo-away .mo-caret { animation-play-state: paused; }
@keyframes mo-blink { 50% { opacity: 0; } }
.mo-on .mo-card .item { max-height: 0; margin-top: 0; overflow: hidden; opacity: 0; transform: translateX(14px); transition: max-height 380ms var(--mo-out), margin-top 380ms var(--mo-out), opacity 300ms var(--mo-out) 60ms, transform 450ms var(--mo-out) 60ms; }
.mo-on .mo-card .item.in { max-height: 2.6em; margin-top: var(--itm, 7px); opacity: 1; transform: none; }
.mo-on .mo-flip { opacity: 0; transition: opacity 220ms var(--mo-out); }
.mo-on .mo-flip.in { opacity: 1; }
.mo-on .mo-mark { display: block; position: absolute; left: var(--x); top: var(--y); width: var(--w); height: var(--h); border-radius: 16px; box-shadow: 0 0 0 3px var(--color-accent), 0 0 0 9px rgb(79 107 76 / 0.16); opacity: 0; transform: scale(1.06); transition: opacity 260ms var(--mo-out), transform 420ms var(--mo-out); pointer-events: none; }
.mo-on .mo-mark.round { border-radius: 12px; }
.mo-on .mo-mark.in { opacity: 1; transform: none; }
/* the finger: a sage disc with a light rim, so it shows on the app's black "Log set" button and on light rows alike */
.mo-on .mo-tap { display: block; position: absolute; left: var(--x); top: var(--y); width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%; background: rgb(157 181 154 / 0.55); box-shadow: 0 0 0 2px rgb(255 255 255 / 0.75), 0 0 0 3px rgb(17 19 17 / 0.14); opacity: 0; transform: scale(0.4); pointer-events: none; }
.mo-on .mo-tap.go { animation: mo-tap 620ms var(--mo-out) forwards; }
@keyframes mo-tap { 0% { opacity: 0; transform: scale(0.4); } 25% { opacity: 1; transform: scale(0.9); } 100% { opacity: 0; transform: scale(1.7); } }
.mo-on .mo-route { display: block; position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.mo-route path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
/* light screens: the app's route is knocked back to a pale trace, and the run builds up over it in the app's own route
   colour (#4F6B4C, 14 px in capture pixels, the same as the app draws it) with a white casing; once the loop is run the
   overlay fades and the app's own route is what is left, so nothing jumps. Dark screens (round 5, REVIEW-4 N1): the same
   idea, so the route is drawn by the dot there too: the app's route is knocked back to a dim night trace, and the run
   builds up in the app's own dark-mode route colour (#9DB59A, 14 px) with a soft sage glow.
   The start pin and the museum label (cut out of the capture, round 5 N2) sit above the drawn line, as in the app. */
.mo-route .knock { stroke: #F8F7F2; stroke-width: 26; opacity: 0.74; }
.mo-route .glow { display: none; stroke: #9DB59A; stroke-width: 34; opacity: 0.32; }
.mo-route .case { stroke: #FFFFFF; stroke-width: 26; }
.mo-route .line { stroke: #4F6B4C; stroke-width: 14; }
.mo-route .dot { fill: #4F6B4C; stroke: #FFFFFF; stroke-width: 8; }
.mo-route .pin-d { display: none; }
.mo-on .mo-km { display: block; position: absolute; left: 4.6%; right: 4.6%; top: var(--y); height: 4.6%; margin-top: -2.3%; border-radius: 10px; background: rgb(79 107 76 / 0.12); opacity: 0; transition: opacity 260ms var(--mo-out); pointer-events: none; }
.mo-on .mo-km.in { opacity: 1; }
.mo-on .mo-km.best.top { background: rgb(79 107 76 / 0.2); box-shadow: inset 0 0 0 2px rgb(79 107 76 / 0.5); }
.mo-on .mo-eve-list li { opacity: 0; transform: translateY(8px); transition: opacity 300ms var(--mo-out), transform 420ms var(--mo-out); }
.mo-on .mo-eve-list li.in { opacity: 1; transform: none; }
.mo-on .mo-week { opacity: 0; transform: translateY(8px); transition: opacity 360ms var(--mo-out), transform 460ms var(--mo-out); }
.mo-on .mo-week.lit { opacity: 1; transform: none; }
.mo-on .mo-week .mo-wk i.on { transform: scale(0.6); transition: transform 380ms var(--mo-out); }
.mo-on .mo-week.lit .mo-wk i.on { transform: none; }
.mo-on .mo-week.lit .mo-wk i.on:nth-child(2) { transition-delay: 60ms; } .mo-on .mo-week.lit .mo-wk i.on:nth-child(4) { transition-delay: 120ms; } .mo-on .mo-week.lit .mo-wk i.on:nth-child(6) { transition-delay: 220ms; }

/* dark screens: the marks and the run overlay switch to the sage set */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mo-route .glow { display: inline; }
  :root:not([data-theme="light"]) .mo-route .knock { stroke: #10141C; opacity: 0.76; }
  :root:not([data-theme="light"]) .mo-route .case { display: none; }
  :root:not([data-theme="light"]) .mo-route .line { stroke: #9DB59A; }
  :root:not([data-theme="light"]) .mo-route .pin-l { display: none; }
  :root:not([data-theme="light"]) .mo-route .pin-d { display: inline; }
  :root:not([data-theme="light"]) .mo-route .dot { fill: #9DB59A; stroke: #111311; }
  :root:not([data-theme="light"]) .mo-km { background: rgb(157 181 154 / 0.14); }
  :root:not([data-theme="light"]) .mo-mark { box-shadow: 0 0 0 3px #9DB59A, 0 0 0 9px rgb(157 181 154 / 0.18); }
}

@media (max-width: 59.99rem) {
  .mo-on .mo-day-grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto minmax(0, 1fr); grid-template-areas: "head" "time" "cap" "prog" "card"; padding: 18px var(--gutter) calc(var(--mo-reserve) + 4px); column-gap: 0; }
  .mo-on .mo-day-head h2 { font-size: 1.375rem; }
  .mo-on .mo-day-head p { font-size: var(--text-sm); margin-top: 2px; }
  .mo-on .mo-clock { margin-top: 10px; font-size: clamp(3rem, 12vw, 4.25rem); }
  .mo-on .mo-cap { margin-top: 4px; }
  .mo-on .mo-cap h3 { font-size: 1.375rem; }
  .mo-on .mo-cap p { font-size: var(--text-sm); }
  .mo-on .mo-prog { margin-top: 14px; max-width: none; }
  /* the frame fills the rest of the screen, centred (tablets too) */
  .mo-on .mo-dev, .mo-on .mo-card { align-self: stretch; height: auto; width: 100%; max-width: 440px; margin-top: 14px; }
  .mo-on .mo-card { padding: 16px; gap: 10px; }
  .mo-on .mo-real { padding: 0; gap: 0; }
  .mo-on .mo-real::after { height: 44px; }
  .mo-on .mo-real-run::after { height: 36px; }
  .mo-on .mo-eve-ring { flex: 1 1 0; height: auto; min-height: 92px; max-height: 230px; margin-block: auto; }
  /* tablets: the frame stays phone-shaped (no taller than 560 px), centred under the clock */
  .mo-on .mo-dev, .mo-on .mo-card { max-height: 560px; }
  .mo-on .mo-bk .meal { margin-top: auto; }
  .mo-on .mo-eve-ring .mo-rc b { font-size: 1.75rem; }
  .mo-on .mo-card .meal { flex: 0 1 auto; min-height: 0; overflow: hidden; }
}
@media (max-width: 59.99rem) and (max-height: 760px) {
  .mo-on .mo-day-head p { display: none; }
  .mo-on .mo-clock { font-size: 2.75rem; margin-top: 6px; }
  .mo-on .mo-prog { margin-top: 10px; }
  .mo-on .mo-prog .labs { margin-top: 4px; }
  .mo-on .mo-dev, .mo-on .mo-card { margin-top: 10px; }
  .mo-on .mo-card { padding: 12px 12px; gap: 8px; }
  .mo-on .mo-real { padding: 0; }
  .mo-on .mo-act { flex-basis: 96px; min-height: 84px; }
  .mo-on .mo-sum { padding: 8px 10px; gap: 10px; }
  .mo-on .mo-sring { width: 52px; height: 52px; }
  .mo-on .mo-sring b { font-size: 0.875rem; }
  .mo-on .mo-sring small { display: none; }
  .mo-on .mo-sbars { margin-top: 4px; gap: 3px; }
  .mo-on .mo-sbars span { height: 4px; }
  .mo-on .mo-recent small { display: none; }
  .mo-on .mo-find, .mo-on .mo-recent { padding: 10px; gap: 6px; }
  .mo-on .mo-field { height: 34px; }
  .mo-on .mo-res { padding: 5px 10px; }
  .mo-on .mo-card .meal { padding: 8px 11px; }
  .mo-on .mo-card .item { padding: 0; }
  .mo-on .mo-card { --itm: 4px; }
  .mo-on .mo-eve-list li { padding: 6px 0; }
  .mo-on .mo-week { padding-top: 8px; }
  .mo-on .mo-eve-ring .mo-rc b { font-size: 1.375rem; }
  .mo-on .mo-eve-ring .mo-rc small { font-size: 0.6875rem; }
}
/* the smallest phones (320x568): the evening card fits whole (round 5: its "This week" row was cut off by the card's
   bottom edge, and the week's seven days wrapped onto a second line) */
@media (max-width: 59.99rem) and (max-height: 620px) {
  .mo-on .mo-eve { gap: 6px; }
  .mo-on .mo-eve-ring { min-height: 72px; }
  .mo-on .mo-eve-list li { padding: 3px 0; }
  .mo-on .mo-week { padding-top: 6px; gap: 6px; }
  .mo-on .mo-wk { gap: 4px; }
  .mo-on .mo-wk i { width: 21px; height: 21px; }
}

/* ============ 4. TRACK AS LOOSELY OR AS CLOSELY (the ring) ============ */
.mo-ring-sec { padding-block: clamp(3.5rem, 4vw + 2rem, 5.5rem); }
.mo-ring-grid { display: grid; gap: var(--space-xl); align-items: center; }
.mo-note { margin-top: var(--space-md); color: var(--color-muted); font-size: var(--text-sm); }
.mo-ring-wrap { display: grid; justify-items: center; gap: 14px; width: 100%; perspective: 1600px; }
.mo-seg { position: relative; display: grid; grid-template-columns: 1fr 1fr; width: min(100%, 400px); margin: 0; padding: 4px; border: 0; border-radius: var(--radius-pill); background: var(--color-tint); font: 700 var(--text-sm)/1 var(--font-display); }
.mo-seg label { position: relative; z-index: 1; display: grid; place-items: center; min-height: 44px; padding: 0 10px; border-radius: var(--radius-pill); color: var(--color-muted); text-align: center; cursor: pointer; transition: color 300ms var(--mo-out); }
.mo-seg input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.mo-seg label:has(input:checked) { color: var(--color-ink); }
.mo-seg label:has(input:focus-visible) { outline: 3px solid var(--color-focus); outline-offset: 2px; }
.mo-seg > i { position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: var(--radius-pill); background: var(--color-card); box-shadow: 0 1px 2px rgb(var(--color-shadow) / 0.08), 0 6px 16px -8px rgb(var(--color-shadow) / 0.25); transition: transform 460ms var(--mo-out); }
.mo-seg:has(input[value="all"]:checked) > i { transform: translateX(100%); }

.mo-rcard { width: min(100%, 400px); padding: 22px 22px 24px; border-radius: 34px; background: var(--color-card); border: 1px solid var(--color-rule); box-shadow: var(--shadow-screen), 0 30px 70px -40px rgb(var(--color-shadow) / 0.35); font-variant-numeric: tabular-nums; transform-origin: 50% 100%; }
.mo-rhead { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; }
.mo-rhead small { display: block; color: var(--color-muted); font-size: var(--text-xs); font-weight: 500; }
.mo-rhead b { display: block; margin-top: 2px; font: 900 1.5rem/1 var(--font-display); letter-spacing: -0.035em; }
/* Go all in: the range sits beside the card title, the way the app's Food screen shows it, so the ring's centre only
   holds the number (round 4: the "Range" line no longer runs into the ring on phones). Keep it loose shows the range on
   the ring itself (the band and its two labels), so the two never show at once. */
.mo-rrange { text-align: right; opacity: 0; transition: opacity 360ms var(--mo-out); }
.mo-ring-wrap[data-mode="all"] .mo-rrange { opacity: 1; }
.mo-rhead .mo-rrange b { font: 700 1rem/1.15 var(--font-display); letter-spacing: -0.01em; white-space: nowrap; }
.mo-rrange b span { font: 500 0.8125rem var(--font-body); color: var(--color-muted); }
/* the centre text is sized from the ring itself (cqw = 1% of the ring's width; the track's inner edge is at 72.5cqw
   across), so it keeps at least 6 px clear of the ring at every size */
.mo-ring { position: relative; width: min(260px, 70%); aspect-ratio: 1; margin: 18px auto 10px; container-type: inline-size; }
.mo-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.mo-ring circle { fill: none; }
.mo-ring .trk { stroke: var(--color-tint-2); stroke-width: 18; }
.mo-ring .arc { stroke-width: 18; stroke-linecap: round; }
.mo-ring .one, .mo-ring .a0 { stroke: var(--color-protein); } .mo-ring .a1 { stroke: var(--color-carb); } .mo-ring .a2 { stroke: var(--color-fat); }
.mo-ring .band { stroke: var(--color-accent); stroke-width: 6; stroke-linecap: round; opacity: 0.45; transition: opacity 300ms var(--mo-out); }
.mo-ring .band.lit { opacity: 1; }
.mo-tick { position: absolute; left: var(--tx); top: var(--ty); translate: -50% -50%; color: var(--color-muted); font: 600 0.75rem/1 var(--font-body); white-space: nowrap; }
/* the range is the last eighth of the ring (2,450 at 10:30, 2,800 at 12): one label each side of the band */
.mo-tick[data-tick="0"] { --tx: 2%; --ty: 9%; } .mo-tick[data-tick="1"] { --tx: 64%; --ty: -5%; }
.mo-ring .mo-rc small { margin-top: 3px; color: var(--color-muted); font-size: clamp(0.6875rem, 5.4cqw, 0.8125rem); font-weight: 500; line-height: 1.2; }
.mo-c-loose b { margin-top: 2px; font: 900 clamp(0.6875rem, 8.6cqw, 1.5rem)/1.05 var(--font-display); letter-spacing: -0.035em; white-space: nowrap; }
.mo-c-all .mo-kcal { font: 900 clamp(1.25rem, 18cqw, 3rem)/1 var(--font-display); letter-spacing: -0.04em; }
.mo-legend { display: grid; margin-top: 8px; }
.mo-lg { grid-area: 1 / 1; display: grid; align-content: start; gap: 10px; transition: opacity 360ms var(--mo-out), transform 460ms var(--mo-out); }
.mo-mac { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto; align-items: center; gap: 4px 10px; font-size: var(--text-sm); }
.mo-mac > i { width: 10px; height: 10px; border-radius: 50%; background: var(--color-protein); }
.mo-mac > i.m { background: var(--color-carb); }
.mo-mac b { font-weight: 600; }
.mo-mac .mo-bar2, .mo-rbar { grid-column: 2 / -1; position: relative; height: 6px; border-radius: 9px; background: var(--color-tint-2); overflow: hidden; }
.mo-mac .mo-bar2 i { display: block; height: 100%; border-radius: inherit; transform-origin: left; transform: scaleX(var(--f, 1)); }
.mo-mac[data-m="0"] > i, .mo-mac[data-m="0"] .mo-bar2 i { background: var(--color-protein); }
.mo-mac[data-m="1"] > i, .mo-mac[data-m="1"] .mo-bar2 i { background: var(--color-carb); }
.mo-mac[data-m="2"] > i, .mo-mac[data-m="2"] .mo-bar2 i { background: var(--color-fat); }
.mo-rbar s { position: absolute; left: 60%; width: 26%; top: 0; bottom: 0; border-radius: 9px; background: var(--color-accent-soft); box-shadow: inset 0 0 0 1.5px var(--color-accent); }
.mo-rbar i { position: absolute; top: 50%; left: var(--pm, 79%); width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: var(--color-accent); }
.mo-rbar { overflow: visible; }
.mo-dots { grid-column: 2 / -1; display: flex; gap: 6px; }
.mo-dots i { width: 22px; height: 6px; border-radius: 9px; background: var(--color-tint-2); }
.mo-dots i.on, .mo-dots:not([data-n]) i { background: var(--color-carb); }
.mo-lg-loose { align-content: space-between; }
.mo-quiet { padding: 8px 12px; border-radius: 12px; background: var(--color-tint); color: var(--color-muted); font-size: 0.8125rem; line-height: 1.35; }
.mo-micro { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 2px; }
.mo-micro span { padding: 7px 8px; border-radius: 12px; background: var(--color-tint); color: var(--color-muted); font-size: 0.75rem; line-height: 1.25; }
.mo-micro b { display: block; color: var(--color-ink); font: 700 0.875rem/1.2 var(--font-display); }
/* the two states: Keep it loose shows words and a range, Go all in shows every number */
.mo-c-loose, .mo-c-all, .mo-tick { transition: opacity 360ms var(--mo-out); }
.mo-on .mo-tick { opacity: 0; } .mo-on .mo-tick.in { opacity: 1; }
.mo-c-all, .mo-lg-all { opacity: 0; }
.mo-lg-all { transform: translateY(8px); pointer-events: none; }
.mo-ring-wrap[data-mode="all"] .mo-c-loose, .mo-ring-wrap[data-mode="all"] .mo-lg-loose, .mo-ring-wrap[data-mode="all"] .mo-tick { opacity: 0 !important; }
.mo-ring-wrap[data-mode="all"] .mo-lg-loose { transform: translateY(-8px); }
.mo-ring-wrap[data-mode="all"] .mo-c-all, .mo-ring-wrap[data-mode="all"] .mo-lg-all { opacity: 1; transform: none; }
.mo-ring .arc.a0, .mo-ring .arc.a1, .mo-ring .arc.a2 { opacity: 0; }
/* no JavaScript at all: the radios still switch the card */
html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-c-loose, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-lg-loose, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-tick, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-ring .band, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-ring .one { opacity: 0; }
html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-rrange, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-c-all, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .mo-lg-all, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .arc.a0, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .arc.a1, html:not(.js) .mo-ring-wrap:has(input[value="all"]:checked) .arc.a2 { opacity: 1; transform: none; }

@media (min-width: 60rem) {
  .mo-ring-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3xl); }
  .mo-rcard { width: min(100%, 440px); padding: 26px 26px 28px; }
  .mo-seg { width: min(100%, 440px); }
  .mo-ring { width: min(290px, 74%); }
}
.mo-on .mo-ring-sec { padding-block: 0; }
.mo-on .mo-ring-track { height: 175vh; height: 175svh; }
.mo-on .mo-ring-grid { height: 100%; padding-block: var(--space-lg) var(--mo-reserve); }
.mo-on .mo-rcard { will-change: transform; }
@media (max-width: 59.99rem) {
  .mo-on .mo-ring-grid { grid-template-rows: auto minmax(0, 1fr); align-items: start; gap: 14px; padding: 18px var(--gutter) calc(var(--mo-reserve) + 4px); }
  .mo-on .mo-ring-grid .mo-h2 { font-size: clamp(1.625rem, 6.4vw, 2.25rem); max-width: 20ch; }
  .mo-on .mo-ring-grid .mo-intro { margin-top: 8px; font-size: var(--text-sm); }
  .mo-on .mo-ring-grid .mo-note { display: none; }
  .mo-on .mo-ring-wrap { align-self: start; gap: 10px; }
  .mo-on .mo-rcard { padding: 18px 18px 20px; }
  .mo-on .mo-ring { width: min(220px, 60%); margin: 12px auto 8px; }
}
@media (max-width: 59.99rem) and (max-height: 760px) {
  .mo-on .mo-ring-grid .mo-intro { display: none; }
  .mo-on .mo-ring { width: min(176px, 52%); margin: 6px auto 4px; }
  .mo-on .mo-rcard { padding: 14px 16px 16px; }
  .mo-on .mo-lg { gap: 7px; }
  .mo-on .mo-seg label { min-height: 40px; }
}
/* the smallest phones (iPhone SE 1st gen, 320x568): everything a step tighter so the whole card clears the join bar */
@media (max-width: 59.99rem) and (max-height: 620px) {
  .mo-on .mo-ring-grid { gap: 10px; padding-top: 12px; }
  .mo-on .mo-ring-grid .mo-h2 { font-size: 1.375rem; }
  .mo-on .mo-ring-wrap { gap: 8px; }
  .mo-on .mo-seg label { min-height: 36px; }
  .mo-on .mo-rcard { padding: 10px 14px 12px; border-radius: 26px; }
  .mo-on .mo-rhead > div:first-child b { font-size: 1.25rem; }
  .mo-on .mo-rhead .mo-rrange b { font-size: 0.9375rem; }
  .mo-on .mo-ring { margin: 2px auto 0; }
  .mo-on .mo-lg { gap: 4px; }
  .mo-on .mo-mac { font-size: var(--text-xs); }
  .mo-on .mo-quiet { padding: 5px 10px; font-size: 0.75rem; }
  .mo-on .mo-micro span { padding: 4px 8px; }
}
@media (min-width: 60rem) and (max-height: 800px) {
  .mo-on .mo-ring { width: min(230px, 62%); margin: 10px auto 6px; }
  .mo-on .mo-rcard { padding: 20px 22px 22px; }
}

/* ============ 5. LOG FOOD YOUR WAY ============ */
.mo-amt { display: flex; align-items: center; gap: 10px; margin-top: var(--space-lg); }
.mo-amt-v { padding: 9px 16px; border-radius: 14px; background: var(--color-card); font: 800 1.25rem/1 var(--font-display); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.mo-amt-seg { display: inline-grid; grid-template-columns: auto auto; padding: 3px; border-radius: var(--radius-pill); background: var(--color-card); font-size: var(--text-sm); font-weight: 600; }
.mo-amt-seg b, .mo-amt-seg span { padding: 6px 12px; border-radius: var(--radius-pill); }
.mo-amt-seg b { background: var(--color-accent); color: var(--color-on-accent); }
.mo-amt-seg span { color: var(--color-tinted-ink); }
.rough-vis { display: grid; gap: var(--space-md); margin-top: var(--space-lg); }
.rough-vis .taps { margin-top: 0; }
@media (min-width: 60rem) {
  .bento .rough-cell { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-xl); align-items: center; }
  .rough-vis { margin-top: 0; }
}

/* ============ 6. CREW: the invite fills up ============ */
.mo-invite { width: min(100%, 400px); justify-self: center; padding: 22px 20px; border-radius: 30px; background: var(--color-night-2); border: 1px solid var(--color-night-rule); color: var(--color-on-night); box-shadow: 0 50px 100px -50px rgb(0 0 0 / 0.6); }
.mo-inv-head small { display: block; color: var(--color-night-muted); font-size: var(--text-xs); }
.mo-inv-head b { display: block; margin-top: 2px; font: 900 1.375rem/1.1 var(--font-display); letter-spacing: -0.03em; }
.mo-mates { display: grid; gap: 2px; margin-top: 14px; }
.mo-mate { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--color-night-rule); }
.mo-av { display: grid; place-content: center; width: 44px; height: 44px; border-radius: 50%; background: #2F3A2E; color: #C6D6C2; font: 800 1rem/1 var(--font-display); }
.mo-mate b { display: block; font-weight: 600; }
.mo-mate small { color: var(--color-night-muted); font-size: var(--text-xs); }
.mo-reply { padding: 8px 12px; border-radius: var(--radius-pill); font: 700 0.8125rem/1 var(--font-display); white-space: nowrap; background: #9DB59A; color: #111311; }
.mo-reply.no { background: var(--color-night-rule); color: var(--color-on-night); }
.mo-on .mo-mate { opacity: 0; transform: translateY(14px); transition: opacity 360ms var(--mo-out), transform 520ms var(--mo-out); }
.mo-on .mo-mate .mo-reply { opacity: 0; scale: 0.6; transition: opacity 240ms var(--mo-out) 220ms, scale 420ms var(--mo-out) 220ms; }
.mo-on .mo-mate.in { opacity: 1; transform: none; }
.mo-on .mo-mate.in .mo-reply { opacity: 1; scale: 1; }

/* ============ 7. PLANS, PROGRESS AND THE REST ============ */
.mo-gal { padding-bottom: clamp(3rem, 3vw + 2rem, 4.5rem); }
.mo-row { display: flex; gap: var(--space-lg); margin-top: var(--space-xl); padding: 4px var(--gutter) 18px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: thin; }
.mo-row:focus-visible { outline: 3px solid var(--color-focus); outline-offset: -3px; border-radius: 12px; }
.mo-item { flex: none; width: min(62vw, 250px); scroll-snap-align: start; }
.mo-item .shot { border-radius: 26px; }
.mo-item h3 { margin-top: var(--space-md); font: 800 var(--text-lg)/1.1 var(--font-display); letter-spacing: -0.025em; }
.mo-item p { margin-top: var(--space-xs); color: var(--color-muted); font-size: var(--text-sm); }
.mo-also { margin-top: var(--space-2xl); max-width: 62ch; color: var(--color-muted); font-size: var(--text-sm); text-wrap: pretty; }
.mo-also b { color: var(--color-ink); font-weight: 600; }
@media (min-width: 60rem) {
  .mo-row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-lg); max-width: var(--max); margin-inline: auto; padding: 4px var(--gutter) 0; overflow: visible; scroll-snap-type: none; }
  .mo-item { width: auto; }
  .mo-item .shot { border-radius: 24px; }
  .mo-item h3 { font-size: var(--text-md); }
}
.mo-on .mo-item { will-change: transform; }
@media (min-width: 60rem) { .mo-on .mo-item { opacity: 0; transition: opacity 500ms var(--mo-out); } .mo-on .mo-item.in { opacity: 1; } }
/* wide screens with motion (round 4, N8): bigger screens (up to 290 px, was about 200) in one row that starts on the
   page's left content edge and runs off the right; the row drifts left as the section scrolls by, until the last screen
   ends on the right content edge with the first still partly in view (round 5). The still page keeps the 5-column grid. */
@media (min-width: 60rem) {
  .mo-on .mo-gal { overflow: hidden; }
  .mo-on .mo-row { display: flex; gap: 28px; width: max-content; max-width: none; margin-inline: 0; padding: 4px var(--gp, max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter)))) 0; will-change: transform; }
  .mo-on .mo-item { width: var(--gc, clamp(240px, 20vw, 290px)); }   /* --gc, --gp: motion.js (round 5) */
  .mo-on .mo-item h3 { font-size: var(--text-lg); }
}

/* ============ 9. LAST CALL ============ */
.last-card h2 .mo-l { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.last-card h2 .mo-l > span { display: block; }
.mo-on .last-card, .mo-on .last-card .big-mark { will-change: transform; }
.appstore { display: inline-flex; margin-top: var(--space-lg); border-radius: 10px; }
.appstore svg { display: block; }

/* ============ phone join bar + the sheet it opens ============ */
/* the ink button (the light theme's own, and "ink" on the dark one) has a light rim, 1.5 px at 35% (round 5; was 1 px at
   14%), so it can never fully melt into a dark block it touches; the light and sage buttons keep the faint 1 px one */
:root { --bar-rim: 0 0 0 1.5px rgb(255 255 255 / 0.35); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --bar-rim: 0 0 0 1px rgb(255 255 255 / 0.14); } }
.sticky-join a { box-shadow: 0 12px 30px -10px rgb(var(--color-shadow) / 0.4), var(--bar-rim); transition: background-color 220ms var(--mo-out), color 0s linear 110ms; }   /* the label flips at the half-way point, so it never fades into the button */
/* data-bar: what is under and round the bar is too close to the button's own colour, so it takes the colour that stands
   out best there (motion.js): sage, or ink on the dark theme over a light picture */
.sticky-join[data-bar="sage"] a { background: #9DB59A; color: #111311; box-shadow: 0 12px 30px -10px rgb(var(--color-shadow) / 0.4), 0 0 0 1px rgb(255 255 255 / 0.14); }
.sticky-join[data-bar="sage"] a:hover { background: #B3C7B0; }
.sticky-join[data-bar="ink"] a { background: #111311; color: #F2F3EE; box-shadow: 0 12px 30px -10px rgb(0 0 0 / 0.4), 0 0 0 1.5px rgb(255 255 255 / 0.35); }

.mo-sheet { position: fixed; inset: auto 0 0 0; width: 100%; max-width: 560px; max-height: 100%; margin: 0 auto; padding: 0; border: 0; background: transparent; color: var(--color-ink); overflow: visible; overscroll-behavior: contain; }
.mo-sheet::backdrop { background: rgb(17 19 17 / 0.5); }
/* never taller than what the keyboard leaves (motion.js sets --vvh from visualViewport); the inside scrolls */
.mo-sheet-in { max-height: calc(var(--vvh, 100vh) - 12px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0 var(--gutter) calc(26px + env(safe-area-inset-bottom)); border-radius: 28px 28px 0 0; background: var(--color-card); box-shadow: 0 -20px 60px -20px rgb(0 0 0 / 0.4); }
.mo-sheet[data-kb] .mo-sheet-in { padding-bottom: 16px; }
/* the title row stays pinned while the inside scrolls. It runs edge to edge (round 5: the gutter is pulled back in as
   padding) and is opaque, so a field scrolled under it can't show its focus ring round the title's sides */
.mo-sheet-head { position: sticky; top: 0; z-index: 2; display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-inline: calc(-1 * var(--gutter)); padding: 18px var(--gutter) 6px; background: var(--color-card); }
.mo-sheet[data-kb] .mo-sheet-sub { display: none; }   /* keyboard up: every line counts */
.mo-sheet[data-kb] .mo-sheet-head { padding-top: 10px; padding-bottom: 4px; }
.mo-sheet[data-kb] .mo-sheet-head h2 { font-size: 1.25rem; }
/* the sheet's form (round 5): an email error sits right under the email field, so the field you have to fix and what is
   wrong with it are one block; the tick's error stays under the tick */
.mo-sheet .join { display: flex; flex-direction: column; gap: var(--space-xs); }
.mo-sheet .join-row { display: contents; }
.mo-sheet .join .field { order: 1; } .mo-sheet .join .btn { order: 3; } .mo-sheet .join .consent { order: 4; } .mo-sheet .join .form-msg { order: 5; } .mo-sheet .join .join-done { order: 6; }
.mo-sheet .join .consent, .mo-sheet .join .form-msg { margin-top: 4px; }
.mo-sheet .join:has(.field[aria-invalid="true"]) .form-msg { order: 2; margin-top: -2px; padding-inline: 20px; }
html.mo-locked, html.mo-locked body { overflow: hidden; }
.mo-sheet-head h2 { font: 900 1.625rem/1.1 var(--font-display); letter-spacing: -0.035em; }
.mo-sheet-x { display: grid; place-content: center; width: 44px; height: 44px; flex: none; border: 0; border-radius: 50%; background: var(--color-tint); cursor: pointer; }
.mo-sheet-x svg { width: 20px; height: 20px; }
.mo-sheet-sub { margin-top: 6px; color: var(--color-muted); }
.mo-sheet .join { margin-top: var(--space-md); max-width: none; }
.mo-sheet[open] .mo-sheet-in { animation: mo-sheet-up 420ms var(--mo-out); }
.mo-sheet[open]::backdrop { animation: mo-fade 300ms var(--mo-out); }
.mo-sheet.closing .mo-sheet-in { animation: mo-sheet-down 240ms var(--mo-in) forwards; }
.mo-sheet.closing::backdrop { animation: mo-fade 240ms var(--mo-in) reverse forwards; }
@keyframes mo-sheet-up { from { transform: translateY(100%); } }
@keyframes mo-sheet-down { to { transform: translateY(100%); } }
@keyframes mo-fade { from { opacity: 0; } }

/* ---------- one-time reveals for the plain sections ---------- */
.mo-on .mo-rv { opacity: 0; transform: translateY(18px); transition: opacity 700ms var(--mo-out), transform 900ms var(--mo-out); }
.mo-on .mo-rv.in { opacity: 1; transform: none; }
.mo-on .bento .cell.mo-rv:nth-child(2) { transition-delay: 90ms; }
.mo-on .bento .cell.mo-rv:nth-child(3) { transition-delay: 180ms; }
.mo-on .bento .cell.mo-rv:nth-child(4) { transition-delay: 270ms; }

/* reduced motion: no pins, no loops, finished states (home-boot.js never sets .mo-on). */
@media (prefers-reduced-motion: reduce) { .mo-caret { animation: none !important; } .mo-sheet .mo-sheet-in, .mo-sheet::backdrop { animation: none !important; } }

/* desktop sizes for the cards (after the base rules on purpose) */
@media (min-width: 60rem) {
  .mo-card { padding: 24px 22px; font-size: 0.9375rem; gap: 14px; }
  .mo-real { padding: 0; gap: 0; }
  .mo-ttl { font-size: 1.5rem; }
  .mo-act { flex-basis: 150px; }
  .mo-eve-ring { height: 230px; }
  .mo-on .mo-eve-ring { flex: 1 1 0; height: auto; min-height: 140px; max-height: 250px; margin-block: auto; }
  .mo-on .mo-bk .meal { margin-top: auto; }
  .mo-on .mo-real::after { height: 36px; }
}

/* launch day, wide screens: a QR code beside the badge, for people reading on a laptop */
.appstore-row { display: flex; align-items: center; gap: var(--space-lg); margin-top: var(--space-lg); }
.appstore-row .appstore { margin-top: 0; }
.mo-qr { display: none; align-items: center; gap: 12px; max-width: 15rem; color: var(--color-muted); font-size: var(--text-xs); line-height: 1.35; }
.mo-qr svg { flex: none; width: 92px; height: 92px; padding: 6px; border-radius: 12px; background: #fff; box-shadow: inset 0 0 0 1px var(--color-rule); }
.last-card .mo-qr { color: var(--color-night-muted); }
@media (min-width: 60rem) { .mo-qr { display: flex; } }
.mo-units { margin-top: var(--space-xs); }

/* the evening ring on the smallest phones (see .mo-eve-ring above): the centre holds the number and "kcal" only, sized
   from the ring (cqw = 1% of the ring's width; the track's inner edge is at 72% across) */
@container (max-width: 129px) {
  .mo-on .mo-eve-ring .mo-rc b { font-size: 19cqw; }
  .mo-on .mo-eve-ring .mo-rc small { margin-top: 2px; font-size: max(0.5625rem, 8cqw); }
  .mo-on .mo-eve-ring .mo-rc .mo-inr { display: none; }
}

/* ============ values the mockup set in style="" (the CSP blocks inline styles) ============ */
/* breakfast's three macro bars, finished (motion.js redraws them from the scroll) */
.mo-sbars [data-bkm="0"] { --f: .178; } .mo-sbars [data-bkm="1"] { --f: .278; } .mo-sbars [data-bkm="2"] { --f: .094; }
/* the gym screen's marks (last time, the trophy) and the finger, in the screenshot's own proportions */
.mo-mark[data-mk="0"] { --x: 13.2%; --y: 20.72%; --w: 16.4%; --h: 22.63%; }
.mo-mark[data-mk="1"] { --x: 38.6%; --y: 21.01%; --w: 20.6%; --h: 4.08%; }
.mo-tap { --x: 50%; --y: 94.29%; }
/* the run's four miles */
.mo-km[data-km="0"] { --y: 77.1%; } .mo-km[data-km="1"] { --y: 82.3%; } .mo-km[data-km="2"] { --y: 87.6%; } .mo-km[data-km="3"] { --y: 92.8%; }
/* Go all in: protein, carbs and fat bars */
.mo-mac[data-m="0"] .mo-bar2 i { --f: .82; } .mo-mac[data-m="1"] .mo-bar2 i { --f: .76; } .mo-mac[data-m="2"] .mo-bar2 i { --f: .68; }
/* finished rings for no JS and reduced motion (the motion layer redraws them from the scroll). One day, the app's own
   numbers (Food screen, Sat Oct 24): 2,498 kcal in a 2,450-2,800 range; protein 649, carbs 1,249, fat 600 kcal; every
   ring runs to 2,800, as the app's Food ring does. Arc = (kcal / 2800 x circumference) less the cap (stroke + 3), offset
   by half the cap; the same numbers the mockup's build.py wrote into style="". */
.mo-ring [data-arc="0"] { stroke-dasharray: 118.81 603.19; stroke-dashoffset: -10.50; }
.mo-ring [data-arc="1"] { stroke-dasharray: 248.06 603.19; stroke-dashoffset: -150.31; }
.mo-ring [data-arc="2"] { stroke-dasharray: 108.25 603.19; stroke-dashoffset: -419.37; }
.mo-ring [data-one] { stroke-dasharray: 517.13 603.19; stroke-dashoffset: -10.50; }
.mo-ring [data-band] { stroke-dasharray: 85.32 722.57; stroke-dashoffset: -634.75; }
.mo-eve-ring [data-earc="0"] { stroke-dasharray: 97.51 502.65; stroke-dashoffset: -9.50; }
.mo-eve-ring [data-earc="1"] { stroke-dasharray: 205.22 502.65; stroke-dashoffset: -126.01; }
.mo-eve-ring [data-earc="2"] { stroke-dasharray: 88.71 502.65; stroke-dashoffset: -350.23; }
.mo-sring [data-bkarc] { stroke-dasharray: 34.27 188.50; stroke-dashoffset: 0; }
