99 lines
5.2 KiB
TypeScript
99 lines
5.2 KiB
TypeScript
|
|
import { ChatBgVariants } from './types';
|
||
|
|
import { firefliesDrift } from './animFireflies.css';
|
||
|
|
|
||
|
|
// Fireflies — a warm summer-dusk meadow. A few soft golden-green motes drift over
|
||
|
|
// a deep base, each mote a bright core melting into a warm halo. Sparse by design
|
||
|
|
// so the reading column stays clear; the motion is a slow, gentle background-
|
||
|
|
// position PAN (see animFireflies.css.ts) that reads as fireflies wandering.
|
||
|
|
//
|
||
|
|
// Layer stacking order (topmost first — CSS paints image #1 on top):
|
||
|
|
// 1. large bright motes — crisp warm core -> warm halo, sparse, largest step
|
||
|
|
// 2. medium motes — dimmer, smaller, more of them
|
||
|
|
// 3. tiny far sparks — faintest, smallest tile, calm distant layer
|
||
|
|
// 4. center vignette — keeps the reading center the calmest area
|
||
|
|
// 5. warm dusk wash A — ambient glow, upper
|
||
|
|
// 6. warm dusk wash B — ambient glow, lower
|
||
|
|
// Mote tiles use coprime-ish sizes (227/293/179) so their repeats never line up
|
||
|
|
// and the field reads as scattered, not gridded.
|
||
|
|
//
|
||
|
|
// getChatBg STRIPS the `animation` for prefers-reduced-motion / pause, so the
|
||
|
|
// authored backgroundPosition already composes a finished, gorgeous still scene
|
||
|
|
// of glowing motes on its own — the animation only sets them gently adrift.
|
||
|
|
export const animFireflies: ChatBgVariants = {
|
||
|
|
// Dark: warm gold-green glows on a deep forest-navy base with a soft vignette.
|
||
|
|
// Cores sit near oklch(0.85 0.13 110); halos fall to a warm amber-green. All
|
||
|
|
// opacities are kept low so message text stays crisp (WCAG-AA) over the field.
|
||
|
|
dark: {
|
||
|
|
backgroundColor: 'oklch(0.17 0.035 175)',
|
||
|
|
backgroundImage: [
|
||
|
|
// 1. large bright motes — golden-green core fading through a warm halo
|
||
|
|
'radial-gradient(circle at center, oklch(0.85 0.13 110 / 0.55) 1.4px, oklch(0.72 0.14 95 / 0.16) 3px, transparent 6px)',
|
||
|
|
// 2. medium motes — a touch cooler-green, dimmer, more numerous
|
||
|
|
'radial-gradient(circle at center, oklch(0.82 0.13 128 / 0.40) 1.1px, oklch(0.70 0.12 110 / 0.12) 2.4px, transparent 5px)',
|
||
|
|
// 3. tiny far sparks — faint warm pinpoints, the calm distant layer
|
||
|
|
'radial-gradient(circle at center, oklch(0.88 0.11 100 / 0.28) 0.8px, transparent 2.4px)',
|
||
|
|
// 4. center vignette — darkens the edges, keeps reading center calmest
|
||
|
|
'radial-gradient(ellipse 125% 95% at 50% 44%, transparent 40%, oklch(0.10 0.03 175 / 0.55) 100%)',
|
||
|
|
// 5. warm dusk wash A — a low amber-green glow drifting in from upper-right
|
||
|
|
'radial-gradient(ellipse 140% 120% at 80% 10%, oklch(0.30 0.07 120 / 0.45) 0%, transparent 58%)',
|
||
|
|
// 6. warm dusk wash B — deep teal-navy pooling into the lower-left
|
||
|
|
'radial-gradient(ellipse 135% 115% at 16% 94%, oklch(0.22 0.05 190 / 0.50) 0%, transparent 60%)',
|
||
|
|
].join(','),
|
||
|
|
backgroundSize: [
|
||
|
|
'227px 227px', // large motes
|
||
|
|
'293px 293px', // medium motes
|
||
|
|
'179px 179px', // far sparks
|
||
|
|
'100% 100%', // vignette
|
||
|
|
'100% 100%', // wash A
|
||
|
|
'100% 100%', // wash B
|
||
|
|
].join(','),
|
||
|
|
backgroundPosition: [
|
||
|
|
'0 0', // large (matches firefliesDrift 0%)
|
||
|
|
'83px 47px', // medium (offset breaks alignment)
|
||
|
|
'131px 101px', // far (offset again)
|
||
|
|
'0 0', // vignette (static)
|
||
|
|
'0 0', // wash A (static)
|
||
|
|
'0 0', // wash B (static)
|
||
|
|
].join(','),
|
||
|
|
animation: `${firefliesDrift} 44s linear infinite`,
|
||
|
|
},
|
||
|
|
|
||
|
|
// Light: a cozy warm dim-dusk. No harsh dots on white — soft amber motes with
|
||
|
|
// gentle halos float on a warm blush->honey gradient. Contrast stays low so the
|
||
|
|
// reading area is comfortable and text remains crisp (WCAG-AA).
|
||
|
|
light: {
|
||
|
|
backgroundColor: 'oklch(0.955 0.02 85)',
|
||
|
|
backgroundImage: [
|
||
|
|
// 1. large amber motes — warm honey core into a soft amber halo
|
||
|
|
'radial-gradient(circle at center, oklch(0.80 0.11 80 / 0.30) 1.4px, oklch(0.85 0.09 70 / 0.12) 3px, transparent 6px)',
|
||
|
|
// 2. medium motes — slightly greener-gold, softer
|
||
|
|
'radial-gradient(circle at center, oklch(0.78 0.10 95 / 0.22) 1.1px, oklch(0.86 0.08 85 / 0.10) 2.4px, transparent 5px)',
|
||
|
|
// 3. tiny far sparks — faint warm pinpoints for texture, never noise
|
||
|
|
'radial-gradient(circle at center, oklch(0.75 0.10 75 / 0.16) 0.8px, transparent 2.4px)',
|
||
|
|
// 4. center vignette — brightens the calm reading center a touch
|
||
|
|
'radial-gradient(ellipse 125% 95% at 50% 44%, oklch(1 0 0 / 0.40) 30%, transparent 100%)',
|
||
|
|
// 5. warm dusk wash A — honey glow from the upper-right
|
||
|
|
'radial-gradient(ellipse 140% 120% at 80% 8%, oklch(0.92 0.06 85 / 0.55) 0%, transparent 60%)',
|
||
|
|
// 6. warm dusk wash B — soft rose blush pooling lower-left
|
||
|
|
'radial-gradient(ellipse 135% 115% at 15% 95%, oklch(0.93 0.05 40 / 0.45) 0%, transparent 62%)',
|
||
|
|
].join(','),
|
||
|
|
backgroundSize: [
|
||
|
|
'227px 227px', // large motes
|
||
|
|
'293px 293px', // medium motes
|
||
|
|
'179px 179px', // far sparks
|
||
|
|
'100% 100%', // vignette
|
||
|
|
'100% 100%', // wash A
|
||
|
|
'100% 100%', // wash B
|
||
|
|
].join(','),
|
||
|
|
backgroundPosition: [
|
||
|
|
'0 0', // large (matches firefliesDrift 0%)
|
||
|
|
'83px 47px', // medium
|
||
|
|
'131px 101px', // far
|
||
|
|
'0 0', // vignette (static)
|
||
|
|
'0 0', // wash A (static)
|
||
|
|
'0 0', // wash B (static)
|
||
|
|
].join(','),
|
||
|
|
animation: `${firefliesDrift} 44s linear infinite`,
|
||
|
|
},
|
||
|
|
};
|