feat(chat-bg): redesign 19 chat backgrounds as modular per-pattern files
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>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { keyframes } from '@vanilla-extract/css';
|
||||
|
||||
// Star Drift — a slow, serene PAN of a deep-space starfield with real parallax.
|
||||
//
|
||||
// The starfield in animStars.ts stacks six background layers:
|
||||
// 1. near stars — tile 137x137, brighter, drifts FASTEST
|
||||
// 2. mid stars — tile 191x191, medium
|
||||
// 3. far dust — tile 233x233, dimmest, drifts SLOWEST
|
||||
// 4. center vignette (100% 100%) — STATIC
|
||||
// 5. nebula wash A (100% 100%) — STATIC
|
||||
// 6. nebula wash B (100% 100%) — STATIC
|
||||
//
|
||||
// Seamless parallax: the single `animation` shorthand shares ONE duration across
|
||||
// all layers, so speed differences are produced purely by how FAR each layer
|
||||
// travels in the keyframe. For a perfectly seamless loop each star layer must
|
||||
// translate by an EXACT integer multiple of its own tile period, so the pixel
|
||||
// re-entering at the wrap is identical to the one that left. We move:
|
||||
// near : -274px = 2 x 137 (two tiles -> fastest apparent drift)
|
||||
// mid : -191px = 1 x 191 (one tile -> medium)
|
||||
// far : -233px = 1 x 233 (one tile, but larger tile => slowest apparent)
|
||||
// so near/mid/far read as three depths sliding past each other, yet every layer
|
||||
// lands back on an identical phase at 100% for a jump-free repeat.
|
||||
//
|
||||
// A diagonal component (both x and y shift) makes the drift feel like gentle
|
||||
// motion through space rather than a flat slide. The static layers are pinned at
|
||||
// '0 0' every frame so the vignette and nebula never move under the text.
|
||||
//
|
||||
// The start frame ('0%') MUST match the static backgroundPosition authored in
|
||||
// animStars.ts, so that when getChatBg STRIPS this animation for
|
||||
// prefers-reduced-motion the finished starfield shows without a jump.
|
||||
export const starDrift = keyframes({
|
||||
'0%': {
|
||||
backgroundPosition: '0 0, 61px 43px, 113px 97px, 0 0, 0 0, 0 0',
|
||||
},
|
||||
'100%': {
|
||||
// near: -274/-274 (2 tiles), mid: 61-191/43-191, far: 113-233/97-233
|
||||
backgroundPosition: '-274px -274px, -130px -148px, -120px -136px, 0 0, 0 0, 0 0',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user