Skip to content

Commit 7c3c507

Browse files
OnlineChefcursoragentnavarrocorbi-prog
authored
redesign(gui): adopt ChefGroep design language (warm palette, blue accent, shadcn + skins) (#30)
* redesign(gui): adopt ChefGroep design language (warm palette, blue accent, Archivo/JetBrains Mono, shadcn buttons, ripple, strak skin) Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> * redesign(gui): blue input focus ring, Dutch-first default, keep faithful dark basalt Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> * redesign(gui): typography system (caps labels, tabular nums, type ladder, tracking) + motion (page reveal, press-physics, matte modal) + gui/DESIGN.md taste guide Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> * redesign(gui): bulletproof page-reveal via keyed wrapper; align provider-overview cards to design tokens (caps labels, tabular counts) Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> * redesign(gui): deeper design-system taste — authentic Stroom ripple-bar, neutral nav-active (accent reserved), caps section headers, range/kbd primitives, taste-rules in DESIGN.md Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> * chore(gui): drop unused ibm-plex-mono after Archivo/JetBrains adoption Co-authored-by: navarrocorbi-prog <navarrocorbi-prog@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: OnlineChef <OnlineChef@users.noreply.github.com> Co-authored-by: navarrocorbi-prog <navarrocorbi-prog@users.noreply.github.com>
1 parent 63a4157 commit 7c3c507

7 files changed

Lines changed: 400 additions & 128 deletions

File tree

gui/DESIGN.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# gui/DESIGN.md — de ontwerptaal van het dashboard
2+
3+
> De levende ontwerp- en smaakgids voor het opencodex-dashboard (`gui/`).
4+
> Dit is de ChefGroep-taal (v2 "Devin-richting"): een stil, warm, mat instrument.
5+
> Bron van waarheid voor de *taal*: [`OnlineChefGroep/design-system`](https://github.com/OnlineChefGroep/design-system)
6+
> (`tokens.css`, `DESIGN.md`, `motion-spec.md`). Dit bestand legt vast hoe die
7+
> taal in dít dashboard leeft, en — belangrijker — **hoe je 'm uitbreidt zonder
8+
> 'm te breken**.
9+
10+
Alles hier is gebouwd op tokens in `src/styles.css`. Verzin nooit losse
11+
px-waarden of kleuren in een component; gebruik een token. Zo blijft de hele
12+
app in één keer te herstemmen.
13+
14+
---
15+
16+
## 1. De drie pijlers
17+
18+
1. **Stil oppervlak.** Warm off-white, haarlijnen, plat. Geen glow, geen
19+
gradients, geen glasmorfisme, geen geneste schaduw.
20+
2. **Levende activiteit.** Werk toon je als rust of een golfje, nooit als
21+
ronddraaiende spinner.
22+
3. **Begrijpelijk.** Eén accent, één type-ladder, één set radii, één easing.
23+
Hiërarchie komt uit grootte/gewicht/kleur — niet uit decoratie.
24+
25+
---
26+
27+
## 2. Kleur
28+
29+
Eén accent: blauw (`--accent-blue`). Alles wat "klik mij / hier ben je / dit is
30+
aan" zegt is blauw: links, focus-ring, actieve nav, geselecteerde tab, toggles,
31+
selectie. De **primaire knop** blijft juist monochroom (tekst↔achtergrond
32+
omgekeerd) — dat is de shadcn-conventie, geen tweede accent.
33+
34+
| Rol | Token |
35+
|---|---|
36+
| Achtergrond / rail / kaart | `--bg` · `--rail` · `--surface` · `--raised` |
37+
| Lijnen | `--border` (sterk) · `--border-soft` (hairline) |
38+
| Tekst | `--text` · `--muted` · `--faint` |
39+
| Primaire actie | `--accent` (+ `--accent-ink`) |
40+
| Het accent | `--accent-blue` · `--accent-blue-ink` · `--accent-soft` (ring/tint) |
41+
| Semantiek | `--green` (git/PR/toestemming) · `--amber` (wacht-op-jou) · `--red` (destructief) |
42+
43+
Regels: groen/amber/rood zijn **gereserveerd**, nooit decoratie. Neutraal is
44+
warm, nooit koudgrijs. Dark mode is basalt-warm, geen zuiver zwart. Elke token
45+
is `light-dark(licht, donker)` — schrijf beide kanten, altijd.
46+
47+
---
48+
49+
## 3. Typografie
50+
51+
- **Archivo** (`--font-ui`) voor alles; **JetBrains Mono** (`--font-code`)
52+
uitsluitend voor machinedata (timers, model-id's, paden, diffs, tellers).
53+
- Eén type-ladder — gebruik de tokens, nooit losse px:
54+
55+
| Token | px | Gebruik |
56+
|---|---|---|
57+
| `--text-micro` | 10.5 | meta, tellers, caps-labels |
58+
| `--text-caption` | 11.5 | labels, captions |
59+
| `--text-label` | 12.5 | secundair / beschrijvingen |
60+
| `--text-control` | 13.5 | **UI-standaard** (body van de app) |
61+
| `--text-body` | 14 | leestekst |
62+
| `--text-subtitle` | 16 | kleine titels |
63+
| `--text-section` | 18 | sectiekoppen |
64+
| `--text-title` | 22 | paginatitels |
65+
| `--text-display` | 28 | hero-getallen |
66+
67+
- Koppen: gewicht 500, `letter-spacing: var(--tracking-tight)` (−0.02em),
68+
`text-wrap: balance`. Leading via `--leading-*` (tight 1.2 / ui 1.45 /
69+
body 1.55 / relaxed 1.65).
70+
- **Getallen lijnen uit**: alles wat een getal is krijgt `.num` of
71+
`font-variant-numeric: tabular-nums` (stat-waarden, quota, tellers, timers).
72+
- Utilities: `.num` (tabulaire cijfers), `.caps` (uppercase microlabel),
73+
`.prose` (68ch leesmaat). Componeer hiermee; verzin geen nieuwe.
74+
75+
---
76+
77+
## 4. Motion
78+
79+
Bewegen is transform + opacity, nooit `width/height/top/left`. Eén easing
80+
(`--ease-out`), duren `--motion-fast/normal/slow` (140/280/420ms). Alles settle-t
81+
vroeg, niets bounct, niets loopt oneindig. De vaste set:
82+
83+
- **Intent-reveal:** één rustige rise per navigatie (`.main-inner > *`), niet
84+
per kaart.
85+
- **Press-physics:** `scale(0.97–0.98)` op knoppen, nav-rijen, tabs, chips,
86+
segments. Nooit op inputs, tekst of panelen.
87+
- **Modal:** scrim vervaagt in, kaart rijst en settle-t.
88+
- **Ripple i.p.v. spinner:** `.spin` is een kalm blauw golfje.
89+
90+
`prefers-reduced-motion` zet **alles** uit met nul informatieverlies (globale
91+
guard in `styles.css`). Nieuwe animatie = tokenduur + één keyframe in het
92+
Motion-blok. Meer niet.
93+
94+
---
95+
96+
## 5. Skins (`data-style`)
97+
98+
Dezelfde taal draagt meerdere complete skins:
99+
100+
- `devin` (default) — warm, zacht, ronder (`:root`).
101+
- `strak` — koeler grijs-blauw, scherpere radii.
102+
103+
Zetten: `?style=strak` of een opgeslagen keuze (`localStorage` `ocx-style`),
104+
toegepast vóór eerste paint in `main.tsx`. Een nieuwe skin = één blok
105+
token-overrides in `styles.css` (light **én** dark). De taal (§1–§4) blijft
106+
onder elke skin gelden.
107+
108+
---
109+
110+
## 5b. Taste-regels (overgenomen uit `design-system/taste/`)
111+
112+
Bindend voor nieuw werk. Twee observaties minimum per regel (zie de bron).
113+
114+
- **Kleur:** neutraal warm tinten, **één accent max**; licht is eersteklas
115+
standaard. Geen paarse gradients, AI-glow, acid-on-black. Het accent is voor
116+
links/focus/toggles/status — **niet** voor nav-selectie (die is een kalme
117+
`--raised`).
118+
- **Type:** Archivo/General Sans-humanist voor interface; mono **strikt** voor
119+
data. Nooit Inter/Geist/Space Grotesk of mono voor labels/prose.
120+
- **Motion:** vroeg settelen, lage amplitude/frequentie; **één** signatuur-
121+
systeem (de Stroom/ripple), geen verspreide micro-animaties. Geen bounce,
122+
elastic of oneindige ambient motion.
123+
- **Dichtheid:** compact, informatiedicht (dichtheid 5–7). `h28`/`r6` voor
124+
secundaire controls, `r10` voor kaarten. Geen marketing-witruimte in product.
125+
- **Stem:** warm, direct, menselijk Nederlands op Joep-vlakken. Geen em-dashes,
126+
buzzwords, lifecycle-jargon of verzonnen metrics.
127+
- **Structuur:** haarlijnen + ruimte voor scheiding. **Geen** kaart-in-kaart,
128+
bento-velden of geneste elevation. Tweebaans sidebar met vaste glyph-baan.
129+
- **Iconen:** echte SVG-lijniconen (Lucide/shadcn, ~1.75px stroke, 15–16px
130+
grid). Nooit emoji als icoon — nergens.
131+
- **Metafoor:** water/stroom voor systeemstatus; instrument-framing
132+
("gezandstraald instrument"). Geen keuken/bon/brigade of corporate-dashboard.
133+
134+
## 6. Bans (hard)
135+
136+
- Geen spinners/loaders (ripple vervangt ze).
137+
- Geen emoji als icoon of in copy. Iconen zijn SVG-lijniconen (Lucide-stijl).
138+
- Geen em-dashes, buzzwords of verzonnen metrics in copy.
139+
- Geen gradients, glow, glasmorfisme, bento-kaartjes.
140+
- Geen kaart-in-kaart, geen geneste elevation.
141+
- Geen oneindige ambient motion.
142+
143+
---
144+
145+
## 7. Zo breid je uit
146+
147+
- **Nieuwe kleur/rol:** token toevoegen in `:root` mét `light-dark()`, en in
148+
élke skin (`[data-style="strak"]`). Nooit een losse hex in een component.
149+
- **Nieuwe component:** hergebruik `.btn`/`.badge`/`.input`/`.switch`/`.seg`,
150+
radii- en type-tokens. Haarlijn-border, rustige hover, press-physics als het
151+
klikbaar is.
152+
- **Nieuwe tekst:** géén hardgecodeerde UI-strings in `src/pages`/
153+
`src/components` (zie `gui/AGENTS.md`). Zet de string in **alle** locale-
154+
bestanden (`src/i18n/*.ts`) en render met `useT()`. Draai `bun run lint:i18n`.
155+
- **Nieuwe motion:** tokenduur + keyframe in het Motion-blok; transform/opacity
156+
only; check `prefers-reduced-motion`.
157+
- **Controleren:** `bun run typecheck`, `bun --bun run lint:gui`,
158+
`bun run lint:i18n`, `bun run privacy:scan`. Zie `AGENTS.md`.

gui/bun.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gui/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"preview": "vite preview"
1515
},
1616
"dependencies": {
17+
"@fontsource-variable/archivo": "^5.3.0",
18+
"@fontsource-variable/jetbrains-mono": "^5.3.0",
1719
"@tanstack/react-virtual": "^3.14.5",
1820
"react": "^19.2.7",
1921
"react-dom": "^19.2.7"

gui/src/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ export default function App() {
288288

289289
<main className="main" inert={navOpen}>
290290
<div className={`main-inner${page === "combos" ? " main-inner--combos" : ""}`}>
291+
<div className="page-reveal" key={page}>
291292
<ErrorBoundary
292-
key={page}
293293
pageName={t(PAGE_TKEY[page])}
294294
title={t("errorBoundary.title")}
295295
message={t("errorBoundary.message")}
@@ -310,6 +310,7 @@ export default function App() {
310310
{page === "claude" && <Claude apiBase={API_BASE} />}
311311
{page === "grok" && <Grok apiBase={API_BASE} />}
312312
</ErrorBoundary>
313+
</div>
313314
</div>
314315
</main>
315316
</div>

gui/src/main.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
import React from "react";
22
import ReactDOM from "react-dom/client";
3+
// ChefGroep design language: Archivo (UI, the free General Sans equivalent) +
4+
// JetBrains Mono (data only). Bundled locally so nothing depends on a CDN.
5+
import "@fontsource-variable/archivo/wght.css";
6+
import "@fontsource-variable/jetbrains-mono";
37
import App from "./App";
48
import { LanguageProvider } from "./i18n/provider";
59
import "./styles.css";
610

11+
// ChefGroep design language ships two complete skins (design-system §14).
12+
// devin (warm, default) is the :root skin; strak (cool, sharp) is opt-in via
13+
// ?style=strak or a saved choice. Applied before first paint to avoid a flash.
14+
try {
15+
const params = new URLSearchParams(window.location.search);
16+
const style = params.get("style") ?? localStorage.getItem("ocx-style");
17+
if (style === "strak" || style === "devin") {
18+
document.documentElement.setAttribute("data-style", style);
19+
localStorage.setItem("ocx-style", style);
20+
}
21+
} catch { /* ignore */ }
22+
723
ReactDOM.createRoot(document.getElementById("root")!).render(
824
<React.StrictMode>
925
<LanguageProvider>

0 commit comments

Comments
 (0)