diff --git a/.planning/phases/05-nuxt-content-setup-renderer/05-UI-SPEC.md b/.planning/phases/05-nuxt-content-setup-renderer/05-UI-SPEC.md new file mode 100644 index 0000000..95678c3 --- /dev/null +++ b/.planning/phases/05-nuxt-content-setup-renderer/05-UI-SPEC.md @@ -0,0 +1,192 @@ +--- +phase: 5 +slug: nuxt-content-setup-renderer +status: draft +shadcn_initialized: false +preset: none +created: 2026-04-21 +--- + +# Phase 5 — UI Design Contract +## @nuxt/content Setup & Renderer + +> Contrat visuel et d'interaction pour la phase d'infrastructure de rendu markdown. +> Généré par gsd-ui-researcher — à valider par gsd-ui-checker. + +--- + +## Design System + +| Property | Value | Source | +|----------|-------|--------| +| Tool | Nuxt UI v3 | CONTEXT.md / nuxt.config.ts | +| Preset | not applicable (Nuxt UI, pas shadcn) | nuxt.config.ts | +| Component library | Nuxt UI v3 (@nuxt/ui) | nuxt.config.ts modules | +| Icon library | Heroicons via Nuxt UI (i-heroicons-*) | RESEARCH.md Pattern 5 | +| Font | Hérité du site (pas de font custom déclarée dans main.css) | app/assets/css/main.css | +| Tailwind | v4 avec @theme tokens brand-* | app/assets/css/main.css | + +> Note : pas de shadcn dans ce projet — stack Nuxt UI v3 + Tailwind v4. La shadcn gate ne s'applique pas. + +--- + +## Spacing Scale + +Échelle 8-points standard (multiples de 4). Tailwind v4 gère ces valeurs via ses classes utilitaires. + +| Token | Value | Usage dans cette phase | +|-------|-------|------------------------| +| xs | 4px | Gap icône/texte dans les callouts Alert | +| sm | 8px | Padding interne compact (inline code, badges tags) | +| md | 16px | Padding article, espacement entre blocs prose | +| lg | 24px | Marge verticale entre sections de l'article | +| xl | 32px | Padding extérieur du wrapper `
` | +| 2xl | 48px | — (réservé Phase 6 pour les pages) | +| 3xl | 64px | — (réservé Phase 6 pour les pages) | + +Exceptions : +- `my-4` (16px) sur les composants `Alert.vue` — conforme à l'échelle, source : RESEARCH.md Pattern 5 +- Images prose : `rounded-lg w-full` sans contrainte de hauteur fixe — taille naturelle de l'image + +--- + +## Typography + +La typographie du corps de l'article est entièrement gérée par `@tailwindcss/typography` via la classe `prose`. +Les valeurs ci-dessous reflètent les valeurs par défaut du plugin, conformes aux décisions D-01. + +| Role | Size | Weight | Line Height | Usage | +|------|------|--------|-------------|-------| +| Body prose | 16px (1rem) | 400 (regular) | 1.75 | Corps du texte dans `
` | +| Label / caption | 14px (0.875rem) | 400 (regular) | 1.5 | Tags frontmatter, métadonnées date | +| Heading article (h2/h3) | 20–24px | 600 (semibold) | 1.25 | Titres de sections générés par prose | +| Inline code | 14px (0.875rem) | 400 (regular) | 1.5 | `` `code` `` inline dans prose | + +> Source : valeurs par défaut `@tailwindcss/typography` — RESEARCH.md D-01, Pattern 3. +> Police héritée du site (system-ui ou celle définie par Nuxt UI). Pas de font custom dans cette phase. + +--- + +## Color + +Le site utilise dark mode par défaut (`colorMode.preference: 'dark'`) avec cookie SSR-safe. + +| Role | Value | Usage | +|------|-------|-------| +| Dominant (60%) | `bg-background` (Nuxt UI token — dark: ~#0f172a, light: #ffffff) | Surface principale de l'article, fond de page | +| Secondary (30%) | `bg-muted` / `bg-elevated` (Nuxt UI token) | Blocs de code Shiki (fond), callouts Alert background | +| Accent (10%) | `--color-brand-500: #85cb85` (vert) | Liens dans prose, bordure left des callouts `tip`, focus states | +| Destructive | `color-error` (Nuxt UI token — rouge) | Callouts `danger` uniquement | + +Accent réservé exclusivement à : +- Liens hypertextes dans le contenu `prose` (`:hover` underline brand-500) +- Bordure gauche du callout `::alert{type="tip"}` (couleur success = vert) +- Aucun autre usage dans cette phase + +Thème Shiki : +- `default: 'github-light'` en mode light +- `dark: 'github-dark'` en mode dark +- Synchronisé via `html.dark` (classSuffix: '' confirmé dans nuxt.config.ts) +- Source : RESEARCH.md Pattern 1, assumption A1 validée (cohérence avec charte vert/dark du site) + +--- + +## Component Inventory + +Composants à créer dans cette phase (zéro shadcn — tout Nuxt UI ou Tailwind CSS) : + +| Composant | Chemin | Rôle | Base | +|-----------|--------|------|------| +| ProseImg | `components/content/ProseImg.vue` | Override prose img → NuxtImg optimisé | `` déjà installé | +| Alert | `components/content/Alert.vue` | Callout MDC `::alert{type}` | `` Nuxt UI | + +Types de callouts MDC à implémenter (minimum) : + +| Type | Icône Heroicons | Couleur Nuxt UI | Usage | +|------|-----------------|-----------------|-------| +| `info` | `i-heroicons-information-circle` | `info` | Notes générales | +| `warning` | `i-heroicons-exclamation-triangle` | `warning` | Avertissements | +| `tip` | `i-heroicons-light-bulb` | `success` (vert brand) | Conseils pratiques | +| `danger` | `i-heroicons-x-circle` | `error` | Erreurs critiques | + +Source : RESEARCH.md Pattern 5 — iconMap et colorMap déjà définis, à utiliser tel quel. + +--- + +## Copywriting Contract + +Cette phase est une phase d'infrastructure — aucune page publique n'est exposée. +Le seul contenu visible est l'article de test servant à valider les critères de succès. + +| Element | Copy (FR) | Copy (EN) | +|---------|-----------|-----------| +| Titre article de test | "Test Kotlin Syntax Highlighting" | "Test Kotlin Syntax Highlighting" | +| Description article de test | "Article de test pour valider le renderer @nuxt/content" | "Test article to validate the @nuxt/content renderer" | +| Contenu callout info de test | "Ceci est un callout d'information." | "This is an information callout." | +| Contenu callout warning de test | "Ceci est un avertissement." | "This is a warning." | +| Contenu callout tip de test | "Conseil pratique de développement Kotlin." | "Practical Kotlin development tip." | +| Alt image de test | "Image de test pour NuxtImg dans les articles" | "Test image for NuxtImg in articles" | + +États d'erreur (infrastructure — pas d'UI utilisateur) : +- Aucun état d'erreur visible par l'utilisateur dans cette phase +- En cas d'échec du build SQLite : erreur côté serveur uniquement (logs), pas de fallback UI + +Aucune action destructive dans cette phase. + +--- + +## Prose Wrapper Contract + +Le wrapper autour de `` suit ce contrat exact : + +```html +
+ +
+``` + +- `max-w-none` : la contrainte de largeur est gérée par le layout parent (Phase 6), pas par prose +- `dark:prose-invert` : inverse automatiquement les couleurs prose en dark mode +- Source : RESEARCH.md D-01, Pattern 3 + +--- + +## Frontmatter Schema (minimal Phase 5) + +Déclaré dans `content.config.ts` via Zod. Utilisé par l'article de test. + +| Champ | Type | Requis | Usage | +|-------|------|--------|-------| +| `title` | `z.string()` | Oui | Titre de l'article | +| `description` | `z.string()` | Oui | Meta description (Phase 7) | +| `date` | `z.string()` | Oui | Date ISO 8601 (YYYY-MM-DD) | +| `tags` | `z.array(z.string()).optional()` | Non | Tags thématiques | +| `image` | `z.string().optional()` | Non | Chemin image og (Phase 7) | + +Source : RESEARCH.md Pattern 2 — schema `blogSchema` à utiliser tel quel. + +--- + +## Registry Safety + +| Registry | Blocks Used | Safety Gate | +|----------|-------------|-------------| +| Nuxt UI officiel | `UAlert` | Non requis — composant officiel @nuxt/ui | +| @nuxt/content officiel | `ContentRenderer`, `ContentSlot` | Non requis — module officiel Nuxt | +| Tiers | aucun | Non applicable | + +> Note : Ce projet utilise Nuxt UI, pas shadcn. La registry safety gate shadcn ne s'applique pas. +> Aucun composant tiers hors ecosystem Nuxt officiel dans cette phase. + +--- + +## Checker Sign-Off + +- [ ] Dimension 1 Copywriting: PASS +- [ ] Dimension 2 Visuals: PASS +- [ ] Dimension 3 Color: PASS +- [ ] Dimension 4 Typography: PASS +- [ ] Dimension 5 Spacing: PASS +- [ ] Dimension 6 Registry Safety: PASS + +**Approval:** pending