/* ===========================================================================
   «Vendemos tiempo» (ensamble-tiempo.html). The scroll-driven opener: a
   believable week calendar whose repetitive, manual blocks get done by
   themselves as you scroll, leaving a 15-minute human review and free time.
   Alberto chose this idea on 27-sep-2026; storyboard reviewed by Codex
   (propuestas/codex-guion-tiempo.md) and the engine by the architect.

   How it plays: every animation below is declared only under .is-live, paused,
   on a 10 s timeline; ensamble-tiempo.js sets currentTime = p × 10 s, where p
   is the smoothed scroll progress through the section. So keyframe % = scroll
   %. A block's own moment is its --at (in %), turned into an animation-delay
   of --at × 100 ms; the counter reads the same --at and data-save.
   Base style = the final frame (no JS, reduced motion, first paint).

   Scroll, in % (Codex: 10 / 20 / 15 / 25 / 30):
     0–10   the week, full: 11 manual blocks (18 h 45 min)
     10–30  invoices: the camera frames Monday 9:00, the piece docks and clicks
            (16); the block shrinks to its 15-minute review and the camera
            holds on its label until 21; then it pulls back and Wednesday and
            Friday follow (23.8, 25.4)
     30–45  order e-mails: Monday 11:30 (34), then Tuesday → Friday (41.2–43)
     45–70  afternoon: Tuesday's calls (49), Thursday's (56.2); Friday's report (62)
     70–100 the piece hands the time back: close-ups on Monday and Wednesday
            mornings (74, 78.5) and Friday afternoon (83.5), the piece beside
            each new human block, then the whole week (93); the three human
            blocks take part of the freed time, and more than half stays free
   The video explains itself with the calendar's own notifications (Alberto:
   «que en el propio vídeo se explicase», then not the icon, and readable):
   18.3 invoices · 36.3 e-mails · 51.3 calls · 64.3 report, each «Ya no … tú:
   solo …»; 72 «16 h libres cada semana», which stays. 600vh of scroll, and
   the self-playing mode holds on each one.
   Sample figures: 18 h 45 min manual; 11 reviews × 15 min; 16 h recovered.
   World: .tw is 100 × 62.5 cqw (16:10). Shot: translate(50cqw, C) scale(S)
   translate(-X, -Y), C = half the stage height (31.25cqw, or 66.667cqw on the
   3:4 phone stage).
   =========================================================================== */
.motion-hint{text-align:center;display:flex;justify-content:center;align-items:center;gap:9px;font-size:11px;color:#5f6e84;padding:26px 0 0}
.motion-hint span{width:19px;height:27px;border:1px solid #a7b4c9;border-radius:10px;display:grid;place-items:center;color:#2453ec;overflow:hidden}
/* the arrow bounces down inside its capsule: quick on the way down, easing back up (Alberto, 29-09-2026) */
.motion-hint span i{display:block;font-style:normal;line-height:1;animation:hint-bob 1.6s infinite}
@keyframes hint-bob{0%,100%{transform:translateY(-3px);animation-timing-function:cubic-bezier(.5,0,.9,.6)}40%{transform:translateY(3px);animation-timing-function:cubic-bezier(.2,.6,.4,1)}}

.time-story{position:relative;background:#eef1f7}
.time-pin{display:grid;grid-template-columns:minmax(260px,.8fr) minmax(0,1.9fr);align-items:center;gap:clamp(24px,4vw,64px);padding:72px 5vw}
.time-copy{min-width:0}
.time-beats{display:grid}
.time-beat{grid-area:1/1;opacity:0;transform:translateY(10px);transition:opacity .4s ease,transform .4s ease}
.time-beat.is-on{opacity:1;transform:none}
.time-beat .eyebrow{margin:0 0 14px;color:#516078}
.time-h{margin:0;font-size:clamp(30px,3.3vw,50px);font-weight:570;letter-spacing:-.045em;line-height:1.06;color:#17202c}
.time-h span{color:#2453ec}
/* The close is a motto, not a literal offer (Alberto, 29-09-2026: «ponlo con las comillas para destacar
   que es una frase»): « » drawn by <q>, the closing one in the blue of its line, both hung on wide screens
   (absolute at their own static place: they take no width), so the words keep the left edge of the eyebrow and the paragraph and the column wraps
   them exactly as it wrapped the bare words. */
.time-quote q{quotes:"«" "»"}
.time-quote q::after{color:#2453ec}
@media (min-width:761px){.time-quote q::before,.time-quote q::after{position:absolute}.time-quote q::before{transform:translateX(-100%)}}
.time-p{margin:16px 0 0;max-width:36ch;font-size:16px;line-height:1.5;color:#546176}
.time-count{display:flex;align-items:baseline;gap:12px;margin:34px 0 0}
.time-count b{font-size:clamp(44px,5vw,76px);font-weight:750;letter-spacing:-.045em;line-height:1;color:#2453ec;font-variant-numeric:tabular-nums}
.time-count small{max-width:14ch;font-size:14px;line-height:1.3;color:#546176}
.time-view{display:grid;gap:14px;width:100%;min-width:0;justify-self:center}
/* Jumping between parts: a short dip of the copy and the scene (JS adds .is-cutting). */
.time-copy,.time-stage{transition:opacity .22s ease}
.is-cutting .time-copy,.is-cutting .time-stage{opacity:0}
/* The parts: chapters of the scene, clickable, with their own progress. */
.time-parts{display:none}
.is-live .time-parts{display:flex;align-items:flex-start;gap:16px}
.time-play{flex:none;width:36px;height:36px;margin-top:-2px;border:1px solid #cfd6e2;border-radius:50%;background:#fff;color:#17202c;display:grid;place-items:center;cursor:pointer}
.time-play svg{width:13px;height:13px;fill:currentColor}
.time-play .i-pause,.time-play[aria-pressed="true"] .i-play{display:none}
.time-play[aria-pressed="true"] .i-pause{display:block}
.time-parts ol{flex:1;min-width:0;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;margin:0;padding:0;list-style:none}
.time-parts ol button{position:relative;width:100%;display:flex;gap:6px;align-items:baseline;padding:11px 0 0;border:0;background:none;text-align:left;font:inherit;font-size:13px;font-weight:550;line-height:1.25;color:#5c6878;cursor:pointer}
.time-parts ol button i{position:absolute;left:0;right:0;top:0;height:3px;border-radius:2px;background:#d3d9e4;overflow:hidden}
/* One --p (0–100) on the nav; each part knows its range (--s, --e) from the beats. */
.time-parts ol button i::after{content:"";position:absolute;inset:0;background:#2453ec;transform-origin:0 50%;transform:scaleX(clamp(0,(var(--p,100) - var(--s,0)) / (var(--e,100) - var(--s,0)),1))}
.time-parts ol button span{font-size:11px;font-weight:650;color:#5f6b7e;font-variant-numeric:tabular-nums}
.time-parts ol button[aria-current="step"]{color:#17202c}
.time-parts ol button[aria-current="step"] span{color:#2453ec}
.time-parts button:hover{color:#2453ec}
.time-parts button:focus-visible{outline:3px solid #2453ec;outline-offset:4px;border-radius:6px}
.time-stage{position:relative;container-type:inline-size;width:100%;aspect-ratio:16/10;justify-self:center;overflow:hidden;border-radius:18px;background:#e3e8f0 radial-gradient(circle,#c8d1df 1px,transparent 1.3px) 0 0/22px 22px}

/* ---- the calendar (world coordinates in cqw) ---- */
.tw{position:absolute;left:0;top:0;width:400cqw;height:250cqw;container-type:inline-size;transform:scale(.25);transform-origin:0 0;font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}
.tw>*{position:absolute}
.tw-app{left:2cqw;top:2cqw;width:96cqw;height:58.5cqw;border-radius:1.1cqw;background:#fff;box-shadow:0 .2cqw .5cqw #17202b12,0 2.4cqw 4.8cqw -2.4cqw #243f7350}
.tw-app>*{position:absolute}
.tw-bar{left:0;right:0;top:0;height:5.6cqw;border-bottom:4px solid #e6e9ef;display:flex;align-items:center;gap:1.2cqw;padding:0 2.2cqw;font-size:1.3cqw;color:#5c6878;white-space:nowrap}
.tw-bar b{font-size:1.55cqw;font-weight:750;color:#17202b;letter-spacing:-.02em}
.tw-who{padding-right:1.4cqw;border-right:4px solid #e6e9ef}
.tw-date{display:flex;align-items:center;gap:.5cqw}
.tw-date i{font-style:normal;display:grid;place-items:center;width:2cqw;height:2cqw;border-radius:.5cqw;background:#f1f3f7;color:#5c6878;font-size:1.3cqw}
.tw-view{margin-left:auto;margin-right:5.4cqw;display:flex;gap:.2cqw;padding:.25cqw;border-radius:.8cqw;background:#f1f3f7}
.tw-view i{font-style:normal;padding:.35cqw 1cqw;border-radius:.6cqw;font-size:1.05cqw}
.tw-view .on{background:#fff;color:#17202b;font-weight:650;box-shadow:0 .1cqw .3cqw #17202b1f}
.tw-day{left:calc(9cqw + var(--d) * 17.2cqw);top:5.6cqw;width:17.2cqw;height:4cqw;display:grid;place-items:center;font-size:1.15cqw;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:#6b778a}
.tw-hour{left:1cqw;width:6.6cqw;top:calc(9.6cqw + (var(--s) - 8) * 4.75cqw - .6cqw);text-align:right;font-size:1cqw;color:#8a95a6;font-variant-numeric:tabular-nums}
.tw-grid{left:9cqw;top:9.6cqw;width:86cqw;height:47.5cqw;border-top:4px solid #e6e9ef;background:repeating-linear-gradient(to bottom,transparent 0 calc(4.75cqw - 4px),#eef0f4 calc(4.75cqw - 4px) 4.75cqw),repeating-linear-gradient(to right,#e6e9ef 0 4px,transparent 4px 17.2cqw)}

/* Blocks: --d day (0 = Monday), --s / --e start and end hours. */
.tb,.tb-r,.tc{left:calc(11.35cqw + var(--d) * 17.2cqw);top:calc(11.6cqw + (var(--s) - 8) * 4.75cqw + .12cqw)}
.tb{z-index:1;width:16.5cqw;height:calc((var(--e) - var(--s)) * 4.75cqw - .24cqw);box-sizing:border-box;padding:.6cqw .8cqw;border-radius:.55cqw;overflow:hidden;line-height:1.2}
.tb b{display:block;font-size:1.2cqw;font-weight:650;letter-spacing:-.01em}
.tb small{display:flex;align-items:center;gap:.5cqw;margin-top:.2cqw;font-size:.95cqw;font-variant-numeric:tabular-nums}
.tb i{font-style:normal;padding:.08cqw .45cqw;border-radius:1cqw;background:#f3d9a8;color:#7a4f0e;font-size:.72cqw;font-weight:750;letter-spacing:.06em;text-transform:uppercase}
.tb.n{background:#eef1f6;box-shadow:inset .35cqw 0 0 #9aa6b8}.tb.n b{color:#2b3646}.tb.n small{color:#6b778a}
.tb.m{background:#fcefd8;box-shadow:inset .35cqw 0 0 #d99a3c;clip-path:inset(0 0 100% 0)}.tb.m b{color:#5d3f0c}.tb.m small{color:#8a6a3a}
.tb.h{z-index:2;background:#e6edff;box-shadow:inset .35cqw 0 0 #2453ec}.tb.h b{color:#16307a}.tb.h small{color:#4a5f9a}.tb.h i{background:#d2defd;color:#1b3a9e}
/* The 15-minute human review each manual block leaves behind. */
.tb-r{z-index:2;width:16.5cqw;height:calc(1.19cqw - .24cqw);border-radius:.35cqw;background:#dcefe4;box-shadow:inset .35cqw 0 0 #3e8460}
/* Label for the block in focus, written in the time it frees. */
.tc{z-index:3;margin:calc(1.19cqw + .9cqw) 0 0 .9cqw;padding-left:.8cqw;border-left:.2cqw solid #3e8460;opacity:0;line-height:1.25;white-space:nowrap}
.tc b{display:block;font-size:1.05cqw;font-weight:700;color:#24553b}
.tc small{display:block;font-size:.95cqw;color:#5c6878}
/* What happens, said the way software says it: notifications in the corner of
   the calendar, outside the camera (they never zoom). Each one stays until the
   next (JS). The camera keeps the piece and the review labels above the
   corner where they land. */
.time-feed{position:absolute;z-index:6;right:14px;bottom:14px;width:min(320px,40%);pointer-events:none}
.time-story:not(.is-live) .time-feed{display:none}
.note{position:absolute;right:0;bottom:0;box-sizing:border-box;width:100%;margin:0;padding:10px 14px 11px 44px;border-radius:14px;background:#fffffff7;box-shadow:0 0 0 1px #d9e0ec,0 14px 28px -16px #1b2f7a80;font-size:13px;line-height:1.35;color:#46526a;opacity:0;transform:translateY(calc(var(--y,0px) + 14px));transition:transform .5s cubic-bezier(.2,0,0,1),opacity .35s ease}
.note.is-in{opacity:1;transform:translateY(var(--y,0px))}
.note.is-old{opacity:.55}
.note small{display:block;margin-bottom:1px;font-size:11px;font-weight:600;letter-spacing:.02em;color:#8a95a6}
.note b{display:block;font-size:14px;font-weight:650;letter-spacing:-.01em;color:#17202c}
.note .ni{position:absolute;left:12px;top:12px;width:22px;height:22px;border-radius:50%;background:#dcefe4;display:grid;place-items:center}
.note .ni svg{width:14px;height:14px;fill:none;stroke:#2f7a52;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.note.h .ni{background:#e0e8ff}.note.h .ni svg{stroke:#2453ec}
.note.h b{color:#1b3a9e}
/* The piece ends in Tuesday's free midday (36.8, 40.1), clear of every label. */
.tw .tv{z-index:5;left:34.6cqw;top:37.9cqw;width:4.4cqw;border-radius:1.1cqw}

/* ---- playing: everything paused, driven by the scroll ---- */
.time-story.is-live{height:600vh}
.is-live .time-pin{position:sticky;top:var(--hdr,0px);height:calc(100vh - var(--hdr,0px));height:calc(100svh - var(--hdr,0px));box-sizing:border-box;padding-block:28px}
/* seen once to the end, the scene lets go of the scroll (ensamble-tiempo.js): one screen, its last frame */
.time-story.is-live.is-free{height:auto}
/* reduced motion: the parts in cuts (ensamble-tiempo.js), and no play button while it holds the reader (playing
   would move the page); once let go, the button plays it in place, gliding, like a video. Every animation
   of the scene must be declared under .is-live (and so be collected by the JS): vibilog-base.css lets only
   those live under reduced motion, paused on a resting frame; one declared elsewhere would play freely. */
.is-steps:not(.is-free) .time-play{display:none}
.time-story.is-free .time-pin{position:relative;top:auto}
.is-live .time-view{max-width:calc((100svh - 124px - var(--hdr,0px)) * 1.6)}
.is-live .tw,.is-live .tw .tv,.is-live .tv .vb-l,.is-live .tv .vb-r,.is-live .tb.m,.is-live .tb-r,.is-live .tc,.is-live .tb.h{animation-duration:10s;animation-timing-function:linear;animation-fill-mode:both;animation-play-state:paused}
.is-live .tw{animation-name:tw-cam}
.is-live .tw .tv{animation-name:tw-piece,tw-edge}
.is-live .tv .vb-l{animation-name:tw-l}
.is-live .tv .vb-r{animation-name:tw-r}
.is-live .tb.m{animation-name:tw-go;animation-duration:180ms;animation-delay:calc(var(--at) * 100ms)}
.is-live .tb-r{animation-name:tw-rev;animation-duration:60ms;animation-delay:calc(var(--at) * 100ms + 130ms)}
.is-live .tc{animation-name:tw-call;animation-duration:800ms;animation-delay:calc(var(--at) * 100ms + 100ms)}
.is-live .tb.h{animation-name:tw-in;animation-duration:150ms;animation-delay:calc(var(--at) * 100ms)}

/* A manual block: a blue ring (it is being connected), then it shrinks up
   to its review. */
@keyframes tw-go{
  0%{clip-path:inset(0 0 0 0);box-shadow:inset .35cqw 0 0 #d99a3c}
  35%{clip-path:inset(0 0 0 0);box-shadow:inset .35cqw 0 0 #d99a3c,inset 0 0 0 .25cqw #2453ec;animation-timing-function:cubic-bezier(.6,0,.3,1)}
  100%{clip-path:inset(0 0 100% 0);box-shadow:inset .35cqw 0 0 #d99a3c,inset 0 0 0 .25cqw #2453ec}}
@keyframes tw-rev{0%{opacity:0;transform:scaleX(.6)}100%{opacity:1;transform:none}}
.tb-r{transform-origin:0 50%}
@keyframes tw-call{0%{opacity:0;transform:translateY(.5cqw)}5%,85%{opacity:1;transform:none}100%{opacity:0;transform:none}}
@keyframes tw-in{0%{opacity:0;transform:translateY(.8cqw)}100%{opacity:1;transform:none}}


/* Camera, 16:10 stage. */
@keyframes tw-cam{
  0%{transform:translate(50cqw,31.25cqw) scale(0.25) translate(-200cqw,-125cqw)}
  10%{transform:translate(50cqw,31.25cqw) scale(0.26) translate(-200cqw,-125cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  14%{transform:translate(50cqw,31.25cqw) scale(0.6) translate(-106cqw,-84cqw)}
  21%{transform:translate(50cqw,31.25cqw) scale(0.6125) translate(-106cqw,-84cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  23.5%{transform:translate(50cqw,31.25cqw) scale(0.27) translate(-200cqw,-116cqw)}
  30%{transform:translate(50cqw,31.25cqw) scale(0.2725) translate(-200cqw,-116cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  33%{transform:translate(50cqw,31.25cqw) scale(0.6) translate(-106cqw,-124cqw)}
  38.8%{transform:translate(50cqw,31.25cqw) scale(0.6125) translate(-106cqw,-124cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  41%{transform:translate(50cqw,31.25cqw) scale(0.27) translate(-200cqw,-128cqw)}
  45%{transform:translate(50cqw,31.25cqw) scale(0.2725) translate(-200cqw,-128cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  48%{transform:translate(50cqw,31.25cqw) scale(0.6) translate(-180cqw,-192cqw)}
  53.8%{transform:translate(50cqw,31.25cqw) scale(0.6125) translate(-180cqw,-192cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  56%{transform:translate(50cqw,31.25cqw) scale(0.35) translate(-256cqw,-154cqw)}
  58%{transform:translate(50cqw,31.25cqw) scale(0.355) translate(-256cqw,-154cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  61.5%{transform:translate(50cqw,31.25cqw) scale(0.55) translate(-312cqw,-208cqw)}
  68.5%{transform:translate(50cqw,31.25cqw) scale(0.56) translate(-312cqw,-208cqw);animation-timing-function:cubic-bezier(.6,0,.9,.5)}
  70.3%{transform:translate(50cqw,31.25cqw) scale(0.35) translate(-228cqw,-144cqw);animation-timing-function:cubic-bezier(.1,.5,.4,1)}
  72.5%{transform:translate(50cqw,31.25cqw) scale(0.45) translate(-154cqw,-92cqw)}
  80.5%{transform:translate(50cqw,31.25cqw) scale(0.455) translate(-154cqw,-92cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  83%{transform:translate(50cqw,31.25cqw) scale(0.55) translate(-320cqw,-208cqw)}
  86%{transform:translate(50cqw,31.25cqw) scale(0.555) translate(-320cqw,-208cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  93%,100%{transform:translate(50cqw,31.25cqw) scale(0.25) translate(-200cqw,-125cqw)}}

/* The piece: docks on the right edge of the first block of each family
   (centres 27.85,21.7 · 27.85,31.2 · 45.05,53.76 · 96.65,51.4) and closes
   (clicks at 16, 34, 49 and 62); then it hands the time back, beside each new
   human block: Monday (27.85,22.9), Wednesday (62.25,22.9), Friday
   (96.65,50.8). On the desktop it ends sitting in Tuesday's free midday
   (36.8,40.1), speaking upwards into empty time (tw-piece); on the phone,
   whose last shot is Friday close up, it stays beside Friday (tw-piece-m).
   Translations are from where each one ends. */
@keyframes tw-piece{
  0%,12%{opacity:0;transform:translate(-8.95cqw,-18.4cqw) scale(.85)}
  15%,30%{opacity:1;transform:translate(-8.95cqw,-18.4cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  33%,45%{transform:translate(-8.95cqw,-8.9cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  48%,58%{transform:translate(8.25cqw,13.66cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  61%,68%{transform:translate(59.85cqw,11.3cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  71.5%,76.5%{transform:translate(-8.95cqw,-17.2cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  78.3%,80%{transform:translate(25.45cqw,-17.2cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  83%,86%{transform:translate(59.85cqw,10.7cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  93%,100%{opacity:1;transform:none}}
@keyframes tw-piece-m{
  0%,12%{opacity:0;transform:translate(-68.8cqw,-29.1cqw) scale(.85)}
  15%,30%{opacity:1;transform:translate(-68.8cqw,-29.1cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  33%,45%{transform:translate(-68.8cqw,-19.6cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  48%,58%{transform:translate(-51.6cqw,2.96cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  61%,68%{transform:translate(0,.6cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  71.5%,76.5%{transform:translate(-68.8cqw,-27.9cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  78.3%,80%{transform:translate(-34.4cqw,-27.9cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  83%,100%{opacity:1;transform:none}}
/* The halves move in the V drawing's own units (its viewBox is 32 wide), whatever the size of the tile or
   of the 4× world: the click is ∓5 and ±.35, as everywhere (vibilog-pieza.css). They were ∓20 since the
   world went 4×, and the open V left its tile (Alberto, 29-09-2026). */
@keyframes tw-l{
  0%,14.2%{transform:translateX(-5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  16%{transform:translateX(.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  16.7%,30%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  31.2%,32.2%{transform:translateX(-5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  34%{transform:translateX(.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  34.7%,45%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  46.2%,47.2%{transform:translateX(-5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  49%{transform:translateX(.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  49.7%,58%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  59.2%,60.2%{transform:translateX(-5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  62%{transform:translateX(.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  62.7%,100%{transform:none}}
@keyframes tw-r{
  0%,14.2%{transform:translateX(5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  16%{transform:translateX(-.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  16.7%,30%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  31.2%,32.2%{transform:translateX(5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  34%{transform:translateX(-.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  34.7%,45%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  46.2%,47.2%{transform:translateX(5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  49%{transform:translateX(-.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  49.7%,58%{transform:none;animation-timing-function:cubic-bezier(.2,0,0,1)}
  59.2%,60.2%{transform:translateX(5px);animation-timing-function:cubic-bezier(.45,0,.9,.35)}
  62%{transform:translateX(-.35px);animation-timing-function:cubic-bezier(.2,0,.2,1)}
  62.7%,100%{transform:none}}
@keyframes tw-edge{
  0%,15.8%{box-shadow:inset 0 0 0 .25cqw #c9d7f5,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  16.4%{box-shadow:inset 0 0 0 .4cqw #2453ec,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  19%,33.8%{box-shadow:inset 0 0 0 .25cqw #c9d7f5,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  34.4%{box-shadow:inset 0 0 0 .4cqw #2453ec,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  37%,48.8%{box-shadow:inset 0 0 0 .25cqw #c9d7f5,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  49.4%{box-shadow:inset 0 0 0 .4cqw #2453ec,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  52%,61.8%{box-shadow:inset 0 0 0 .25cqw #c9d7f5,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  62.4%{box-shadow:inset 0 0 0 .4cqw #2453ec,0 1.6cqw 3.2cqw -1.4cqw #243f7370}
  65%,100%{box-shadow:inset 0 0 0 .25cqw #c9d7f5,0 1.6cqw 3.2cqw -1.4cqw #243f7370}}

/* ---- phone: copy on top, a 3:4 stage below; the camera frames one or two
   columns at a time and follows each change as it spreads to the other days
   (Codex: the whole week, on a phone, is only legible as a start), and ends
   close on Friday, so the time handed back stays legible. */
@media (max-width:800px){
  .time-pin{grid-template-columns:minmax(0,1fr);gap:18px;padding:40px 16px}
  .time-h{font-size:clamp(26px,7vw,34px)}
  .time-p{margin-top:10px;font-size:14px}
  .time-count{margin-top:16px}
  .time-count b{font-size:38px}
  .time-count small{max-width:none;font-size:13px}
  .is-live .time-pin{grid-template-rows:auto minmax(0,1fr);align-content:start;padding:18px 16px 16px;gap:14px}
  .time-story:not(.is-live) .time-stage{aspect-ratio:3/4}
  .time-story:not(.is-live) .tw{transform:translate(50cqw,66.667cqw) scale(0.75) translate(-112cqw,-114cqw)}
  /* The stage shrinks to fit a short screen (Safari's bars take ~180px); the chapter bar keeps
     the full width, or its five labels pile onto each other in 220px. */
  .is-live .time-view{width:100%;align-self:center}
  /* pinned under the sticky header (--hdr, vibilog-base.css), as on a wide screen */
  .is-live .time-pin{top:var(--hdr,0px);height:calc(100svh - var(--hdr,0px))}
  .is-live .time-stage{width:min(100%,calc((100svh - 336px - var(--hdr,0px)) * .75))}
  .is-live .time-stage{aspect-ratio:3/4}
  .is-live .time-parts{gap:10px}
  .time-parts ol{gap:6px}
  /* Numbers only: the chapter's name is already the eyebrow above (and stays for screen readers). */
  .time-parts ol button{padding-top:9px;font-size:0;line-height:1.2}
  .time-parts ol button span{font-size:13px}
  .time-feed{left:10px;right:10px;bottom:10px;width:auto}
  .note{padding:8px 12px 9px 40px;font-size:12px}
  .note b{font-size:13px}
  .note .ni{left:10px;top:10px}
  .is-live .tw{transform:translate(50cqw,66.667cqw) scale(0.8) translate(-328cqw,-176cqw);animation-name:tw-cam-m}
  .is-live .tw .tv{left:94.45cqw;top:48.6cqw;animation-name:tw-piece-m,tw-edge}
}
@keyframes tw-cam-m{
  0%{transform:translate(50cqw,66.667cqw) scale(0.25) translate(-200cqw,-125cqw)}
  10%{transform:translate(50cqw,66.667cqw) scale(0.26) translate(-200cqw,-125cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  14%{transform:translate(50cqw,66.667cqw) scale(1) translate(-74cqw,-94cqw)}
  21%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-74cqw,-94cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  23.3%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-216cqw,-110cqw)}
  24.6%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-216cqw,-110cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  25.4%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-320cqw,-110cqw)}
  30%{transform:translate(50cqw,66.667cqw) scale(0.655) translate(-320cqw,-110cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  33%{transform:translate(50cqw,66.667cqw) scale(1) translate(-74cqw,-124cqw)}
  38.8%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-74cqw,-124cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  41%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-180cqw,-124cqw)}
  42.2%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-180cqw,-124cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  43%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-304cqw,-132cqw)}
  45%{transform:translate(50cqw,66.667cqw) scale(0.655) translate(-304cqw,-132cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  48%{transform:translate(50cqw,66.667cqw) scale(1) translate(-152cqw,-186cqw)}
  53.8%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-152cqw,-186cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  56%{transform:translate(50cqw,66.667cqw) scale(0.65) translate(-284cqw,-184cqw)}
  58%{transform:translate(50cqw,66.667cqw) scale(0.655) translate(-284cqw,-184cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  61.5%{transform:translate(50cqw,66.667cqw) scale(1) translate(-352cqw,-177.2cqw)}
  68.5%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-352cqw,-177.2cqw);animation-timing-function:cubic-bezier(.6,0,.9,.5)}
  70.3%{transform:translate(50cqw,66.667cqw) scale(0.325) translate(-200cqw,-160cqw);animation-timing-function:cubic-bezier(.1,.5,.4,1)}
  72.5%{transform:translate(50cqw,66.667cqw) scale(1) translate(-74cqw,-88cqw)}
  76.5%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-74cqw,-88cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  78.3%{transform:translate(50cqw,66.667cqw) scale(1) translate(-214cqw,-88cqw)}
  80%{transform:translate(50cqw,66.667cqw) scale(1.005) translate(-214cqw,-88cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  83%{transform:translate(50cqw,66.667cqw) scale(1) translate(-352cqw,-177.2cqw)}
  86%{transform:translate(50cqw,66.667cqw) scale(1.0125) translate(-352cqw,-177.2cqw);animation-timing-function:cubic-bezier(.65,0,.35,1)}
  92%,100%{transform:translate(50cqw,66.667cqw) scale(0.8) translate(-328cqw,-176cqw)}}
