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 Esc to 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-motion support, touch-action isolation.
  • 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.

Built With

Share this project:

Updates

Submission history