# Design System — @jason/ui-kit The single source of truth for how every app looks and feels. Tokens live in `src/lib/tokens.ts` and `src/styles/globals.css`; the Tailwind preset (`tailwind-preset.cjs`) exposes them as utilities. ## Color Warm-tinted neutrals (never pure black/gray) on a warm dark base, with a single gold brand accent. Semantic colors: success / warning / danger / info. | Token | Dark (default) | Use | |---|---|---| | `bg` | #232022 | Page background | | `surface` / `surface-2` | #2b282a / #333031 | Cards, raised panels | | `border` | #3a3638 | Hairlines, inputs | | `text` / `muted` | #F5F1EC / #A99F97 | Body / secondary | | `brand` / `brand-bright` | #DCBB4F / #F5CD15 | Accent, primary actions | A `.light` class on `` flips neutrals for light surfaces; brand stays constant. Rebrand any app by overriding the CSS variables in `globals.css` — no recompile. ## Type - Display / headings: **Montserrat** (600/700) - Body / UI: **Open Sans** - Code / data: **JetBrains Mono** Never Inter, Arial, or system defaults for headings (Impeccable anti-slop rule). ## Radius, elevation, motion - Radius scale: 6 / 10 / 14 / 20px. - Shadows are **layered and tinted** (`shadow-sm/md/lg/glow`) — depth, not flat. - Motion: 120/180/320ms with an ease-out curve. **No bounce/elastic easing.** - Everything honors `prefers-reduced-motion`. ## Component rules 1. Use `cn()` for all conditional classes. 2. Variants via `class-variance-authority`, not ad-hoc conditionals. 3. Interactive primitives wrap Radix (focus traps, keyboard nav, ARIA for free). 4. Focus-visible ring on every interactive element. 5. Don't nest cards inside cards. Don't put gray text on colored fills. ## Included Primitives: Button, Card, Input, Select (themed Radix popover), Textarea, Label, Badge, Dialog, DropdownMenu, Table, Toaster, Spinner, EmptyState, StatCard. Motion: FadeIn, Stagger/StaggerItem. Animated: AnimatedNumber, SpotlightCard. Blocks: AppShell, CommandPalette, Hero, FeatureGrid, Pricing.