e9a970a75b
Settings dropdowns (Bug #3): - Add reusable SettingsSelect component using Menu+PopOut+FocusTrap — exact same pattern as Message Layout, so all dropdowns look consistent - Replace raw <select> for Seasonal Theme, UI Font, AFK Timeout, and Join & Leave Sounds with SettingsSelect Animated chat backgrounds bleeding onto content (Bug #6 / #7): - Remove filter:brightness() and opacity animations from chatBackground.ts (animRainGlowKeyframe, animGridBrightnessKeyframe, animFirefliesGlowKeyframe, animFirefliesBlinkKeyframe). These were applied to the Page element which caused ALL descendants (messages, composer) to flash in sync. Also created a CSS stacking context on Page that pushed SeasonalEffect (position:fixed; z-index:9997) behind the animated background layer. - Only backgroundPosition / backgroundSize animations remain — safe, do not affect descendants, and do not create stacking contexts. - Remove now-unused animation keyframe imports from chatBackground.ts. Voice ringing in persistent rooms (Bug #5): - Narrow the ringing condition from (Invite|Knock|Restricted) to only Invite, matching exactly the rooms where the call button is visible. - Add room.isCallRoom() early-exit so m.join_rule:call rooms never ring. Avatar decoration images not loading (Bug #8): - Change loading="lazy" → loading="eager" in DecorationPreviewCell. Lazy loading does not reliably trigger for images inside nested overflow scroll containers (the settings panel scroll area), so images never loaded. Docs: LOTUS_BUGS.md updated with root cause and resolution for all 5 new bugs. Docs: LOTUS_TODO.md adds P5-35/P5-36 (deferred desktop notification/jump list). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
498 lines
21 KiB
TypeScript
498 lines
21 KiB
TypeScript
import { CSSProperties } from 'react';
|
|
import { ChatBackground } from '../../state/settings';
|
|
import {
|
|
animRainKeyframe,
|
|
animStarsDriftKeyframe,
|
|
animGridPulseKeyframe,
|
|
animAuroraKeyframe,
|
|
animFirefliesKeyframe,
|
|
} from '../../styles/Animations.css';
|
|
|
|
export const BG_OPTIONS: { value: ChatBackground; label: string }[] = [
|
|
{ value: 'none', label: 'None' },
|
|
{ value: 'blueprint', label: 'Blueprint' },
|
|
{ value: 'carbon', label: 'Carbon' },
|
|
{ value: 'stars', label: 'Stars' },
|
|
{ value: 'topographic', label: 'Topographic' },
|
|
{ value: 'herringbone', label: 'Herringbone' },
|
|
{ value: 'crosshatch', label: 'Crosshatch' },
|
|
{ value: 'chevron', label: 'Chevron' },
|
|
{ value: 'polka', label: 'Polka' },
|
|
{ value: 'triangles', label: 'Triangles' },
|
|
{ value: 'plaid', label: 'Plaid' },
|
|
{ value: 'tactical', label: 'Tactical' },
|
|
{ value: 'circuit', label: 'Circuit' },
|
|
{ value: 'hexgrid', label: 'Hex Grid' },
|
|
{ value: 'waves', label: 'Waves' },
|
|
{ value: 'neon', label: 'Neon Grid' },
|
|
{ value: 'aurora', label: 'Aurora' },
|
|
{ value: 'anim-rain', label: 'Digital Rain' },
|
|
{ value: 'anim-stars', label: 'Star Drift' },
|
|
{ value: 'anim-pulse', label: 'Grid Pulse' },
|
|
{ value: 'anim-aurora', label: 'Aurora Flow' },
|
|
{ value: 'anim-fireflies', label: 'Fireflies' },
|
|
];
|
|
|
|
const DARK: Record<ChatBackground, CSSProperties> = {
|
|
none: {},
|
|
|
|
blueprint: {
|
|
backgroundColor: '#0a1628',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(100,149,237,0.14) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(100,149,237,0.14) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(100,149,237,0.05) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(100,149,237,0.05) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '80px 80px, 80px 80px, 16px 16px, 16px 16px',
|
|
},
|
|
|
|
carbon: {
|
|
backgroundColor: '#0e0e0e',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(45deg, rgba(255,255,255,0.035) 0, rgba(255,255,255,0.035) 2px, transparent 0, transparent 50%)',
|
|
'repeating-linear-gradient(135deg, rgba(255,255,255,0.035) 0, rgba(255,255,255,0.035) 2px, transparent 0, transparent 50%)',
|
|
].join(','),
|
|
backgroundSize: '8px 8px',
|
|
},
|
|
|
|
stars: {
|
|
backgroundColor: '#050510',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(255,255,255,0.85) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(255,255,255,0.55) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(200,200,255,0.3) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '130px 130px, 190px 190px, 260px 260px',
|
|
backgroundPosition: '0 0, 65px 32px, 32px 97px',
|
|
},
|
|
|
|
topographic: {
|
|
backgroundColor: '#0f0f17',
|
|
backgroundImage: [
|
|
'repeating-radial-gradient(circle at 20% 20%, transparent 0, transparent 30px, rgba(152,0,0,0.07) 31px, transparent 32px)',
|
|
'repeating-radial-gradient(circle at 80% 80%, transparent 0, transparent 25px, rgba(100,100,200,0.06) 26px, transparent 27px)',
|
|
'repeating-radial-gradient(circle at 50% 10%, transparent 0, transparent 45px, rgba(152,0,0,0.04) 46px, transparent 47px)',
|
|
].join(','),
|
|
},
|
|
|
|
herringbone: {
|
|
backgroundColor: '#111118',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(60deg, rgba(180,160,210,0.08) 0, rgba(180,160,210,0.08) 1px, transparent 0, transparent 50%)',
|
|
'repeating-linear-gradient(120deg, rgba(180,160,210,0.08) 0, rgba(180,160,210,0.08) 1px, transparent 0, transparent 50%)',
|
|
].join(','),
|
|
backgroundSize: '20px 36px',
|
|
},
|
|
|
|
crosshatch: {
|
|
backgroundColor: '#0f0f0f',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(255,255,255,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(255,255,255,0.022) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(255,255,255,0.022) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
},
|
|
|
|
// Interlocking zigzag stripes
|
|
chevron: {
|
|
backgroundColor: '#0f0f17',
|
|
backgroundImage: [
|
|
'linear-gradient(135deg, rgba(180,160,210,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(225deg, rgba(180,160,210,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(315deg, rgba(180,160,210,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(45deg, rgba(180,160,210,0.1) 25%, transparent 25%)',
|
|
].join(','),
|
|
backgroundSize: '20px 20px',
|
|
},
|
|
|
|
// Even dot grid
|
|
polka: {
|
|
backgroundColor: '#0e0e14',
|
|
backgroundImage: 'radial-gradient(circle, rgba(255,255,255,0.2) 2px, transparent 2px)',
|
|
backgroundSize: '28px 28px',
|
|
},
|
|
|
|
// Isometric triangle grid
|
|
triangles: {
|
|
backgroundColor: '#111118',
|
|
backgroundImage: [
|
|
'linear-gradient(60deg, rgba(100,149,237,0.09) 25%, transparent 25%, transparent 75%, rgba(100,149,237,0.09) 75%)',
|
|
'linear-gradient(120deg, rgba(100,149,237,0.09) 25%, transparent 25%, transparent 75%, rgba(100,149,237,0.09) 75%)',
|
|
].join(','),
|
|
backgroundSize: '40px 70px',
|
|
backgroundPosition: '0 0, 20px 35px',
|
|
},
|
|
|
|
// Tartan-inspired crossing lines with accent colour
|
|
plaid: {
|
|
backgroundColor: '#0a1020',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(100,149,237,0.13) 39px, rgba(100,149,237,0.13) 40px)',
|
|
'repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(100,149,237,0.13) 39px, rgba(100,149,237,0.13) 40px)',
|
|
'repeating-linear-gradient(0deg, transparent, transparent 7px, rgba(152,0,0,0.08) 7px, rgba(152,0,0,0.08) 8px)',
|
|
'repeating-linear-gradient(90deg, transparent, transparent 7px, rgba(152,0,0,0.08) 7px, rgba(152,0,0,0.08) 8px)',
|
|
].join(','),
|
|
},
|
|
|
|
// LotusGuild TDS exact dot-grid
|
|
tactical: {
|
|
backgroundColor: '#030508',
|
|
backgroundImage: 'radial-gradient(circle, rgba(0,212,255,0.055) 1px, transparent 1px)',
|
|
backgroundSize: '28px 28px',
|
|
},
|
|
|
|
// Circuit board — green grid with node dots
|
|
circuit: {
|
|
backgroundColor: '#040a04',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(0,255,136,0.045) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,255,136,0.045) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(0,255,136,0.20) 1.5px, transparent 1.5px)',
|
|
].join(','),
|
|
backgroundSize: '40px 40px, 40px 40px, 40px 40px',
|
|
backgroundPosition: '0 0, 0 0, 20px 20px',
|
|
},
|
|
|
|
// True pointy-top hexagonal grid via SVG data URI
|
|
hexgrid: {
|
|
backgroundColor: '#060c14',
|
|
backgroundImage:
|
|
'url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2229%22%20height%3D%2250%22%3E%3Cpath%20d%3D%22M14.5%200L29%208L29%2025L14.5%2033L0%2025L0%208Z%20M14.5%2033L29%2041V50%20M14.5%2033L0%2041V50%22%20fill%3D%22none%22%20stroke%3D%22rgba%280%2C212%2C255%2C0.13%29%22%20stroke-width%3D%220.8%22/%3E%3C/svg%3E")',
|
|
backgroundSize: '29px 50px',
|
|
},
|
|
|
|
// Flowing sine-wave lines
|
|
waves: {
|
|
backgroundColor: '#080c18',
|
|
backgroundImage: [
|
|
'repeating-radial-gradient(ellipse at 0% 50%, transparent 0, transparent 18px, rgba(80,130,255,0.07) 19px, transparent 20px)',
|
|
'repeating-radial-gradient(ellipse at 100% 50%, transparent 0, transparent 28px, rgba(80,130,255,0.05) 29px, transparent 30px)',
|
|
'repeating-radial-gradient(ellipse at 50% 0%, transparent 0, transparent 22px, rgba(100,60,200,0.06) 23px, transparent 24px)',
|
|
].join(','),
|
|
},
|
|
|
|
// Neon cyberpunk grid — orange/cyan TDS colors
|
|
neon: {
|
|
backgroundColor: '#020408',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(255,107,0,0.10) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(255,107,0,0.10) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(0,212,255,0.05) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,212,255,0.05) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
},
|
|
|
|
// Aurora borealis — flowing gradient bands
|
|
aurora: {
|
|
backgroundColor: '#030810',
|
|
backgroundImage: [
|
|
'radial-gradient(ellipse at 20% 30%, rgba(0,255,136,0.08) 0%, transparent 55%)',
|
|
'radial-gradient(ellipse at 80% 70%, rgba(0,100,255,0.08) 0%, transparent 55%)',
|
|
'radial-gradient(ellipse at 50% 10%, rgba(120,0,255,0.06) 0%, transparent 50%)',
|
|
'radial-gradient(ellipse at 60% 90%, rgba(0,212,255,0.06) 0%, transparent 50%)',
|
|
].join(','),
|
|
},
|
|
|
|
// Animated: Matrix digital rain — scrolling stripe columns + phosphor glow flicker
|
|
'anim-rain': {
|
|
backgroundColor: '#010804',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(180deg, rgba(0,255,136,0.16) 0px, rgba(0,255,136,0.16) 1px, transparent 1px, transparent 20px)',
|
|
'repeating-linear-gradient(180deg, rgba(0,255,136,0.07) 0px, rgba(0,255,136,0.07) 1px, transparent 1px, transparent 8px)',
|
|
].join(','),
|
|
backgroundSize: '40px 200px, 12px 200px',
|
|
backgroundPosition: '0 0, 0 0',
|
|
animation: `${animRainKeyframe} 8s linear infinite`,
|
|
},
|
|
|
|
// Animated: drifting star field — three seamlessly-tiling layers at different speeds
|
|
'anim-stars': {
|
|
backgroundColor: '#050510',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(255,255,255,0.85) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(200,220,255,0.55) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(180,200,255,0.3) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '130px 130px, 190px 190px, 260px 260px',
|
|
backgroundPosition: '0 0, 65px 32px, 32px 97px',
|
|
animation: `${animStarsDriftKeyframe} 30s linear infinite`,
|
|
},
|
|
|
|
// Animated: neon grid pulse — size breathe + independent brightness oscillation
|
|
'anim-pulse': {
|
|
backgroundColor: '#030508',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(255,107,0,0.12) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(255,107,0,0.12) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(0,212,255,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,212,255,0.06) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
animation: `${animGridPulseKeyframe} 4s ease-in-out infinite`,
|
|
},
|
|
|
|
// Animated: aurora borealis — four bands each travel an independent path
|
|
'anim-aurora': {
|
|
backgroundColor: '#020a10',
|
|
backgroundImage: [
|
|
'radial-gradient(ellipse 80% 60% at 20% 30%, rgba(0,255,136,0.12) 0%, transparent 70%)',
|
|
'radial-gradient(ellipse 70% 50% at 80% 70%, rgba(0,100,255,0.12) 0%, transparent 70%)',
|
|
'radial-gradient(ellipse 90% 70% at 50% 10%, rgba(191,95,255,0.09) 0%, transparent 65%)',
|
|
'radial-gradient(ellipse 75% 55% at 60% 90%, rgba(0,212,255,0.09) 0%, transparent 65%)',
|
|
].join(','),
|
|
backgroundSize: '200% 200%, 250% 250%, 300% 300%, 220% 220%',
|
|
backgroundPosition: '0% 0%, 100% 0%, 50% 100%, 0% 50%',
|
|
animation: `${animAuroraKeyframe} 28s ease-in-out infinite`,
|
|
},
|
|
|
|
// Animated: fireflies — drift + brightness glow + opacity blink at prime periods
|
|
'anim-fireflies': {
|
|
backgroundColor: '#030508',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(255,220,50,0.7) 1.5px, rgba(255,160,0,0.18) 3px, transparent 4px)',
|
|
'radial-gradient(circle, rgba(255,200,30,0.55) 1px, rgba(255,140,0,0.14) 2.5px, transparent 3.5px)',
|
|
'radial-gradient(circle, rgba(255,240,100,0.4) 1px, transparent 2px)',
|
|
].join(','),
|
|
backgroundSize: '200px 200px, 280px 280px, 160px 160px',
|
|
backgroundPosition: '0 0, 120px 80px, 60px 140px',
|
|
animation: `${animFirefliesKeyframe} 30s linear infinite`,
|
|
},
|
|
};
|
|
|
|
const LIGHT: Record<ChatBackground, CSSProperties> = {
|
|
none: {},
|
|
|
|
blueprint: {
|
|
backgroundColor: '#eef3ff',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(50,100,220,0.16) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(50,100,220,0.16) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(50,100,220,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(50,100,220,0.06) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '80px 80px, 80px 80px, 16px 16px, 16px 16px',
|
|
},
|
|
|
|
carbon: {
|
|
backgroundColor: '#efefef',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(45deg, rgba(0,0,0,0.04) 0, rgba(0,0,0,0.04) 2px, transparent 0, transparent 50%)',
|
|
'repeating-linear-gradient(135deg, rgba(0,0,0,0.04) 0, rgba(0,0,0,0.04) 2px, transparent 0, transparent 50%)',
|
|
].join(','),
|
|
backgroundSize: '8px 8px',
|
|
},
|
|
|
|
// Stars is intentionally always dark — it's a night-sky theme
|
|
stars: {
|
|
backgroundColor: '#050510',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(255,255,255,0.85) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(255,255,255,0.55) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(200,200,255,0.3) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '130px 130px, 190px 190px, 260px 260px',
|
|
backgroundPosition: '0 0, 65px 32px, 32px 97px',
|
|
},
|
|
|
|
topographic: {
|
|
backgroundColor: '#faf8f5',
|
|
backgroundImage: [
|
|
'repeating-radial-gradient(circle at 20% 20%, transparent 0, transparent 30px, rgba(100,60,60,0.09) 31px, transparent 32px)',
|
|
'repeating-radial-gradient(circle at 80% 80%, transparent 0, transparent 25px, rgba(60,60,130,0.07) 26px, transparent 27px)',
|
|
'repeating-radial-gradient(circle at 50% 10%, transparent 0, transparent 45px, rgba(100,60,60,0.05) 46px, transparent 47px)',
|
|
].join(','),
|
|
},
|
|
|
|
herringbone: {
|
|
backgroundColor: '#f9f9f9',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(60deg, rgba(80,70,110,0.09) 0, rgba(80,70,110,0.09) 1px, transparent 0, transparent 50%)',
|
|
'repeating-linear-gradient(120deg, rgba(80,70,110,0.09) 0, rgba(80,70,110,0.09) 1px, transparent 0, transparent 50%)',
|
|
].join(','),
|
|
backgroundSize: '20px 36px',
|
|
},
|
|
|
|
crosshatch: {
|
|
backgroundColor: '#ffffff',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(0,0,0,0.07) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,0,0,0.07) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(0,0,0,0.025) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,0,0,0.025) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
},
|
|
|
|
chevron: {
|
|
backgroundColor: '#f9f8ff',
|
|
backgroundImage: [
|
|
'linear-gradient(135deg, rgba(80,60,130,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(225deg, rgba(80,60,130,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(315deg, rgba(80,60,130,0.1) 25%, transparent 25%)',
|
|
'linear-gradient(45deg, rgba(80,60,130,0.1) 25%, transparent 25%)',
|
|
].join(','),
|
|
backgroundSize: '20px 20px',
|
|
},
|
|
|
|
polka: {
|
|
backgroundColor: '#fafafa',
|
|
backgroundImage: 'radial-gradient(circle, rgba(0,0,0,0.18) 2px, transparent 2px)',
|
|
backgroundSize: '28px 28px',
|
|
},
|
|
|
|
triangles: {
|
|
backgroundColor: '#f4f7ff',
|
|
backgroundImage: [
|
|
'linear-gradient(60deg, rgba(50,100,220,0.1) 25%, transparent 25%, transparent 75%, rgba(50,100,220,0.1) 75%)',
|
|
'linear-gradient(120deg, rgba(50,100,220,0.1) 25%, transparent 25%, transparent 75%, rgba(50,100,220,0.1) 75%)',
|
|
].join(','),
|
|
backgroundSize: '40px 70px',
|
|
backgroundPosition: '0 0, 20px 35px',
|
|
},
|
|
|
|
plaid: {
|
|
backgroundColor: '#f5f0ff',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(100,50,180,0.15) 39px, rgba(100,50,180,0.15) 40px)',
|
|
'repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(100,50,180,0.15) 39px, rgba(100,50,180,0.15) 40px)',
|
|
'repeating-linear-gradient(0deg, transparent, transparent 7px, rgba(200,0,0,0.09) 7px, rgba(200,0,0,0.09) 8px)',
|
|
'repeating-linear-gradient(90deg, transparent, transparent 7px, rgba(200,0,0,0.09) 7px, rgba(200,0,0,0.09) 8px)',
|
|
].join(','),
|
|
},
|
|
|
|
tactical: {
|
|
backgroundColor: '#f0f4fa',
|
|
backgroundImage: 'radial-gradient(circle, rgba(0,100,200,0.08) 1px, transparent 1px)',
|
|
backgroundSize: '28px 28px',
|
|
},
|
|
|
|
circuit: {
|
|
backgroundColor: '#f0f8f0',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(0,160,80,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,160,80,0.06) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(0,160,80,0.22) 1.5px, transparent 1.5px)',
|
|
].join(','),
|
|
backgroundSize: '40px 40px, 40px 40px, 40px 40px',
|
|
backgroundPosition: '0 0, 0 0, 20px 20px',
|
|
},
|
|
|
|
hexgrid: {
|
|
backgroundColor: '#f4f8ff',
|
|
backgroundImage:
|
|
'url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2229%22%20height%3D%2250%22%3E%3Cpath%20d%3D%22M14.5%200L29%208L29%2025L14.5%2033L0%2025L0%208Z%20M14.5%2033L29%2041V50%20M14.5%2033L0%2041V50%22%20fill%3D%22none%22%20stroke%3D%22rgba%2850%2C100%2C220%2C0.11%29%22%20stroke-width%3D%220.8%22/%3E%3C/svg%3E")',
|
|
backgroundSize: '29px 50px',
|
|
},
|
|
|
|
waves: {
|
|
backgroundColor: '#eef3ff',
|
|
backgroundImage: [
|
|
'repeating-radial-gradient(ellipse at 0% 50%, transparent 0, transparent 18px, rgba(50,100,220,0.09) 19px, transparent 20px)',
|
|
'repeating-radial-gradient(ellipse at 100% 50%, transparent 0, transparent 28px, rgba(50,100,220,0.07) 29px, transparent 30px)',
|
|
'repeating-radial-gradient(ellipse at 50% 0%, transparent 0, transparent 22px, rgba(80,40,180,0.07) 23px, transparent 24px)',
|
|
].join(','),
|
|
},
|
|
|
|
neon: {
|
|
backgroundColor: '#fafafa',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(196,78,0,0.12) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(196,78,0,0.12) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(0,98,184,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,98,184,0.06) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
},
|
|
|
|
aurora: {
|
|
backgroundColor: '#f4faf8',
|
|
backgroundImage: [
|
|
'radial-gradient(ellipse at 20% 30%, rgba(0,160,80,0.09) 0%, transparent 55%)',
|
|
'radial-gradient(ellipse at 80% 70%, rgba(0,80,200,0.09) 0%, transparent 55%)',
|
|
'radial-gradient(ellipse at 50% 10%, rgba(100,0,200,0.07) 0%, transparent 50%)',
|
|
'radial-gradient(ellipse at 60% 90%, rgba(0,160,200,0.07) 0%, transparent 50%)',
|
|
].join(','),
|
|
},
|
|
|
|
// Animated light variants
|
|
|
|
'anim-rain': {
|
|
backgroundColor: '#f0fff4',
|
|
backgroundImage: [
|
|
'repeating-linear-gradient(180deg, rgba(0,160,80,0.16) 0px, rgba(0,160,80,0.16) 1px, transparent 1px, transparent 20px)',
|
|
'repeating-linear-gradient(180deg, rgba(0,160,80,0.07) 0px, rgba(0,160,80,0.07) 1px, transparent 1px, transparent 8px)',
|
|
].join(','),
|
|
backgroundSize: '40px 200px, 12px 200px',
|
|
backgroundPosition: '0 0, 0 0',
|
|
animation: `${animRainKeyframe} 8s linear infinite, ${animRainGlowKeyframe} 2.1s ease-in-out infinite`,
|
|
},
|
|
|
|
'anim-stars': {
|
|
backgroundColor: '#f5f5ff',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(60,60,160,0.50) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(80,80,180,0.35) 1px, transparent 1px)',
|
|
'radial-gradient(circle, rgba(100,100,200,0.20) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '130px 130px, 190px 190px, 260px 260px',
|
|
backgroundPosition: '0 0, 65px 32px, 32px 97px',
|
|
animation: `${animStarsDriftKeyframe} 30s linear infinite`,
|
|
},
|
|
|
|
'anim-pulse': {
|
|
backgroundColor: '#ffffff',
|
|
backgroundImage: [
|
|
'linear-gradient(rgba(0,98,184,0.14) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,98,184,0.14) 1px, transparent 1px)',
|
|
'linear-gradient(rgba(0,98,184,0.06) 1px, transparent 1px)',
|
|
'linear-gradient(90deg, rgba(0,98,184,0.06) 1px, transparent 1px)',
|
|
].join(','),
|
|
backgroundSize: '60px 60px, 60px 60px, 12px 12px, 12px 12px',
|
|
animation: `${animGridPulseKeyframe} 4s ease-in-out infinite, ${animGridBrightnessKeyframe} 3.3s ease-in-out infinite`,
|
|
},
|
|
|
|
'anim-aurora': {
|
|
backgroundColor: '#f0f8f4',
|
|
backgroundImage: [
|
|
'radial-gradient(ellipse 80% 60% at 20% 30%, rgba(0,160,80,0.13) 0%, transparent 70%)',
|
|
'radial-gradient(ellipse 70% 50% at 80% 70%, rgba(0,80,200,0.13) 0%, transparent 70%)',
|
|
'radial-gradient(ellipse 90% 70% at 50% 10%, rgba(140,60,220,0.10) 0%, transparent 65%)',
|
|
'radial-gradient(ellipse 75% 55% at 60% 90%, rgba(0,160,200,0.10) 0%, transparent 65%)',
|
|
].join(','),
|
|
backgroundSize: '200% 200%, 250% 250%, 300% 300%, 220% 220%',
|
|
backgroundPosition: '0% 0%, 100% 0%, 50% 100%, 0% 50%',
|
|
animation: `${animAuroraKeyframe} 28s ease-in-out infinite`,
|
|
},
|
|
|
|
'anim-fireflies': {
|
|
backgroundColor: '#fffdf0',
|
|
backgroundImage: [
|
|
'radial-gradient(circle, rgba(180,120,0,0.70) 1.5px, rgba(160,90,0,0.18) 3px, transparent 4px)',
|
|
'radial-gradient(circle, rgba(160,100,0,0.55) 1px, rgba(140,80,0,0.14) 2.5px, transparent 3.5px)',
|
|
'radial-gradient(circle, rgba(200,140,0,0.40) 1px, transparent 2px)',
|
|
].join(','),
|
|
backgroundSize: '200px 200px, 280px 280px, 160px 160px',
|
|
backgroundPosition: '0 0, 120px 80px, 60px 140px',
|
|
animation: `${animFirefliesKeyframe} 30s linear infinite`,
|
|
},
|
|
};
|
|
|
|
export const getChatBg = (
|
|
bg: ChatBackground,
|
|
isDark: boolean,
|
|
pauseAnimations?: boolean,
|
|
): CSSProperties => {
|
|
const style = isDark ? DARK[bg] : LIGHT[bg];
|
|
const reducedMotion =
|
|
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
if ((pauseAnimations || reducedMotion) && style.animation) {
|
|
const { animation: _anim, ...rest } = style;
|
|
return rest;
|
|
}
|
|
return style;
|
|
};
|