From 430792ecddb734bf2aec1dcf5d0922519f135f83 Mon Sep 17 00:00:00 2001 From: timevans666 Date: Thu, 21 May 2026 23:14:32 +0000 Subject: [PATCH] =?UTF-8?q?Directive=2019:=20CRT=20distortion=20=E2=80=94?= =?UTF-8?q?=20scanline=20drift,=20occasional=20tear,=20refresh=20sweep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three layered CRT motion effects, all subtle, all GPU-cheap: 1. SCANLINE DRIFT — the scanlines slowly migrate downward by 4px over 9 seconds, looping. Imperceptible at first glance, builds the 'this screen is alive' sense over a session. 2. CRT TEAR — every 13s the scanline layer briefly shifts horizontally by 1-2px at four irregular moments (18.5%, 47.5%, 72.6-73%, 91.5% of cycle). The 72.6% tear also dims opacity slightly — a stronger 'glitch' beat among smaller ones. Cadence designed to feel random, not metronomic. 3. REFRESH SWEEP — a 180px-tall faint amber band rolls from top to bottom of the viewport every 17 seconds. Mimics the CRT refresh pass. Opacity capped at 0.045 — present, not distracting. All three use prime-ish durations (9, 13, 17) so the layered effects never sync back into the same pattern within a session. --- .../apps/directive-19/index.html | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/scenario-library/blade-runner-rpg/apps/directive-19/index.html b/scenario-library/blade-runner-rpg/apps/directive-19/index.html index 95d9cee..ab22143 100644 --- a/scenario-library/blade-runner-rpg/apps/directive-19/index.html +++ b/scenario-library/blade-runner-rpg/apps/directive-19/index.html @@ -82,7 +82,7 @@ body::before { linear-gradient(180deg, rgba(255,152,24,0.015), transparent 30%, rgba(0,0,0,0.25)); } -/* CRT scanlines — overlaid on everything, very subtle */ +/* CRT scanlines — overlaid on everything, slow drift + occasional horizontal tear */ body::after { content:""; position:fixed; inset:0; pointer-events:none; z-index:1000; @@ -95,6 +95,55 @@ body::after { ); mix-blend-mode: multiply; opacity: 0.7; + animation: scanline-drift 9s linear infinite, crt-tear 13s infinite; + will-change: transform, background-position; +} + +/* Scanlines drift slowly downward — barely perceptible, just enough to feel alive */ +@keyframes scanline-drift { + from { background-position: 0 0; } + to { background-position: 0 -4px; } +} + +/* Occasional one-pixel horizontal tear at irregular intervals — CRT signal drift */ +@keyframes crt-tear { + 0%, 18%, 19%, 47%, 48%, 72.4%, 73.2%, 91%, 92%, 100% { + transform: translateX(0); + opacity: 0.7; + } + 18.5% { transform: translateX(1px); } + 47.5% { transform: translateX(-1px); } + 72.6%, 73% { + transform: translateX(2px); + opacity: 0.55; /* this tear also dims slightly — stronger glitch moment */ + } + 91.5% { transform: translateX(-1px); } +} + +/* Slow rolling refresh sweep — a faint amber band passes top to bottom every 17s */ +html::before { + content: ""; + position: fixed; + left: 0; right: 0; + top: 0; + height: 180px; + pointer-events: none; + z-index: 999; + background: linear-gradient( + 180deg, + transparent 0%, + rgba(255, 180, 80, 0.02) 30%, + rgba(255, 200, 120, 0.045) 50%, + rgba(255, 180, 80, 0.02) 70%, + transparent 100% + ); + animation: crt-refresh-sweep 17s linear infinite; + will-change: transform; +} + +@keyframes crt-refresh-sweep { + 0% { transform: translateY(-180px); } + 100% { transform: translateY(100vh); } } /* ============================================================