Split the 808-line SeasonalEffect monolith into one self-contained module per theme under seasonal/themes/ (<Theme>.tsx + <Theme>.css.ts), and gave every theme a premium, research-backed redesign (one Opus agent per theme against a shared brief). SeasonalEffect now just imports the 11 overlays and dispatches; the orphaned shared Seasonal.css.ts is removed (each theme owns its keyframes). Each overlay: layered oklch palettes, GPU-only animation (transform/opacity), `contain: layout paint style` to kill repaint flicker, ≤~40-element perf budget, particles seeded once via useMemo (no per-frame state), a gorgeous STATIC prefers-reduced-motion form (the settings preview thumbnail), WCAG-AA-preserving low opacities, and no new deps / no external assets (inline SVG data-URIs, Tauri/CSP-safe). Themes: Halloween, Christmas, New Year, Autumn, April Fools, Lunar New Year, Valentines, St. Patrick's, Earth Day, Deep Space, Arcade. Gates: tsc clean, ESLint clean, Prettier clean, build OK, 551 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71 lines
3.0 KiB
TypeScript
71 lines
3.0 KiB
TypeScript
import { keyframes } from '@vanilla-extract/css';
|
|
|
|
/**
|
|
* Earth Day overlay keyframes. Every animation touches ONLY `transform` and
|
|
* `opacity` so the compositor can run them on the GPU — no layout/paint thrash.
|
|
* keyframes() returns the generated animation-name string, applied inline.
|
|
*
|
|
* Motif: verdant, hopeful nature. Leaves tumble, seeds/spores drift, pollen
|
|
* motes glow and pulse, soft sun rays breathe from above, the blue-marble
|
|
* Earth gently respires in a corner.
|
|
*/
|
|
|
|
/** Falling leaf: tumbles down with a wide pendular sway and slow spin. */
|
|
export const animLeafTumble = keyframes({
|
|
'0%': { transform: 'translate3d(0, -10vh, 0) rotate(-18deg)', opacity: '0' },
|
|
'8%': { opacity: '0.7' },
|
|
'28%': { transform: 'translate3d(4vw, 22vh, 0) rotate(60deg)' },
|
|
'52%': { transform: 'translate3d(-3vw, 48vh, 0) rotate(165deg)' },
|
|
'76%': { transform: 'translate3d(5vw, 74vh, 0) rotate(280deg)' },
|
|
'90%': { opacity: '0.5' },
|
|
'100%': { transform: 'translate3d(1vw, 112vh, 0) rotate(360deg)', opacity: '0' },
|
|
});
|
|
|
|
/** Tiny seed / spore: drifts slowly downward, swaying like dandelion fluff. */
|
|
export const animSeedDrift = keyframes({
|
|
'0%': { transform: 'translate3d(0, -6vh, 0) rotate(0deg)', opacity: '0' },
|
|
'12%': { opacity: '0.55' },
|
|
'40%': { transform: 'translate3d(3vw, 34vh, 0) rotate(140deg)' },
|
|
'70%': { transform: 'translate3d(-2.5vw, 64vh, 0) rotate(250deg)' },
|
|
'88%': { opacity: '0.4' },
|
|
'100%': { transform: 'translate3d(2vw, 110vh, 0) rotate(360deg)', opacity: '0' },
|
|
});
|
|
|
|
/** Pollen mote: floats gently upward in a soft serpentine path. */
|
|
export const animPollenFloat = keyframes({
|
|
'0%': { transform: 'translate3d(0, 0, 0) scale(0.75)', opacity: '0' },
|
|
'14%': { opacity: '0.9' },
|
|
'38%': { transform: 'translate3d(10px, -22vh, 0) scale(1)' },
|
|
'64%': { transform: 'translate3d(-10px, -46vh, 0) scale(0.92)', opacity: '0.7' },
|
|
'90%': { opacity: '0.2' },
|
|
'100%': { transform: 'translate3d(6px, -72vh, 0) scale(0.7)', opacity: '0' },
|
|
});
|
|
|
|
/** Soft brightness twinkle layered on each pollen mote's glow. */
|
|
export const animPollenGlow = keyframes({
|
|
'0%': { opacity: '0.55' },
|
|
'50%': { opacity: '1' },
|
|
'100%': { opacity: '0.55' },
|
|
});
|
|
|
|
/** Sun rays from above: slow breathing of opacity + a faint scale shimmer. */
|
|
export const animRayBreathe = keyframes({
|
|
'0%': { transform: 'scaleY(1)', opacity: '0.4' },
|
|
'50%': { transform: 'scaleY(1.05)', opacity: '0.7' },
|
|
'100%': { transform: 'scaleY(1)', opacity: '0.4' },
|
|
});
|
|
|
|
/** Green aurora veil: a wide, slow horizontal sway with a gentle swell. */
|
|
export const animAuroraSway = keyframes({
|
|
'0%': { transform: 'translate3d(-6%, 0, 0) scale(1.1)', opacity: '0.45' },
|
|
'50%': { transform: 'translate3d(6%, -2%, 0) scale(1.2)', opacity: '0.7' },
|
|
'100%': { transform: 'translate3d(-6%, 0, 0) scale(1.1)', opacity: '0.45' },
|
|
});
|
|
|
|
/** Blue-marble Earth: a barely-perceptible respiration of its halo. */
|
|
export const animEarthRespire = keyframes({
|
|
'0%': { transform: 'scale(1)', opacity: '0.85' },
|
|
'50%': { transform: 'scale(1.04)', opacity: '1' },
|
|
'100%': { transform: 'scale(1)', opacity: '0.85' },
|
|
});
|