Genesis give-away template · every UI primitive, live
This page is the canonical reference for the Genesis template UI kit. Every primitive exported from @/components/ui is shown here with real, interactive examples. Partner AIs should read this page to understand available components, their props, and the semantic-token skinning model before building any feature screen.
All components use semantic tokens only (e.g. bg-action-primary, text-content-secondary). Never use raw palette classes like gray-500 or blue-600 — and never use dark: variants.
variant × size matrix, loading state, disabled, fullWidth.
Variants (size md)
Sizes (variant primary)
Loading state
Disabled
fullWidth
Input (all types + invalid + disabled), Textarea, Select, Label (required), Field + FormError, Switch.
Label
Input — types
Input — states
This field has an error.
Textarea
Up to 500 characters.
Notes are required.
Select
Please select a plan.
FormError (submit-level)
Something went wrong. Please try again.
Switch (live toggle)
Spinner, Loading, Skeleton, EmptyState, ErrorState, Alert (4 tones), Badge (5 tones), StatusBadge (tone-derived), useToast.
Spinner
Loading
Skeleton (compose to mimic loaded layout)
EmptyState
No records yet
Create your first record to get started. It only takes a minute.
ErrorState
Failed to load records. Please try again.
Alert — 4 tones
Info
Saved
Warning
Error
Badge — 5 tones
StatusBadge — tone auto-derived from status string
active/paid/completed → success · pending/in_progress → info · overdue → warning · cancelled/failed → danger · unknown → neutral
useToast — fire a toast
Toasts auto-dismiss after 4 s. Click to dismiss immediately. Mount <ToastProvider> once in the provider stack (already done in app/providers.tsx).
Modal (controlled, Esc + backdrop close, bottom-sheet on mobile) and ConfirmDialog (destructive-action gate).
Modal — pass open, onClose, title, footer. Esc key and backdrop click both call onClose.
ConfirmDialog — adds onConfirm, danger, loading props. Use for all destructive actions (delete, archive, revoke).
TableScroll > Table > TableHeader / TableBody / TableRow / TableHead / TableCell; MoneyDisplay (amount is always a STRING); PageHeader.
PageHeader
Manage customer accounts and subscriptions.
MoneyDisplay (amount is a string — L-MONEY)
Money is stored as NUMERIC(18,6) in the DB and as a string on the wire (L-MONEY). Pass the raw string directly — never parse to float. Use formatMoney() for non-JSX contexts. Add maskUnless="permission.key" to cosmetically hide sensitive amounts from unpermissioned users.
Table
| Customer | Plan | MRR | Status |
|---|---|---|---|
| Acme Corp | Pro | $2,499.00 | Active |
| Globex LLC | Starter | $99.00 | Pending |
| Initech Inc | Pro | $2,499.00 | Overdue |
| Umbrella Co | Free | $0.00 | Cancelled |
Wrap in <TableScroll> to keep wide tables scrollable on mobile. On small screens prefer a Card-list layout over a table.
How the token model works and how to re-skin the template for a new tenant.
Surface tokens
Content tokens (text / icon)
Action tokens (backgrounds)
How skinning works
Re-skin a tenant by changing only the four brand tokens in --brand-primary, --brand-surface-card, --brand-radius-md, and --brand-font-family. These are the only tenant-overridable tokens (applied at runtime by lib/theme.tsx via applyBrandTokens()).
Semantic tokens (action-primary, surface-card, etc.) derive from brand tokens via CSS custom properties in app/globals.css. Every component references only semantic tokens — so a single brand-primary change recolors every CTA, focus ring, and link in the app automatically.
Dark, high-contrast, and outdoor color schemes are handled by CSS variable overrides on the .dark, .high-contrast, and .outdoor selectors in globals.css — never by adding dark: Tailwind variants to component markup. The active class is set by the FOUC inline script reading the genesis-theme cookie before React hydrates, so there is no flash of unstyled content.
surface-*, content-*, and action-* token classes listed in tailwind.config.ts. Never hardcode palette values (gray-500, blue-600, etc.) and never use dark: variants.Genesis design-system showcase · public route · no auth required