/* ============================================================
   Vidzero concept v3. THE WORK (the monitor wall)
   Each film is on a broadcast monitor mounted in a row along a dark studio
   wall. At rest one monitor fills the screen near full-frame. To move: the
   camera PULLS BACK off it (revealing the wall of monitors), WHIPS sideways
   to the next monitor with a heavy motion blur, then PUSHES IN until it fills
   the screen again. Real 3D (perspective + preserve-3d); the motion blur is
   applied to a 2D camera wrapper so the 3D underneath is preserved.
   ============================================================ */
/* 100% not 100vw: 100vw counts the scrollbar and overflows by its width.
   Height and clipping live on .trk__stage since the hundred was built: under
   reduced motion the giving stacks below the stage as a plain block, so the
   section itself must be free to grow. */
.trk { position: relative; width: 100%;
  background: #050509; color: var(--on-dark); touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.trk__stage { position: relative; height: 100vh; min-height: 620px; overflow: hidden; }
.trk__stage::before { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(70% 55% at 50% 40%, rgba(82,113,255,.12), transparent 62%), linear-gradient(180deg, #090910 0%, #030307 74%); }

/* THE CONSTRAIN'S LANDING (round 8b): the trk pins inside .workhold exactly
   as the v4 work did, under the producer at z-index 0, fully built and
   opaque, nothing in it animating. flow.js lands the producer's film on the
   live monitor's screen, measured per frame because the wall is a
   transformed scene and offsets cannot see transforms. Inert until the film
   has landed: a transparent top layer still hit-tests, and the arrow keys
   gate on the same class in main.js. */
.workhold .trk { position: sticky; top: 0; z-index: 0; pointer-events: none; }
.trk.is-armed { pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  /* no scroll driving, so the join cannot run. The trk becomes a plain
     section under the stacked producer; flow.js arms it. The override sits
     AFTER the rules it overrides: a media query has no extra specificity.
     RELATIVE, never static: the camera and scene are position absolute, and
     on a static trk they re-parent to .workhold and escape this section's
     overflow clip. Measured: 129,600px of horizontal scroll, which is
     exactly the fifth monitor's 1800vw translateX at 1440. */
  .workhold .trk { position: relative; top: auto; pointer-events: auto; }
  /* the hundred's stacked reduce layout lives AFTER the giving's base rules
     further down: declared up here it loses the cascade to them, which is
     the media-query-order trap, re-paid on this very section. */
}

/* the camera: a flat wrapper we blur during the move (keeps the 3D intact) */
.trk__cam { position: absolute; inset: 0; z-index: 1; }
/* directional (horizontal) motion blur during a fly: smears the lights into
   streak trails, unlike a uniform blur which just softens */
.trk__cam.is-flying { filter: url(#trk-mblur); }

.trk__scene { position: absolute; inset: 0; perspective: 1000px; perspective-origin: 50% 44%; }

/* studio floor, receding */
.trk__floor { position: absolute; left: -60%; right: -60%; bottom: -4%; height: 52%; pointer-events: none;
  background-image: linear-gradient(rgba(120,140,255,.12) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(120,140,255,.08) 1px, transparent 1px);
  background-size: 70px 70px; transform: perspective(560px) rotateX(74deg); transform-origin: 50% 100%;
  mask-image: linear-gradient(180deg, transparent, #000 55%); -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%); opacity: .5; }

/* the wall of monitors. --restX centres the focused monitor; the fly
   animation drives --fromX/--toX plus a Z pull-back and push-in. */
.trk__wall { position: absolute; inset: 0; transform-style: preserve-3d;
  /* --pw (eased) is the pull-wide: the camera pulls straight back and the
     field resolves. Flights are disarmed once the pull begins, so the fly
     keyframes and this term never fight. */
  transform: translateX(var(--restX, 0px)) translateZ(calc(var(--pw, 0) * -1500px)); }
.trk__wall.is-flying { animation: trk-fly 1.4s var(--ease-inout) forwards; }
@keyframes trk-fly {
  0%   { transform: translateX(var(--fromX)) translateZ(0px); }
  22%  { transform: translateX(var(--fromX)) translateZ(-5200px); }
  78%  { transform: translateX(var(--toX))   translateZ(-5200px); }
  100% { transform: translateX(var(--toX))   translateZ(0px); }
}

/* a monitor: dark bezel + screen, mounted along the wall */
/* 116vh not 128, and centred at 54% not 50% (round 9): the heading row
   needs the top band. The landing needs no retuning: the film's target is
   measured from the live monitor's rect every frame. */
.mon3d { --mon-gap: 1800vw; position: absolute; top: 54%; left: 50%; width: min(84vw, 116vh);
  transform: translate(-50%, -50%) translateX(calc(var(--i, 0) * var(--mon-gap)));
  background: linear-gradient(158deg, #1b1b22, #0d0d12); padding: clamp(10px, 1.1vw, 18px);
  border-radius: 16px; box-shadow: 0 50px 110px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.06);
  backface-visibility: hidden; border: 0; cursor: pointer; }
.mon3d__screen { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden;
  background: #000; box-shadow: inset 0 0 0 1px rgba(0,0,0,.8), inset 0 0 40px rgba(0,0,0,.6); }
.mon3d__v { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mon3d__grade { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(4,4,10,.15), transparent 40%, transparent 62%, rgba(4,4,10,.5)); }
.mon3d__tally { position: absolute; top: 10px; left: 12px; display: inline-flex; align-items: center; gap: .4em;
  font-family: var(--f-mono); font-size: .58rem; letter-spacing: .16em; text-transform: uppercase; color: var(--on-dark-soft); opacity: 0; transition: opacity .3s; }
.mon3d__tally i { width: 7px; height: 7px; border-radius: 50%; background: var(--rec); box-shadow: 0 0 7px var(--rec); }
.mon3d.is-live .mon3d__tally { opacity: 1; }
/* dim monitors that are not the focus (visible when pulled back) */
.mon3d::after { content: ""; position: absolute; inset: 0; border-radius: 16px; pointer-events: none;
  background: rgba(5,5,12,.55); transition: opacity .5s var(--ease-out); }
.mon3d.is-live::after { opacity: 0; }
.mon3d.is-live { box-shadow: 0 50px 120px rgba(0,0,0,.65), inset 0 0 0 1px rgba(82,113,255,.4), 0 0 70px rgba(82,113,255,.18); }

/* THE FIELD: the hundred's screens. Physical positions baked in the markup
   (--fx/--fy/--fz/--fw per screen); the wrapper cancels the wall's --restX so
   the field centres on whichever monitor is live. Opacity is PER SCREEN:
   opacity on the preserve-3d wrapper would flatten the 3D. Windows read the
   RAW progress (--pwraw): phases on the eased master front-load dead scroll,
   the trap already written on the cine. */
.trk__field { position: absolute; inset: 0; transform-style: preserve-3d;
  transform: translateX(calc(-1 * var(--restX, 0px))); pointer-events: none; }
.trk__field span { position: absolute; top: 54%; left: 50%;
  width: var(--fw); aspect-ratio: 16 / 9;
  transform: translate(-50%, -50%) translateX(var(--fx)) translateY(var(--fy)) translateZ(var(--fz));
  background-color: #0b0b10;
  background-image: url("../img/field-sprite.jpg?v=20260827a");
  background-size: 900% 600%;
  background-position: var(--sx) var(--sy);
  border-radius: 4px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .55), inset 0 0 0 1px rgba(255, 255, 255, .05);
  opacity: calc(var(--fo, .6) * clamp(0, (var(--pwraw, 0) - .04) * 2.4, 1));
}

/* studio lights: hidden when a monitor is open; they appear ONLY during a fly
   and ONLY in the gaps between monitors, so you streak past them mid-move
   (positions/depths/sizes set in JS) */
.trk__orb { position: absolute; top: 50%; left: 50%; border-radius: 50%; pointer-events: none;
  opacity: 0; transition: opacity .25s var(--ease-out); }
.trk__cam.is-flying .trk__orb { opacity: 1; }

/* --- HUD (fixed 2D over the scene, never blurred) --- */
.trk__hud { position: absolute; inset: 0; z-index: 5; pointer-events: none;
  opacity: calc(1 - clamp(0, var(--pwraw, 0) * 1.9, 1));
  transition: visibility 0s .2s; }
.trk__hud button, .trk__hud a { pointer-events: auto; }
/* once wide, the carousel chrome leaves the tab order too: it is inoperable
   by design out there, so hiding it is correct, not the old CTA trap */
.trk.is-wide .trk__hud { visibility: hidden; }
.trk.is-wide .trk__hud button, .trk.is-wide .trk__hud a { pointer-events: none; }

/* chrome positions are all in vh so they scale with the (vh-capped) monitor and
   never collide across viewport sizes. Monitor is height-capped at ~72vh, so
   there is always ~14vh of clear band top and bottom for the chrome. */
/* the heading row (round 9): heading left, portfolio link right, one
   baseline. The top padding puts the row BELOW the fixed brand mark and
   menu pill bands (both end by ~64px), which also retires the 8.5rem
   pill-clearance hack the bare link needed. */
.trk__topbar { position: absolute; top: 0; left: 0; right: 0; max-width: var(--container); margin-inline: auto;
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem 2rem;
  padding-block: clamp(4rem, 9vh, 5.5rem) 0; padding-inline: var(--container-pad); }
.trk__head {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2rem, 4.6vw, 3.8rem); line-height: 1.02; letter-spacing: -.03em;
  color: #fff; text-wrap: balance;
}
.trk__tag { display: inline-flex; align-items: center; gap: .6em; font-family: var(--f-mono); font-size: .72rem;
  letter-spacing: .18em; text-transform: uppercase; color: var(--on-dark-soft); }
.trk__tag i { width: 9px; height: 9px; border-radius: 50%; background: var(--rec); box-shadow: 0 0 8px var(--rec); }
.trk__all { display: inline-flex; align-items: center; gap: .5em; font-family: var(--f-mono); font-size: .76rem;
  letter-spacing: .1em; text-transform: uppercase; color: #fff; padding-bottom: .25em; border-bottom: 1.5px solid rgba(255,255,255,.3);
  transition: border-color var(--dur-1); }
.trk__all span { transition: transform var(--dur-1) var(--ease-out); }
.trk__all:hover { border-color: var(--accent); }
.trk__all:hover span { transform: translateX(4px); }

/* no backdrop-filter anywhere in this section any more: the trk is pinned
   (sticky) inside .workhold since round 8b, and backdrop-filter inside a
   sticky ancestor is the frozen-paint-layer trap. Opacity raised instead. */
.trk__arrow { position: absolute; top: 50%; transform: translateY(-50%); width: clamp(46px, 5vw, 66px); height: clamp(46px, 5vw, 66px);
  border-radius: 50%; background: rgba(8,6,28,.62); border: 1.5px solid rgba(255,255,255,.32); color: #fff;
  font-size: clamp(1.5rem, 2.4vw, 2.1rem); line-height: 1; display: grid; place-items: center;
  transition: background var(--dur-1), border-color var(--dur-1), transform var(--dur-1); }
.trk__arrow--prev { left: clamp(1rem, 2.5vw, 2rem); }
.trk__arrow--next { right: clamp(1rem, 2.5vw, 2rem); }
.trk__arrow:hover { background: var(--accent); border-color: var(--accent); }
.trk__arrow--prev:hover { transform: translateY(-50%) translateX(-3px); }
.trk__arrow--next:hover { transform: translateY(-50%) translateX(3px); }
.trk__arrow[disabled] { opacity: .28; pointer-events: none; }

.trk__panel { position: absolute; left: 0; right: 0; max-width: var(--container); margin-inline: auto; padding-inline: var(--container-pad);
  bottom: 15.5vh; display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem 2rem; flex-wrap: wrap; }
.trk__meta { max-width: 60ch; }
/* Both small labels carry the same solid dark chip: the panel sits over the
   monitor's PLAYING footage, and bright frames gutted their contrast
   intermittently (index p5 1.07 at 1024, category 3.7 to 4.2 at three
   widths). The category's old translucent border is gone too: its mid-tone
   ring over white footage was itself the p5 floor. Round 11. */
.trk__idx { display: inline-block; font-family: var(--f-mono); font-size: .8rem; letter-spacing: .1em; color: var(--on-dark-soft);
  background: rgba(8, 6, 28, .85); padding: .3em .6em; border-radius: var(--r-xs); }
.trk__idx b { color: #fff; font-weight: 700; }
.trk__idx i { font-style: normal; }
.trk__cat { display: inline-block; margin-left: .8em; font-family: var(--f-mono); font-size: .6rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent-on-dark); background: rgba(8, 6, 28, .85);
  padding: .38em .6em; border-radius: var(--r-xs); }
.trk__name { font-family: var(--f-display); font-weight: 800; font-size: clamp(2rem, 6vw, 5rem); line-height: 1.05;
  letter-spacing: -0.03em; color: #fff; margin-top: .35em; text-shadow: 0 2px 30px rgba(0,0,0,.75);
  /* always reserve two lines and sit on the same baseline, so 1-line and
     2-line project names occupy the same footprint and nothing shifts */
  min-height: 2.1em; display: flex; align-items: flex-end; }
.trk__idx b { font-variant-numeric: tabular-nums; }

/* ============================================================
   THE HUNDRED's copy: bottom left over the field, on the producer's own
   grade recipe. Arrives on the raw window after the field has resolved.
   ============================================================ */
.trk__giving { position: absolute; inset: 0; z-index: 6; pointer-events: none;
  display: grid; align-items: end;
  opacity: clamp(0, (var(--pwraw, 0) - .45) / .4, 1); }
/* stronger than the producer's recipe on purpose: the ground here is not one
   graded film but a field of bright frames, and the heading measured 1.5:1
   over a sunset until the wash won */
.trk__giving::before { content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(5, 5, 9, .95) 0%, rgba(5, 5, 9, .86) 32%,
                            rgba(5, 5, 9, .58) 58%, rgba(5, 5, 9, .16) 82%,
                            rgba(5, 5, 9, 0) 100%),
    linear-gradient(100deg, rgba(5, 5, 9, .88) 0%, rgba(5, 5, 9, .48) 46%,
                            rgba(5, 5, 9, 0) 76%); }
.trk__giving-copy { position: relative;
  width: 100%; max-width: var(--container); margin-inline: auto;
  padding: 0 var(--container-pad) clamp(3.5rem, 9vh, 6rem);
  /* the copy is real text, so it must be selectable: the trk carries
     user-select none for the drag gesture and pointer-events none while
     disarmed, and both inherit. Selection needs both re-enabled. */
  user-select: text; -webkit-user-select: text; }
/* pointer events come back ONLY once the section is wide: at rest this
   invisible block sits over the panel and the watch button, and a
   transparent top layer still hit-tests. */
.trk.is-wide .trk__giving-copy { pointer-events: auto; }
.trk__giving h2 {
  font-family: var(--f-display); font-weight: 800;
  font-size: clamp(2.1rem, 4.8vw, 4.2rem); line-height: 1; letter-spacing: -.03em;
  color: #fff; max-width: 18ch; text-wrap: balance;
}
/* one size across the lede, the bridge and the proof (the size split read
   as a mistake, Nick, 27 August 2026); the wash and the brighter ink are
   the proof's emphasis */
.trk__giving-lead, .trk__giving-story {
  margin-top: clamp(.9rem, 2vw, 1.3rem); max-width: 50ch; text-wrap: pretty;
  font-family: var(--f-prose); font-size: clamp(1.08rem, 1.35vw, 1.32rem);
  line-height: 1.55; color: rgba(240, 238, 252, .92);
}
/* the proof stands apart ON PURPOSE (the tint alone was too subtle to read
   as deliberate, Nick, 27 August 2026): the display face at title-card
   weight, full ink, behind the page's own accent bar, with the wash still
   on the outcome. */
.trk__giving-story {
  color: #fff;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(1.22rem, 1.65vw, 1.62rem);
  line-height: 1.38; letter-spacing: -.015em;
  max-width: 42ch;
  border-left: 4px solid var(--accent);
  padding-left: clamp(1rem, 2vw, 1.4rem);
  margin-top: clamp(1.3rem, 2.6vw, 1.8rem);
}

/* the section's one closing action: the hundred page (the strategy's
   secondary action). The story link lives in the producer's copy, so each
   section closes on a single link. */
.trk__giving-more {
  margin-top: clamp(1.3rem, 2.6vw, 1.8rem);
  font-family: var(--f-prose); font-weight: 600;
  font-size: clamp(1.05rem, 1.25vw, 1.22rem);
}

/* the hundred, stacked under reduced motion: no pull-wide exists, so the
   copy becomes a plain block below the carousel. This block sits AFTER the
   base rules it overrides, because a media query has no extra specificity
   (the trap was re-paid on this very section: declared above them, these
   rules silently lost the cascade and the copy stayed invisible). */
@media (prefers-reduced-motion: reduce) {
  .trk__giving { position: relative; inset: auto; opacity: 1; z-index: auto;
    pointer-events: auto;
    padding-block: clamp(3rem, 8vh, 5rem) 0; }
  .trk__giving-copy { pointer-events: auto; }
  .trk__giving::before { display: none; }
}

/* re-key flicker on the label as it scrambles, like a feed switching sources */
@keyframes trk-flicker { 0%, 100% { opacity: 1; } 10% { opacity: .3; } 24% { opacity: 1; } 42% { opacity: .5; } 60% { opacity: 1; } 76% { opacity: .72; } }
.trk__panel.is-rekey .trk__meta { animation: trk-flicker .52s steps(1, end); }
.trk__watch { display: inline-flex; align-items: center; gap: .6em; font-family: var(--f-display); font-weight: 700; font-size: .95rem;
  color: #fff; background: rgba(8,6,28,.72); border: 1.5px solid rgba(255,255,255,.36); border-radius: var(--r-pill);
  padding: .7em 1.3em; white-space: nowrap;
  transition: background var(--dur-1), border-color var(--dur-1), transform var(--dur-1); }
.trk__watch-i { width: 0; height: 0; border-left: 10px solid #fff; border-top: 7px solid transparent; border-bottom: 7px solid transparent; }
.trk__watch:hover { background: var(--accent); border-color: var(--accent); transform: translateY(-2px); }

.trk__strip { position: absolute; left: 50%; transform: translateX(-50%); bottom: 5vh;
  display: flex; gap: .55rem; }
.trk__dot { width: 32px; height: 4px; border-radius: 2px; background: rgba(255,255,255,.26);
  transition: background var(--dur-1), width var(--dur-1); }
.trk__dot:hover { background: rgba(255,255,255,.55); }
.trk__dot.is-active { background: var(--accent); width: 52px; }

/* --- responsive --- */
@media (max-width: 720px) {
  .mon3d { width: 90vw; top: 45%; }
  /* the heading needed air under the brand bar, and the monitor rises to
     close the dead gap beneath it (Nick's mobile pass) */
  .trk__topbar { flex-direction: column; align-items: flex-start; gap: .55rem;
    padding-block: clamp(5.2rem, 12vh, 6.5rem) 0; }
  .trk__panel { bottom: clamp(4.6rem, 12vh, 6rem); }
  .trk__watch { padding: .6em 1em; font-size: .85rem; }
  .trk__hint { display: none; }
  .trk__cat { display: inline-block; margin-left: 0; margin-top: .5em; }
  /* stacked, but the chip must hug its content: display block would draw a
     full-width dark bar */
  .trk__idx { display: block; width: fit-content; }
}

/* --- reduced motion: no fly, no blur, cut straight to the monitor --- */
@media (prefers-reduced-motion: reduce) {
  .trk__wall.is-flying { animation: none; }
  .trk__cam.is-flying { animation: none; }
}


/* ============================================================
   THE EDIT: the services timeline (round 26). A fixed playhead in the
   page's own REC blue (--rec is the accent here, never broadcast red),
   the track scrubbing under it with the scroll, the track header
   pinned left the way an editing app pins its headers. The clips run at
   natural width like real cuts. flow.js writes --tlx (the strip's x)
   and toggles is-live on the clip under the playhead.
   ============================================================ */
.tline {
  /* block explicitly: a global rule flexes sections, and as a flex item
     the band sized itself to the 1708px strip, which pushed the playhead
     off the viewport's centre (and clean off phone screens) */
  display: block;
  position: relative;
  background: #0A0722;
  color: rgba(240, 238, 252, .92);
  /* a strip, not a room: the first cut's padding read as a mistake at
     wide screens (Nick, round 29) */
  padding-block: clamp(4rem, 9vh, 6rem);
  /* no inline padding: the band must run the full viewport, or scrubbed
     clips reappear in the uncovered gutter LEFT of the track header
     before the section edge clips them (Nick's catch, round 27) */
  padding-inline: 0;
  overflow: hidden;
}
.tline__band { position: relative; width: 100%; }
.tline__strip { will-change: transform; transform: translateX(var(--tlx, 50vw)); }
/* the ruler scrubs WITH the clips, under the fixed playhead: minor ticks
   every 12px, major every 96px, drawn as bottom-anchored stripes */
.tline__ruler {
  height: 26px; margin-bottom: 10px; width: var(--tl-w, 300vw);
  border-bottom: 1px solid rgba(240, 238, 252, .25);
  background:
    repeating-linear-gradient(90deg, rgba(240, 238, 252, .34) 0 1px, transparent 1px 96px),
    repeating-linear-gradient(90deg, rgba(240, 238, 252, .16) 0 1px, transparent 1px 12px);
  background-size: auto 14px, auto 8px;
  background-position: 0 100%, 0 100%;
  background-repeat: repeat-x;
}
.tline__clips { display: flex; gap: 6px; width: max-content; margin: 0; padding: 0; list-style: none; }
.tline__clip {
  min-width: 11ch;
  padding: 1.1em 1.6em 1.25em;
  background: rgba(240, 238, 252, .055);
  border: 1px solid rgba(240, 238, 252, .16);
  border-radius: 6px;
  transition: border-color .25s var(--ease-out), background-color .25s var(--ease-out);
}
.tline__clip span {
  font-family: var(--f-display); font-weight: 600;
  font-size: clamp(1rem, 1.15vw, 1.15rem); letter-spacing: -.01em;
  color: rgba(240, 238, 252, .92); white-space: nowrap;
  transition: color .25s var(--ease-out);
}
/* the clip under the playhead is the selected one, in the NLE's own
   grammar: the accent border and a lift, nothing else */
.tline__clip.is-live { border-color: var(--accent); background: rgba(82, 113, 255, .16); }
.tline__clip.is-live span { color: #fff; }
.tline__headcell {
  position: absolute; inset: 0 auto 0 0; z-index: 2;
  display: flex; flex-direction: column; justify-content: center;
  min-width: clamp(13rem, 20vw, 19rem);
  padding-inline: var(--container-pad) 1.6rem;
  background: linear-gradient(90deg, #0A0722 80%, rgba(10, 7, 34, 0));
  font-family: var(--f-machine); text-transform: uppercase; letter-spacing: .16em;
}
.tline__headcell span { font-size: .72rem; color: rgba(240, 238, 252, .88); }
.tline__playhead {
  position: absolute; top: -4px; bottom: -8px; left: 50%; z-index: 3;
  width: 2px; background: var(--rec);
  box-shadow: 0 0 10px color-mix(in srgb, var(--rec) 45%, transparent);
}
.tline__playhead i {
  position: absolute; top: -2px; left: 50%; transform: translateX(-50%);
  width: 14px; height: 12px; background: var(--rec);
  clip-path: polygon(0 0, 100% 0, 100% 55%, 50% 100%, 0 55%);
}
@media (max-width: 720px) {
  .tline { padding-block: clamp(4.5rem, 12vh, 7rem); }
  /* the header sits above the band on phones so the strip runs full bleed */
  .tline__headcell { position: static; min-width: 0; background: none;
    flex-direction: row; align-items: baseline; gap: .9em;
    padding: 0 var(--container-pad) 1.3rem; }
  .tline__clip { min-width: 9ch; padding: 1em 1.2em 1.1em; }
  .tline__clip span { font-size: .98rem; }
}
/* reduced motion: no scrub, no playhead; the clips wrap as a static
   grid of slabs and flow.js marks the first one selected */
@media (prefers-reduced-motion: reduce) {
  .tline__strip { transform: none; }
  .tline__ruler, .tline__playhead { display: none; }
  .tline__clips { flex-wrap: wrap; width: auto; padding-inline: var(--container-pad); }
  .tline__headcell { position: static; min-width: 0; background: none;
    flex-direction: row; align-items: baseline; gap: .9em;
    padding: 0 var(--container-pad) 1.4rem; }
}
