chore: initial DSMMG v0.2 — refonte architecturale complète
Mise en place du Design System ManageMate Group v0.2 — refonte du
système de tokens (préfixe --mmg-color-*), 9 presets accent
user-themable validés WCAG AA, overlays Radix UI + Floating UI,
Storybook 8 + Vitest + axe-core en CI, doc Astro Starlight,
DESIGN.md (format google-labs-code) et exports tokens DTCG/CSS/
TS/Figma/Tailwind v3 et v4.
- 4 packages monorepo pnpm : @managemate/{tokens,css,react,icons}
- 62 composants React headless-first (Sheet, HoverCard, ContextMenu,
Slider, ToggleGroup, AvatarGroup, UserCard, ProfileHeader,
MetricCard, PricingCard, FeatureCard, Text/Display/Eyebrow/Lead…)
- Lint contraste WCAG : 37/37 paires AA, branché CI
- Toast pile Sonner-style avec ResizeObserver
- Theming user (9 presets) sans casser sémantique fixe
- Identité Synapse (rose #D12B6A) préservée
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,468 @@
|
||||
---
|
||||
version: "0.2"
|
||||
name: DSMMG
|
||||
description: >
|
||||
Design System ManageMate Group — référence pour Synapse, HRTime, Forge,
|
||||
Orbit, MSLM, Espace-Client et sites publics. Headless-first sur Radix UI,
|
||||
RGAA 4.1 / WCAG 2.2 AA, theming utilisateur via 9 presets accent.
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# COULEURS — primitives → semantic → accent (user-themable)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
colors:
|
||||
# — Neutrals (warm-cool mix : frais en light, neutre en dark) ——————
|
||||
neutral-0: "#FFFFFF"
|
||||
neutral-50: "#F7F6FB"
|
||||
neutral-100: "#F0EFF9"
|
||||
neutral-150: "#EDEDFA"
|
||||
neutral-200: "#E4E3F4"
|
||||
neutral-300: "#C9C7E0"
|
||||
neutral-400: "#AAA8C9"
|
||||
neutral-500: "#7875A1"
|
||||
neutral-600: "#56557A"
|
||||
neutral-700: "#3B3A56"
|
||||
neutral-800: "#1F1E32"
|
||||
neutral-900: "#111120"
|
||||
|
||||
# — Synapse (rose corporate ManageMate, défaut accent) ——————
|
||||
synapse-50: "#FEF0F4"
|
||||
synapse-100: "#FCE0EA"
|
||||
synapse-200: "#FAD0DF"
|
||||
synapse-300: "#F4A0BD"
|
||||
synapse-400: "#ED608E"
|
||||
synapse-500: "#D12B6A" # ★ marque ManageMate
|
||||
synapse-600: "#BA245F"
|
||||
synapse-700: "#A82257"
|
||||
synapse-800: "#831B45"
|
||||
synapse-900: "#5A132F"
|
||||
|
||||
# — Presets accent user (8 alternatives au synapse) ——————
|
||||
rose-500: "#E11D48"
|
||||
blue-500: "#2563EB"
|
||||
violet-500: "#7C3AED"
|
||||
green-500: "#0E9F6E"
|
||||
amber-500: "#D97706"
|
||||
red-500: "#DC2626"
|
||||
cyan-500: "#0891B2"
|
||||
slate-500: "#475569"
|
||||
|
||||
# — Sémantique fixe (NE CHANGE JAMAIS avec l'accent user) ——————
|
||||
success: "#059669"
|
||||
warning: "#D97706"
|
||||
danger: "#DC2626"
|
||||
info: "#2563EB"
|
||||
|
||||
# — Active accent (alias dynamique, par défaut synapse) ——————
|
||||
primary: "{colors.synapse-500}"
|
||||
secondary: "{colors.neutral-600}"
|
||||
tertiary: "{colors.neutral-300}"
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# TYPOGRAPHIE — Figtree partout, 3 échelles selon contexte
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
typography:
|
||||
# — Display (landings produits — HRTime, Synapse, Forge, Orbit) ——
|
||||
display-2xl:
|
||||
fontFamily: Figtree
|
||||
fontSize: 72px
|
||||
fontWeight: 800
|
||||
letterSpacing: "-0.035em"
|
||||
lineHeight: 1.0
|
||||
display-xl:
|
||||
fontFamily: Figtree
|
||||
fontSize: 60px
|
||||
fontWeight: 800
|
||||
letterSpacing: "-0.03em"
|
||||
lineHeight: 1.05
|
||||
display-lg:
|
||||
fontFamily: Figtree
|
||||
fontSize: 48px
|
||||
fontWeight: 700
|
||||
letterSpacing: "-0.025em"
|
||||
lineHeight: 1.1
|
||||
display-md:
|
||||
fontFamily: Figtree
|
||||
fontSize: 36px
|
||||
fontWeight: 700
|
||||
letterSpacing: "-0.02em"
|
||||
lineHeight: 1.15
|
||||
|
||||
# — Headlines (apps métier — h1 → h6 sémantiques) ————————
|
||||
h1:
|
||||
fontFamily: Figtree
|
||||
fontSize: 36px
|
||||
fontWeight: 700
|
||||
letterSpacing: "-0.02em"
|
||||
lineHeight: 1.2
|
||||
h2:
|
||||
fontFamily: Figtree
|
||||
fontSize: 30px
|
||||
fontWeight: 700
|
||||
letterSpacing: "-0.015em"
|
||||
lineHeight: 1.25
|
||||
h3:
|
||||
fontFamily: Figtree
|
||||
fontSize: 24px
|
||||
fontWeight: 700
|
||||
letterSpacing: "-0.01em"
|
||||
lineHeight: 1.3
|
||||
h4:
|
||||
fontFamily: Figtree
|
||||
fontSize: 20px
|
||||
fontWeight: 600
|
||||
letterSpacing: "-0.005em"
|
||||
lineHeight: 1.35
|
||||
h5:
|
||||
fontFamily: Figtree
|
||||
fontSize: 17px
|
||||
fontWeight: 600
|
||||
lineHeight: 1.4
|
||||
h6:
|
||||
fontFamily: Figtree
|
||||
fontSize: 15px
|
||||
fontWeight: 600
|
||||
lineHeight: 1.45
|
||||
|
||||
# — Body ————————————————————————————————————————
|
||||
body-lg:
|
||||
fontFamily: Figtree
|
||||
fontSize: 17px
|
||||
lineHeight: 1.6
|
||||
body:
|
||||
fontFamily: Figtree
|
||||
fontSize: 15px
|
||||
lineHeight: 1.55
|
||||
body-sm:
|
||||
fontFamily: Figtree
|
||||
fontSize: 13px
|
||||
lineHeight: 1.5
|
||||
body-xs:
|
||||
fontFamily: Figtree
|
||||
fontSize: 11px
|
||||
lineHeight: 1.45
|
||||
|
||||
# — Auxiliaires ————————————————————————————————
|
||||
eyebrow:
|
||||
fontFamily: Figtree
|
||||
fontSize: 13px
|
||||
fontWeight: 600
|
||||
letterSpacing: "0.06em"
|
||||
textTransform: uppercase
|
||||
lead:
|
||||
fontFamily: Figtree
|
||||
fontSize: 20px
|
||||
fontWeight: 400
|
||||
letterSpacing: "-0.005em"
|
||||
lineHeight: 1.5
|
||||
overline:
|
||||
fontFamily: Figtree
|
||||
fontSize: 11px
|
||||
fontWeight: 600
|
||||
letterSpacing: "0.08em"
|
||||
textTransform: uppercase
|
||||
caption:
|
||||
fontFamily: Figtree
|
||||
fontSize: 11px
|
||||
lineHeight: 1.4
|
||||
code:
|
||||
fontFamily: "JetBrains Mono"
|
||||
fontSize: 13px
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# RAYONS — pill par défaut sur interactifs et conteneurs
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
rounded:
|
||||
none: 0
|
||||
sm: 8px
|
||||
md: 12px
|
||||
card: 20px
|
||||
panel: 24px
|
||||
icon: 12px
|
||||
pill: 9999px
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# ESPACEMENT — grille 4pt (multiples de 4 ou 8 exclusivement)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
spacing:
|
||||
"0": 0
|
||||
"1": 4px
|
||||
"2": 8px
|
||||
"3": 12px
|
||||
"4": 16px
|
||||
"5": 20px
|
||||
"6": 24px
|
||||
"7": 32px
|
||||
"8": 40px
|
||||
"9": 48px
|
||||
"10": 64px
|
||||
"11": 80px
|
||||
"12": 120px
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# MOTION — animation = feedback fonctionnel, jamais décoratif
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
motion:
|
||||
duration:
|
||||
fast: 120ms # micro-interactions (hover, focus)
|
||||
base: 200ms # transitions UI standard
|
||||
slow: 320ms # navigation (modals, drawers)
|
||||
easing:
|
||||
default: "cubic-bezier(0.4, 0, 0.2, 1)" # matériel, doux
|
||||
emphasis: "cubic-bezier(0.2, 0.8, 0.2, 1)" # rebond léger
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# DENSITÉ — 3 modes adaptables par préférence user
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
density:
|
||||
comfortable:
|
||||
rowHeight: 44px
|
||||
inputHeight: 40px
|
||||
paddingX: 16px
|
||||
paddingY: 12px
|
||||
cozy:
|
||||
rowHeight: 36px
|
||||
inputHeight: 36px
|
||||
paddingX: 12px
|
||||
paddingY: 8px
|
||||
compact:
|
||||
rowHeight: 28px
|
||||
inputHeight: 30px
|
||||
paddingX: 8px
|
||||
paddingY: 4px
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# COMPOSANTS — extraits clé. Liste exhaustive : @managemate/react
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
components:
|
||||
button-primary:
|
||||
backgroundColor: "{colors.primary}"
|
||||
textColor: "{colors.neutral-0}"
|
||||
typography: "{typography.body-sm}"
|
||||
fontWeight: 600
|
||||
rounded: "{rounded.pill}"
|
||||
padding: "10px 22px"
|
||||
minHeight: 40px
|
||||
|
||||
button-tonal:
|
||||
backgroundColor: "{colors.synapse-50}"
|
||||
textColor: "{colors.synapse-800}"
|
||||
typography: "{typography.body-sm}"
|
||||
fontWeight: 600
|
||||
rounded: "{rounded.pill}"
|
||||
padding: "10px 22px"
|
||||
|
||||
button-ghost:
|
||||
backgroundColor: transparent
|
||||
textColor: "{colors.neutral-700}"
|
||||
typography: "{typography.body-sm}"
|
||||
fontWeight: 600
|
||||
|
||||
card:
|
||||
backgroundColor: "{colors.neutral-0}"
|
||||
rounded: "{rounded.card}"
|
||||
padding: "{spacing.6}"
|
||||
borderColor: "{colors.neutral-200}"
|
||||
|
||||
input:
|
||||
backgroundColor: "{colors.neutral-0}"
|
||||
textColor: "{colors.neutral-900}"
|
||||
borderColor: "{colors.neutral-200}"
|
||||
rounded: "{rounded.md}"
|
||||
padding: "10px 14px"
|
||||
minHeight: 40px
|
||||
|
||||
badge:
|
||||
backgroundColor: "{colors.neutral-150}"
|
||||
textColor: "{colors.neutral-700}"
|
||||
typography: "{typography.body-xs}"
|
||||
fontWeight: 600
|
||||
rounded: 6px
|
||||
padding: "2px 8px"
|
||||
|
||||
toast:
|
||||
backgroundColor: "{colors.neutral-0}"
|
||||
borderColor: "{colors.neutral-200}"
|
||||
rounded: 14px
|
||||
padding: "14px 14px 14px 16px"
|
||||
|
||||
tile:
|
||||
backgroundColor: "{colors.neutral-0}"
|
||||
borderColor: "{colors.neutral-200}"
|
||||
rounded: "{rounded.card}"
|
||||
padding: "{spacing.6}"
|
||||
---
|
||||
|
||||
# DSMMG — Design System ManageMate Group
|
||||
|
||||
> **Version 0.2** · La source de vérité visuelle, comportementale et accessible pour les produits ManageMate (Synapse, HRTime, Forge, Orbit, MSLM, Espace-Client, sites publics).
|
||||
|
||||
## Overview
|
||||
|
||||
Le DSMMG est un design system **headless-first** construit sur Radix UI. Trois mots :
|
||||
|
||||
- **Cohérence** — un bouton dans n'importe quel produit ManageMate a la même structure et la même couleur de base. La différenciation se fait par contenu, pas par couleur.
|
||||
- **Accessibilité** — RGAA 4.1 / WCAG 2.2 AA non-négociable. Validé `axe-core` en CI. Plusieurs clients (collectivités, opérateurs publics) sont soumis au RGAA par la loi.
|
||||
- **Theming utilisateur** — 9 presets accent (rose Synapse par défaut), chaque utilisateur choisit dans ses préférences. La sémantique (success/danger/warning/info) reste fixe.
|
||||
|
||||
## Colors
|
||||
|
||||
Trois couches verticales :
|
||||
|
||||
```
|
||||
primitives → semantic → accent (user-themable)
|
||||
```
|
||||
|
||||
1. **Primitives** — rampes brutes (`neutral-0..900`, `synapse-50..900`, et 8 presets). Ne JAMAIS référencer directement dans les composants.
|
||||
2. **Sémantiques** — `bg-page`, `text-primary`, `border`, `success/warning/danger/info`. **Stables, ne changent pas avec l'accent user.**
|
||||
3. **Accent** — `--mmg-color-accent-*`. Posé par `[data-mmg-accent="<preset>"]` sur `<html>`. SEUL token couleur user-themable.
|
||||
|
||||
### Presets accent disponibles
|
||||
|
||||
`synapse` (défaut), `rose`, `blue`, `violet`, `green`, `amber`, `red`, `cyan`, `slate`.
|
||||
|
||||
Chaque preset a sa version dark adaptée (saturation -2pts, luminosité +3pts) pour confort visuel.
|
||||
|
||||
### Règle absolue
|
||||
|
||||
- ❌ **Aucun hex en dur dans les composants.**
|
||||
- ❌ **Jamais de `--mmg-color-synapse-*` direct** dans un composant — toujours via `--mmg-color-accent-*`.
|
||||
|
||||
## Typography
|
||||
|
||||
**Figtree** partout (Google Fonts, sans-serif géométrique). 3 échelles selon contexte :
|
||||
|
||||
| Famille | Cas d'usage | Tailles |
|
||||
|---|---|---|
|
||||
| **Display** | Hero des landings produits (HRTime, Synapse…) | 36px → 72px |
|
||||
| **Headlines** | Apps métier (h1-h6 sémantiques) | 15px → 36px |
|
||||
| **Body** | Texte courant et UI | 11px → 17px |
|
||||
| **Auxiliaires** | eyebrow, lead, overline, caption | 11px → 20px |
|
||||
|
||||
**Modificateurs** : `mono`, `tabular`, `balance` (titres), `pretty` (body), `italic`, `emphasis` (italique + accent), `highlight`, `underline`, `strike`, `gradient`, `rainbow`.
|
||||
|
||||
> **Choisir le tag (`as`) selon la SÉMANTIQUE, pas selon la taille.** Un titre de page reste `<h1>` même si visuellement il s'affiche en `display-xl`.
|
||||
|
||||
## Layout & Spacing
|
||||
|
||||
Grille **4 points** stricte. Multiples de 4 ou 8 uniquement. Aucune valeur intermédiaire (10, 14, 22) qui casse l'alignement vertical.
|
||||
|
||||
12 niveaux : `0` (0) → `12` (120px).
|
||||
|
||||
**Densité** adaptable par utilisateur via `[data-mmg-density="comfortable|cozy|compact"]`. Touch target minimum **44×44** quel que soit le mode (WCAG SC 2.5.5).
|
||||
|
||||
## Elevation & Depth
|
||||
|
||||
Light mode :
|
||||
- `shadow-1` — 0 1px 4px ink + 1px ring
|
||||
- `shadow-2` — 0 4px 16px ink + 1px ring
|
||||
- `shadow-3` — 0 12px 32px ink (modals, dropdowns)
|
||||
- `shadow-elevated` — neutre, pour boutons elevated
|
||||
|
||||
Dark mode :
|
||||
- Ombres = noir + halo blanc subtil 4-6 % (jamais "noir s'évapore")
|
||||
- backdrop-filter blur 12-14px sur overlays/popovers/toasts pour effet verre dépoli
|
||||
|
||||
Ombres teintées accent via `color-mix(in srgb, var(--mmg-color-accent) X%, transparent)` — s'adaptent automatiquement au preset user.
|
||||
|
||||
## Shapes
|
||||
|
||||
Pill par défaut sur **interactifs** (buttons, inputs, badges-pills) et **conteneurs principaux** (Tile, Card, Hero).
|
||||
|
||||
| Token | Valeur | Usage |
|
||||
|---|---|---|
|
||||
| `rounded-sm` | 8px | inputs, badges-discrets |
|
||||
| `rounded-md` | 12px | cards compact, popover, menu |
|
||||
| `rounded-card` | 20px | cards principales, tiles |
|
||||
| `rounded-panel` | 24px | modals, sheets |
|
||||
| `rounded-pill` | 9999px | boutons, badges-pills |
|
||||
|
||||
## Motion
|
||||
|
||||
Animation = **feedback fonctionnel**, jamais décoratif. Trois durées :
|
||||
|
||||
- 120ms — micro-interactions (hover, focus, ripple)
|
||||
- 200ms — transitions UI standard
|
||||
- 320ms — navigation (modals, drawers, sheets)
|
||||
|
||||
`prefers-reduced-motion: reduce` désactive tout (durée 0.001ms). WCAG SC 2.3.3 AAA.
|
||||
|
||||
## Components
|
||||
|
||||
Catalogue complet (~62 composants) dans `@managemate/react`. Les principaux :
|
||||
|
||||
**Forms** : Button, Input, Textarea, Select, Combobox, Checkbox, Radio, Switch, Slider, ToggleGroup, FileUpload.
|
||||
|
||||
**Layout** : Container, Section, Stack, Inline, Card, Tile, Hero.
|
||||
|
||||
**Feedback** : Alert, Notice, Banner, Badge (avec dot indicator + pulse), Spinner, Skeleton, Toast (pile Sonner-style empilable).
|
||||
|
||||
**Overlays** : Tooltip, Popover, Menu, Dialog, ConfirmDialog, Sheet (4 sides × 5 sizes), Drawer, HoverCard, ContextMenu — **tous Radix-backed**.
|
||||
|
||||
**Navigation** : Header (mega-menu DSFR-style), Footer, Breadcrumb, Tabs, Pagination, AppShell, Sidebar, Topbar, SkipLink.
|
||||
|
||||
**Profile & Cards** : Avatar (status indicator + auto-color), AvatarGroup, UserCard, ProfileHeader (cover + débord), MetricCard (KPI avec trend), PricingCard, FeatureCard, Stat.
|
||||
|
||||
**Article** : ArticlePage, ArticleHeader, ArticleAside, ArticleFooter, ArticleCallout, ArticleTOC.
|
||||
|
||||
**Theming** : ThemePicker (radiogroup avec navigation flèches/Home/End).
|
||||
|
||||
## Do's and Don'ts
|
||||
|
||||
### ✅ Do
|
||||
|
||||
- Utiliser les **tokens sémantiques** (`--mmg-color-text-primary`, `--mmg-color-bg-surface`).
|
||||
- Choisir le tag HTML selon **la sémantique**, pas selon la taille visuelle.
|
||||
- Tester en clavier : Tab, Shift+Tab, Esc, flèches, Enter, Espace.
|
||||
- Tester en zoom 200 % et reflow 320px.
|
||||
- Tester avec `prefers-reduced-motion: reduce` activé.
|
||||
- Préférer les composants Radix-backed (Tooltip, Menu, Dialog…) aux implémentations custom.
|
||||
- Documenter le composant dans Storybook + MDX avant de le livrer.
|
||||
|
||||
### ❌ Don't
|
||||
|
||||
- **Aucun hex en dur** dans les composants.
|
||||
- **Aucune référence directe** à `--mmg-color-synapse-*` — toujours via `--mmg-color-accent-*`.
|
||||
- **Pas de couleur seule** porteuse d'info (RGAA 9). Toujours redonder avec icône, texte ou pattern.
|
||||
- **Pas de placeholder** en remplacement de label (RGAA 11.1).
|
||||
- **Pas de focus invisible** ni `outline: none` sans alternative.
|
||||
- **Pas de `<div onClick>`** au lieu de `<button>`.
|
||||
- **Pas d'animation** sans `prefers-reduced-motion`.
|
||||
- **Pas de composant** sans navigation clavier complète.
|
||||
- **Pas de composant** sans test axe-core.
|
||||
- **Pas de fichier** monolithique > 300 lignes mélangeant N composants.
|
||||
|
||||
## Accessibilité (engagement)
|
||||
|
||||
- **RGAA 4.1 / WCAG 2.2 AA ≥ 95 %**, validé `axe-core` en CI.
|
||||
- **Sanctions légales** : jusqu'à 50 000 € par service en ligne non conforme (loi 2005-102 + décret 2019-768).
|
||||
- **Couverture handicaps** : visuels (cécité, malvoyance, daltonisme 8 % des hommes), auditifs, moteurs (paralysie, tremblements, bras cassé), cognitifs (dyslexie, TDAH, autisme, fatigue, langue non maternelle), temporaires/situationnels (soleil, mauvaise connexion, vieux device).
|
||||
|
||||
### Tests automatisés
|
||||
|
||||
- `axe-core` 4.10 (vitest-axe) — chaque composant interactif.
|
||||
- Couverture : `wcag2a + wcag2aa + wcag21a + wcag21aa + best-practice`.
|
||||
- Threshold CI : 60 % ligne / branche / function / statement (à monter à 80 % v0.3).
|
||||
|
||||
### Tests manuels recommandés
|
||||
|
||||
- NVDA (Windows), VoiceOver (macOS/iOS).
|
||||
- Clavier 100 % (souris débranchée).
|
||||
- Zoom 200 % + reflow 320px.
|
||||
- `prefers-reduced-motion`, `prefers-contrast: more`, `forced-colors: active`.
|
||||
|
||||
## Distribution
|
||||
|
||||
Monorepo pnpm avec 4 packages :
|
||||
|
||||
| Package | Rôle |
|
||||
|---|---|
|
||||
| `@managemate/tokens` | Source DTCG W3C des tokens. Génère CSS, JS/TS, Figma, Tailwind v3, Tailwind v4. |
|
||||
| `@managemate/css` | CSS vanilla — tokens, base, composants, utilitaires `@layer`. |
|
||||
| `@managemate/icons` | 96 icônes (line + fill) Remix Icon, subset par icône possible. |
|
||||
| `@managemate/react` | Composants React typés, headless-first sur Radix UI, tree-shakable (`sideEffects: false`). |
|
||||
|
||||
Versioning : SemVer strict. Packages **fixed** (même version) pour éviter les incompatibilités cross-package. Changesets sur `main` → release auto.
|
||||
|
||||
---
|
||||
|
||||
> Ce fichier est lisible par des agents IA via le format [google-labs-code/design.md](https://github.com/google-labs-code/design.md). Front matter YAML = tokens normatifs, corps Markdown = contexte d'application.
|
||||
Reference in New Issue
Block a user