evOo-local/DESIGN.md
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

106 lines
4.4 KiB
Markdown

# EvOo UI Scale
Central design tokens live in `@rakazo/ui-tokens` and surface through Tailwind utilities in `@rakazo/ui-web`. Use these instead of pixel literals (`text-[11px]`, `size={14}`, `h-8`) on primary shell surfaces.
## Typography
| Token utility | CSS var | Size | Use |
|---------------|---------|------|-----|
| `text-ui-caption` | `--font-size-caption` | 12px | Dense tables, keyboard hints only |
| `text-ui-label` | `--font-size-label` | 13.5px | Section headers, badges, timestamps, metadata |
| `text-ui-body-sm` | `--font-size-body-sm` | 14px | Secondary copy, picker subtitles |
| `text-ui-body` | `--font-size-body` | 15.5px | Default UI chrome — sidebar rows, headers, buttons |
| `text-ui-reading` | `--font-size-reading` | 17px | Chat message body (`.rk-chat-markdown`) |
| `text-ui-title-sm` | `--font-size-title-sm` | 18px | Panel titles |
| `text-ui-title` | `--font-size-title` | 20px | Page headings |
**Rule:** No `text-[10px]` / `text-[11px]` on primary UI. If it must be smaller than body, use `text-ui-label` (13.5px minimum for labels).
React typography helpers: `Caption`, `LabelText`, `Muted`, `Small` in `@rakazo/ui-web`.
## Icons
| Utility | Size | Use |
|---------|------|-----|
| `size-icon-sm` | 16px | Inline badges, compact chips |
| `size-icon-md` | 18px | Default — matches control height |
| `size-icon-lg` | 20px | Composer actions, header emphasis |
Prefer `<Icon icon={Search} size="md" />` from `@rakazo/ui-web` over Lucide `size={N}`.
## Controls
| Utility | Height | Use |
|---------|--------|-----|
| `h-control-xs` / `size-control-xs` | 28px | Compact density (tables, button groups) |
| `h-control-sm` / `size-control-sm` | 36px | Secondary actions |
| `h-control-md` / `size-control-md` | 40px | Default buttons, inputs, selects |
| `h-control-lg` / `size-control-lg` | 44px | Touch targets — header/sidebar icon buttons |
Button sizes map: `default` → md, `sm` → sm, `lg` → lg, `icon` → md, `icon-lg` → lg (44px).
## Shell helpers (`apps/web/src/styles.css`)
| Class | Purpose |
|-------|---------|
| `rk-shell-section-label` | Uppercase sidebar section headers |
| `rk-shell-icon-btn` | 44px icon button with focus ring |
| `rk-shell-meta` | Muted secondary line |
| `rk-shell-row-title` | Sidebar / list primary label |
## Spacing
| CSS var | Value | Use |
|---------|-------|-----|
| `--spacing-shell` | 10px | General shell gaps |
| `--spacing-sidebar-row-x` | 12px | Sidebar row horizontal padding |
| `--spacing-sidebar-row-y` | 10px | Sidebar row vertical padding |
Tailwind: `gap-rk-shell`, `px-rk-sidebar-x`, `py-rk-sidebar-y`.
## Accessibility
- Interactive chrome targets ≥44px (`size-control-lg`, `rk-shell-icon-btn`).
- Focus rings: `focus-visible:ring-3 focus-visible:ring-ring/50` on primitives.
- Muted text uses `--muted-foreground` (#A1A8B5 dark) for ≥4.5:1 on surfaces.
## When to use compact density
Only inside dense data tables, keyboard legends, or `Button size="xs"`. Never on sidebar, header, composer, or chat chrome.
## evOo Oo brand lock
> **Oo trademark = asymmetric Kulleraugen + size difference**
Non-negotiable for all mascot surfaces (`EvooMascot`, `BotAvatar`, Wordmark):
1. **Size asymmetry** — one big eye (O), one small eye (o); never equal radii.
2. **Kulleraugen** — round glossy sclera, cute googly pupils with catchlights.
Mouth, hands, accessories, and poses extend personality **on top** of this — never symmetrize eyes or swap in generic emoji faces. Constants and CI guard: `packages/ui-web/src/evoo-character/brand-lock.ts`. Full pose map: `packages/ui-web/CHARACTER.md`.
## EvOo Wordmark / Mascot
Sidebar `<Wordmark />` uses `<EvooMascot trackPointer="none" interactive />`:
- **No** window-level pointer follow (eyes no longer stare down-right while you work).
- Calm idle life: blinks, micro-saccades, soft breathe, rare gentle look-around.
- Click still triggers wave / wink delight.
| `trackPointer` | Behavior |
|----------------|----------|
| `"none"` (default) | Idle-only — chrome logo, avatars |
| `"hover"` | Follow pointer while over mascot — welcome hero, call view |
| `"global"` | Legacy full-window tracking — avoid in chrome |
`interactive` controls click/keyboard only; it does **not** enable tracking.
## Regenerating tokens
```bash
pnpm --filter @rakazo/ui-tokens generate
pnpm --filter @rakazo/ui-tokens test
```
Edit `packages/ui-tokens/src/index.ts`, not `tokens.css`.