Cascade @layer (tf-tokens/tf-reset) + HANDOFF P1 : audit Puppeteer 360/768/1280 clair-sombre-reduced-motion OK

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 18:34:02 +02:00
parent 795ca7ed4e
commit d4873c7e0b

83
HANDOFF.md Normal file
View File

@@ -0,0 +1,83 @@
# 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 `<link>` 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 → `theme/tmip.css` est un placeholder commenté. À remplir en P2 (procédure PROTOCOLE §5).
## 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.