/* h5 Deporte wow (from h3 Deporte en movimiento) - page layer on top of the Gio system 2026.
   Static and complete first. Motion: the no-preference blocks at the end set only what CSS can do
   alone (entrances that end visible, hover); everything scroll-linked is GSAP in home.js, which also
   sets every hidden starting state itself, so without JS nothing is left hidden. */

/* Round 2: the visible number is real HTML text (.tick__v). The CSS counter (::before) only paints
   while a count runs (.tick.run) or on hover; the hidden text keeps the box at its final width. */
:root{--tilt:1.2deg;--cut:calc(100vw * .02095)}  /* round 5: ONE angle. tan(1.2deg) = .02095, so the week cut rises like the tape */
.tick__n{display:inline-grid;justify-items:start}
.tick__n::before,.tick__v{grid-area:1/1}
.tick__n::before{content:none}

.sec-head{max-width:60rem}
.alink{display:inline-flex;align-items:center;min-height:var(--tap);color:var(--link);font-weight:600;text-underline-offset:.2em;text-decoration-thickness:2px}
.acts{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3)}
/* Round 6b (owner, 11-12): "Get the PDF plan by email" is the system's secondary button (same height,
   radius and 3 px border as the primary, outlined in the text colour of its ground) and fills on hover
   and focus. One pair everywhere: filled primary + outlined secondary. */
.btn--secondary{background:transparent;color:var(--on-ground);border-color:currentColor}
.btn--secondary:hover,.btn--secondary:focus-visible{background:var(--on-ground);color:var(--ground)}
.section{scroll-margin-top:1rem}
/* Round 5: the skew leans the top of each letter right; pull slanted headings back so they line up with the
   column optically. Long headings are written as several .slant phrases, so a wrapped line is skewed from
   its own bottom-left corner instead of being pushed right by the line under it. */
.display .slant{margin-left:-.05em}
.display .slant:not(:last-child){padding-right:0}  /* a phrase followed by another: no double gap */

/* ---------- Hero: a living cover ---------- */
.hero{padding-block:0;overflow:hidden;position:relative}
/* Round 5: the channel banner. Yellow ground, cobalt display (4.18:1, large text only), ink text,
   ink button with white text, ink secondary link, cobalt GIO tab with white. */
.hero{--ground:var(--yellow);--on-ground:var(--ink);--on-ground-2:var(--ink);--time:var(--cobalt);--action:var(--ink);--on-action:var(--white);--tab:var(--cobalt);--on-tab:var(--white);--focus:var(--ink);--link:var(--ink)}
.hero h1{color:var(--cobalt)}
.hero__top{display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);padding-top:var(--s-3);position:relative;z-index:3}
.hero .nav{gap:0 var(--s-4)}
.hero .nav a{color:var(--ink);text-underline-offset:.2em;min-width:var(--tap);justify-content:center}
.hero__in{display:grid;grid-template-columns:minmax(0,1fr);grid-template-areas:"h1" "lead" "acts" "go";position:relative;row-gap:0}
.hero__copy{display:contents}
.hero__h1{grid-area:h1;position:relative;z-index:2;display:grid;justify-items:start;padding-top:var(--s-4);line-height:.86;align-self:end}
.hero__free{font-size:clamp(2.75rem,12vw,7rem)}
.hero__row{display:flex;flex-direction:column;align-items:flex-start}
.hero__n{display:block;transform-origin:0 100%}
.hero__digit{display:inline-block;font-size:clamp(11rem,50vw,26rem);line-height:.9;color:var(--time);transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.04em;margin-bottom:-.02em}
/* Round 2: .07em of air between WEEK and PLAN (8 px at 1440); the row stays bottom-aligned with the 4. */
.hero__unit{display:grid;justify-items:start;row-gap:.07em;font-size:clamp(2.75rem,12vw,7rem);line-height:.86;padding-bottom:.04em}
.hero__lead{grid-area:lead;position:relative;z-index:2;padding-top:var(--s-4)}
.hero__in > .hero__copy > .acts{grid-area:acts;position:relative;z-index:2;padding:var(--s-5) 0 0}
/* Round 5: says where the main button goes (aria-describedby on it). */
.hero__go{grid-area:go;position:relative;z-index:2;padding:var(--s-2) 0 var(--s-7);font:500 var(--fs-small)/1.3 var(--font-text)}
/* Round 2 (mobile): the cut-out is whole, inside the gutter, beside the headline (feet included). */
.hero__ph{grid-area:h1;justify-self:end;align-self:end;width:min(62vw,17rem);z-index:1;transform-origin:50% 100%}
.hero__img{width:100%;height:auto}

@media (min-width:48rem){
  .hero__in{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);grid-template-areas:"h1 ph" "lead ph" "acts ph" "go ph";grid-template-rows:1fr auto auto auto}
  .hero__row{flex-direction:row;align-items:flex-end}
  .hero__unit{display:grid;justify-items:start}
  .hero__ph{grid-area:ph;margin-right:calc(-1 * var(--gutter));width:100%;max-width:38rem;align-self:end}
  .hero__h1{padding-top:var(--s-6)}
  .hero__lead{padding-top:var(--s-5)}
  .hero__go{padding-bottom:var(--s-8)}
}
@media (min-width:64rem){
  /* Round 2: the hero leaves 7rem of the first screen for the nav and the whole tape (Pause included).
     The 4 and the photo scale with the viewport height so 1280x720 and 1440x800 keep the button and the tape. */
  .hero__in{min-height:clamp(34rem,calc(100svh - 7rem),52rem)}
  .hero__h1{--d:clamp(11rem,min(50vw,calc(88svh - 22rem)),26rem)}
  .hero__digit{font-size:var(--d)}
  .hero__free,.hero__unit{font-size:min(7rem,calc(var(--d) * .27))}
  .hero__ph{width:auto;max-width:none;margin-right:-1rem;margin-bottom:-2.25rem}
  .hero__img{width:auto;max-width:none;height:min(clamp(28rem,calc(100svh - 8rem),50rem),57.4vw)}
  .hero__lead{max-width:28rem}
  .hero__h1{align-self:end}
  .hero__in > .hero__copy > .acts{padding-top:var(--s-6)}
  .hero__go{padding-bottom:var(--s-7)}
}

/* ---------- Ticker as a slanted tape between hero and plan ----------
   Round 4: it runs by itself again, calm and constant (CSS animation, 70 s a loop). WCAG 2.2.2 without a
   visible button: it pauses on hover, on focus inside it and off screen, and a click / tap on the tape or
   the hidden-until-focused toggle button (aria-pressed) stops it until pressed again. Static without JS
   or with reduced motion. */
.tape{position:relative;z-index:4;overflow-x:clip;margin-top:-1.5rem}
.tape .ticker{width:106%;margin-left:-3%;rotate:calc(-1 * var(--tilt))}
.tape .ticker__view{padding-left:calc(3% + var(--gutter))}
/* The toggle: a real button, invisible until it has keyboard focus (then an ink pill with a ring). It sits
   over the start of the tape, 44 px tall, so a click there is also a click on the tape. */
.ticker__stop{position:absolute;left:calc(3% + var(--gutter));top:50%;translate:0 -50%;z-index:3;min-height:var(--tap);padding:0 var(--s-4);border:3px solid var(--white);border-radius:var(--r-md);background:var(--ink);color:var(--white);font:600 var(--fs-small)/1 var(--font-text);cursor:pointer;opacity:0}
.ticker__stop:focus-visible{opacity:1;outline-color:var(--yellow)}
.ticker__stop[aria-pressed="true"]::after{content:" (paused)"}
/* Round 5: on touch, one short line under the tape says a tap stops it (home.js shows it only on touch
   screens while the tape runs, and swaps the text while it is stopped). Ink-2 on cream 7.6:1. */
.tape__tip{position:absolute;right:var(--gutter);top:100%;margin:.875rem 0 0;font:500 var(--fs-small)/1.3 var(--font-text);color:var(--ink-2)}

/* ---------- Plan intro + stats ---------- */
.plan-intro{padding-top:calc(var(--s-8) + 1rem);padding-bottom:calc(var(--s-7) + var(--cut))}
.plan-intro .sec-head{margin-bottom:0}

/* ---------- Four week panels ---------- */
.weeks-stack{position:relative}
.wk{position:relative;padding-block:calc(var(--s-6) + var(--cut)) var(--s-7);margin-top:calc(-1 * var(--cut));clip-path:polygon(0 var(--cut),100% 0,100% 100%,0 100%)}
.wk__in{display:grid;gap:var(--s-4);grid-template-columns:minmax(0,1fr);grid-template-areas:"name" "side" "days" "links"}
.plan-links{grid-area:links;padding-top:var(--s-4)}
.wk__name{grid-area:name;font-size:clamp(2.25rem,8vw,3.25rem);line-height:.95;padding-right:.2em}
/* Round 2: the skewed heading carries its panel's ground on itself (same colour, invisible). Checked by
   pixel at every scroll position of the stack: week 4's heading only ever sits on its own cobalt
   (white 5.99:1). axe ordered the transformed span below its sticky section and fell through to the
   page cream (1.11:1, a false positive); with the ground on the element it reads the real pair. */
.wk__name .slant,.wk__name .ln{background:var(--ground)}  /* round 3: the split lines carry it too */
/* Round 5 (owner: the banner hybrid): one pair per week, measured in NOTES.md:
   1 cobalt ground, yellow numeral, white text | 2 yellow ground, cobalt numeral, ink text |
   3 ink ground, yellow numeral, white text | 4 orange ground, ink numeral, ink text, ink button | Latest butter, ink. */
.pair-4{--time:var(--ink)}
.wk__side{grid-area:side;display:flex;align-items:flex-end;gap:var(--s-4)}
.wk__n{flex:none;font:400 clamp(7.5rem,34vw,15rem)/.9 var(--font-display);color:var(--time);margin:0 0 -.12em -.05em}
.wk__num{display:inline-block;transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.06em}
.wk__goal{max-width:22rem;font-size:var(--fs-body);line-height:1.45;font-weight:500;padding-bottom:.4rem}
.days{grid-area:days;list-style:none;margin:var(--s-3) 0 0;padding:0;display:grid;gap:var(--s-3)}
.days li{display:grid}
/* Round 6 (C): typographic day cards, no thumbnail. Giant slanted minutes, a rounded "DAY n" tab top-left,
   the plan name in Anton, the real YouTube title small. One pair per week (--c-*), and the hover pair the
   sweep floods in (--h-*), measured in NOTES.md:
   week 1 (cobalt ground)  white card, cobalt minutes, ink text      -> floods ink, yellow minutes, white text
   week 2 (yellow ground)  cobalt card, yellow minutes, white text   -> floods white, cobalt minutes, ink text
   week 3 (ink ground)     butter card, cobalt minutes, ink text     -> floods cobalt, yellow minutes, white text
   week 4 (orange ground)  ink card, yellow minutes, white text      -> floods yellow, cobalt minutes, ink text
   The tab is the text colour with the card colour on it.
   Round 7 (owner, 2026-11-12): NO outline on any card. The 3 px frame is gone, so a card never floods with the
   colour of its own ground (weeks 1 and 2 changed). The card paints no background of its own: both faces sit
   inside the one rounded clip, so no rim of the resting colour shows around a flooded card. */
.day{--c-bg:var(--white);--c-tx:var(--ink);--c-tx2:var(--ink-2);--c-min:var(--cobalt);
     --h-bg:var(--ink);--h-tx:var(--white);--h-tx2:var(--white);--h-min:var(--yellow);
     --sl:1.125rem;position:relative;display:grid;min-height:6.5rem;border-radius:var(--r-lg);color:var(--c-tx);text-decoration:none;overflow:hidden;isolation:isolate}
.pair-2 .day{--c-bg:var(--cobalt);--c-tx:var(--white);--c-tx2:var(--white);--c-min:var(--yellow);--h-bg:var(--white);--h-tx:var(--ink);--h-tx2:var(--ink-2);--h-min:var(--cobalt)}
.pair-3 .day{--c-bg:var(--butter);--c-tx:var(--ink);--c-tx2:var(--ink-2);--c-min:var(--cobalt);--h-bg:var(--cobalt);--h-tx:var(--white);--h-tx2:var(--white);--h-min:var(--yellow)}
.pair-4 .day{--c-bg:var(--ink);--c-tx:var(--white);--c-tx2:var(--white);--c-min:var(--yellow);--h-bg:var(--yellow);--h-tx:var(--ink);--h-tx2:var(--ink);--h-min:var(--cobalt)}
.day .face--on{--c-bg:var(--h-bg);--c-tx:var(--h-tx);--c-tx2:var(--h-tx2);--c-min:var(--h-min)}
/* 390: one row, about 104 px tall. Left: the DAY tab (top-left corner) over the minutes; right: name + title. */
.day .face{display:grid;grid-template-columns:5.25rem minmax(0,1fr);align-items:center;column-gap:var(--s-3);padding:.75rem 1rem .75rem .875rem;background:var(--c-bg);color:var(--c-tx)}
.day__lead{display:flex;flex-direction:column;align-items:flex-start;gap:.375rem}
.day__txt{display:grid;gap:.25rem;min-width:0}
.day__tab{padding:.3125rem .5rem .25rem;border-radius:.5rem;background:var(--c-tx);color:var(--c-bg);font:400 .875rem/1 var(--font-display);text-transform:uppercase}
.day__min{display:flex;align-items:baseline;gap:.05em;font:400 3.5rem/.9 var(--font-display);color:var(--c-min);transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.06em}
.day__min small{font-size:.3em;color:var(--c-tx)}
.day__name{min-width:0;font:400 1.5rem/1 var(--font-display);text-transform:uppercase;text-wrap:balance}
.day__nm{display:inline-block;transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.1em}
.day__yt{min-width:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;font:500 .8125rem/1.25 var(--font-text);color:var(--c-tx2)}

@media (min-width:48rem){
  .days{grid-template-columns:repeat(3,minmax(0,1fr))}
  /* 1440: three per row, the same height in every week (the tallest name + title fits). */
  .day{--sl:2.75rem;min-height:16.25rem}
  .day .face{display:flex;flex-direction:column;align-items:stretch;padding:1rem 1.125rem 1.125rem}
  .day__lead{gap:.625rem}
  .day__min{font-size:6rem}
  .day__txt{margin-top:auto;padding-top:.5rem;gap:.5rem}
  .day__name{font-size:1.5rem;line-height:1}  /* r6 review: two-line names were touching the minutes at 1.75rem */
  .day__yt{font-size:.875rem;min-height:2.5em}  /* r6 review: two lines reserved so the names share a baseline */
}
@media (min-width:64rem){
  .wk{padding-block:calc(var(--s-5) + 2.5rem) var(--s-7)}
  .wk__in{grid-template-columns:minmax(0,19rem) minmax(0,1fr);grid-template-areas:"name name" "side days" ". links";column-gap:var(--s-7);align-items:end}
  .plan-links{padding-top:var(--s-2)}
  .wk__side{flex-direction:column;align-items:flex-start;gap:var(--s-3)}
  .wk__n{font-size:clamp(11rem,16vw,15rem);margin-bottom:0}
  .days{margin-top:0;align-self:end}
}

/* ---------- Latest: a sideways rail at every width ----------
   Round 3 (owner on h4): native swipe on touch (scroll-snap, the next card peeks at the right edge,
   momentum, no hijack) and h4's side arrows on hover devices (home.js unhides them). */
.rail-wrap{position:relative}
.rail{list-style:none;margin:0 calc(-1 * var(--gutter));padding:var(--s-3) var(--gutter) var(--s-4);display:grid;grid-auto-flow:column;grid-auto-columns:min(80%,20rem);gap:var(--s-4);overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y}
.rail > li{display:grid;scroll-snap-align:start}
.rail-foot{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-4);min-height:var(--tap)}
/* Round 6 (B): ONE outlined "Subscribe on YouTube" in the row of the bar and the arrows: right side on wide
   screens, its own line on phones. Ink border and text (13.56 on butter), no fill, no logo, no red. Hover and
   focus fill it ink with cream text (16.80). */
.btn-line{display:inline-flex;align-items:center;justify-content:center;min-height:var(--tap);height:var(--tap);padding:0 1.25rem;border:2px solid var(--ink);border-radius:var(--r-md);background:transparent;color:var(--ink);font:600 1rem/1 var(--font-text);text-decoration:none;white-space:nowrap}
.btn-line:hover,.btn-line:focus-visible{background:var(--ink);color:var(--cream)}
.btn-line:active{background:var(--ink);color:var(--cream)}
.rail-foot .sub{margin-left:auto}
@media (max-width:47.99rem){
  .rail-foot{row-gap:var(--s-3)}
  .rail-foot .sub{flex-basis:100%;margin-left:0;justify-content:flex-start;width:max-content;max-width:max-content}
}
/* Round 5: bar and arrows read as one control, side by side; a disabled arrow dims instead of leaving a hole. */
.rail-ctl:not([hidden]){display:flex;gap:var(--s-2)}
.rail-btn{width:var(--tap);height:var(--tap);display:inline-flex;align-items:center;justify-content:center;border:3px solid currentColor;border-radius:var(--r-md);background:transparent;color:var(--on-ground);font:600 1.25rem/1 var(--font-text);cursor:pointer}
.rail-btn:disabled{opacity:.5;cursor:default}
.latest:has(.rail-ctl:not([hidden])) .rail-hint{display:none}
.vcard--paper{--ground:var(--white);--on-ground:var(--ink);--on-ground-2:var(--ink-2);--time:var(--cobalt)}
/* Round 6: the white text strip holds its face twice (see the sweep at the end); the copy is cobalt with
   white text (5.99), yellow minutes (4.18, large) and an arrow that slides in on the right. */
.vcard__body{display:grid;align-items:stretch;padding:0;--sl:1.125rem}
.vcard .face{position:relative;display:flex;align-items:center;gap:var(--s-3);padding:var(--s-4) 2rem var(--s-4) var(--s-4);background:var(--ground);color:var(--on-ground)}
.vcard .face--on{--ground:var(--cobalt);--on-ground:var(--white);--on-ground-2:var(--white);--time:var(--yellow)}
.vcard__txt{display:grid;gap:.3rem;min-width:0;flex:1}
.vcard__min{min-width:0;font-size:2.75rem;padding-right:.12em}
/* The arrow sits in the right padding of the strip (absolute), so it costs the title no width. */
.vcard__arr{position:absolute;right:.625rem;top:50%;margin-top:-.5em;font:600 1.25rem/1 var(--font-text);visibility:hidden}
.face--on .vcard__arr{visibility:visible}
.rail-bar{display:none}
.rail-hint{font-weight:500}
/* Round 4: the rail ends on an ink card. Round 6: the ink button under the rail is gone; this card is the
   one way to the whole channel here. Its sweep floods cobalt (yellow 100+ 4.18 large, white text 5.99). */
.vend{display:grid;min-height:100%;border-radius:var(--r-lg);background:var(--ink);color:var(--white);text-decoration:none;overflow:hidden;--sl:2.75rem}
.vend .face{--time:var(--yellow);--on-ground:var(--white);display:grid;align-content:space-between;justify-items:start;gap:var(--s-5);padding:var(--s-5);background:var(--ink);color:var(--white)}
.vend .face--on{background:var(--cobalt)}
.vend .vend__n{font-size:clamp(5rem,16vw,7.5rem);gap:0;line-height:.85}
/* Round 5: one line per word group, each skewed from its own bottom-left corner, so "100+", the title and
   "See them all" share one left edge (brand fix). */
.vend__t{display:grid;justify-items:start;font:400 clamp(1.75rem,5vw,2.25rem)/1 var(--font-display);text-transform:uppercase}
.vend__t > span{display:block;transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.1em}
.vend__go{font:600 1.0625rem/1.3 var(--font-text)}
/* Mouse drag on the rail (home.js, fine pointer). */
.rail.is-grab{cursor:grab}
.rail.is-dragging{cursor:grabbing;scroll-snap-type:none;scroll-behavior:auto;user-select:none}
.rail img{-webkit-user-drag:none}
/* From 768 the rail bleeds to the right edge of the screen, so the peeking card is cut by the screen,
   not by the content column; card widths still follow the column (--rc). */
.latest{overflow-x:clip}
/* Round 5: Latest and the playlists share the butter panel (the playlists moved up, right after Latest). */
.lib{padding-top:var(--s-8)}
#latest,#library{scroll-margin-top:calc(1rem + var(--s-8))}
@media (min-width:48rem){
  /* Round 5: the rail's left edge is the content column (it was cut 32 px outside it); it still bleeds
     to the right edge of the screen. The focus ring of a rail card is drawn inside the card so the
     column edge never clips it. */
  .rail{--rc:calc(min(100vw, var(--wrap)) - 2 * var(--gutter));margin-left:0;padding-left:0;scroll-padding-inline:0 var(--gutter);margin-right:calc(50% - 50vw);grid-auto-columns:calc((var(--rc) - 2 * var(--s-4)) / 2.3)}
  .rail .card:focus-visible{outline:3px solid var(--white);outline-offset:-6px;box-shadow:inset 0 0 0 3px var(--ink)}  /* r6 review: white ring inside an ink ring, visible on the photo and on the white strip */
}
@media (min-width:64rem){.rail{grid-auto-columns:calc((var(--rc) - 3 * var(--s-4)) / 3.3)}}

/* ---------- About ---------- */
.about__in{display:grid;gap:var(--s-6);align-items:center}
.about__frame{border-radius:var(--r-lg);overflow:hidden;aspect-ratio:4/5;max-width:26rem;width:100%}
.about__img{width:100%;height:100%;object-fit:cover}
.about__txt{display:grid;gap:var(--s-4);max-width:36rem;justify-items:start}
.about__links{display:flex;flex-wrap:wrap;gap:0 var(--s-5)}
.sign{font:400 2rem/1 var(--font-display);text-transform:uppercase;transform:skewX(var(--slant));padding-right:.1em}
@media (min-width:48rem){.about__in{grid-template-columns:minmax(0,.8fr) minmax(0,1fr);gap:var(--s-8)}}

/* ---------- Playlists ---------- */
.pls{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-3);grid-template-columns:minmax(0,1fr)}
.pls li{display:grid}
.pl{display:grid;min-height:5.5rem;background:var(--white);color:var(--ink);border-radius:var(--r-lg);text-decoration:none;overflow:hidden;--sl:1rem}
.pl .face{display:flex;align-items:center;gap:var(--s-4);padding:var(--s-3) var(--s-5);background:var(--white);color:var(--ink)}
.pl .face--on{--time:var(--yellow);--on-ground:var(--white);background:var(--cobalt);color:var(--white)}
.pl .pl__n{flex:none;font-size:3.5rem}
.pl__n .tick__n{min-width:1.9ch}
.pl__t{flex:1;font:400 1.5rem/1.02 var(--font-display);text-transform:uppercase}
.pl__arr{flex:none;font:600 1.375rem/1 var(--font-text)}
@media (min-width:48rem){.pls{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:64rem){.pls{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ---------- Close: the last cover ---------- */
.close{overflow:hidden;padding-bottom:0;--time:var(--white)}  /* round 5: white 10 on cobalt (5.99:1); the yellow button is the one yellow */
/* Round 2 (mobile): Gio stands beside the headline, pointing at the 12, cut only where the photo itself
   is cut (flush with the screen edge); the button, link and small print get the full width below. */
.close__in{display:grid;grid-template-columns:minmax(0,1fr);grid-template-areas:"h" "act";align-items:end;column-gap:var(--s-3)}
.close__copy{display:contents}
.close__h{grid-area:h;margin-bottom:var(--s-5);position:relative;z-index:1}
.close__act{grid-area:act;padding-bottom:var(--s-8)}
.close__ph{grid-area:ph}
.close__h{display:grid;justify-items:start;font-size:clamp(2.5rem,9vw,5rem);line-height:.9}
.close__n{display:block;font-size:clamp(8.5rem,38vw,17rem);line-height:.9;color:var(--time);transform:skewX(var(--slant));transform-origin:0 100%;padding-right:.06em}
.close__act{display:grid;gap:var(--s-2);justify-items:start}
/* Round 6 (A) + 6b: the same pair as the hero: yellow "Start Day 1", white outlined "Get the PDF plan by email" button, then the note. */
.close__note{max-width:24rem;font:500 var(--fs-small)/1.3 var(--font-text)}
.close__ph{grid-area:h;justify-self:end;align-self:end;width:clamp(7.5rem,38vw,10rem);margin-right:calc(-1 * var(--gutter));margin-bottom:var(--s-5)}
/* Round 4: the cut-out sits in a fixed box (564 x 860) and is contained, feet on the bottom edge, so a
   retouched file with a slightly different size changes nothing in the layout (transparent margins). */
.close__img{width:100%;height:auto;aspect-ratio:564/860;object-fit:contain;object-position:50% 100%;transform-origin:50% 100%}
@media (min-width:48rem){.close__in{grid-template-columns:minmax(0,1fr) auto;column-gap:var(--s-7);grid-template-areas:"h ph" "act ph";grid-template-rows:auto 1fr}.close__h{align-self:end;padding-top:var(--s-4)}.close__ph{grid-area:ph;justify-self:auto;width:clamp(8.5rem,36vw,24rem);margin:0}}
/* Round 5 (desktop): Gio is bigger and stands right next to the headline, his arm pointing at it
   (was 24rem wide with ~450 px of empty cobalt between them). */
@media (min-width:64rem){.close__in{grid-template-columns:auto minmax(0,1fr);column-gap:var(--s-5)}.close__ph{justify-self:start;width:clamp(24rem,31vw,29rem)}}
/* Round 6: the act block is one row now (button + link, then the note); it stays right under the headline
   instead of sinking to the bottom of the photo's row. */
@media (min-width:48rem){.close__act{align-self:start;padding-top:var(--s-3)}}

.footer__nav a{text-underline-offset:.2em}

/* =================== Motion (never required to read or use the page) ===================
   CSS keeps: the hero entrance (ends visible, no opacity), the card sweep, the two scroll-timeline bars.
   GSAP (home.js) does: hero exit, split-line headings, the stack fold, card arrival, numbers,
   the scroll-driven tape, the magnetic button, the close. */
@media (prefers-reduced-motion: no-preference){
  @keyframes slam{from{translate:-40% 0;scale:1.2}to{translate:0 0;scale:1}}
  .hero__digit{animation:slam .75s var(--ease-snap) .05s both}


  /* Rail position bar (scroll timeline of the rail itself, every width). */
  @supports (animation-timeline: scroll()){
    @keyframes rail{from{translate:0 0}to{translate:233.33% 0}}
    .rail-wrap{timeline-scope:--rail}
    .rail{scroll-timeline:--rail inline;scrollbar-width:none}
    .rail::-webkit-scrollbar{display:none}
    .rail-bar{display:block;flex:0 1 12rem;height:.375rem;border-radius:1rem;background:var(--white);overflow:hidden}
    .rail-bar span{display:block;width:30%;height:100%;border-radius:1rem;background:var(--ink);animation:rail linear both;animation-timeline:--rail}
  }
  .rail{scroll-behavior:smooth}
}

/* Everything below needs home.js to drive it: `scripting: enabled` keeps it off with JS disabled. */
@media (prefers-reduced-motion: no-preference) and (scripting: enabled){
  /* Tape: one line, both copies. It runs once home.js has wired its pause controls (html.tape-js). */
  @keyframes tape-run{to{transform:translate3d(-50%,0,0)}}
  .ticker__track{flex-wrap:nowrap;width:max-content}
  .ticker__dup{display:flex}
  .tape-js .ticker__track{animation:tape-run 70s linear infinite}
  .tape-js .ticker{cursor:pointer}
  .tape:is(.is-stop,.is-off) .ticker__track,.tape:focus-within .ticker__track{animation-play-state:paused}
  @media (hover:hover){.tape:hover .ticker__track{animation-play-state:paused}}

  /* Numbers: odometer overlay drawn by home.js over the real digits (which keep the box). */
  .odo-on,.odo-wait{-webkit-text-fill-color:transparent}
  .odo{position:absolute;left:0;top:0;display:flex;-webkit-text-fill-color:currentColor;pointer-events:none;white-space:nowrap}
  .odo__c{display:block;overflow:hidden}
  .odo__s{display:block;will-change:transform}
  .odo__s > span{display:block}
  .odo-host{position:relative}

  /* Split-line headings: the mask is padded so Anton's corners and the skew never get cut. */
  .ln-mask{padding:.12em .2em .12em 0;margin:-.12em -.2em -.12em 0}

  /* Magnetic main button: GSAP owns its transform. */
  .js-magnet{transition:none}
  .js-magnet:hover,.js-magnet:active{transform:none}

  .about__img{scale:1.14}
  /* Skewed words that GSAP slides sideways: the offset rides in a custom property so the skew stays. */
  .hero__free,.close__h > .slant{--fx:0px;transform:translate3d(var(--fx),0,0) skewX(var(--slant))}
  html.lenis,html.lenis body{height:auto}

  /* ---- The stack: the four weeks and "Latest workouts" slide over each other like covers.
     Plain CSS sticky (native scroll, smooth on phones); home.js only writes each panel's height (--h)
     and scrubs the fold (scale + shade). A panel taller than the screen sticks by its bottom edge,
     so every pixel of it has been on screen before the next one covers it. Latest is the fifth
     panel: it is not sticky, it slides over week 4 and takes the whole stack with it. */
  .weeks-stack{--off:3rem}
  .panel{--top:min(calc(var(--i) * var(--off)),calc(100svh - var(--h,200vh)))}
  .wk{position:sticky;top:var(--top);margin-top:0;clip-path:none;padding-top:.75rem;border-radius:var(--r-lg) var(--r-lg) 0 0;transform-origin:50% 0}
  .latest.panel{position:relative;border-radius:var(--r-lg) var(--r-lg) 0 0;padding-top:var(--s-6);min-height:calc(100svh - 4 * var(--off))}
  #latest{scroll-margin-top:calc(4 * var(--off) + var(--s-6))}
  /* Round 4: Latest lands at 4 strips from the top (only the "Week 4" strip shows above it) and then the
     whole stack leaves together. For that every week must release at the same moment as Latest lands:
     home.js gives each week an invisible bottom extension (--ext, bottom padding) up to Latest's landing
     bottom and pulls the next panel back up by the same amount (negative margin on the zero-height mark
     before it), so the flow does not move. Sticky keeps the MARGIN box inside the stack, which is why the
     negative margin cannot sit on the week itself. Latest is at least a screen minus the strips tall.
     The extension always sits under the next panel. */
  .wk{--pb:var(--s-6);padding-bottom:calc(var(--pb) + var(--ext,0px))}
  .panel__shade{position:absolute;inset:0;background:var(--ink);opacity:0;pointer-events:none;z-index:4;border-radius:inherit}
  /* A panel with keyboard focus comes to the front, unshaded (WCAG 2.4.11). */
  .wk:has(:focus-visible){z-index:6}
  .wk:has(:focus-visible) .panel__shade{opacity:0!important}
  @media (min-width:64rem){
    .weeks-stack{--off:4.25rem}
    .wk{padding-top:1rem;--pb:var(--s-6)}
  }
}

/* 404 */
.nf{min-height:100svh;padding-bottom:var(--s-8)}
.nf__in{display:grid;gap:var(--s-5);justify-items:start;padding-top:var(--s-6)}
.nf__n .hero__digit{font-size:clamp(9rem,40vw,20rem)}

/* Round 2, first view: on phones and tablets the four week panels and the latest-videos rail are not
   laid out until they come near the screen, so their lazy thumbnails are not fetched with the first view
   (Chromium fetches lazy images up to ~3000 px ahead on an unknown connection). The estimates below are
   the measured content heights; `auto` remembers the real size once seen. Round 3: desktop as well.
   Round 5: re-measured (real YouTube titles on the day cards, compact mobile weeks, the playlists now
   inside the Latest panel). */
@media (max-width:63.99rem){
  /* Round 6 (typographic day cards, 104 px each) measured content boxes at 360 / 390 / 430 wide:
     weeks 1-3 526-544 px, week 4 (plan links) 656-670, Latest panel (Latest + playlists) 1423-1468 */
  .wk > .wk__in{content-visibility:auto;contain-intrinsic-size:auto calc(25.7vw + 27.1rem)}
  .wk.pair-4 > .wk__in{contain-intrinsic-size:auto calc(20vw + 36.5rem)}
  .latest{content-visibility:auto;contain-intrinsic-size:auto 89rem}
}
@media (min-width:48rem) and (max-width:63.99rem){
  /* measured at 768: weeks 557 px, week 4 627, Latest panel 1095 */
  .wk > .wk__in{contain-intrinsic-size:auto 34.8rem}
  .wk.pair-4 > .wk__in{contain-intrinsic-size:auto 39.2rem}
  .latest{contain-intrinsic-size:auto 68.4rem}
}
/* Round 6, measured at 1024 / 1440 / 1920: weeks 1-2 341-365 px, week 3 341-390, week 4 403-427,
   Latest panel 989-998. */
@media (min-width:64rem){
  .wk > .wk__in{content-visibility:auto;contain-intrinsic-size:auto 22rem}
  .wk.pair-3 > .wk__in{contain-intrinsic-size:auto calc(22.5rem + 1vw)}
  .wk.pair-4 > .wk__in{contain-intrinsic-size:auto calc(24.5rem + 1vw)}
  .latest{content-visibility:auto;contain-intrinsic-size:auto 62rem}
}

/* =================== Round 6 (E): one hover gesture, a slanted sweep ===================
   Every card holds its face twice in one grid cell; the copy (.face--on, aria-hidden) is in the hover colours
   and clipped by a parallelogram leaning like the slanted Anton (--sl = the card height x tan 10deg, set per
   card type). home.js sets data-sw="l|r": the side the pointer came in by, then the side it left by. The copy
   sweeps in from that side and out the other way, so text changes colour exactly at the edge. The card box
   never moves or resizes (only clip-path changes). Keyboard focus: the same end state, in from the left,
   plus the ring. Touch: the colour on :active, no sweep. Reduced motion: the state changes, no sweep. */
.face{grid-area:1/1;min-width:0}
.face--on{pointer-events:none;
  /* 1 px past the top and bottom edges, so no anti-aliased seam shows against the card. */
  --off-l:polygon(0 -1px,0 -1px,calc(0% - var(--sl)) calc(100% + 1px),calc(0% - var(--sl)) calc(100% + 1px));
  --off-r:polygon(calc(100% + var(--sl)) -1px,calc(100% + var(--sl)) -1px,100% calc(100% + 1px),100% calc(100% + 1px));
  --full:polygon(0 -1px,calc(100% + var(--sl)) -1px,100% calc(100% + 1px),calc(0% - var(--sl)) calc(100% + 1px));
  clip-path:var(--off-l)}
[data-sw="r"] .face--on{clip-path:var(--off-r)}
.card.is-on .face--on,.card:focus-visible .face--on{clip-path:var(--full)}
@media (hover:hover) and (pointer:fine){html:not(.sw-js) .card:hover .face--on{clip-path:var(--full)}}
@media (hover:none){.card:active .face--on{clip-path:var(--full)}}
.vend:focus-visible{outline-color:var(--white)}  /* the ring is inside the card on desktop: white on ink 18.65:1 */
@media (prefers-reduced-motion: no-preference){
  .face--on{transition:clip-path .26s cubic-bezier(.55,0,.75,.2)}
  .card.is-on .face--on,.card:focus-visible .face--on{transition:clip-path .42s cubic-bezier(.22,1,.36,1)}
  @media (hover:hover) and (pointer:fine){html:not(.sw-js) .card:hover .face--on{transition:clip-path .42s cubic-bezier(.22,1,.36,1)}}
  .day.is-on .face:not(.face--on),.day:focus-visible .face:not(.face--on){transition:opacity 0s .42s}
  @media (hover:hover) and (pointer:fine){html:not(.sw-js) .day:hover .face:not(.face--on){transition:opacity 0s .42s}}
  .vcard__arr{transition:translate .42s cubic-bezier(.22,1,.36,1) .08s}
  .sw-js .vcard:not(.is-on):not(:focus-visible) .face--on .vcard__arr{translate:-.75em 0}
  .btn-line{transition:background-color .2s var(--ease-out),color .2s var(--ease-out)}
  .btn--secondary{transition:transform var(--d-fast) var(--ease-out),background-color .2s var(--ease-out),color .2s var(--ease-out)}
}
@media (hover:none){.card:active .face--on{transition:none}}
.sw-snap .face--on{transition:none!important}
/* No rim (round 7): once the copy covers a day card, the resting face under it stops painting, so no 1 px of the
   resting colour shows on the rounded edge. Opacity, not visibility: the real text stays for screen readers. */
.day.is-on .face:not(.face--on),.day:focus-visible .face:not(.face--on){opacity:0}
@media (hover:hover) and (pointer:fine){html:not(.sw-js) .day:hover .face:not(.face--on){opacity:0}}
@media (hover:none){.day:active .face:not(.face--on){opacity:0}}
