Component sandbox

Visual proofs for Phase 4 primitives. The “default” column has real interactive behavior; the other columns freeze each state via className override for visual demonstration only.

Button

Light surface

Primary
default
hover
pressed
focus
disabled
Secondary
default
hover
pressed
focus
disabled

Ghost is reserved for the green canvas — not rendered on light surfaces.

Green canvas

Primary
default
hover
pressed
focus
disabled
Secondary
default
hover
pressed
focus
disabled
Ghost
default
hover
pressed
focus
disabled

Card / glass surface

Green canvas

Single canonical recipe (2026-05-19 consolidation): gradient 0.18→0.06 white-alpha · backdrop-blur-md · 20% white border · 14px radius. Every glass surface in production flows through the <Card> primitive. The ten cells below mirror every production card 1:1 at the real phone content width (390px) so typography can be compared side-by-side. See _design-system-reference/preview/components-glass-surface.htmlfor the canonical DS doc.

Typography standard (post-2026-05-21 pass): every card header is font-display text-h4 (16px / 600 Niramit); every card sub-header / supporting line is font-body text-body (14px / 400 Source Sans 3 at white/65-70). Matches the Countdown FeaturedCountdown reference at /plans/countdown.

1. Home — Hero (level up)

app/(app)/page.tsx · header text-h3

Good job!
You reached level 5

[JungleIllustration]

2. Home — UP NEXT teaser

app/(app)/page.tsx · h4 + body
🦥
UP NEXTSloth

Check off 7 more to-dos to unlock a sloth

3. Today — Events section

app/(app)/today/page.tsx · h4 section header + h4 row title + body AM/PM + body meta + overline 'Now' pill
Events3
  • 9:30AM
    Team standupNow

    Work · 30 min

  • 2:00PM
    Coffee with Maya

    Joe's Coffee · 1 hr

4. Today — Top to-dos section

app/(app)/today/page.tsx · h4 section header + list-label items
To-dos2 left
  • Buy bread + orange juice
  • Send pictures to Mom
  • Book dentist for next month

5. Today — Coming up section

app/(app)/today/page.tsx · h4 section header + body 'days'
Coming upNext 7 days
  • 3days

    Anna's visit

    Thursday, May 21 · 9:30 AM

  • 5days

    Luca's Birthday party

    Saturday, May 23

6. Profile — Your journey (stats)

app/(app)/profile/page.tsx · h4 title + h2 numbers + body labels

Your journey

47Trees grown
12Day streak
247Tasks done

7. Profile — Settings list

app/(app)/profile/page.tsx · list-label rows, no header
Notifications
Daily forest visit9:00 AM
Privacy

8. Calendar — AgendaCard

components/calendar/agenda-card.tsx · h4 day-header + Today-style event rows (time + bar + h4 title + meta + Now)

Today

  • 9:30AM
    Team standup

    Work · 30 min

  • 2:00PM
    Coffee with Maya

    Joe's Coffee · 1 hr

  • 6:30PM
    Yoga class

    Power Yoga Studio · 1 hr

9. Countdown — FeaturedCountdown

components/countdown/featured-countdown.tsx · h4 title + body 'days' · REFERENCE
3days

Anna's visit

Thursday, May 21 · 9:30 AM

10. Countdown — CountdownItem

components/countdown/countdown-item.tsx · h4 title + body 'days'
5days

Luca's Birthday party

Saturday, May 23

Raw token reference: --surface-card-* applied via inline style (without the <Card> primitive).

This Card-equivalent is built from inline style consuming the canonical tokens directly. Visually identical to a <Card>.

Input

Green canvas

Default · empty
Default · with value
Focus (frozen via className override)
Disabled
Clearable: × appears in the right slot once the user types; click to clear.

Checkbox

Green canvas

unchecked
checked
indeterminate
disabled
focus (frozen)
With label (composition via wrapping label element)

Tabs

Green canvas

Working switcher (Calendar / To-do-list / Countdown). Click to change active tab.
To-do-list panel content.
Container is the production canvas (bg-primary). Tabs is surface-agnostic — renders against whatever canvas it's placed on.
With one disabled tab.
Active panel content.

Icons

Green canvas

Full brand icon set (13 icons, displayed uniformly at 16×16)
home
today
profile
calendar
to-do
trash
add
countdown
pencil
tree
chevron-right
Size override via Tailwind className (caller-controlled, no size prop)
size-4 (16px)
size-5 (20px)
size-6 (24px)
size-8 (32px)
Color via parent text-* class (currentColor inheritance)
text-white
text-yellow
text-moss
text-sky

BottomNav

Bottom navigation bar

Five nav items + central FAB. Active item highlighted in yellow. Sandbox sits on the production canvas (bg-primary), the same surface BottomNav renders above in the app shell.
Currently active: homeFAB clicked: 0 times

StatusBar

Green canvas

Production-scale OS chrome simulation (h-[50px], 17px time). Center band ~140px reserved for the dynamic island contract; flex justify-between keeps left/right groups out of that space. aria-hidden on root — purely decorative chrome.

AppHeader

Green canvas

Default — no context-menu dots (used on every route except To-Do).
With dots — vertical ⋮ menu glyph on the right (used on To-Do, others TBD). The layout reads pathname → PATH_TO_SHOWS_DOTS lookup → boolean prop.

iPhone Frame

Responsive behavior

The bezeled device frame (414 × 868) is previewed at 768px and above. On narrower screens the same PhoneFrame component is designed to expand and fill the whole viewport — that is how real app screens render on a phone — so it is shown here at desktop widths only.