02b2ce8109
Same treatment as the seasonal themes: split the 502-line chatBackground.ts Record into one premium module per background under lotus/backgrounds/ (each exposes a tuned dark + light ChatBgVariants), one Opus agent per background against a shared brief. chatBackground.ts now assembles DARK/LIGHT from the modules; getChatBg is unchanged. Carbon + Aurora are kept inline as-is (user favorites); none stays the empty layer. Every redesign: layered oklch palettes, seamless tiling with worked-out tile math (integer-multiple periods; edge-wrapping inline-SVG data-URIs for circuit/hexgrid/waves/herringbone/chevron/tactical), independently-tuned dark+light (not a recolor), and low "felt-not-read" opacity so chat text stays WCAG-AA legible. The 5 animated backgrounds (rain, star drift, grid pulse, aurora flow, fireflies) each colocate a vanilla-extract keyframe .css.ts, animate only background-position for a jump-free loop, and — since getChatBg strips animation for reduced-motion — render a finished static frame too. Redesigned: blueprint, stars, topographic, herringbone, crosshatch, chevron, polka, triangles, plaid, tactical, circuit, hexgrid, waves, neon, anim-rain, anim-stars, anim-pulse, anim-aurora, anim-fireflies. Gates: tsc clean, ESLint clean, Prettier clean, build OK, 551 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
23 lines
1.1 KiB
TypeScript
23 lines
1.1 KiB
TypeScript
import { keyframes } from '@vanilla-extract/css';
|
|
|
|
// Digital Rain — a slow vertical PAN of the streak columns.
|
|
//
|
|
// The streak SVG tile is authored 200px tall (see animRain.ts, backgroundSize
|
|
// height = 200px). The falling illusion is a pure background-position translate
|
|
// downward by EXACTLY one tile height (200px) over the cycle, so the loop is
|
|
// perfectly seamless — the pixel at y re-enters where the pixel at y-200 was,
|
|
// which is identical because the tile repeats.
|
|
//
|
|
// Only the first background layer (the streak SVG) is panned; every subsequent
|
|
// comma-separated layer is kept at its authored position ('0 0') so the base
|
|
// gradients / vignette stay put while the rain falls over them. Listing a value
|
|
// per layer is required — a single value would pan ALL layers.
|
|
//
|
|
// getChatBg adds `willChange: 'background-position'` for the animated case, and
|
|
// STRIPS this whole `animation` for reduced-motion, at which point the static
|
|
// backgroundPosition authored in animRain.ts is what shows.
|
|
export const rainFall = keyframes({
|
|
'0%': { backgroundPosition: '0 0, 0 0, 0 0, 0 0' },
|
|
'100%': { backgroundPosition: '0 200px, 0 0, 0 0, 0 0' },
|
|
});
|