Skip to content

Design Tokens ​

Rungu's web UI uses a semantic token system defined in web/src/app.css. All v0.5.0 board components must consume tokens instead of one-off values.

Tiers ​

TierExampleRule
Semantic (colors)--color-primary, --color-status-planned, --color-muted-foregroundThe only colors components may reference. Defined for light and .dark.
Component (board)--vote-rail-width, --board-row-pad-y, --sort-tab-active-bgComponent-scoped values for the board surface. May alias semantic tokens.
Type roles--board-title-size, --board-meta-sizeNamed roles mapped onto the existing Tailwind text scale.

Primitives (raw OKLCH values) live only inside the token definitions in app.css — never in components.

Board component tokens (#199) ​

Card-list row (used by the post list) ​

TokenLightPurpose
--board-row-min-height7remMinimum row height (density target: ≥ 4.5 rows at 1440×900)
--board-row-pad-y0.875remRow vertical padding
--board-row-pad-x1remRow horizontal padding
--board-row-divider-colorvar(--color-border)Hairline between rows

Vote rail ​

TokenLightPurpose
--vote-rail-width3.5remRail column width (56px)
--vote-target-min2.75remMinimum tap target, 44px HIG minimum
--vote-count-size1.125remVote count font size (18px semibold)
--vote-voted-bg / --vote-voted-fg / --vote-voted-borderprimary tintsVoted state
--vote-hover-bgneutral tintHover state
--vote-rail-divider-colorvar(--color-border)Vertical divider between rail and content

Sort tabs ​

TokenLightPurpose
--sort-tab-height2.25remTab height (36px desktop; 44px on mobile hit areas)
--sort-tab-radius9999pxPill shape
--sort-tab-active-bg / --sort-tab-active-fgvar(--color-primary) / var(--color-primary-foreground)Selected state (must be obvious in both themes)
--sort-tab-inactive-fgvar(--color-muted-foreground)Unselected text
--sort-tab-inactive-hover-bgneutral tintUnselected hover

Type roles ​

TokenValueRole
--board-title-size1remPost title on cards (pair with font-semibold)
--board-body-size0.875remClamped post body
--board-meta-size0.75remAuthor/time/comment meta row
--board-section-label-size0.75remUppercase section labels

Rules for contributors ​

  1. Reference tokens via Tailwind arbitrary values, e.g. h-[var(--vote-target-min)] — or map new utilities in the @theme inline block if a value is reused across components.
  2. Never hardcode OKLCH, px, or hex values in .svelte files; add a token instead.
  3. Every new token needs a light and dark value (or must alias a token that adapts).
  4. Contrast: body text ≥ 4.5:1, large text/UI ≥ 3:1 (WCAG AA), in both themes.
  5. Interactive targets: ≥ 44×44px on touch surfaces.

Verification ​

  • grep -rnE '#[0-9a-fA-F]{3,8}|oklch\(' web/src --include='*.svelte' should return no component-level color literals.
  • Light/dark screenshot parity is checked per feature PR (playwright recipe: two contexts with color_scheme='light' / 'dark').