# Librodrome

Site vitrine du projet Le Librodrome — livre + chansons sur l'économie du don.

## Protocole de début de session

1. `git pull --rebase origin main` (récupère les commits admin git sync YAML prod)
2. Vérifier que `data/messages.yml` existe — si absent, signaler avant toute opération
3. Si l'objectif de la session n'est pas précisé, le demander

## Stack

- Nuxt 4 (Vue 3, TypeScript, Nitro) + Nuxt Content, Pinia, UnoCSS, VueUse, Nuxt Image
- Icônes : Lucide + Phosphor (via @iconify-json) ; Package manager : pnpm
- Déploiement : Docker + Traefik, CI via Woodpecker

## Structure

```
app/
  pages/
    numerique/          # index + [slug]
    economique/         # index, monnaie-libre, commande, productions-collectives
      modele-eco/       # sommaire + chapitres [slug]
    citoyenne/          # index + [slug]
    en-musique/         # player audio
    admin/              # back-office (pages/, book/, songs, messages, media)
  components/
    book/Actions.vue    # boutons partagés (player, PDF, chapitres, commande)
    home/               # BookSection, AxisBlock, AxisGrid, HeroSection, HomeMessages
    admin/, player/, song/, ui/
  composables/          # useAudioPlayer, useBookData, useGrateWizard, usePageContent
  stores/palette.ts     # 4 palettes saisonnières (été par défaut, persisté localStorage)
  assets/css/main.css   # UnoCSS + overrides light mode
site/
  pages/                # Contenu YAML administrable par section (sous-dossiers)
  site.yml              # Config globale (nav, footer, GrateWizard)
  bookplayer.config.yml # Config player/chapitres
data/
  messages.yml          # Runtime — volume Docker ../data:/src/data — JAMAIS dans git
server/
  api/content/          # GET pages YAML (chemins imbriqués)
  api/admin/content/    # PUT pages YAML + liste
  api/messages/         # GET (publiés) + POST (nouveau message)
  api/admin/messages/   # GET tous + PUT (type, reply, published) + DELETE
  utils/content.ts      # readDataYaml/writeDataYaml (data/) + readYaml/writeYaml (site/)
  middleware/redirects.ts  # 301 : /gestation, /modele-eco, /decision, /lire
docker/
  Dockerfile, docker-compose.yml, docker-compose.dev.yml
```

## Données runtime (CRITIQUE)

- `data/messages.yml` : volume Docker monté `../data:/src/data` (relatif à `docker/`)
- Persisté entre les rebuilds — **jamais écrasé par les commits ni par le déploiement**
- Structure message : `{ id, author, email, text, type, published, createdAt, reply: { text, publishedAt } | null }`
- Types : `reaction` (ancien, affiché "Réaction", plus proposé dans les formulaires) | `question` | `suggestion` | `retour`
- En dev local : `<racine>/data/messages.yml`
- **Avant toute migration de chemin ou écriture sur data/ : demander confirmation**

## Intégration GrateWizard

- URL dev : `app/app.config.ts` → `localhost:3001`
- URL prod : `https://gratewizard.axiom-team.fr`

## Contenu administrable

- YAML dans `site/pages/` par section ; API supporte les chemins imbriqués
- Admin : `/admin/pages` liste, `/admin/pages/{path}` édite en YAML
- Git sync auto en prod (`ADMIN_GIT_SYNC=true`) → d'où le `git pull --rebase` obligatoire en début de session

## Commandes

```bash
pnpm dev                                 # Dev server :3000
pnpm build                               # Build production
PORT=3099 node .output/server/index.mjs  # Test build prod (toujours avant commit)
```

## Conventions

- CSS via UnoCSS + variables CSS palettes ; composants Vue SFC `<script setup lang="ts">`
- Shadoks SVG inline thématiques sur chaque page (hidden mobile, opacity 0.18–0.28)
- Hexagramme 益 (#42 Yi, Augmentation) dans `layouts/default.vue`
- Signature § (logo calligraphique SVG gradient) dans `TheHeader.vue` — ne pas modifier sans demander

## SEO & Recherche IA — Checklist permanente

### À chaque nouvelle page Vue

1. **Appeler `useSeoPage()`** — jamais `useHead({ title })` seul
   ```ts
   useSeoPage({
     title: 'Titre page — Le Librodrome',       // 50–60 chars
     description: 'Description...',              // 120–155 chars
     image: '/images/og-specifique.jpg',         // optionnel, sinon og-default.png (logo §)
     type: 'website' | 'article' | 'book',       // défaut: website
   })
   ```
2. **og:image** : utiliser la couverture `/images/Couv-Economie-du-don.jpg` pour les pages livre/musique ; `og-default.png` (logo §) pour les pages site générales
3. **type: 'article'** pour les chapitres du modele-eco ; **type: 'book'** pour les index livre

### À chaque nouveau fichier YAML dans `site/pages/`

Ajouter le bloc `seo:` en tête :
```yaml
seo:
  title: "Titre SEO — 50-60 chars max"
  description: "Description 120-155 chars, avec mots-clés naturels"
  # image: /images/og-specifique.jpg   # optionnel
  # keywords: [monnaie libre, TRM, économie du don]
```

### Règles description SEO

- Commence par un verbe d'action ou une affirmation forte
- Contient les mots-clés : économie du don, monnaie libre, TRM, June, bassin de vie, autonomie
- 120–155 caractères (ni trop court, ni tronqué)
- Différente du titre et du H1

### JSON-LD automatique

- JSON-LD `Organization` + `Book` : injecté globalement dans `app.vue` — ne pas redupliquer
- Chapitres → og:type `article` via `useSeoPage({ type: 'article' })`
- Sitemap : géré par `@nuxtjs/sitemap` — ajouter manuellement les nouvelles routes statiques dans `nuxt.config.ts > sitemap.urls`

### Analytics — Nouveaux composants

- Tout bouton CTA externe : `trackCta(label, url)` depuis `useTracking()`
- Tout `<a target="_blank">` : capturé automatiquement par `useScrollTracking()` dans `default.vue`
- Tout nouveau lecteur média : appeler `trackAudioPlay` / `trackPdfOpen` depuis `useTracking()`
