# 04 — Spécifications UI et composants ## 1. Design tokens (Tailwind CSS 4) Fichier source : `app/globals.css` (via `@import "tailwindcss"` + `@theme`). | Token | Valeur | Usage | | --- | --- | --- | | `--color-surface` | blanc (`#ffffff`) | feuille A4 | | `--color-paper` | `#f1f5f9` gris très clair | fond de l'application hors feuille | | `--color-ink` | `#0f172a` | texte principal | | `--color-muted` | `#64748b` | texte secondaire | | `--color-accent` | `#2563eb` | actions, focus, onglet actif | | `--color-danger` | `#dc2626` | boutons « × » suppression | | `--color-border` | `#e2e8f0` | bordures et séparateurs | | `--radius-*` | `0.5rem` (md), `0.375rem` (sm) | cohérence des angles | | `--font-sans` | système + `Inter` en fallback | lisibilité écran et impression | Typographie du CV (feuille A4) : | Élément | Suggestion | | --- | --- | | Nom / accroche (header) | `text-base font-semibold` à `text-xl font-bold` | | Titres de section | `text-[0.75rem] uppercase tracking-wide text-muted font-bold` | | Corps | `text-[0.8rem] leading-snug text-ink` | ### Palette neutre recommandée Le CV imprimé doit rester sobre : **encre sombre** sur blanc, onglet actif en accent, **aucun fond de couleur sur la feuille A4** (économie d'encre et lisibilité). ## 2. Barre d'application (`CvToolbar`) | Élément | Contenu | | --- | --- | | Gauche | Logo (icône `FileText`) + « CV-Maker » | | Droite | Bouton **Imprimer / PDF**, bouton **Importer JSON**, bouton **Exporter JSON**, bouton **Réinitialiser**, lien **Documentation** | Rendre les liens actifs en `font-semibold` et inactifs en `text-muted` (page courante) — navigation classique App Router (`usePathname`). ## 2bis. Pied de page (`Footer`) - **Masqué à l'impression** (`print-hidden`), bordure supérieure. - Contenu : nom de l'application + lien **Mentions légales** vers `/mentions-legales` (remplace l'ancien lien RGPD de la barre). ## 3. Panneau latéral gauche ### 3.1 `CvTabs` — onglets 1 à 5 - Basé sur la primitive `ui/Tabs` : `role="tablist"`, boutons `role="tab"`, `aria-selected`, `role="tabpanel"`. - Affichage : barre de 5 boutons horizontaux, libellé = `numéro + label` (`1 · Accroche`, `2 · État civil`, …). - Onglet actif : fond `accent`, texte blanc ; inactifs : bordure `border` + texte `muted`. - **Contenu piloté par le parent** (`activeTab` dans `CvInputPanel`) : un seul `MarkdownTextarea` monté pour l'onglet actif. Le texte de l'onglet actif est le `value` contrôlé. ### 3.2 `MarkdownTextarea` | Élément | Spécification | | --- | --- | | Props | `label: string`, `value: string`, `onChange(text: string): void`, `placeholder?: string` | | Comportement | `textarea` contrôlé, `onChange` → mise à jour immédiate de l'état + persistance | | UX | `min-h` variable (accroche + courte), `resize-y`, monospace en saisie (`font-mono`) avec bascule visuelle explicite « le texte est en Markdown » | | Note Markdown | petite légende « Syntaxe Markdown supportée » avec lien vers `/documentation` | ### 3.3 `ExperienceManager` Composition : - **En-tête** : titre « Expériences » + bouton **+** (`ui/Button`, variante `primary`) → prépare une nouvelle expérience (zones titre/contenu vidées, focus du formulaire). - **Formulaire** : deux champs — `titre` (input texte) + `contenu` (textarea Markdown, même composant que les zones 1-5). Boutons : **Enregistrer** et **Annuler** (annulation quand modification). - **Liste numérotée** : sous le formulaire. États internes suivants : ```ts type ExperienceEditor = | { mode: "closed" } // rien en édition | { mode: "new" } // ajout en cours | { mode: "edit"; id: Experience["id"] }; // modification en cours ``` ### 3.4 Ligne d'expérience (`ExperienceItem`) Format visuel : `1. Titre de l'expérience [Modifier] [×]` | Action | Clé | Comportement | | --- | --- | --- | | Modifier | bouton icône `Pencil` + libellé | passe en mode `edit`, recharge titre/contenu dans le formulaire | | Supprimer | bouton `×` (`IconButton`, variante danger) | **confirmation** (petit état interne « Confirmer la suppression ? [Oui/Non] » ou `window.confirm`) puis `removeExperience(id)` | > Composants `ui/Button`, `ui/IconButton`, `ui/Textarea`, `ui/Tabs` sont les primitives réutilisables (cf. le volet « composants réutilisables » du cahier des charges). ## 4. Panneau latéral droit — feuille A4 (`CvPreview`) ### 4.1 Conteneur de feuille ```tsx