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:
2026-06-30 20:23:54 -04:00
parent 26f998d243
commit 02b2ce8109
26 changed files with 2003 additions and 409 deletions
+121
View File
@@ -0,0 +1,121 @@
import { ChatBgVariants } from './types';
// neon — a synthwave neon grid with real bloom, kept restrained for readability.
//
// Concept: a retro-futuristic magenta/cyan grid that *glows* rather than shouts.
// The glow is built the way a real neon tube reads: a crisp hairline of light
// sitting inside a much wider, softer halo of the same hue. We achieve this per
// axis by stacking TWO linear-gradient layers that share the identical tile size
// (so their lines land on exactly the same pixel column/row across every repeat):
// - a wide "bloom" line: a fat, very-low-opacity band with a soft gradient
// falloff on both sides (transparent -> colour -> transparent), reading as
// out-of-focus glow;
// - a crisp "core" line: a 1px bright hairline centred in that bloom.
// A dark radial vignette then pulls the whole grid back toward the edges and
// keeps the reading column — the calm centre — darkest and highest-contrast, so
// text stays crisp. Pure CSS: only linear + radial gradients, no assets.
//
// Seamless tiling: every grid layer uses the SAME backgroundSize per axis
// (magenta and cyan share one 88px module in dark; the fine cyan sub-grid is an
// exact 1/2 divisor at 44px so it re-registers). Because the bloom and core for
// an axis share a size and a 0/0 position, their lines are always co-registered
// and no seam is possible. Vignette/wash layers are 100% 100% and never tile.
export const neon: ChatBgVariants = {
// Dark: magenta + cyan tubes glowing over near-black, bloom kept low so the
// lines are felt, not read. Vignette darkens the centre for legibility.
dark: {
backgroundColor: 'oklch(0.135 0.02 285)',
backgroundImage: [
// 1. magenta core hairlines — crisp, bright, thin (vertical + horizontal)
'linear-gradient(90deg, oklch(0.68 0.21 350 / 0.34) 0 1px, transparent 1px)',
'linear-gradient(0deg, oklch(0.68 0.21 350 / 0.34) 0 1px, transparent 1px)',
// 2. magenta bloom — a wide soft halo hugging the same lines
'linear-gradient(90deg, transparent 0, oklch(0.66 0.2 350 / 0.11) 3px, transparent 7px)',
'linear-gradient(0deg, transparent 0, oklch(0.66 0.2 350 / 0.11) 3px, transparent 7px)',
// 3. cyan core hairlines on the offset half-grid — the cross accent
'linear-gradient(90deg, oklch(0.82 0.13 200 / 0.20) 0 1px, transparent 1px)',
'linear-gradient(0deg, oklch(0.82 0.13 200 / 0.20) 0 1px, transparent 1px)',
// 4. cyan bloom — soft cool halo on the same half-grid lines
'linear-gradient(90deg, transparent 0, oklch(0.80 0.12 200 / 0.07) 2px, transparent 5px)',
'linear-gradient(0deg, transparent 0, oklch(0.80 0.12 200 / 0.07) 2px, transparent 5px)',
// 5. vignette — recede the grid, keep the reading centre calm & dark
'radial-gradient(ellipse 125% 95% at 50% 44%, transparent 34%, oklch(0.10 0.02 285 / 0.72) 100%)',
// 6. horizon wash — a faint magenta->cyan synthwave glow low on the canvas
'radial-gradient(ellipse 150% 90% at 50% 108%, oklch(0.4 0.14 340 / 0.30) 0%, transparent 60%)',
].join(','),
backgroundSize: [
'88px 88px', // magenta core V
'88px 88px', // magenta core H
'88px 88px', // magenta bloom V
'88px 88px', // magenta bloom H
'44px 44px', // cyan core V (exact 1/2 divisor — re-registers)
'44px 44px', // cyan core H
'44px 44px', // cyan bloom V
'44px 44px', // cyan bloom H
'100% 100%', // vignette
'100% 100%', // horizon wash
].join(','),
backgroundPosition: [
'0 0', // magenta core V
'0 0', // magenta core H
'-3px 0', // magenta bloom V — centre the 7px halo on the 1px core
'0 -3px', // magenta bloom H
'22px 22px', // cyan core V — sit the fine grid between magenta lines
'22px 22px', // cyan core H
'20px 22px', // cyan bloom V — centre the 5px halo on the cyan core
'22px 20px', // cyan bloom H
'0 0', // vignette
'0 0', // horizon wash
].join(','),
},
// Light: "neon" reinterpreted as a soft luminous violet/teal grid on a pale
// cool-white base — no glow-on-black, just gentle coloured light. Bloom is even
// lighter here; a subtle centre-brightening vignette lifts the reading column.
light: {
backgroundColor: 'oklch(0.972 0.006 275)',
backgroundImage: [
// 1. violet core hairlines — soft but defined
'linear-gradient(90deg, oklch(0.55 0.17 330 / 0.16) 0 1px, transparent 1px)',
'linear-gradient(0deg, oklch(0.55 0.17 330 / 0.16) 0 1px, transparent 1px)',
// 2. violet bloom — the merest wide halo for luminosity
'linear-gradient(90deg, transparent 0, oklch(0.6 0.16 330 / 0.06) 3px, transparent 7px)',
'linear-gradient(0deg, transparent 0, oklch(0.6 0.16 330 / 0.06) 3px, transparent 7px)',
// 3. teal core hairlines on the offset half-grid — cool accent
'linear-gradient(90deg, oklch(0.58 0.11 200 / 0.11) 0 1px, transparent 1px)',
'linear-gradient(0deg, oklch(0.58 0.11 200 / 0.11) 0 1px, transparent 1px)',
// 4. teal bloom — faint cool halo on the same half-grid lines
'linear-gradient(90deg, transparent 0, oklch(0.62 0.1 200 / 0.045) 2px, transparent 5px)',
'linear-gradient(0deg, transparent 0, oklch(0.62 0.1 200 / 0.045) 2px, transparent 5px)',
// 5. vignette — brighten the calm reading centre for max legibility
'radial-gradient(ellipse 125% 95% at 50% 44%, oklch(1 0 0 / 0.50) 30%, transparent 100%)',
// 6. horizon wash — a whisper of violet->teal light low on the canvas
'radial-gradient(ellipse 150% 90% at 50% 108%, oklch(0.8 0.09 320 / 0.28) 0%, transparent 60%)',
].join(','),
backgroundSize: [
'88px 88px', // violet core V
'88px 88px', // violet core H
'88px 88px', // violet bloom V
'88px 88px', // violet bloom H
'44px 44px', // teal core V
'44px 44px', // teal core H
'44px 44px', // teal bloom V
'44px 44px', // teal bloom H
'100% 100%', // vignette
'100% 100%', // horizon wash
].join(','),
backgroundPosition: [
'0 0', // violet core V
'0 0', // violet core H
'-3px 0', // violet bloom V
'0 -3px', // violet bloom H
'22px 22px', // teal core V
'22px 22px', // teal core H
'20px 22px', // teal bloom V
'22px 20px', // teal bloom H
'0 0', // vignette
'0 0', // horizon wash
].join(','),
},
};