Inspiration
The 24 solar terms (二十四节气) have guided Chinese agriculture and daily life for over two millennia. They're not just a calendar — they're a poetic rhythm of nature, each term carrying its own mood: the awakening thunder of Jingzhe (惊蛰), the gentle rain of Yushui (雨水), the frosty stillness of Shuangjiang (霜降).
We wanted to bring this rhythm to life as a digital experience — a place where users could feel each solar term through visual atmosphere, not just read about it. Traditional Chinese ink-wash painting (水墨画), with its misty mountains, sparse ink dots, and flowing emptiness, felt like the perfect visual language: understated, evocative, and deeply Chinese.
The project became a hackathon experiment: Can we capture the mood of 24 solar terms using nothing but CSS, SVG, and JavaScript — zero external images?
What It Does
Mood Weather is a dynamic wallpaper that takes you on a journey through all 24 solar terms. Each term you visit presents:
- A unique SVG mountain landscape — hand-crafted bezier paths that shift from spring's gentle peaks to winter's jagged ridges
- Ink-wash themed colors — paper tones, ink darkness, and mountain hues that evolve across seasons
- Atmospheric particle effects — rain drizzles for Rain Water, snow flurries for Minor Snow, drifting mist for White Dew, frost crystals for Frost Descent, dew drops for Cold Dew, swaying wheat for Grain Buds
- Poem + description — each term has a classical Chinese poem and a cultural explanation
- Fluid navigation — swipe on touch devices, arrow keys on desktop, click the dots, or press
Escto return to the beginning
The result is a meditative, scrolling experience that feels less like a website and more like a breathing ink painting.
How We Built It
Zero frameworks. Zero images. Maximum craft.
The entire visual is built on a single SVG that renders differently for each term. Mountain silhouettes are defined as d-path strings in visuals.js — we tuned each curve so that from spring to winter, the landscape subtly ages and sharpens.
The ink-wash aesthetic comes from layered SVG elements:
| Layer | Effect |
|---|---|
| Far mountain | Pale, blurred (<feGaussianBlur>) |
| Front mountain | Sharper, darker ink |
| Ink blobs | Flowing elliptical stains that drift with CSS keyframes |
| Mist | Opacity-pulsing <ellipse> elements |
Six particle effect modules sit in src/effects/, each a self-contained vanilla JS class that spawns and animates DOM/SVG elements. They're lazy — effects stop when you leave a term — and maintain 60fps even on mobile by using CSS transform and opacity compositing.
The carousel engine (carousel.js) manages state, rendering, transitions, and an easter egg: rapidly switching terms triggers a hidden solar eclipse animation for Summer Solstice (夏至).
We used Tailwind CSS v4 for utility-first responsive design and Playwright for automated E2E testing across viewports (375×812 mobile, 768×1024 tablet, 1920×1080 desktop).
Challenges We Ran Into
SVG Responsiveness
Ink-wash paintings have natural composition — they don't stretch or crop well. The background needed to fill any viewport without distorting mountain proportions or clipping ink elements. We solved it with preserveAspectRatio="xMidYMid slice" and carefully tested at three breakpoints.
Touch Swipe + Visual Drag
Implementing touch feedback on mobile was delicate: the slide needs to literally follow the user's finger (translateX), then either snap to the next term or bounce back. We had to direction-gate (horizontal vs vertical swipe) so users could still scroll vertically on the page. The solution uses real-time touchmove transforms with a 250ms CSS bounce-back, plus a quick-flick fallback for users who swipe without dragging.
Cross-Platform Chinese Fonts
macOS has beautiful system Song/Kai fonts (华文宋体, 楷体), but Linux and Windows render differently. We subsetted Google Fonts to only the 27 Chinese characters actually used in the project — Noto Serif SC at ~50KB instead of 5MB — and added font-display: swap to eliminate FOIT.
Particle Effect Performance on Mobile
Fog and rain effects need many elements. We had to use will-change: transform sparingly, throttle particle counts on small viewports, and leverage CSS animations instead of JS requestAnimationFrame loops where possible.
Accomplishments That We're Proud Of
- Zero external images — The entire visual — mountains, ink blots, mist, decorations, particle effects — is pure code. Every "brush stroke" is a mathematical curve.
- 29 hand-crafted SVG decorations — Flowers, willow branches, bamboo, autumn leaves, frost patterns, snow-covered reeds — each placed per-term with specific position and scale.
- 6 distinct particle systems (rain, snow, mist, dew, frost, swaying grass) that feel genuinely atmospheric, not like generic screen-savers.
- Full accessibility — ARIA labels, keyboard navigation, focus management,
prefers-reduced-motionsupport,touch-actionisolation. - Robust testing — Playwright suite with touch simulation, console error monitoring, and viewport-specific assertions.
- The Summer Solstice easter egg — Rapid-switch 5+ times and the sun darkens into a partial eclipse — a nod to the historical solar eclipse recorded during 夏至.
What We Learned
- SVG is shockingly expressive. With careful path design and a few filters, you can create rich, atmospheric landscapes that feel hand-painted.
- Touch gesture handling requires real architecture. Direction-gating, threshold detection, velocity calculation, and visual feedback each need their own concern — you can't just
addEventListener('touchmove')and hope. - Subsetting Chinese fonts changes the game. Full CJK fonts are massive; the text parameter trick on Google Fonts made this project feasible for a zero-lag experience.
- CSS
clamp()is a superpower. All typography uses fluid sizing —font-size: clamp(28px, 2vw + 20px, 48px)— which eliminated the need for most media query overrides. - Hackathon constraints breed creativity. The "no images" rule forced us to think in primitives — paths, gradients, transforms — and the result is more cohesive than if we had reached for stock assets.
What's Next
- Mood logging — Let users record their mood for each solar term and see a year-long emotional landscape.
- Dynamic weather integration — Pull real-time weather data and subtly tint the ink-wash scene to match the day's conditions.
- Animated transitions — Smoother crossfades between terms with SVG morphing (mountain paths that interpolate).
- Printable art mode — Export the current term's scene as a high-res wallpaper or print.
- More easter eggs — The solar eclipse was fun — we'd love to hide more seasonal surprises.
- i18n — Full Japanese and Korean translations, since the 24 solar terms were historically shared across East Asia.
Log in or sign up for Devpost to join the conversation.