
Foundations
The tokens every screen is built from, copied from the app's source. Change a token in the code first; this page follows.
Colour Tokens
Each token is a CSS variable behind a Tailwind class (bg-background, text-subtext, border-border) and a matching value from useThemeColors(). The two files must change together.
The last five rows exist only as JS values in ThemeColors.tsx. brand in color-theme.ts holds the raw values for gradients.
Type Scale
A compact scale: every text-* class in the app is smaller than Tailwind's default, because the default reads oversized on a phone. Text with no size class is 14pt.
font-outfit-boldfont-outfitfont-bold, body, labels, numbersSpacing
Tailwind's 4pt grid, plus one named step: global, the 20pt screen gutter. It sits between Luna's 16 and the 24 of Feedy and Walley.
px-global, p-globalThemedScroller, Header and ThemedFooter. Never add it again inside them.-mx-globalCardScroller.gap-2py-3py-5ListLink) and Expandable rows.Radius
- Buttons, chips, status badges and pills are fully round.
- Inputs and code boxes use 8; tiles 12; choice rows and stat cards 16; tip cards, list groups and session panels 24.
- This site uses tighter corners for its own chrome (8 to 12, large panels 16) so the app examples read as screens.
Elevation
Four presets, from shadowPresets, spread into style. Never hand-written. In dark mode shadows barely show; surfaces separate by colour (secondary on background).
0 1 / 2.5 · 0.2
0 2 / 3.84 · 0.2
0 3 / 5 · 0.2
0 5 / 20.84 · 0.04
Offset y / blur radius · opacity. large is softer than it looks in code: it passes a translucent colour and an opacity, so the effective alpha is 0.04. Used on the record button.
Layout and Sizing
44pt controls
Buttons and the welcome pills are 44pt tall (py-3), not the templates' 52pt.
14pt body
The compact scale throughout; titles in Title Case.
20pt gutter
px-global on every screen, from the shell components.
Text-only CTAs
Full-width calls to action carry words, not icons.
One-line choices
Each choice of who can use it is one line, with a short pay tag.
One accent
One live colour leads each screen.
The Screen Pattern
Header: tabs without a back button, pushed screens with one.ThemedScrollerfor the body; it already has the gutter and a bottom spacer.ThemedFooterfor sticky actions, padded for the home indicator.Placeholderfor empty states,SkeletonLoaderorPageLoaderwhile loading.- Horizontal scrolling is always
CardScroller; bottom sheets are alwaysActionSheetThemed.