| 1 | # codewhale-design |
| 2 | |
| 3 | Keep every Codewhale surface on one set of design tokens. |
| 4 | |
| 5 | This repository is the source of truth for Codewhale's colours, type, spacing, |
| 6 | radii and motion constants. The desktop app, the website, the terminal UI |
| 7 | (`codewhale-ratatui`) and the mobile app each vendor a copy and verify it at |
| 8 | build time, so no consumer needs the network or a sibling checkout. |
| 9 | |
| 10 | Update tokens: edit `tokens.json`, bump its version, run `python3 generate.py`, |
| 11 | then run `scripts/sync-to.sh <consumer-repo>` for each consumer. |
| 12 | |
| 13 | ## Details |
| 14 | |
| 15 | `tokens.json` is the versioned semantic design authority. Desktop consumes |
| 16 | `tokens.rs`; GPUI mobile vendors this folder and consumes the same Rust data; |
| 17 | web-next vendors this folder and imports `tokens.css`. No network access or |
| 18 | sibling checkout is required to build a consumer. |
| 19 | |
| 20 | Change the JSON here, increment its version, run `python3 generate.py`, |
| 21 | and copy this entire folder into each consumer's `vendor/codewhale-design`. |
| 22 | Run the generator with `--check` in each repository. Generated files include the |
| 23 | source digest; consumer tests reject drift. Layout remains native to each |
| 24 | surface. Focus and reduced-motion settings must remain accessible on each host. |
| 25 | |
| 26 | Typography and palette come from the shipping desktop theme. Icons retain the |
| 27 | 24-unit, 1.7-pixel rounded stroke family; semantic names and accessible labels |
| 28 | stay with the host controls. Desktop spring constants and reduced-motion poll |
| 29 | cadence are shared without introducing decorative animation on web or phones. |
| 30 | |
| 31 | CSS consumers use `font-family: var(--font-family), var(--font-fallbacks), sans-serif` |
| 32 | to keep the shared family and CJK fallbacks together. The generator rejects |
| 33 | selection and primary-hover opacity values outside the inclusive 0–1 range, |
| 34 | and any palette that misses WCAG AA contrast in either mode: every text role |
| 35 | at 4.5:1 (`muted_foreground` at 5.5:1) and `border_strong` at 3:1 on |
| 36 | `background`, `surface`, `sidebar`, `hover` and `selected`, and `primary_foreground` on `primary` at 4.5:1. A new |
| 37 | colour, such as a named blue, enters the tokens only once it passes. |
| 38 |