/*
 * @saas/renderer presets.css: the motion preset catalogue (docs/designer-architecture.md §C.3, §C.4) and the renderer's base rules.
 * Keyframe names are the contract with pagedoc's closed lists: pdi-<in>, pde-<emphasis>, pdo-<out>, pdp-<page>, with
 * -<direction> for presets that take one (pagedoc catalogue.json), -rtl for the right-to-left typewriter. test/presets.test.ts
 * asserts every catalogue name has its keyframes and every keyframes rule here is a catalogue name (or a base rule).
 * Chrome >= 56 subset (§C.2, checked by test/css-allowlist.test.ts): transform / opacity / clip-path inset()+polygon() / filter /
 * letter-spacing / visibility / background-position only; no custom properties inside @keyframes, no grid, no gap, no inset:,
 * no clamp()/min()/max(). An `in` direction is the side the element comes FROM; an `out` direction the side it leaves TO.
 * Polygons that animate keep one vertex count per preset (stripes: 4 slats of 4 points joined along an edge; blind: 6 slats).
 */

/* ---- base ---------------------------------------------------------------------------------------------------------------- */
.pd-stage { position: relative; overflow: hidden; --pd-presets: 1; }
.pd-canvas, .pd-page, .pd-layer { position: absolute; left: 0; top: 0; }
.pd-page, .pd-layer { width: 100%; height: 100%; }
.pd-canvas { transform-origin: 0 0; }
.pd-paused, .pd-paused * { animation-play-state: paused; }
.pd-el { box-sizing: border-box; }
.pd-flip { display: inline-block; position: relative; }
.pd-flip-new { display: inline-block; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.pd-flip-old { display: inline-block; position: absolute; left: 0; top: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
/* atomic inline-blocks get no decoration from their block: they paint the one applyDeco() set as --pd-deco (DS-R-strike-fix) */
.pd-flip, .pd-flip-new, .pd-flip-old, .pd-fsi { text-decoration: var(--pd-deco, none); }
.pd-flip-whole-old { position: absolute; left: 0; top: 0; width: 100%; }
.pd-highlight { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none;
  background-image: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,236,150,0.6) 50%, rgba(255,255,255,0) 100%);
  background-size: 50% 100%; background-repeat: no-repeat; background-position: -100% 0; }
.pd-strike-old { display: inline-block; text-decoration: line-through; font-size: 0.55em; opacity: 0.75; margin: 0 0.35em; vertical-align: middle; }

/* element time window: hidden outside [start, end) */
@keyframes pd-window { 0%, 100% { visibility: visible; } }

/* marquee tracks (text scroll, ticker): the track moves by its own size */
@keyframes pd-scroll-left { from { transform: translateX(0); } to { transform: translateX(-100%); } }
@keyframes pd-scroll-right { from { transform: translateX(0); } to { transform: translateX(100%); } }
@keyframes pd-scroll-up { from { transform: translateY(0); } to { transform: translateY(-100%); } }
@keyframes pd-scroll-down { from { transform: translateY(0); } to { transform: translateY(100%); } }

/* ---- in ------------------------------------------------------------------------------------------------------------------ */
@keyframes pdi-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pdi-slide-left { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes pdi-slide-right { from { transform: translateX(100%); } to { transform: none; } }
@keyframes pdi-slide-up { from { transform: translateY(-100%); } to { transform: none; } }
@keyframes pdi-slide-down { from { transform: translateY(100%); } to { transform: none; } }
@keyframes pdi-wipe-left { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-wipe-right { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-wipe-up { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-wipe-down { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-zoomIn { from { transform: scale(0.3); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-zoomUpFrom0 { from { transform: scale(0); } to { transform: none; } }
@keyframes pdi-appear { 0% { opacity: 0; animation-timing-function: step-end; } 100% { opacity: 1; } }
@keyframes pdi-fly-left { 0% { transform: translateX(-300%); opacity: 0; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 100% { transform: none; opacity: 1; } }
@keyframes pdi-fly-right { 0% { transform: translateX(300%); opacity: 0; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 100% { transform: none; opacity: 1; } }
@keyframes pdi-fly-up { 0% { transform: translateY(-300%); opacity: 0; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 100% { transform: none; opacity: 1; } }
@keyframes pdi-fly-down { 0% { transform: translateY(300%); opacity: 0; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); } 100% { transform: none; opacity: 1; } }
@keyframes pdi-bounceIn-left { 0% { transform: translateX(-200%); opacity: 0; } 60% { transform: translateX(8%); opacity: 1; } 80% { transform: translateX(-3%); } 100% { transform: none; } }
@keyframes pdi-bounceIn-right { 0% { transform: translateX(200%); opacity: 0; } 60% { transform: translateX(-8%); opacity: 1; } 80% { transform: translateX(3%); } 100% { transform: none; } }
@keyframes pdi-bounceIn-up { 0% { transform: translateY(-200%); opacity: 0; } 60% { transform: translateY(8%); opacity: 1; } 80% { transform: translateY(-3%); } 100% { transform: none; } }
@keyframes pdi-bounceIn-down { 0% { transform: translateY(200%); opacity: 0; } 60% { transform: translateY(-8%); opacity: 1; } 80% { transform: translateY(3%); } 100% { transform: none; } }
@keyframes pdi-flipIn-left { from { transform: perspective(800px) rotateY(-90deg); opacity: 0; } to { transform: perspective(800px) rotateY(0deg); opacity: 1; } }
@keyframes pdi-flipIn-right { from { transform: perspective(800px) rotateY(90deg); opacity: 0; } to { transform: perspective(800px) rotateY(0deg); opacity: 1; } }
@keyframes pdi-flipIn-up { from { transform: perspective(800px) rotateX(90deg); opacity: 0; } to { transform: perspective(800px) rotateX(0deg); opacity: 1; } }
@keyframes pdi-flipIn-down { from { transform: perspective(800px) rotateX(-90deg); opacity: 0; } to { transform: perspective(800px) rotateX(0deg); opacity: 1; } }
@keyframes pdi-rotateIn { from { transform: rotate(-200deg) scale(0.3); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-fallIn { 0% { transform: translateY(-120%) rotate(-6deg); opacity: 0; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 80% { transform: translateY(4%) rotate(1deg); opacity: 1; } 100% { transform: none; } }
@keyframes pdi-quickIn { 0% { transform: scale(1.6); opacity: 0; animation-timing-function: cubic-bezier(0.1, 0.9, 0.2, 1); } 100% { transform: none; opacity: 1; } }
@keyframes pdi-brightnessIn { from { filter: brightness(0); opacity: 0; } to { filter: brightness(1); opacity: 1; } }
@keyframes pdi-typewriter { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-typewriter-rtl { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-trackingExpand { from { letter-spacing: -0.5em; opacity: 0; } to { letter-spacing: 0; opacity: 1; } }
@keyframes pdi-curtain-left { from { clip-path: inset(0 50% 0 50%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-curtain-right { from { clip-path: inset(0 50% 0 50%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-curtain-up { from { clip-path: inset(50% 0 50% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-curtain-down { from { clip-path: inset(50% 0 50% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-stripes-left {
  from { clip-path: polygon(0% 100%, 0% 0%, 0% 0%, 0% 100%, 25% 100%, 25% 0%, 25% 0%, 25% 100%, 50% 100%, 50% 0%, 50% 0%, 50% 100%, 75% 100%, 75% 0%, 75% 0%, 75% 100%); }
  to { clip-path: polygon(0% 100%, 0% 0%, 25% 0%, 25% 100%, 25% 100%, 25% 0%, 50% 0%, 50% 100%, 50% 100%, 50% 0%, 75% 0%, 75% 100%, 75% 100%, 75% 0%, 100% 0%, 100% 100%); } }
@keyframes pdi-stripes-right {
  from { clip-path: polygon(25% 100%, 25% 0%, 25% 0%, 25% 100%, 50% 100%, 50% 0%, 50% 0%, 50% 100%, 75% 100%, 75% 0%, 75% 0%, 75% 100%, 100% 100%, 100% 0%, 100% 0%, 100% 100%); }
  to { clip-path: polygon(0% 100%, 0% 0%, 25% 0%, 25% 100%, 25% 100%, 25% 0%, 50% 0%, 50% 100%, 50% 100%, 50% 0%, 75% 0%, 75% 100%, 75% 100%, 75% 0%, 100% 0%, 100% 100%); } }
@keyframes pdi-stripes-up {
  from { clip-path: polygon(100% 0%, 0% 0%, 0% 0%, 100% 0%, 100% 25%, 0% 25%, 0% 25%, 100% 25%, 100% 50%, 0% 50%, 0% 50%, 100% 50%, 100% 75%, 0% 75%, 0% 75%, 100% 75%); }
  to { clip-path: polygon(100% 0%, 0% 0%, 0% 25%, 100% 25%, 100% 25%, 0% 25%, 0% 50%, 100% 50%, 100% 50%, 0% 50%, 0% 75%, 100% 75%, 100% 75%, 0% 75%, 0% 100%, 100% 100%); } }
@keyframes pdi-stripes-down {
  from { clip-path: polygon(100% 25%, 0% 25%, 0% 25%, 100% 25%, 100% 50%, 0% 50%, 0% 50%, 100% 50%, 100% 75%, 0% 75%, 0% 75%, 100% 75%, 100% 100%, 0% 100%, 0% 100%, 100% 100%); }
  to { clip-path: polygon(100% 0%, 0% 0%, 0% 25%, 100% 25%, 100% 25%, 0% 25%, 0% 50%, 100% 50%, 100% 50%, 0% 50%, 0% 75%, 100% 75%, 100% 75%, 0% 75%, 0% 100%, 100% 100%); } }
@keyframes pdi-quadrant {
  0% { clip-path: polygon(0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%); }
  25% { clip-path: polygon(0% 0%, 50% 0%, 50% 50%, 50% 50%, 0% 50%, 0% 50%); }
  50% { clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 50% 50%, 0% 50%, 0% 50%); }
  75% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 50% 100%, 50% 50%, 0% 50%); }
  100% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%, 0% 50%); } }
@keyframes pdi-swiss {
  0% { clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%); }
  50% { clip-path: polygon(40% 0%, 60% 0%, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0% 60%, 0% 40%, 40% 40%); }
  100% { clip-path: polygon(0% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 0%, 0% 0%); } }
@keyframes pdi-corner-ne { from { clip-path: inset(0 0 100% 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-corner-se { from { clip-path: inset(100% 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-corner-sw { from { clip-path: inset(100% 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-corner-nw { from { clip-path: inset(0 100% 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdi-rollOn { from { clip-path: inset(0 0 100% 0); transform: perspective(800px) rotateX(-70deg); } to { clip-path: inset(0 0 0 0); transform: perspective(800px) rotateX(0deg); } }
@keyframes pdi-scrollIn { 0% { transform: translateY(100%); opacity: 0; animation-timing-function: ease-out; } 100% { transform: none; opacity: 1; } }
@keyframes pdi-shortFade-n { from { transform: translateY(-15%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-shortFade-e { from { transform: translateX(15%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-shortFade-s { from { transform: translateY(15%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-shortFade-w { from { transform: translateX(-15%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-knight-up { 0% { transform: translate(-60%, 80%); opacity: 0; } 50% { transform: translate(-60%, 0); opacity: 1; } 100% { transform: none; } }
@keyframes pdi-knight-down { 0% { transform: translate(-60%, -80%); opacity: 0; } 50% { transform: translate(-60%, 0); opacity: 1; } 100% { transform: none; } }
@keyframes pdi-jumpIn-left { 0% { transform: translate(-150%, 0); opacity: 0; } 40% { transform: translate(-60%, -30%); opacity: 1; } 70% { transform: translate(-15%, 0); } 85% { transform: translate(-5%, -8%); } 100% { transform: none; } }
@keyframes pdi-jumpIn-right { 0% { transform: translate(150%, 0); opacity: 0; } 40% { transform: translate(60%, -30%); opacity: 1; } 70% { transform: translate(15%, 0); } 85% { transform: translate(5%, -8%); } 100% { transform: none; } }
@keyframes pdi-fallAndFade-left { from { transform: translate(-40%, -60%) rotate(-12deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-fallAndFade-right { from { transform: translate(40%, -60%) rotate(12deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-closeGarage { 0% { clip-path: inset(0 0 100% 0); animation-timing-function: ease-in; } 85% { clip-path: inset(0 0 0 0); } 92% { clip-path: inset(0 0 4% 0); } 100% { clip-path: inset(0 0 0 0); } }
@keyframes pdi-float { 0% { transform: translateY(30%); opacity: 0; animation-timing-function: ease-out; } 100% { transform: none; opacity: 1; } }
@keyframes pdi-totalRecall { from { transform: scale(3); opacity: 0; filter: blur(8px); } to { transform: none; opacity: 1; filter: blur(0); } }
@keyframes pdi-spinFade { from { transform: rotate(-360deg) scale(0.5); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-damped { 0% { transform: scale(0); } 40% { transform: scale(1.15); } 60% { transform: scale(0.92); } 80% { transform: scale(1.04); } 100% { transform: none; } }
@keyframes pdi-uncover { from { clip-path: inset(0 0 0 100%); transform: translateX(10%); } to { clip-path: inset(0 0 0 0); transform: none; } }
@keyframes pdi-quarterFlyOn { from { transform: translate(-100%, -100%) scale(0.25); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdi-cutBlackFade { 0% { opacity: 0; filter: brightness(0); } 50% { opacity: 1; filter: brightness(0); } 100% { opacity: 1; filter: brightness(1); } }

/* ---- emphasis ------------------------------------------------------------------------------------------------------------ */
@keyframes pde-pulse { 0%, 100% { transform: none; } 50% { transform: scale(1.08); } }
@keyframes pde-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.15; } }
@keyframes pde-shake { 0%, 100% { transform: none; } 20% { transform: translateX(-4%); } 40% { transform: translateX(4%); } 60% { transform: translateX(-3%); } 80% { transform: translateX(2%); } }
@keyframes pde-rotate { 0% { transform: rotate(0deg); animation-timing-function: linear; } 100% { transform: rotate(360deg); } }
@keyframes pde-overturn { from { transform: perspective(800px) rotateY(0deg); } to { transform: perspective(800px) rotateY(360deg); } }
@keyframes pde-floating { 0%, 100% { transform: none; } 50% { transform: translateY(-6%); } }
@keyframes pde-glow { 0%, 100% { filter: drop-shadow(0 0 0 rgba(255,235,170,0)); } 50% { filter: drop-shadow(0 0 18px rgba(255,235,170,0.9)); } }
@keyframes pde-wobble { 0%, 100% { transform: none; } 15% { transform: translateX(-3%) rotate(-5deg); } 30% { transform: translateX(2%) rotate(3deg); } 45% { transform: translateX(-2%) rotate(-3deg); } 60% { transform: translateX(1%) rotate(2deg); } 75% { transform: rotate(-1deg); } }

/* ---- out ----------------------------------------------------------------------------------------------------------------- */
@keyframes pdo-fade { from { opacity: 1; } to { opacity: 0; } }
@keyframes pdo-slide-left { from { transform: none; } to { transform: translateX(-100%); } }
@keyframes pdo-slide-right { from { transform: none; } to { transform: translateX(100%); } }
@keyframes pdo-slide-up { from { transform: none; } to { transform: translateY(-100%); } }
@keyframes pdo-slide-down { from { transform: none; } to { transform: translateY(100%); } }
@keyframes pdo-wipe-left { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 100% 0 0); } }
@keyframes pdo-wipe-right { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 0 0 100%); } }
@keyframes pdo-wipe-up { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 0 100% 0); } }
@keyframes pdo-wipe-down { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(100% 0 0 0); } }
@keyframes pdo-zoomOut { from { transform: none; opacity: 1; } to { transform: scale(0.3); opacity: 0; } }
@keyframes pdo-disappear { 0% { opacity: 1; animation-timing-function: step-end; } 100% { opacity: 0; } }
@keyframes pdo-fly-left { 0% { transform: none; opacity: 1; animation-timing-function: cubic-bezier(0.8, 0, 0.8, 0.2); } 100% { transform: translateX(-300%); opacity: 0; } }
@keyframes pdo-fly-right { 0% { transform: none; opacity: 1; animation-timing-function: cubic-bezier(0.8, 0, 0.8, 0.2); } 100% { transform: translateX(300%); opacity: 0; } }
@keyframes pdo-fly-up { 0% { transform: none; opacity: 1; animation-timing-function: cubic-bezier(0.8, 0, 0.8, 0.2); } 100% { transform: translateY(-300%); opacity: 0; } }
@keyframes pdo-fly-down { 0% { transform: none; opacity: 1; animation-timing-function: cubic-bezier(0.8, 0, 0.8, 0.2); } 100% { transform: translateY(300%); opacity: 0; } }
@keyframes pdo-bounceOut-left { 0% { transform: none; opacity: 1; } 30% { transform: translateX(8%); } 100% { transform: translateX(-200%); opacity: 0; } }
@keyframes pdo-bounceOut-right { 0% { transform: none; opacity: 1; } 30% { transform: translateX(-8%); } 100% { transform: translateX(200%); opacity: 0; } }
@keyframes pdo-bounceOut-up { 0% { transform: none; opacity: 1; } 30% { transform: translateY(8%); } 100% { transform: translateY(-200%); opacity: 0; } }
@keyframes pdo-bounceOut-down { 0% { transform: none; opacity: 1; } 30% { transform: translateY(-8%); } 100% { transform: translateY(200%); opacity: 0; } }
@keyframes pdo-flipOut-left { from { transform: perspective(800px) rotateY(0deg); opacity: 1; } to { transform: perspective(800px) rotateY(-90deg); opacity: 0; } }
@keyframes pdo-flipOut-right { from { transform: perspective(800px) rotateY(0deg); opacity: 1; } to { transform: perspective(800px) rotateY(90deg); opacity: 0; } }
@keyframes pdo-flipOut-up { from { transform: perspective(800px) rotateX(0deg); opacity: 1; } to { transform: perspective(800px) rotateX(90deg); opacity: 0; } }
@keyframes pdo-flipOut-down { from { transform: perspective(800px) rotateX(0deg); opacity: 1; } to { transform: perspective(800px) rotateX(-90deg); opacity: 0; } }
@keyframes pdo-rotateOut { from { transform: none; opacity: 1; } to { transform: rotate(200deg) scale(0.3); opacity: 0; } }
@keyframes pdo-fallOut { 0% { transform: none; opacity: 1; animation-timing-function: cubic-bezier(0.55, 0, 1, 0.45); } 100% { transform: translateY(150%) rotate(12deg); opacity: 0; } }
@keyframes pdo-quickOut { from { transform: none; opacity: 1; } to { transform: scale(1.6); opacity: 0; } }
@keyframes pdo-brightnessOut { from { filter: brightness(1); opacity: 1; } to { filter: brightness(0); opacity: 0; } }
@keyframes pdo-reduce { from { transform: none; } to { transform: scale(0); } }
@keyframes pdo-typewriterOut { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 100% 0 0); } }
@keyframes pdo-typewriterOut-rtl { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 0 0 100%); } }
@keyframes pdo-trackingContract { from { letter-spacing: 0; opacity: 1; } to { letter-spacing: -0.5em; opacity: 0; } }
@keyframes pdo-curtain-left { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 50% 0 50%); } }
@keyframes pdo-curtain-right { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 50% 0 50%); } }
@keyframes pdo-curtain-up { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(50% 0 50% 0); } }
@keyframes pdo-curtain-down { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(50% 0 50% 0); } }
@keyframes pdo-stripes-left {
  from { clip-path: polygon(0% 100%, 0% 0%, 25% 0%, 25% 100%, 25% 100%, 25% 0%, 50% 0%, 50% 100%, 50% 100%, 50% 0%, 75% 0%, 75% 100%, 75% 100%, 75% 0%, 100% 0%, 100% 100%); }
  to { clip-path: polygon(0% 100%, 0% 0%, 0% 0%, 0% 100%, 25% 100%, 25% 0%, 25% 0%, 25% 100%, 50% 100%, 50% 0%, 50% 0%, 50% 100%, 75% 100%, 75% 0%, 75% 0%, 75% 100%); } }
@keyframes pdo-stripes-right {
  from { clip-path: polygon(0% 100%, 0% 0%, 25% 0%, 25% 100%, 25% 100%, 25% 0%, 50% 0%, 50% 100%, 50% 100%, 50% 0%, 75% 0%, 75% 100%, 75% 100%, 75% 0%, 100% 0%, 100% 100%); }
  to { clip-path: polygon(25% 100%, 25% 0%, 25% 0%, 25% 100%, 50% 100%, 50% 0%, 50% 0%, 50% 100%, 75% 100%, 75% 0%, 75% 0%, 75% 100%, 100% 100%, 100% 0%, 100% 0%, 100% 100%); } }
@keyframes pdo-stripes-up {
  from { clip-path: polygon(100% 0%, 0% 0%, 0% 25%, 100% 25%, 100% 25%, 0% 25%, 0% 50%, 100% 50%, 100% 50%, 0% 50%, 0% 75%, 100% 75%, 100% 75%, 0% 75%, 0% 100%, 100% 100%); }
  to { clip-path: polygon(100% 0%, 0% 0%, 0% 0%, 100% 0%, 100% 25%, 0% 25%, 0% 25%, 100% 25%, 100% 50%, 0% 50%, 0% 50%, 100% 50%, 100% 75%, 0% 75%, 0% 75%, 100% 75%); } }
@keyframes pdo-stripes-down {
  from { clip-path: polygon(100% 0%, 0% 0%, 0% 25%, 100% 25%, 100% 25%, 0% 25%, 0% 50%, 100% 50%, 100% 50%, 0% 50%, 0% 75%, 100% 75%, 100% 75%, 0% 75%, 0% 100%, 100% 100%); }
  to { clip-path: polygon(100% 25%, 0% 25%, 0% 25%, 100% 25%, 100% 50%, 0% 50%, 0% 50%, 100% 50%, 100% 75%, 0% 75%, 0% 75%, 100% 75%, 100% 100%, 0% 100%, 0% 100%, 100% 100%); } }
@keyframes pdo-swissOut {
  0% { clip-path: polygon(0% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 0%, 0% 0%); }
  50% { clip-path: polygon(40% 0%, 60% 0%, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0% 60%, 0% 40%, 40% 40%); }
  100% { clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%); } }
@keyframes pdo-corner-ne { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 0 100% 100%); } }
@keyframes pdo-corner-se { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(100% 0 0 100%); } }
@keyframes pdo-corner-sw { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(100% 100% 0 0); } }
@keyframes pdo-corner-nw { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 100% 100% 0); } }

/* ---- page (page-in only) ------------------------------------------------------------------------------------------------- */
@keyframes pdp-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pdp-cutBlack { 0% { filter: brightness(0); } 40% { filter: brightness(0); } 100% { filter: brightness(1); } }
@keyframes pdp-zoomUp { from { transform: scale(0); } to { transform: none; } }
@keyframes pdp-quadrant {
  0% { clip-path: polygon(0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%); }
  25% { clip-path: polygon(0% 0%, 50% 0%, 50% 50%, 50% 50%, 0% 50%, 0% 50%); }
  50% { clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 50% 50%, 0% 50%, 0% 50%); }
  75% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 50% 100%, 50% 50%, 0% 50%); }
  100% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%, 0% 50%); } }
@keyframes pdp-curtain-left { from { clip-path: inset(0 50% 0 50%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-curtain-right { from { clip-path: inset(0 50% 0 50%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-curtain-up { from { clip-path: inset(50% 0 50% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-curtain-down { from { clip-path: inset(50% 0 50% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-uncover { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-swiss {
  0% { clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 50% 50%); }
  50% { clip-path: polygon(40% 0%, 60% 0%, 60% 40%, 100% 40%, 100% 60%, 60% 60%, 60% 100%, 40% 100%, 40% 60%, 0% 60%, 0% 40%, 40% 40%); }
  100% { clip-path: polygon(0% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%, 0% 100%, 0% 100%, 0% 100%, 0% 0%, 0% 0%); } }
@keyframes pdp-wipe-left { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-wipe-right { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-wipe-up { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-wipe-down { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pdp-shortFade-n { from { transform: translateY(-4%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdp-shortFade-e { from { transform: translateX(4%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdp-shortFade-s { from { transform: translateY(4%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdp-shortFade-w { from { transform: translateX(-4%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pdp-blind {
  from { clip-path: polygon(100% 0%, 0% 0%, 0% 0%, 100% 0%, 100% 16.667%, 0% 16.667%, 0% 16.667%, 100% 16.667%, 100% 33.333%, 0% 33.333%, 0% 33.333%, 100% 33.333%, 100% 50%, 0% 50%, 0% 50%, 100% 50%, 100% 66.667%, 0% 66.667%, 0% 66.667%, 100% 66.667%, 100% 83.333%, 0% 83.333%, 0% 83.333%, 100% 83.333%); }
  to { clip-path: polygon(100% 0%, 0% 0%, 0% 16.667%, 100% 16.667%, 100% 16.667%, 0% 16.667%, 0% 33.333%, 100% 33.333%, 100% 33.333%, 0% 33.333%, 0% 50%, 100% 50%, 100% 50%, 0% 50%, 0% 66.667%, 100% 66.667%, 100% 66.667%, 0% 66.667%, 0% 83.333%, 100% 83.333%, 100% 83.333%, 0% 83.333%, 0% 100%, 100% 100%); } }
@keyframes pdp-turn { from { transform: perspective(2000px) rotateY(-90deg); } to { transform: perspective(2000px) rotateY(0deg); } }
@keyframes pdp-dissolve { from { opacity: 0; filter: blur(6px); } to { opacity: 1; filter: blur(0); } }

/* ---- value change (onChange, §C.4) --------------------------------------------------------------------------------------- */
@keyframes pdc-flip-out { from { transform: perspective(400px) rotateX(0deg); opacity: 1; } to { transform: perspective(400px) rotateX(90deg); opacity: 0; } }
@keyframes pdc-flip-in { from { transform: perspective(400px) rotateX(-90deg); opacity: 0; } to { transform: perspective(400px) rotateX(0deg); opacity: 1; } }
@keyframes pdc-pulse { 0%, 100% { transform: none; filter: brightness(1); } 40% { transform: scale(1.12); filter: brightness(1.35); } }
@keyframes pdc-highlight { from { background-position: -100% 0; } to { background-position: 200% 0; } }
@keyframes pdc-strike { 0% { opacity: 0; } 8% { opacity: 0.75; } 85% { opacity: 0.75; } 100% { opacity: 0; } }
@keyframes pdc-fade { from { opacity: 0; } to { opacity: 1; } }

/* The harness page around the stage: full viewport, black, stage centred. Not part of the renderer. */
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #000000; }
#stage { position: absolute; left: 0; top: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }

/* The live rig's own bits around the stage (the debug corner label, the Refresh button). Same CSS subset as the renderer: no grid, no gap. */
#asof { position: absolute; right: 8px; bottom: 6px; padding: 2px 8px; font: 14px/1.4 monospace; color: #ffffff; background: rgba(0,0,0,0.55); z-index: 10; pointer-events: none; }
#refresh { position: absolute; left: 8px; bottom: 6px; padding: 6px 14px; font: 16px/1.2 sans-serif; z-index: 10; }
#asof[hidden], #refresh[hidden] { display: none; }
