Foundations

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

apps/mobile/utils/color-theme.ts (Tailwind classes) app/contexts/ThemeColors.tsx (JS values) tailwind.config.js

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.

TokenDark (default)LightUse

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

apps/mobile/tailwind.config.js fontSize

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.

FamilyClassUsed for
Outfit Boldfont-outfit-boldDisplay titles: greetings, setup titles, session titles
Outfit Regularfont-outfitDefined, not used by any screen today
Platform font(default)Everything else: titles in font-bold, body, labels, numbers

Spacing

tailwind.config.js spacing.global apps/mobile/CLAUDE.md §3b

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.

TokenPointsWhere
px-global, p-global20Screen gutter; built into ThemedScroller, Header and ThemedFooter. Never add it again inside them.
-mx-global−20Full-bleed content inside a scroller, such as CardScroller.
gap-28Between stat cards, chips and actions.
py-312Buttons: 12 above and below a 20pt line gives 44pt.
py-520Settings rows (ListLink) and Expandable rows.

Radius

Tailwind defaults as used across apps/mobile/components

  • 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

apps/mobile/utils/useShadow.ts shadowPresets

Four presets, from shadowPresets, spread into style. Never hand-written. In dark mode shadows barely show; surfaces separate by colour (secondary on background).

small
0 1 / 2.5 · 0.2
card
0 2 / 3.84 · 0.2
medium
0 3 / 5 · 0.2
large
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

apps/mobile/CLAUDE.md §3b and §4

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

  1. Header: tabs without a back button, pushed screens with one.
  2. ThemedScroller for the body; it already has the gutter and a bottom spacer.
  3. ThemedFooter for sticky actions, padded for the home indicator.
  4. Placeholder for empty states, SkeletonLoader or PageLoader while loading.
  5. Horizontal scrolling is always CardScroller; bottom sheets are always ActionSheetThemed.
Payout Method
Add a Payout Method
Where Nzinga sends your money. Kept on this phone only.
Mobile moneyBank account