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>
57 lines
3.6 KiB
TypeScript
57 lines
3.6 KiB
TypeScript
import { CSSProperties } from 'react';
|
||
import { ChatBgVariants } from './types';
|
||
|
||
// crosshatch — fine pen-and-ink engraving, like a banknote guilloché.
|
||
// Three hatch directions (right-leaning, left-leaning, near-horizontal cross)
|
||
// are layered at low opacity so the eye reads a woven ink texture rather than
|
||
// discrete stripes. Each direction uses a slightly different pitch so the
|
||
// combined pattern never lines up into a coarse moire, and a barely-there
|
||
// diagonal tonal gradient lends etched depth.
|
||
//
|
||
// Seamless tiling: each hatch is a `repeating-linear-gradient`, which repeats
|
||
// infinitely by definition, so the layers are left at `backgroundSize: auto`
|
||
// and tile with no visible seam at any element size (constraining a diagonal
|
||
// repeat to a small square would clip it mid-period and create a seam). The
|
||
// tonal wash is a single non-repeating gradient stretched to `cover`.
|
||
//
|
||
// Opacities are kept in the 0.02–0.05 range so the texture is felt, not read —
|
||
// crisp message text sits comfortably above it in both themes (WCAG-AA safe).
|
||
|
||
const dark: CSSProperties = {
|
||
// near-black base with a whisper of cool blue so silver ink reads as engraving
|
||
backgroundColor: 'oklch(0.16 0.01 255)',
|
||
backgroundImage: [
|
||
// faint tonal gradient — top-left slightly lifted for etched depth
|
||
'linear-gradient(135deg, oklch(0.20 0.012 255 / 0.5) 0%, oklch(0.15 0.01 255 / 0) 55%, oklch(0.14 0.008 260 / 0.45) 100%)',
|
||
// primary hatch, right-leaning fine lines (cool silver ink), ~9px pitch
|
||
'repeating-linear-gradient(45deg, oklch(0.75 0.02 250 / 0.05) 0, oklch(0.75 0.02 250 / 0.05) 0.75px, transparent 0.75px, transparent 9px)',
|
||
// secondary hatch, left-leaning — the cross of the crosshatch
|
||
'repeating-linear-gradient(135deg, oklch(0.75 0.02 250 / 0.045) 0, oklch(0.75 0.02 250 / 0.045) 0.75px, transparent 0.75px, transparent 9px)',
|
||
// tertiary hatch, right-leaning at a denser pitch for engraved richness
|
||
'repeating-linear-gradient(45deg, oklch(0.78 0.018 250 / 0.02) 0, oklch(0.78 0.018 250 / 0.02) 0.5px, transparent 0.5px, transparent 4.5px)',
|
||
// quaternary near-horizontal fill line, very faint, weaves the mesh together
|
||
'repeating-linear-gradient(20deg, oklch(0.72 0.015 255 / 0.018) 0, oklch(0.72 0.015 255 / 0.018) 0.5px, transparent 0.5px, transparent 13px)',
|
||
].join(','),
|
||
backgroundSize: 'cover, auto, auto, auto, auto',
|
||
};
|
||
|
||
const light: CSSProperties = {
|
||
// warm paper base — graphite ink on cream stock
|
||
backgroundColor: 'oklch(0.975 0.006 85)',
|
||
backgroundImage: [
|
||
// faint tonal wash — soft warm depth for aged-paper feel
|
||
'linear-gradient(135deg, oklch(0.94 0.008 85 / 0.55) 0%, oklch(0.98 0.005 85 / 0) 55%, oklch(0.93 0.01 80 / 0.5) 100%)',
|
||
// primary hatch, right-leaning graphite lines, ~9px pitch
|
||
'repeating-linear-gradient(45deg, oklch(0.42 0.01 265 / 0.055) 0, oklch(0.42 0.01 265 / 0.055) 0.75px, transparent 0.75px, transparent 9px)',
|
||
// secondary hatch, left-leaning — the cross
|
||
'repeating-linear-gradient(135deg, oklch(0.42 0.01 265 / 0.05) 0, oklch(0.42 0.01 265 / 0.05) 0.75px, transparent 0.75px, transparent 9px)',
|
||
// tertiary denser right-leaning hatch for engraved fineness
|
||
'repeating-linear-gradient(45deg, oklch(0.40 0.012 265 / 0.025) 0, oklch(0.40 0.012 265 / 0.025) 0.5px, transparent 0.5px, transparent 4.5px)',
|
||
// quaternary near-horizontal weave line, barely-there
|
||
'repeating-linear-gradient(20deg, oklch(0.45 0.01 260 / 0.022) 0, oklch(0.45 0.01 260 / 0.022) 0.5px, transparent 0.5px, transparent 13px)',
|
||
].join(','),
|
||
backgroundSize: 'cover, auto, auto, auto, auto',
|
||
};
|
||
|
||
export const crosshatch: ChatBgVariants = { dark, light };
|