.ticker { left: 0; right: 0; top: 0; margin: 0; padding: .3cqw 0; overflow: hidden; white-space: nowrap; font: 4.2cqw/1 "VT323", monospace; color: #3dff5a; text-shadow: 0 0 .8cqw rgba(60,255,90,.7); }
.ticker span { display: inline-block; animation: tick 60s linear infinite; }
@keyframes tick { to { transform: translateX(-50%); } }
/* The projected picture: fills the lit rectangle edge to edge, light on
   brick, the section name across the top and the title over the picture
   (3.1 hub banner). */
/* The picture is the brightest thing on screen: projector light on brick.
   It glows past its edges a little; faint mortar lines show through. */
.poster { position: relative; width: 100%; height: 100%; overflow: hidden; background: #fff8e8;
  -webkit-mask-image: radial-gradient(ellipse 75% 80% at 50% 50%, #000 78%, rgba(0,0,0,.85) 100%); mask-image: radial-gradient(ellipse 75% 80% at 50% 50%, #000 78%, rgba(0,0,0,.85) 100%); }
.poster::after { content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: multiply;
  background: repeating-linear-gradient(0deg, rgba(150,110,95,.35) 0 2px, transparent 2px 22px),
    repeating-linear-gradient(90deg, rgba(150,110,95,.2) 0 2px, transparent 2px 48px); }
/* Projector light lifts the picture's darks: nothing in it is darker than lit brick. */
.poster::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: screen; background: rgba(255,236,205,.22); }
.poster > * { z-index: 2; }
.poster .pic { z-index: 0; }
[data-quad="poster"] { filter: drop-shadow(0 0 14px rgba(255,240,210,.55)); }
.pic { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: brightness(1.25) contrast(1) saturate(1.1); }
.band { position: absolute; left: 0; right: 0; top: 0; margin: 0; padding: 8px 18px 6px; background: linear-gradient(rgba(40,44,20,.85), rgba(40,44,20,.55));
  border-bottom: 4px solid #e9d25a; font: 400 44px/1 "Anton", Impact, sans-serif; letter-spacing: 3px; text-transform: uppercase; color: #f2e27a; }
.cap { position: absolute; right: 16px; bottom: 16px; left: 30%; margin: 0; text-align: right; font: italic 800 40px/1.02 "Jost", sans-serif; color: #fff;
  text-shadow: 3px 3px 0 #111, -1px -1px 0 #111; overflow-wrap: anywhere; }
.cap.small { left: 16px; top: 42%; bottom: auto; text-align: center; font-size: 32px; color: #2f2a20; text-shadow: none; }
.flick { inset: 0; pointer-events: none; background: rgba(255,240,200,.04); animation: flick .12s steps(2) infinite; mix-blend-mode: screen; }
@keyframes flick { 50% { opacity: .3; } }
.count { right: 3.5%; bottom: 5.5%; margin: 0; font: 5cqw/1 "VT323", monospace; color: #3dff5a; text-shadow: 0 0 .8cqw rgba(60,255,90,.7); }
.hit { top: 20%; bottom: 20%; width: 18%; } .hit.l { left: 0; } .hit.r { right: 0; }

/* Motion. The fly-in plays over the still, then the idle loop; the picture
   only appears once the projector has struck up (body.lit). */
[data-quad="poster"] { opacity: 0; }
body.lit [data-quad="poster"] { opacity: 1; animation: strike .9s steps(9) both; }
@keyframes strike { 0% { opacity: 0; } 20% { opacity: .9; } 30% { opacity: .1; } 45% { opacity: 1; } 55% { opacity: .35; } 100% { opacity: 1; } }
/* A running projector: the lamp flickers at the shutter rate and the film
   weaves in the gate. */
body.lit .poster { animation: flick .12s steps(2) infinite, weave .9s steps(9) infinite; }
@keyframes flick { 50% { filter: brightness(.9); } }
@keyframes weave { 0%, 100% { translate: 0 0; } 20% { translate: .6px -.8px; } 40% { translate: -.4px .5px; } 60% { translate: .8px .3px; } 80% { translate: -.6px -.4px; } }
/* Dust and hairs on the print, a new pattern every few frames. */
.dust { position: absolute; inset: 0; z-index: 3; pointer-events: none; mix-blend-mode: multiply; opacity: .7;
  background:
    radial-gradient(circle at 12% 30%, #211 0 1.5px, transparent 2.5px), radial-gradient(circle at 70% 64%, #211 0 1px, transparent 2px),
    radial-gradient(circle at 44% 82%, #211 0 2px, transparent 3px), linear-gradient(97deg, transparent 58%, rgba(30,20,15,.5) 58.2%, transparent 58.5%);
  animation: dust .5s steps(1) infinite; }
@keyframes dust {
  25% { background-position: 30px -40px, -80px 20px, 120px -60px, -70px 0; }
  50% { background-position: -140px 60px, 40px -90px, -30px 30px, 150px 0; }
  75% { background-position: 90px 110px, -160px -30px, 60px -120px, -20px 0; } }
/* Changing the reel: a leader counts down 3, 2, 1 over the new picture. */
.leader { position: absolute; inset: 0; z-index: 4; display: none; place-items: center; background: #d9d0bb;
  background-image: conic-gradient(from 0deg, rgba(0,0,0,.35) 0 var(--sweep, 0deg), transparent 0), radial-gradient(circle, transparent 38%, #222 38.5% 39.5%, transparent 40%, transparent 48%, #222 48.5% 49.5%, transparent 50%),
    linear-gradient(#222, #222), linear-gradient(#222, #222);
  background-size: auto, auto, 2px 100%, 100% 2px; background-repeat: no-repeat; background-position: center; }
.leader b { grid-area: 1 / 1; font: 400 170px/1 "Anton", Impact, sans-serif; color: #1a1a1a; opacity: 0; }
body.flip .leader { display: grid; animation: leader .66s steps(1) both; }
body.flip .leader b { animation: num .66s steps(1) both; }
body.flip .leader b:nth-child(1) { --from: 0; } body.flip .leader b:nth-child(2) { animation-name: num2; } body.flip .leader b:nth-child(3) { animation-name: num3; }
@keyframes leader { 0% { opacity: 1; } 99% { opacity: 1; } 100% { opacity: 0; } }
@keyframes num { 0% { opacity: 1; } 33% { opacity: 0; } }
@keyframes num2 { 0% { opacity: 0; } 33% { opacity: 1; } 66% { opacity: 0; } }
@keyframes num3 { 0% { opacity: 0; } 66% { opacity: 1; } 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .vid.fly { display: none; } }
