# HANDOFF — P1 fondation → P2 (TMIP) / P3 (racine) État au 2026-07-19. Repo : `git.trans-former.fr/jules/design-system`, branche `main`. Local : `~/dev/design-system` (Linux). ## 1. Le contrat — ce que P2/P3 consomment ### Tokens (schéma complet, `tokens.css`, layer `tf-tokens`) - **Couleur (rôles)** : `--bg` `--bg-alt` `--surface` `--surface-2` `--text` `--text-muted` `--text-subtle` `--border` `--border-strong` `--primary` `--primary-hover` `--on-primary` `--accent` `--on-accent` `--link` `--link-hover` `--focus-ring` `--success` `--warning` `--danger` - **Typo** : `--font-heading` `--font-body` `--font-mono` · tailles fluides `--fs-xs|sm|base|lg|xl|2xl|3xl|4xl` (clamp 360→1280) · `--lh-tight|base|loose` · `--fw-regular|medium|semibold|bold` - **Spacing** : `--space-2xs|xs|sm|md|lg|xl|2xl|3xl` (4/8px, fluide sur 2xl/3xl) - **Rayons** : `--radius-sm|md|lg|full` · **Ombres** : `--shadow-sm|md|lg` - **Layout** : `--container-max` (75rem) `--container-pad` (fluide 16→32) - **Z-index** : `--z-nav|overlay|modal|toast` (100/200/300/400) - **Motion** : `--dur-fast|base|slow` (150/250/400ms) · `--ease-out|in-out|spring` - **Breakpoints** (constantes, PAS des variables) : 360 base · 480 sm · 768 md · 1024 lg · 1280 xl — media queries en rem, `min-width` only. Mode sombre : préférence système + `data-theme` explicite qui gagne dans les deux sens. Helper `window.tfSetTheme('light'|'dark'|'auto')` fourni par BaseLayout. ### API des primitives (props → détail en tête de chaque fichier) | Primitive | Props | Slots | |-----------|-------|-------| | `BaseLayout.astro` | `title`* · `description` · `lang`('fr') · `ogImage` · `canonical` | default, header, footer, head | | `Nav.astro` | `links: {href,label}[]`* · `label` | brand, actions | | `Footer.astro` | — | default, legal | | `Button.astro` | `variant: primary\|secondary\|ghost\|link` · `size: sm\|md\|lg` · `href` · `type` · `disabled` · `class` + attrs passthrough | default | | `Card.astro` | `href` (carte cliquable + hover élévation) · `class` | media, default | | `Prose.astro` | `class` | default (HTML long) | | `Section.astro` | `alt` (fond alterné) · `size: base\|lg` · `id` · `class` | default | | `Container.astro` | `size: base\|narrow` · `class` | default | | `Reveal.astro` | `delay` (ms) · `class` | default | Utilitaire nu : `js/reveal.js` → `initReveal(selector?)`. ### Consommation (rappel pour P2) ```jsonc // package.json du site "dependencies": { "@transformer/ui": "git+https://git.trans-former.fr/jules/design-system.git" } ``` ```astro --- import BaseLayout from "@transformer/ui/BaseLayout.astro"; import "@transformer/ui/theme/tmip.css"; // ← le seul import qui change par site --- ``` Fallback submodule + variante Tailwind 4 (racine) : voir `README.md`. Pont Tailwind : `tailwind.css` (`@theme inline`) — namespaces en collision non mappés, syntaxe `rounded-(--radius-md)` etc. (PROTOCOLE §4). ## 2. Déviations vs brief + blockers - **Chemin local** : brief dit `C:\dev\` (Windows) ; la machine est Linux → repo dans `~/dev/design-system` (même logique hors-Dropbox, remote Gitea identique). - **Ajout `@layer`** (pas dans le brief) : Astro inline le CSS des thèmes AVANT le `` du bundle tokens → l'ordre d'import ne suffisait pas. `tokens.css`→`@layer tf-tokens`, `reset.css`→`@layer tf-reset`, thèmes non-layerés → la cascade est correcte quel que soit l'ordre de bundling. Règle : ne jamais layerer un thème. - **Ajout `tailwind.css`** (maj ligne 18 du brief) : pont `@theme inline` pour la racine. - **Blockquote sans border-left** (loi Impeccable « border-left accent » prise au sens strict) : fond `--surface-2` + radius à la place. - **Polices non embarquées** : les thèmes ne définissent que les stacks ; chaque site charge ses `@font-face` (la démo affiche donc les fallbacks système, pas Poppins/Open Sans). - ~~**BLOCKER P2** : palette TMIP inconnue~~ → **levé le 2026-07-20** : `theme/tmip.css` rempli depuis la palette réelle (P2), page démo `/demo/tmip` ajoutée. Et `reveal.js` corrigé (threshold 0 — les sections plus hautes que le viewport ne se révélaient jamais). ## 3. Reste à faire pour P2 (migration TMIP) 1. Confirmer la palette TMIP (clair + sombre) + couple de polices → remplir `theme/tmip.css`, ajouter `src/pages/demo/tmip.astro` (4 lignes), valider le kitchen sink. 2. Dans le repo TMIP : ajouter la dépendance `@transformer/ui`, remplacer le layout maison par `BaseLayout` + `Nav` + `Footer`, importer `theme/tmip.css`. 3. Dégraisser le `global.css` de TMIP : supprimer tout ce que tokens/reset/primitives couvrent ; le CSS restant = spécifique métier uniquement, zéro valeur en dur qui duplique un token. 4. Passer la Definition-of-Done (PROTOCOLE §7) : 360/768/1280, clair/sombre, reduced-motion, sans JS, clavier. 5. Tagger `v0.1.0` ici et épingler le tag côté TMIP si on veut du reproductible. ## 4. Auto-audit — lois Impeccable + mobile-first **Vérifié (build + Puppeteer sur le build de prod)** : - 3 pages démo × 3 viewports (360/768/1280) × clair/sombre = 18 combinaisons, **zéro overflow-x**. - Hamburger : `aria-expanded` OK, Échap referme, focus revient au bouton, focus trap actif panneau ouvert. - `prefers-reduced-motion: reduce` → reveals visibles d'office, kill-switch global dans le reset (`!important` layeré, imbattable). - Sans JS → liens de nav visibles, rien de masqué (garde `html[data-js]`). - Lois design : aucun border-left accent, aucun gradient text, pas de glassmorphisme, pas de hero-metric, pas de modal, pas d'auto-play. Ombres discrètes uniquement. - Cibles tactiles : boutons/liens nav ≥ 44px ; `sm` remonte à 44px sur `pointer: coarse`. **Fragile / à surveiller** : - **Contrastes AA vérifiés à l'œil et par calcul ponctuel, pas outillés** : passer un audit Lighthouse/axe sur la démo au prochain cycle (surtout `--text-subtle` sur `--bg-alt` et le jaune `--accent` renovation, utilisable seulement avec `--on-accent` dessus). - Le pont Tailwind n'a **pas été testé contre un vrai build Tailwind 4** (aucun site Tailwind dans ce repo) → à valider en P3 sur `astro-site-cerveau`. - `npm install git+https://…` non testé depuis un site consommateur réel (testé uniquement en local) → premier point à vérifier en P2 ; le fallback submodule est documenté si souci. - La condensation de nav est discrète (padding) ; si un site veut un vrai shrink (logo qui réduit), l'étendre ICI, pas dans le site.