Skip to content
Hooney
한국어
Products

Modules

Design system

A design system shared across Firstage apps, bringing colors, spacing, components, and accessibility standards into one place.

189Component stories, consumed by every app in the monorepo

Period
2024.12 ~ Present
Organization
Firstage
Role
Design and implementation (solo)
Runs on
Frontend
Key features
Apps can choose their own color themes while sharing components and accessibility standards.
Work and results
  • Used by every app, from Journey to ROUND
  • 189 component examples (Storybook stories)
  • Automated checks keep component rules and documentation in line
  • Automated accessibility checks (axe) on the component examples
Tech stack
  • React
  • Tailwind CSS
  • Radix UI
  • tailwind-variants
  • Storybook

Context

The monorepo holds several apps, including Firstage’s Journey app and homepage, the internal Dashboard, the blog, and ROUND, a sports event service. Korean, English, and Japanese copy has to fit a 390px screen without clipping, and accessibility standards cannot vary from app to app. If each app made its own styles, those standards would scatter quickly, so I gathered them into one package that every app consumes.

Decisions and implementation

  • Tokens come in three tiers, primitive, semantic, and component, with colors defined in OKLCH. Interactive elements read only semantic tokens, so an app sets its theme by changing the semantic roles for light and dark modes.
  • Variants are expressed only through three axes: intent, size, and variant. A new case is solved inside those axes instead of with ad hoc styles, and className is reserved for layout so it cannot paint over color, height, or padding. Lint rules check the variant rules and the JSDoc on every public prop.
  • Components style Radix primitives with tailwind-variants, and compound components export separate Root and Part pieces to compose.
  • Apps pass in translated copy, locale, time zone, writing direction, and font. Components never guess language or time zone from the browser, so the same component can follow each app’s own policy.
  • Screens start at 390px and widen from there. Visible focus, meaningful labels, and touch targets of at least 44px on touch devices are the floor, and Storybook runs axe accessibility checks.

Current state

Every app in the monorepo uses this package, and it has 189 Storybook stories. It is still a pre-1.0 beta, and widening the axe checks and adding visual regression tests for Journey screens remain.

Screen gallery

The photo selection showcase: four cherry blossom photos selected, with a resolution note and a button to preview the selection.
The journal composer showcase: a note for September 8 at Seoul Forest beside its context of when, where, and with whom.
The settings showcase: a weekly recap toggle, the default audience for new memories, and the summary language on one screen.