| name | grove-ui-design |
| description | Create warm, nature-themed UI for Grove with glassmorphism, seasonal decorations, randomized forests, and accessible design patterns. Use when building pages, enhancing UI, or adding decorative elements. |
Grove UI Design Skill
When to Activate
Activate this skill when:
- Creating or enhancing pages for Grove sites
- Adding decorative nature elements (trees, clouds, weather effects)
- Implementing glassmorphism effects for readability
- Working with the seasonal theme system
- Building navigation patterns (navbar, mobile overflow menus)
- Creating "story" pages that guide users through content
- Ensuring mobile-friendly, accessible UI
- Choosing icons or visual elements
The Grove Aesthetic
Grove is a place. It's nature-themed, warm, and inviting—like a midnight tea shop with good documentation.
Core Principles
Warm, introspective, queer, unapologetically building something meaningful.
Write with the warmth of a midnight tea shop and the clarity of good documentation.
Every design choice should feel:
- Welcoming — like entering a cozy space
- Organic — natural, not rigid or corporate
- Readable — content-first, decorations enhance, never obstruct
- Alive — subtle animations, seasonal changes, randomization
User Identity Language
Grove uses specific terms for community members in all UI:
| Term | Who | Use For |
|---|
| Wanderer | Everyone | Greetings, welcome messages, all users |
| Rooted | Subscribers | Subscription confirmations, thank-yous |
| Pathfinder | Trusted guides | Community leaders (appointed) |
| Wayfinder | Autumn | The grove keeper (singular) |
In UI text:
- "Welcome, Wanderer." (not "Welcome, user")
- "Welcome back, Wanderer." (dashboard greeting)
- "You've taken root." (subscription confirmation)
- "Thanks for staying rooted." (payment received)
See docs/grove-user-identity.md for full documentation.
Glassmorphism Pattern
Glass effects create readability while revealing hints of background decoration.
The Layering Formula
Background (gradients, vines, nature)
↓
Decorative Elements (trees, clouds, particles)
↓
Glass Surface (translucent + blur)
↓
Content (text, cards, UI)
Glass Components
import { Glass, GlassCard, GlassButton, GlassOverlay } from '@groveengine/ui/ui';
<!-- Container with glass effect -->
<Glass variant="tint" class="p-6 rounded-xl">
<p>Readable text over busy backgrounds</p>
</Glass>
<!-- Card with glass styling -->
<GlassCard title="Settings" variant="default" hoverable>
Content here
</GlassCard>
<!-- Glass button -->
<GlassButton variant="accent">Subscribe</GlassButton>
Glass Variants
| Variant | Use Case | Light Mode | Dark Mode |
|---|
surface | Headers, navbars | 95% white | 95% slate |
tint | Text over backgrounds | 60% white | 50% slate |
card | Content cards | 80% white | 70% slate |
accent | Callouts, highlights | 30% accent | 20% accent |
overlay | Modal backdrops | 50% black | 60% black |
muted | Subtle backgrounds | 40% white | 30% slate |
CSS Utility Classes
<div class="glass rounded-xl p-4">Basic glass</div>
<div class="glass-tint p-6">Text container</div>
<div class="glass-accent p-4">Highlighted section</div>
<nav class="glass-surface sticky top-0">Navbar</nav>
Key Pattern: Sticky Navigation
<nav class="sticky top-[73px] z-30 bg-white/80 dark:bg-slate-900/80 backdrop-blur-sm border-b border-divider">
<!-- Navigation content -->
</nav>
Seasonal Theme System
Grove uses four seasons, each with distinct colors, weather effects, and moods.
Season Detection
import { season } from '$lib/stores/season';
const isSpring = $derived($season === 'spring');
const isAutumn = $derived($season === 'autumn');
const isWinter = $derived($season === 'winter');
// Summer is the default (no flag needed)
Color Palette System
Import from: @autumnsgrove/groveengine/ui/nature or $lib/components/nature/palette
Core Palettes (Year-Round)
import { greens, bark, earth, natural } from '@autumnsgrove/groveengine/ui/nature';
greens.darkForest
greens.deepGreen
greens.grove
greens.meadow
greens.spring
greens.mint
greens.pale
bark.darkBark
bark.bark
bark.warmBark
bark.lightBark
earth.soil, earth.mud, earth.clay, earth.sand, earth.stone, earth.pebble, earth.slate
natural.cream, natural.aspenBark, natural.bone, natural.mushroom, natural.birchWhite
Spring Palettes
import { springFoliage, springSky, wildflowers, cherryBlossoms, cherryBlossomsPeak } from '@autumnsgrove/groveengine/ui/nature';
springFoliage.sprout
springFoliage.newLeaf
springFoliage.freshGreen
springFoliage.budding
springFoliage.tender
springSky.clear
springSky.soft
wildflowers.buttercup
wildflowers.daffodil
wildflowers.crocus
wildflowers.violet
wildflowers.purple
wildflowers.lavender
wildflowers.tulipPink
wildflowers.tulipRed
wildflowers.white
cherryBlossoms.deep
cherryBlossoms.standard
cherryBlossoms.light
cherryBlossoms.pale
cherryBlossoms.falling
cherryBlossomsPeak.deep
cherryBlossomsPeak.standard
cherryBlossomsPeak.light
cherryBlossomsPeak.pale
cherryBlossomsPeak.falling
Unified Flowers Palette (NEW!)
The flowers namespace consolidates all flower colors into one organized structure:
import { flowers } from '@autumnsgrove/groveengine/ui/nature';
flowers.wildflower.buttercup
flowers.wildflower.daffodil
flowers.wildflower.crocus
flowers.wildflower.violet
flowers.wildflower.purple
flowers.wildflower.lavender
flowers.wildflower.tulipPink
flowers.wildflower.tulipRed
flowers.wildflower.white
flowers.cherry.deep
flowers.cherry.standard
flowers.cherry.light
flowers.cherry.pale
flowers.cherry.falling
flowers.cherryPeak.deep
flowers.cherryPeak.standard
flowers.cherryPeak.light
flowers.cherryPeak.pale
flowers.cherryPeak.falling
Use flowers.wildflower instead of accents.flower — the accents version is deprecated.
Autumn & Winter Palettes
import { autumn, autumnReds, winter } from '@autumnsgrove/groveengine/ui/nature';
autumn.rust
autumn.ember
autumn.pumpkin
autumn.amber
autumn.gold
autumn.honey
autumn.straw
autumnReds.crimson
autumnReds.scarlet
autumnReds.rose
autumnReds.coral
winter.snow, winter.frost, winter.ice, winter.glacier
winter.frostedPine, winter.winterGreen, winter.coldSpruce
winter.winterSky, winter.twilight, winter.overcast
winter.bareBranch, winter.frostedBark, winter.coldWood
winter.hillDeep, winter.hillMid, winter.hillNear, winter.hillFront
Accent Palettes
import { accents, wildflowers } from '@autumnsgrove/groveengine/ui/nature';
accents.mushroom.redCap, accents.mushroom.orangeCap, accents.mushroom.brownCap
accents.mushroom.spots, accents.mushroom.gill
accents.firefly.glow, accents.firefly.warmGlow, accents.firefly.body
accents.berry.ripe, accents.berry.elderberry, accents.berry.red
accents.water.surface, accents.water.deep, accents.water.shallow, accents.water.lily
accents.sky.dayLight, accents.sky.dayMid, accents.sky.sunset, accents.sky.night, accents.sky.star
accents.bird.cardinalRed, accents.bird.cardinalMask, accents.bird.cardinalBeak
accents.bird.chickadeeCap, accents.bird.chickadeeBody, accents.bird.chickadeeBelly
accents.bird.robinBody, accents.bird.robinBreast, accents.bird.robinBeak
accents.bird.bluebirdBody, accents.bird.bluebirdWing, accents.bird.bluebirdBreast
Seasonal Helper Functions
import { getSeasonalGreens, getCherryColors, isTreeBare, pickRandom, pickFrom } from '@autumnsgrove/groveengine/ui/nature';
const foliage = getSeasonalGreens(season);
const cherryColors = getCherryColors(season);
if (isTreeBare('cherry', 'winter')) { }
const randomGreen = pickRandom(greens);
const specificGreen = pickFrom(greens, ['grove', 'meadow']);
Deprecated Aliases (Still Work)
import { spring, pinks, springBlossoms } from '@autumnsgrove/groveengine/ui/nature';
Season Mood Summary
| Season | Primary Colors | Mood |
|---|
| Spring | springFoliage, cherryBlossomsPeak, wildflowers | Renewal, hope |
| Summer | greens, cherryBlossoms | Growth, warmth |
| Autumn | autumn, autumnReds | Harvest, reflection |
| Winter | winter (frost, snow, frosted pines) | Rest, stillness |
Seasonal Weather Effects
<!-- Winter: Snowfall -->
{#if isWinter}
<SnowfallLayer count={40} zIndex={5} opacity={{ min: 0.4, max: 0.8 }} spawnDelay={8} />
{/if}
<!-- Spring: Cherry blossom petals -->
{#if isSpring}
<FallingPetalsLayer count={80} zIndex={100} opacity={{ min: 0.5, max: 0.9 }} />
{/if}
<!-- Autumn: Falling leaves (tied to trees) -->
{#if isAutumn}
<FallingLeavesLayer trees={forestTrees} season={$season} minLeavesPerTree={2} maxLeavesPerTree={4} />
{/if}
Seasonal Background Gradients