Files
cinny/src/app/components/seasonal/themes/EarthDay.css.ts
T
jaredandClaude Opus 4.8 26f998d243
CI / Build & Quality Checks (push) Successful in 11m7s
CI / Trigger Desktop Build (push) Successful in 12s
feat(seasonal): redesign all 11 seasonal themes as modular per-theme overlays
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>
2026-06-30 19:41:58 -04:00

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' },
});