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,66 @@
|
||||
import { CSSProperties } from 'react';
|
||||
import { ChatBgVariants } from './types';
|
||||
|
||||
// hexgrid — a refined sci-fi HUD honeycomb lattice.
|
||||
//
|
||||
// The motif is a crisp pointy-top hexagon honeycomb, drawn as thin interlocking
|
||||
// outlines like the readout of a sci-fi interface. It is layered over a soft
|
||||
// depth sheen: a faint central glow lifts the middle of the field and a gentle
|
||||
// vignette settles the corners, so the lattice reads as a lit HUD surface with
|
||||
// dimension rather than a flat repeating tile. Everything is kept at low alpha
|
||||
// (hex lines ~0.14–0.16, washes well under legibility thresholds) so the motif
|
||||
// is *felt, not read* — crisp message text stays comfortably WCAG-AA in both
|
||||
// themes.
|
||||
//
|
||||
// SEAMLESS TILING
|
||||
// The hex outlines live in a single inline-SVG data-URI tile of exactly
|
||||
// √3·s × 3·s = 34.641 × 60 (side length s = 20). That is the natural repeat cell
|
||||
// of a pointy-top honeycomb: one full central hexagon plus the six neighbours
|
||||
// whose bodies straddle the tile edges. Because each straddling hexagon is drawn
|
||||
// in full, the half that spills past one edge is completed pixel-for-pixel by the
|
||||
// matching half re-entering from the opposite edge on the next repeat — the six
|
||||
// vertical side edges land exactly on x = 0 and x = 34.641, the slanted edges
|
||||
// meet across y = 0 / y = 60, so the lattice interlocks with no seam and no
|
||||
// moiré. `backgroundSize: 34.641px 60px` locks the tile to that period; the glow
|
||||
// and vignette are single non-repeating layers sized to 100%.
|
||||
//
|
||||
// DARK vs LIGHT
|
||||
// Dark: cool cyan hex lines (oklch 0.72 0.1 200) on a deep blue-black base, with
|
||||
// a soft cyan-tinted central glow — the classic "cold HUD" look.
|
||||
// Light: soft slate-blue hexes (oklch 0.55 0.07 250) on a pale cool-white sheet,
|
||||
// with a bright paper highlight at centre. Each alpha/lightness is tuned
|
||||
// independently so both feel equally quiet against their own base.
|
||||
|
||||
// One seamless honeycomb tile (√3·20 × 3·20). Colour is injected per-theme.
|
||||
const hexTile = (stroke: string): string =>
|
||||
`url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2234.641%22%20height%3D%2260%22%3E%3Cpath%20d%3D%22M17.32%2010L0%2020L0%2040L17.32%2050L34.64%2040L34.64%2020Z%20M0%20-20L-17.32%20-10L-17.32%2010L0%2020L17.32%2010L17.32%20-10Z%20M34.64%20-20L17.32%20-10L17.32%2010L34.64%2020L51.96%2010L51.96%20-10Z%20M0%2040L-17.32%2050L-17.32%2070L0%2080L17.32%2070L17.32%2050Z%20M34.64%2040L17.32%2050L17.32%2070L34.64%2080L51.96%2070L51.96%2050Z%20M17.32%20-50L0%20-40L0%20-20L17.32%20-10L34.64%20-20L34.64%20-40Z%20M17.32%2070L0%2080L0%20100L17.32%20110L34.64%20100L34.64%2080Z%22%20fill%3D%22none%22%20stroke%3D%22${encodeURIComponent(
|
||||
stroke,
|
||||
)}%22%20stroke-width%3D%220.9%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E")`;
|
||||
|
||||
const dark: CSSProperties = {
|
||||
backgroundColor: 'oklch(0.19 0.03 245)',
|
||||
backgroundImage: [
|
||||
// 1. the honeycomb lattice — cool cyan hex outlines.
|
||||
hexTile('oklch(0.72 0.1 200 / 0.14)'),
|
||||
// 2. central glow — a soft cyan lift so the field looks lit from within.
|
||||
'radial-gradient(120% 90% at 50% 42%, oklch(0.30 0.05 210 / 0.55) 0%, transparent 60%)',
|
||||
// 3. vignette — settles the corners into the deep base for depth.
|
||||
'radial-gradient(130% 130% at 50% 45%, transparent 55%, oklch(0.13 0.02 240 / 0.55) 100%)',
|
||||
].join(','),
|
||||
backgroundSize: '34.641px 60px, 100% 100%, 100% 100%',
|
||||
};
|
||||
|
||||
const light: CSSProperties = {
|
||||
backgroundColor: 'oklch(0.965 0.008 240)',
|
||||
backgroundImage: [
|
||||
// 1. the honeycomb lattice — soft slate-blue hex outlines.
|
||||
hexTile('oklch(0.55 0.07 250 / 0.16)'),
|
||||
// 2. central highlight — a hint of brighter paper toward the middle.
|
||||
'radial-gradient(120% 90% at 50% 40%, oklch(0.99 0.005 240 / 0.7) 0%, transparent 60%)',
|
||||
// 3. vignette — feather the edges into a slightly cooler paper.
|
||||
'radial-gradient(130% 130% at 50% 45%, transparent 58%, oklch(0.90 0.015 245 / 0.5) 100%)',
|
||||
].join(','),
|
||||
backgroundSize: '34.641px 60px, 100% 100%, 100% 100%',
|
||||
};
|
||||
|
||||
export const hexgrid: ChatBgVariants = { dark, light };
|
||||
Reference in New Issue
Block a user