# Structura — UI kit & design language

## 1. Inspiration / références

### Autodesk Tandem
Ce qu'on pique : la densité de l'interface (sidebar compacte, panels qui s'empilent sans respiration excessive), le fond quasi-noir avec des élévations subtiles par des bords lumineux plutôt que des ombres, le pattern "scene 3D à droite / data à gauche". La hiérarchie typographique qui distingue clairement les labels en majuscules micro de 11px des valeurs en mono.

### Palantir Foundry
Ce qu'on pique : la grille de cartes avec borders fins (#223041 environ), les badges de statut compacts, le pattern "table filtrée + panneau détail" côte à côte, les couleurs de données décorrelées (pas de gradient, chaque série a sa propre couleur unie). L'accent bleu froid (#4CC9F0) posé sur fond sombre sans chercher à flasher.

### Grafana
Ce qu'on pique : la logique des panels détachables, les sparklines dans les cellules de tableau, le pattern de l'heatmap (cases colorées par intensité sur fond sombre), les axes de graphes en text.muted, les tooltips contextuels avec fond overlay semi-opaque. L'idée que la donnée est reine et l'UI s'efface.

### Sentry
Ce qu'on pique : les StatusDot animés (pulsation lente sur l'état actif), les badges de criticité avec fond subtle + border de la couleur statut, le pattern timeline avec icône + texte + timestamp alignés sur une colonne étroite. La façon dont les erreurs/warnings ressortent sans agressivité.

### Bentley Acute3D / iTwin
Ce qu'on pique : le contexte sectoriel (vue 3D de structures réelles, capteurs positionnés dans l'espace), les overlays d'info flottants au-dessus de la scène 3D avec fond semi-opaque, le pattern "cliquer sur un objet 3D ouvre un panneau latéral". La sobriété : pas de couleurs vives dans la scène, juste les points capteurs qui brillent.

---

## 2. Palette (dark uniquement, un seul choix tranché)

### Backgrounds

| Rôle | Hex | Usage |
|---|---|---|
| bg.base | `#080C12` | fond de page, sidebar |
| bg.elevated | `#0F1620` | cards, panels, topbar |
| bg.overlay | `#172030` | modales, popovers, tooltips |
| bg.border | `#1E2D3D` | borders de tous les conteneurs |
| bg.subtle | `#111B28` | hover sur items de liste, inputs |

### Texte

| Rôle | Hex | Usage |
|---|---|---|
| text.primary | `#E2EAF4` | titres, valeurs importantes |
| text.secondary | `#8A9BB0` | labels, sous-titres |
| text.muted | `#4E6070` | timestamps, axes de graphes, placeholders |
| text.disabled | `#2E3D4D` | éléments désactivés |

### Accent

| Rôle | Hex | Usage |
|---|---|---|
| accent.DEFAULT | `#3DB8E8` | liens actifs, highlights, boutons primaires |
| accent.hover | `#5CC8F0` | hover de l'accent |
| accent.subtle | `#3DB8E814` | bg des badges accent, hover subtil sur items |
| accent.border | `#3DB8E840` | border des éléments accentués |

### Statuts

| Rôle | Hex | Usage |
|---|---|---|
| status.success | `#34D399` | capteur OK, déploiement réussi |
| status.warning | `#FBBF24` | seuil dépassé, alerte modérée |
| status.danger | `#F87171` | anomalie critique, capteur HS |
| status.info | `#60A5FA` | information neutre |
| status.offline | `#4E6070` | capteur hors ligne, inactif |

### Couleurs de données (séries de graphes)

| Nom | Hex | Usage type |
|---|---|---|
| data.blue | `#3DB8E8` | série principale (amplitude) |
| data.teal | `#2DD4BF` | série secondaire (FFT) |
| data.violet | `#818CF8` | série tertiaire (prédiction) |
| data.amber | `#FBBF24` | alertes / seuils |
| data.rose | `#FB7185` | anomalies détectées |
| data.slate | `#64748B` | série de référence / baseline |
| data.lime | `#86EFAC` | données de validation |

---

## 3. Typographie

### Familles

- **Sans** : Inter (Google Fonts, variable font) — précision technique, excellent rendu à petite taille sur écran dense.
- **Mono** : JetBrains Mono (variable) — valeurs numériques, logs, codes d'identification capteur.

### Hiérarchie

| Niveau | Famille | Size | Line-height | Weight | Usage |
|---|---|---|---|---|---|
| H1 | Inter | 28px | 34px | 600 | Titre de page (PageHeader) |
| H2 | Inter | 20px | 28px | 600 | Titre de section, Card header |
| H3 | Inter | 15px | 22px | 500 | Sous-section, Panel title |
| body | Inter | 13px | 20px | 400 | Contenu courant, descriptions |
| caption | Inter | 11px | 16px | 400 | Timestamps, labels secondaires, uppercase tracked 0.05em |
| label | Inter | 11px | 16px | 500 | Labels de champs, column headers uppercase |
| mono-number | JetBrains Mono | 13px | 20px | 400 | Valeurs numériques (mesures, coordonnées) |
| mono-large | JetBrains Mono | 24px | 30px | 500 | Stat principale (CounterValue) |
| mono-small | JetBrains Mono | 11px | 16px | 400 | Timestamps mono, IDs capteurs |

---

## 4. Grille et spacing

### Échelle de spacing (base 4px)

```
1 → 4px
2 → 8px
3 → 12px
4 → 16px
5 → 20px
6 → 24px
8 → 32px
10 → 40px
12 → 48px
16 → 64px
```

### Rayons (radii)

| Nom | Valeur | Usage |
|---|---|---|
| sm | 3px | Badges, tags compacts |
| md | 6px | Boutons, inputs, items de liste |
| lg | 10px | Cards, panels, popovers |
| xl | 14px | Modales, grandes cards |
| 2xl | 20px | Overlays importants |
| full | 9999px | StatusDot, pills |

### Ombres (dark shadows subtiles)

- **shadow-sm** : `0 1px 2px rgba(0, 0, 0, 0.4)` — boutons, inputs
- **shadow-md** : `0 4px 12px rgba(0, 0, 0, 0.5)` — cards, panels
- **shadow-lg** : `0 8px 24px rgba(0, 0, 0, 0.6)` — modales, popovers
- **glow-accent** : `0 0 12px rgba(61, 184, 232, 0.2)` — StatusDot actif, bouton primaire hover

### Borders

- Border par défaut : 1px solid `#1E2D3D`
- Border accentuée : 1px solid `#3DB8E840`
- Border focus : 1px solid `#3DB8E8`

---

## 5. Motion language

### Durées standard

| Nom | Valeur | Usage |
|---|---|---|
| fast | 150ms | Hover states, tooltips, StatusDot toggle |
| base | 250ms | Ouverture panels, changement d'onglet, badges |
| slow | 400ms | Entrée de page, modales, animations de graphes |

### Easings

- **out** (ease-out-expo) : `cubic-bezier(0.16, 1, 0.3, 1)` — sorties de panels, apparitions d'éléments, tout ce qui arrive dans la vue
- **inOut** (ease-in-out-cubic) : `cubic-bezier(0.65, 0, 0.35, 1)` — transitions de tabs, slider de valeurs
- **linear** : pour les tickers de valeurs numériques (CounterValue)

### Pattern stagger

Listes (projets, partenaires, capteurs) : chaque enfant entre avec un délai de 50ms depuis le précédent, `translateY(8px) → translateY(0)` + `opacity(0) → opacity(1)`, durée slow, easing out.

### Règles absolues

- Jamais de bounce (cubic-bezier avec valeurs > 1)
- Jamais d'animation > 500ms (sauf animation de fond dans le hero, lente et subtile)
- Pas de parallax
- Pas de particle
- Pas d'animation de rotation 3D sur les UI cards (réservé à la scène react-three-fiber)
- Les CounterValues animent leur chiffre en 800ms avec easing linear (ramp up puis plateau)
- La pulsation du StatusDot actif est une loop CSS `scale(1) → scale(1.4) → scale(1)` à 2s, opacity 0.6 → 0 (ring extérieur, pas le dot lui-même)

---

## 6. Composants visuels

### Button
Fond bg.elevated, border bg.border, text.secondary en état default. Hover : bg bg.subtle, text.primary, border accent.border. Actif : bg accent.subtle, text accent.DEFAULT. Disabled : tout en text.disabled, border text.disabled. Variante primary : bg accent.DEFAULT, texte #080C12 (sombre sur accent). Micro-animation : scale(0.97) au click, 80ms.

### Card
Fond bg.elevated, border 1px bg.border, radius lg, shadow-md. Hover optionnel : border accent.border, shadow + glow-accent léger. Pas d'animation d'entrée propre — la card elle-même est statique, c'est le stagger parent qui gère l'entrée. Usage : conteneur de tout bloc d'information.

### Badge
Fond subtle de la couleur statut (ex: status.success avec opacity 15%), border de la couleur statut, texte couleur statut, radius sm, padding 2px 6px, caption uppercase. Variante accent : accent.subtle + text accent.DEFAULT. Pas d'animation.

### Stat
Layout : label caption uppercase text.muted en haut, CounterValue mono-large text.primary au centre, delta en bas (badge success/danger selon direction). Fond transparent ou bg.elevated selon le contexte. Usage sur le dashboard hero et les cartes de projet.

### Panel
Fond bg.elevated, border bg.border, radius lg. Header avec H3 + action optionnelle à droite. Contenu en padding 4 (16px). Entrée : `translateX(16px) → 0` + opacity, 400ms ease-out, utilisé pour le panneau latéral détail capteur.

### Modal
Fond bg.overlay, border bg.border, radius xl, shadow-lg, max-w 640px centré. Backdrop : fond bg.base opacity 80%, blur 4px. Entrée : scale(0.96) → scale(1) + opacity, 250ms ease-out. Sortie : même inverse, 150ms ease-in.

### Tabs
Ligne horizontale de labels caption. Tab active : text.primary, border-bottom 2px accent.DEFAULT. Inactive : text.muted, hover text.secondary. Transition de l'indicateur underline : 150ms ease-in-out (glisse horizontalement). Pas de fond de tab, juste l'underline.

### Input
Fond bg.subtle, border bg.border, radius md, text primary, placeholder text.muted. Focus : border accent.DEFAULT, box-shadow 0 0 0 2px accent.subtle. Height 34px standard. Mono-small pour les inputs de valeurs numériques.

### Select
Même style que Input avec chevron text.muted à droite. Dropdown : fond bg.overlay, border bg.border, radius md, shadow-md. Chaque option : hover bg bg.subtle. Sélectionnée : text accent.DEFAULT + checkmark.

### Tooltip
Fond bg.overlay, border bg.border, radius md, shadow-lg, text body. Apparition après 300ms de hover, fade-in 150ms. Max-w 240px. Arrow 6px. Positionné au-dessus par défaut.

### StatusDot
Cercle 8px radius full. Couleur selon statut. Actif : ring extérieur animé en pulse (scale + opacity). Offline : couleur status.offline sans animation. Usage inline dans les tables et sidebar.

### CounterValue
Valeur numérique en mono-large. Animation sur montée/descente : interpolation du nombre sur 800ms avec easing linear, chiffre défile naturellement. Couleur héritée du contexte (text.primary par défaut, status.danger si alerte). Pas de flip/slot machine.

### LineChart
SVG, fond transparent, axes en text.muted 11px, lignes de grille en bg.border (trait horizontal uniquement). Courbe data.blue 2px strokeWidth, point actif en cercle 4px rempli. Zone sous la courbe en gradient data.blue opacity 0-12%. Tooltip au hover sur le point le plus proche. Animation de tracé à l'entrée : strokeDashoffset 100% → 0 en 600ms ease-out.

### BarChart
SVG, barres avec radius top 3px, couleur data.blue par défaut ou par série. Fond de bar bg.subtle (ghost bar pour référence). Hover : opacity 80% + tooltip. Animation d'entrée : height 0 → valeur, 400ms ease-out, stagger 30ms entre barres.

### Heatmap
Grille de cellules (temps × capteur ou temps × fréquence). Fond bg.elevated, cellules colorées de bg.subtle (valeur 0) à data.rose (valeur max). Radius 2px par cellule, gap 2px. Hover : bordure accent.border + tooltip valeur. Pas d'animation propre.

### SparkLine
SVG miniature (80×24px), fond transparent, pas d'axes. Ligne data.blue ou couleur statut selon contexte. Utilisé dans les cellules de tableau (liste projets). Statique (pas d'animation).

### RingMeter
SVG donut. Fond arc bg.border, arc de valeur en accent.DEFAULT ou status.*. Valeur centrale en mono-large. Radius selon usage (48px pour les stats dashboard, 32px pour les panels). Animation : arc rotate de 0 → valeur en 800ms ease-out-expo.

### SceneWrapper
Conteneur react-three-fiber avec fond bg.base, loader Structura (RingMeter + texte "Chargement scène…") pendant le suspend. Antialiasing activé, ombres désactivées (perf). Taille : remplir le parent via 100% width/height. OrbitControls avec damping. Pas de fog, pas de HDR, éclairage minimaliste (AmbientLight 0.6 + DirectionalLight 1.2).

---

## 7. Patterns récurrents

### Hero dashboard
Layout : topbar 52px + sidebar 220px fixe à gauche + contenu principal. Le hero du dashboard est un row de 3-4 Stat en haut, suivi d'une grille 2 colonnes : à gauche les derniers événements (liste staggered), à droite le SceneWrapper en preview 3D (hauteur 320px). Fond de page bg.base, pas de bannière gradient. L'animation d'entrée de la page staggere les blocs de haut en bas à 60ms.

### Cartes de projet (écran Projets)
Grille 3 colonnes, chaque Card contient : badge type (pont/bâtiment) + badge statut en header, nom du projet en H2, SparkLine de l'activité récente, row de 3 mini-stats (capteurs actifs, alertes, score intégrité). Stagger à l'entrée 50ms. Hover : glow-accent sur la border.

### Panneau capteur (détail 3D)
Sidebar droite 320px, fond bg.elevated, slide-in depuis la droite (translateX(320px) → 0, 400ms ease-out). Header : nom capteur en H2 + StatusDot. Sections : mesures en temps réel (mono-number avec ticker animé), historique (SparkLine), métadonnées (caption + texte). Fermeture par bouton X ou click outside.

### Tabs d'analyses
Les 4 types d'analyse (Amplitude, FFT, Anomalies, Timeline) sont des Tabs horizontales en haut du panneau. Le changement de tab remplace le contenu : fade out 150ms puis fade in 150ms du nouveau graphe. Chaque graphe occupe toute la largeur disponible, hauteur fixe 280px. Axes lisibles, grille subtile.

### Modale "Secure Deploy"
Modal xl centré, header "Déploiement sécurisé" + badge "Chiffré". Corps : sélecteur partenaire (Select) + résumé version (Card compact). Bouton "Lancer le déploiement" primary. Après click : le bouton devient désactivé, un log terminal apparaît en dessous (fond bg.base, text mono-small, lignes qui s'ajoutent avec stagger 80ms), enfin un badge success + message "Build déployé avec succès". Durée animation totale simulée : 3-4s.

---

## 8. Iconographie

Librairie : lucide-react (cohérent avec les autres apps Cortex).

| Contexte | Icône lucide | Variante |
|---|---|---|
| Pont (Bridge) | `Waypoints` | — |
| Bâtiment | `Building2` | — |
| Capteur | `Radio` | Ou `Signal` selon contexte |
| Capteur vibration | `Activity` | — |
| Alerte / anomalie | `TriangleAlert` | couleur status.warning ou danger |
| Capteur offline | `WifiOff` | — |
| Analyse / FFT | `BarChart3` | — |
| Amplitude / courbe | `LineChart` | (icône, pas composant) |
| Heatmap | `Grid3x3` | — |
| Timeline | `CalendarClock` | — |
| Déploiement | `Rocket` | — |
| Chiffrement / sécurité | `ShieldCheck` | — |
| Partenaire / accès | `Users` | — |
| Dashboard | `LayoutDashboard` | — |
| Projet | `FolderOpen` | — |
| Paramètres | `Settings2` | — |
| Statut OK | `CircleCheck` | couleur status.success |
| Statut danger | `CircleX` | couleur status.danger |
| Export / rapport | `FileDown` | — |
| Refresh / sync | `RefreshCw` | spinner animé lors du refresh |

Taille standard : 16px (inline dans texte/badges), 18px (icônes de navigation sidebar), 20px (actions primaires). StrokeWidth : 1.5 (toujours, pas le défaut 2 qui est trop lourd sur fond sombre).
