---
phase: 03-pages-ship
plan: 02
type: execute
wave: 2
depends_on: ["03-01"]
files_modified:
  - app/pages/index.vue
  - app/pages/projects.vue
  - app/pages/project/[id].vue
autonomous: true
requirements:
  - PAGE-01
  - PAGE-02
  - PAGE-03
must_haves:
  truths:
    - "Landing page affiche 6 sections : Hero, FeaturedProjects, Services, Testimonials, FAQ, CTA"
    - "Projects page filtre par recherche texte et boutons categorie"
    - "Project detail affiche description, features, technologies, galerie modale"
    - "Chaque page a ses metadonnees SEO via useSeoMeta()"
  artifacts:
    - path: "app/pages/index.vue"
      provides: "Landing page avec 6 sections"
    - path: "app/pages/projects.vue"
      provides: "Liste projets avec filtres"
    - path: "app/pages/project/[id].vue"
      provides: "Detail projet avec galerie"
  key_links:
    - from: "app/pages/index.vue"
      to: "app/components/sections/*.vue"
      via: "auto-import composants"
      pattern: "HeroSection|FeaturedProjectsSection|ServicesSection"
    - from: "app/pages/project/[id].vue"
      to: "app/components/ProjectGallery.vue"
      via: "useTemplateRef + openGallery"
      pattern: "ProjectGallery|openGallery"
---

<objective>
Construire les 3 pages principales du portfolio : Landing (accueil), Projects (liste), et Project Detail (detail + galerie). Ces pages consomment les composants crees en Plan 01.

Purpose: Ce sont les pages les plus visitees du portfolio — la landing convertit les visiteurs, la liste projets montre le travail, et le detail permet l'exploration approfondie.
Output: 3 pages fonctionnelles dans app/pages/.
</objective>

<execution_context>
@C:\Users\minit\.claude\get-shit-done\workflows\execute-plan.md
@C:\Users\minit\.claude\get-shit-done\templates\summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/03-pages-ship/03-CONTEXT.md
@.planning/phases/03-pages-ship/03-RESEARCH.md
@.planning/phases/03-pages-ship/03-01-SUMMARY.md

@src/views/HomePage.vue
@src/views/ProjectsPage.vue
@src/views/ProjectDetailPage.vue
@app/composables/useProjects.ts
@app/data/projects.ts
@app/data/testimonials.ts
@app/data/faq.ts

<interfaces>
From app/composables/useProjects.ts:
```typescript
export function useProjects(): {
  projects: ComputedRef<Project[]>
  featuredProjects: ComputedRef<Project[]>
  filterByCategory(cat: string): ComputedRef<Project[]>
  search(query: Ref<string> | string): ComputedRef<Project[]>
  findById(id: string): ComputedRef<Project | undefined>
}
```

From app/data/faq.ts:
```typescript
export const homeFAQs: FAQ[]  // { questionKey, answerKey, featuresKey }
```

From app/data/testimonials.ts:
```typescript
export const testimonials: Testimonial[]
export const testimonialsStats: TestimonialsStats
```

Composants disponibles (auto-importes, crees en Plan 01):
- HeroSection — pas de props (utilise i18n interne)
- FeaturedProjectsSection — pas de props (utilise useProjects interne)
- ServicesSection — pas de props (utilise i18n interne)
- TestimonialsSection — props: title, subtitle, testimonials, stats, statsLabels, ctaTitle, ctaSubtitle, ctaText, ctaLink
- FAQSection — props: faqs (FAQ[]), title, subtitle
- CTASection — pas de props (utilise i18n interne)
- ProjectCard — props: project (Project)
- ProjectGallery — props: gallery (string[]), projectTitle (string); expose: openGallery(index)
- TechBadge — props: tech (Technology | string), showLevel?, showImage?
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Page Landing (index.vue) avec 6 sections</name>
  <files>app/pages/index.vue</files>
  <action>
Remplacer le contenu stub de `app/pages/index.vue` par la page landing complete (per D-01, D-02, D-03).

Structure exacte — 6 sections dans cet ordre (per D-01) :
1. `<HeroSection />` — auto-importe, texte seul (per D-02)
2. `<FeaturedProjectsSection />` — auto-importe, 3 projets featured (per D-03)
3. `<ServicesSection />` — auto-importe
4. `<TestimonialsSection>` — passer les props i18n depuis `t()`, importer `testimonials` et `testimonialsStats` depuis `~/data/testimonials`
5. `<FAQSection>` — passer `homeFAQs` depuis `~/data/faq` et titres i18n
6. `<CTASection />` — auto-importe

SEO via `useSeoMeta()` : titre, description, og:title, og:description, og:image (per SEO-01). Conserver le JSON-LD Person + ProfessionalService deja present dans le stub via `useHead({ script })`.

Wrapper `<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">` pour le contenu selon le layout Phase 2 (D-16 max-w-7xl).
  </action>
  <verify>
    <automated>cd C:/Users/minit/Desktop/portfolio/portfolio && grep -c "Section" app/pages/index.vue | grep -q "[456789]" && grep -q "useSeoMeta" app/pages/index.vue && echo "PASS"</automated>
  </verify>
  <done>Page landing avec 6 sections dans l'ordre Hero > FeaturedProjects > Services > Testimonials > FAQ > CTA, SEO meta configurees</done>
</task>

<task type="auto">
  <name>Task 2: Page Projects (projects.vue) avec filtres recherche + categorie</name>
  <files>app/pages/projects.vue</files>
  <action>
Remplacer le stub `app/pages/projects.vue` par la page projets complete (per D-04, PAGE-02).

Migrer depuis `src/views/ProjectsPage.vue` en adaptant pour Nuxt :

1. **Script setup** : `const { projects } = useProjects()` (auto-import). Refs : `searchQuery`, `selectedCategory` (defaut 'all'). Computed `categories` : `['all', ...new Set(projects.value.map(p => p.category))]`. Computed `filteredProjects` : filtre par searchQuery (titre, description, technologies) puis par selectedCategory.

2. **Template** :
   - Section hero : titre `t('projects.title')`, sous-titre, stats (total projets, featured, categories)
   - Section filtres (per D-04) : `UInput` pour recherche avec icone search (`icon="i-lucide-search"`) + boutons categorie `UButton` pour chaque categorie (variant `soft` pour inactif, `solid` pour actif). PAS de select/dropdown — boutons cliquables comme l'actuel.
   - Grille projets : `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6`. Utiliser `<ProjectCard :project="project" />` pour chaque projet filtre.
   - Etat vide : message "Aucun resultat" avec bouton reset filtres.

3. **SEO** : `useSeoMeta()` avec titre, description, og specifiques a la page projets.
  </action>
  <verify>
    <automated>cd C:/Users/minit/Desktop/portfolio/portfolio && grep -q "filteredProjects" app/pages/projects.vue && grep -q "searchQuery" app/pages/projects.vue && grep -q "ProjectCard" app/pages/projects.vue && echo "PASS"</automated>
  </verify>
  <done>Page projects avec recherche texte + filtres categorie boutons, grille ProjectCard, etat vide, SEO meta</done>
</task>

<task type="auto">
  <name>Task 3: Page Project Detail (project/[id].vue) avec galerie modale</name>
  <files>app/pages/project/[id].vue</files>
  <action>
Creer `app/pages/project/[id].vue` — route dynamique (per PAGE-03).

Migrer depuis `src/views/ProjectDetailPage.vue` :

1. **Script setup** :
   - `const route = useRoute()` puis `const { findById } = useProjects()`
   - `const project = findById(route.params.id as string)`
   - 404 si non trouve : `if (!project.value) throw createError({ status: 404, statusText: 'Project not found' })` (per RESEARCH.md Code Examples)
   - `const galleryRef = useTemplateRef('gallery')` pour acceder a ProjectGallery.openGallery
   - Computed `relatedProjects` : meme categorie, exclure le projet courant, slice(0, 3)
   - `useSeoMeta()` avec titre du projet, description

2. **Template** :
   - Breadcrumb : `UButton variant="link"` vers /projects avec icone fleche retour
   - Hero grid 2 colonnes : image principale `NuxtImg` a gauche, infos (categorie, date, titre, description, boutons CTA) a droite
   - Boutons CTA : `UButton` pour demo, source code, boutons custom du projet
   - Section "A propos" : longDescription ou description, liste features avec checkmarks
   - Section technologies : grille `TechBadge` pour chaque tech
   - Section galerie : grille thumbnails cliquables. Au clic sur une image : `galleryRef.value?.openGallery(index)`. Chaque thumbnail : `NuxtImg` avec overlay zoom au hover.
   - Sidebar : card infos projet (date, categorie, status) + projets lies `NuxtLink`
   - `<ProjectGallery ref="gallery" :gallery="project.gallery" :project-title="project.title" />` en bas du template

3. **Responsive** : layout 2 colonnes (main + sidebar) sur desktop, stack sur mobile.
  </action>
  <verify>
    <automated>cd C:/Users/minit/Desktop/portfolio/portfolio && test -f app/pages/project/\[id\].vue && grep -q "findById" app/pages/project/\[id\].vue && grep -q "ProjectGallery" app/pages/project/\[id\].vue && grep -q "createError" app/pages/project/\[id\].vue && echo "PASS"</automated>
  </verify>
  <done>Page project detail avec route dynamique [id], 404 si non trouve, galerie modale via ProjectGallery, projets lies, SEO meta</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| URL params -> findById | route.params.id est une entree utilisateur |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-03-05 | Tampering | project/[id].vue | mitigate | createError(404) si projet non trouve — pas d'injection possible via les donnees statiques |
</threat_model>

<verification>
- `npx nuxi dev` puis naviguer vers `/` — 6 sections visibles
- `/projects` — filtres fonctionnels, cards affichees
- `/project/flowboard` — detail avec galerie, clic image ouvre modal
- `/project/inexistant` — redirige vers page 404
- `curl http://localhost:3000/` contient les balises meta SEO
</verification>

<success_criteria>
- Landing affiche les 6 sections dans l'ordre correct (per D-01)
- Hero est texte seul, pas d'image (per D-02)
- 3 projets featured affiches (per D-03)
- Projects page a recherche texte + boutons categorie (per D-04)
- Project detail a galerie modale UModal+UCarousel fonctionnelle
- Route /project/[id] inexistant retourne 404
- Toutes les pages ont useSeoMeta()
</success_criteria>

<output>
After completion, create `.planning/phases/03-pages-ship/03-02-SUMMARY.md`
</output>
