# Consignes — mon design system (Gruvbox seventies)

> **Tu es un agent IA chargé de produire ou modifier du code utilisant ce design system.**
> Lis ce fichier en entier avant d'écrire la moindre ligne. Suis les règles à la lettre.

---

## 🎯 Identité du système

- **Nom** : mon design system — Gruvbox seventies
- **Vibe** : rétro-industriel, console de monitoring, SCADA, terminal années 70
- **Palette** : orange brûlé Gruvbox + fond brun délavé (pas noir intense) ou gris clair usé (pas blanc pur)
- **Cas d'usage cibles** : tableaux de bord, monitoring, IoT, domotique, ops, scanners réseau
- **Public** : utilisateurs techniques (admin sys, devs, makers) — densité d'info élevée acceptée

---

## 📁 Fichiers à connaître

| Fichier                         | Contient                                              |
|---------------------------------|-------------------------------------------------------|
| `tokens/tokens.css`             | Variables CSS web (`:root[data-theme="dark|light"]`)  |
| `tokens/tokens.gnome.css`       | Tokens GTK 4 / libadwaita (`@define-color`)           |
| `tokens/tokens.json`            | Tokens en JSON pour outils externes                   |
| `components/ui-kit.jsx`         | 14 composants React (Button, Icon, Popup…)            |
| `examples/exemple-minimal.html` | Démo de référence                                     |

---

## ⚠️ Règles absolues — ne JAMAIS enfreindre

1. **Toujours utiliser les variables CSS**, jamais des hex en dur dans le code utilisateur.
   ✅ `color: var(--accent)`
   ❌ `color: #fe8019`

2. **Toujours déclarer `data-theme`** sur un parent (`<html>` ou un wrapper).
   Sans ça, les variables ne sont pas définies et l'UI casse silencieusement.

3. **Composants existants** — ne jamais en réinventer. Vérifier d'abord la liste ci-dessous.

4. **Icônes** — utiliser le composant `<Icon name="…">` avec les noms mappés. JAMAIS d'emoji, JAMAIS de SVG inline custom pour un cas où une icône Font Awesome existe.

5. **Pas d'effet hover** sur les boutons / tuiles / composants généraux (sauf jauges et tuiles Heimdall qui en ont un). Seulement **pression 3D au clic** via `.interactive`.

6. **Toujours des tooltips** sur les boutons icônes seuls (`<IconButton>` exige `label`).

7. **Pas de bordure arrondie excessive**. Tuiles : `border-radius: 10-12px`. Boutons : `8px`. Pastilles : `999px`.

8. **Polices** — respecter strictement les 3 familles :
   - **Inter** → UI (titres, corps, boutons, labels d'interface généraux)
   - **JetBrains Mono** → données numériques, valeurs, code, IDs, IPs
   - **Share Tech Mono** → logs, terminal embarqué, ambiance rétro
   Toute autre police = bug.

9. **Tonalité** : labels en `text-transform: uppercase` + `letter-spacing: 0.08em` (classe `.label` déjà fournie).

10. **Densité** : pas de padding inutile. Ce DS est dense par nature. Tuiles : padding 14-18px. Boutons : 6-10px vertical.

---

## 🎨 Tokens disponibles

### Couleurs (toutes définies en `dark` ET `light`)

#### Fonds (du plus profond au plus haut)
```
--bg-0   très rare, niveau le plus bas
--bg-1   fond application principal
--bg-2   panneaux (sidebar, headerbar)
--bg-3   cartes, tuiles ← LE PLUS UTILISÉ
--bg-4   hover, état actif
--bg-5   press, sélection forte
```

#### Texte (du plus contrasté au moins)
```
--ink-1  texte principal
--ink-2  texte secondaire
--ink-3  labels, hints
--ink-4  désactivé
```

#### Accent
```
--accent        couleur primaire (orange Gruvbox seventies)
--accent-soft   variante foncée (bordures, hover)
--accent-glow   halo (rgba)
--accent-tint   teinte transparente (fonds discrets)
```

#### Statuts
```
--ok     #4dbb26 (vert flashy)
--warn   #fabd2f (jaune)
--err    #fb4934 (rouge)
--info   #83a598 (vert-bleu pastel)
```

#### Datavis additionnel
```
--blue    #3db0d1
--purple  #c882c8
```

#### Bordures
```
--border-1, --border-2, --border-3   du plus subtil au plus marqué
```

#### Ombres / relief
```
--shadow-1, -2, -3          élévations standards
--shadow-press              état pressé (inset)
--tile-3d                   relief 3D marqué pour cartes ← À utiliser sur les tuiles importantes
```

### Polices
```
--font-ui         'Inter', system-ui, sans-serif
--font-mono       'JetBrains Mono', monospace
--font-terminal   'Share Tech Mono', monospace
```

---

## 🧩 Composants — quand utiliser quoi

| Besoin | Composant | Exemple |
|--------|-----------|---------|
| Bouton texte avec ou sans icône | `<Button variant="primary|ghost|danger|default">` | Action principale, secondaire |
| Bouton icône seul | `<IconButton icon="…" label="…">` | Toolbars, headers (le `label` devient tooltip) |
| On/off | `<Toggle on={…} onChange={…} label icon>` | Activer/désactiver une option |
| État système | `<StatusLed status="ok|warn|err|info|off" pulse>` | LED pulsante pour critique |
| Jauge ronde standard | `<RadialGauge value={…} label size>` | KPI compact, cockpit |
| Jauge ronde héro | `<BigRadialGauge value={…} label>` | Métrique principale unique |
| Jauge barre standard | `<BatteryGauge value label>` | Stack vertical de ressources |
| Jauge barre **inline** | `<BatteryGauge compact value label icon>` | Listes denses, label + barre + valeur sur 1 ligne |
| Modale | `<Popup open onClose title footer>` | Confirmation, config détaillée |
| Tree dépliable | `<TreeNav groups activeId onSelect>` | Sidebar hiérarchique (clusters/nodes) |
| Mini graphe | `<Sparkline points color>` | Dans une tuile KPI |
| Graphe ligne | `<LineChart series labels h>` | Évolution temporelle multi-séries |
| Tooltip | `<Tooltip label side><…/></Tooltip>` | Toute icône isolée |
| Icône | `<Icon name="…" size>` | JAMAIS d'emoji, JAMAIS de SVG custom |

### Icônes disponibles (noms logiques → Font Awesome)

`cpu`, `memory`, `disk`, `network`, `clock`, `grid`, `list`, `cog`, `alert`, `bell`, `server`, `chart`, `bars`, `terminal`, `refresh`, `play`, `pause`, `power`, `sun`, `moon`, `search`, `close`, `chevR`, `chevL`, `chevD`, `chevU`, `plus`, `filter`, `download`, `folder`, `node`, `user`.

Pour un nouveau besoin → utiliser une icône Font Awesome (préfixe `fa-solid fa-…`) en ajoutant l'alias dans `ICON_MAP` au sein de `ui-kit.jsx`.

---

## 🏗️ Patterns d'agencement standards

### Layout dashboard 3 colonnes
```
┌─ Header (tabs workspace + search + actions + statut connexion) ─┐
├──────┬────────────────────────────────┬──────────────────────────┤
│ Tree │ Center cockpit (KPIs + jauges) │ Logs/Terminal repliable │
│ nav  │                                 │                          │
├──────┴────────────────────────────────┴──────────────────────────┤
│ Status bar (mode · workspace · stats · horloge)                  │
└──────────────────────────────────────────────────────────────────┘
```

### Tuile KPI standard
```jsx
<div className="glass" style={{ padding: 12, borderRadius: 10, ...}}>
  <Icon name="cpu" /> <span className="label">CPU</span>
  <span className="mono">{value}<span className="label">%</span></span>
  <Sparkline points={trend} color="var(--accent)" />
</div>
```

### Status bar inférieure
- Première cellule = mode courant en fond accent (style tmux)
- Cellules séparées par `border-right: 1px solid var(--border-1)`
- Police `Share Tech Mono` 11-12px
- Horloge à droite

---

## 🚫 Anti-patterns à éviter

### NE PAS faire :

❌ **Mettre des emoji** pour un état :
```jsx
<span>✅ Système OK</span>     // NON
<><StatusLed status="ok" /> Système OK</>  // OUI
```

❌ **Inventer de nouvelles couleurs hors palette** :
```jsx
style={{ color: '#ff00aa' }}   // NON — utilise les tokens
```

❌ **Police arbitraire** :
```jsx
fontFamily: 'Roboto'           // NON
fontFamily: 'var(--font-ui)'   // OUI
```

❌ **Bordures arrondies à 24px+** sur des cartes (vibe trop SaaS pastel).

❌ **Tooltip absent sur une icône isolée** :
```jsx
<button><Icon name="cog" /></button>                                    // NON
<IconButton icon="cog" label="Configurer" onClick={fn} />               // OUI
```

❌ **`window.alert` / `confirm`** — toujours utiliser `<Popup>`.

❌ **Texte secondaire en `--ink-1`** — choisir la bonne couche d'encre selon la hiérarchie.

❌ **Sur-utiliser le glow / shadow** — réservé aux accents importants.

❌ **Mélanger les casses de label** — labels = uppercase mono, titres = sentence case.

---

## ✅ Patterns recommandés

### Hiérarchie de fond
- App / page → `--bg-1`
- Sidebar / headerbar → `--bg-2`
- Tuiles / cartes principales → `--bg-3` ou `.glass`
- Input fields / containers profonds → `--bg-1` avec inset shadow

### Effet glass standard
```jsx
className="glass"   // backdrop-filter + bg semi-transparent + tile-3d shadow
```
ou pour plus marqué :
```jsx
className="glass-strong"
```

### Validation visuelle d'un état critique
```jsx
<StatusLed status="err" pulse />          // pastille pulsante
<Button variant="danger" icon="power">…</Button>
// + bordure rouge sur le conteneur :
style={{ border: '1px solid var(--err)', boxShadow: 'inset 0 1px 0 rgba(251,73,52,0.2), 0 0 18px rgba(251,73,52,0.15)' }}
```

### Sticky footer d'actions (form)
```jsx
<div className="glass-strong" style={{
  padding: '12px 20px',
  display: 'flex', gap: 12, alignItems: 'center',
  borderTop: '1px solid var(--border-2)',
}}>
  <StatusLed status={dirty ? 'warn' : 'ok'} pulse={dirty} />
  <span className="terminal">{dirty ? 'modifications non sauvegardées' : 'à jour'}</span>
  <span style={{ flex: 1 }}></span>
  <Button variant="ghost">Annuler</Button>
  <Button variant="primary" icon="download">Enregistrer</Button>
</div>
```

---

## 🌗 Gestion des deux thèmes

**Règle d'or** : tout ce qui s'affiche doit être lisible et cohérent dans les deux thèmes.

Avant de livrer un écran, **mentalement (ou réellement) bascule `data-theme`** et vérifie :
- Les couleurs personnalisées (en dur) cassent forcément → utilise les tokens
- Les opacités blanches (`rgba(255,255,255,…)`) en dark passent mal en light → préfère les variables `--border-*`
- Les ombres très profondes en dark sont invisibles en light → utilise `--shadow-*` qui s'adapte

Pour basculer dynamiquement :
```jsx
document.documentElement.dataset.theme = 'light';
```

---

## 🪟 Cas particulier : applications GNOME

Pour GTK 4 / libadwaita :
1. Charger `tokens/tokens.gnome.css` via `GtkCssProvider`
2. Le fichier **override les couleurs sémantiques libadwaita** (`@accent_color`, `@window_bg_color`, etc.) — les widgets standards se ré-habillent automatiquement
3. Ajouter `add_css_class("tile")` pour le relief 3D, `("mono")` pour monospace, `("terminal")` pour Share Tech Mono
4. Pour les boutons accent : utiliser la classe libadwaita standard `suggested-action` (déjà restylée)
5. Pour danger : classe `destructive-action`

Polices : penser à installer ou bundler Inter / JetBrains Mono / Share Tech Mono dans le `.flatpak` / `.deb` (sinon GTK fallback sur Cantarell / DejaVu).

---

## 🎯 Quand l'utilisateur demande quelque chose…

### "Ajoute un bouton de déconnexion"
→ `<IconButton icon="power" label="Se déconnecter" danger />` ou
`<Button variant="danger" icon="power">Déconnexion</Button>`

### "Affiche le statut du serveur"
→ Combinaison `<StatusLed status="ok|warn|err" pulse />` + label texte. Le pulse uniquement si c'est critique/nouveau.

### "Mets une jauge CPU"
→ `<BatteryGauge compact value={cpu} label="cpu" icon="cpu" warnAt={70} errAt={85} />` (inline)
ou `<RadialGauge value={cpu} label="CPU" />` (visuel)

### "Crée une modale de confirmation"
→ `<Popup>` avec `footer={<><Button variant="ghost">Annuler</Button><Button variant="primary">Confirmer</Button></>}`

### "Liste hiérarchique des serveurs"
→ `<TreeNav>` avec `groups: [{ id, icon: 'server', label, count, open, children: [{ id, label, status, meta }] }]`

### "Affiche les logs"
→ Conteneur avec `font-family: var(--font-terminal)` + lignes colorées par niveau (ERROR → var(--err), WARN → var(--warn), INFO → var(--ink-2)).

### "Ajoute une option dark/light dans les réglages"
→ `<RadioGroup options={[{value:'dark', icon:'moon'}, {value:'light', icon:'sun'}, {value:'auto', icon:'clock'}]}>` + effet de bord :
```jsx
React.useEffect(() => { document.documentElement.dataset.theme = theme; }, [theme]);
```

---

## 📐 Tailles standards à respecter

| Élément       | Taille / Padding                        |
|---------------|------------------------------------------|
| Boutons sm    | h: 28px · pad: 5px 10px · font: 12px    |
| Boutons md    | h: 34px · pad: 7px 14px · font: 13px    |
| Boutons lg    | h: 40px · pad: 10px 18px · font: 14px   |
| IconButton    | 34px (default) · 26px (compact)         |
| Inputs        | pad: 9px 12px · font: 13px              |
| Toggle        | 42 × 22px                                |
| StatusLed     | 8-14px diamètre                          |
| Header app    | 48-56px hauteur                          |
| Sidebar       | 200-260px largeur                        |
| Volet logs    | 320-360px largeur                        |
| Status bar    | 24-28px hauteur                          |
| Radius tuile  | 10-12px                                  |
| Radius button | 8px                                      |
| Espacement    | 8 / 12 / 14 / 18 / 24px (rythme bas)    |

---

## 💡 Trucs pour ne pas se tromper

1. **Avant de créer un composant, cherche d'abord** dans `ui-kit.jsx`. 90% du temps il existe déjà.
2. **Avant d'inventer une couleur**, regarde les tokens. Tu as 6 fonds, 4 encres, 4 statuts, 2 datavis = largement assez.
3. **Si tu hésites sur une taille de police** : labels = 11px mono uppercase, body = 13-14px, kpi = 18-28px mono bold.
4. **Quand tu ajoutes une tuile**, mets `className="glass"` (ou `glass-strong` pour les modales) — tout le styling est inclus.
5. **Pour un état critique**, combine plusieurs signaux : couleur + pulse LED + icône + position visuelle. Pas juste une couleur.
6. **Quand l'utilisateur demande "un peu d'effet"** : pas de hover (sauf jauges), oui à la pression 3D, oui aux animations d'entrée 200-400ms `cubic-bezier(.3,.7,.3,1.2)`.

---

## 🔚 En cas de doute

- Pas sûr d'une couleur ? → tokens
- Pas sûr d'un composant ? → `ui-kit.jsx`
- Pas sûr d'un layout ? → `examples/exemple-minimal.html`
- Pas sûr d'une convention ? → ce fichier

Toujours préférer la cohérence avec l'existant à l'innovation.
Quand tu doutes, **demande-moi** plutôt que de deviner.
