diff --git a/.gitignore b/.gitignore index 529aa28..b81ffc9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,9 @@ public/pdfjs/pdf.worker.min.mjs # Sources originales (PDF, JPG — pas servies par l'appli) sources/ +# Runtime data (Docker volume — never committed) +data/ + # Local env files .env .env.* diff --git a/CLAUDE.md b/CLAUDE.md index ccd5e78..2f67dfe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,81 +2,84 @@ 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) -- **Modules** : Nuxt Content, Pinia, UnoCSS, VueUse, Nuxt Image -- **Icônes** : Lucide + Phosphor (via @iconify-json) -- **Package manager** : pnpm -- **Déploiement** : Docker + Traefik, CI via Woodpecker +- 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/ # Autonomie numérique (index + [slug] détail) - economique/ # Autonomie économique (index, monnaie-libre, commande, productions-collectives) - modele-eco/ # Livre : sommaire + chapitres [slug] - citoyenne/ # Autonomie citoyenne (index + [slug] détail) - en-musique/ # Player audio - evenement.vue # Événement - admin/ # Back-office (pages/, book/, songs, messages, media) + 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 livre (player, PDF, chapitres, commande) - home/ # BookSection, AxisBlock, AxisGrid, HeroSection, Messages + 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... + 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) + assets/css/main.css # UnoCSS + overrides light mode site/ - pages/ # Contenu YAML par section (numerique/, economique/, citoyenne/) + 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/pages/[...path].get.ts # GET pages YAML (chemins imbriqués) - api/admin/content/pages/[...path].put.ts # PUT pages YAML - api/admin/content/pages.get.ts # Liste toutes les pages - middleware/redirects.ts # 301 : /gestation, /modele-eco, /decision, /lire + 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 ``` -## Ports dev (CRITIQUE) +## Données runtime (CRITIQUE) -| Projet | Port | Config | -|--------|------|--------| -| **librodrome** | **3000** | `nuxt.config.ts` → `devServer.port: 3000` | -| **GrateWizard** | **3001** | `package.json` → `next dev --port 3001` | -| **SejeteralO frontend** | **3009** | `frontend/nuxt.config.ts` → `devServer.port: 3009` | -| **SejeteralO backend** | **8000** | Makefile → `uvicorn --port 8000` | - -**Ne jamais changer ces ports.** +- `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 : `/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` -- Bloc GrateWizard dans la section économique de la home ## Contenu administrable -- YAML dans `site/pages/` organisé par section (sous-dossiers) -- API supporte les chemins imbriqués (`numerique/logiciel-libre`) -- Admin : `/admin/pages` liste toutes les pages, `/admin/pages/{path}` édite en YAML -- Git sync auto en prod (ADMIN_GIT_SYNC=true) +- 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 sur :3000 -pnpm build # Build production +pnpm dev # Dev server :3000 +pnpm build # Build production +PORT=3099 node .output/server/index.mjs # Test build prod (toujours avant commit) ``` ## Conventions -- Langue du site : français -- Commits en français, style concis -- CSS via UnoCSS (utility-first) + variables CSS palettes -- Composants Vue SFC avec ` diff --git a/app/pages/economique/index.vue b/app/pages/economique/index.vue index fb7b60f..f38627f 100644 --- a/app/pages/economique/index.vue +++ b/app/pages/economique/index.vue @@ -387,7 +387,8 @@
- + +
Ğ1 @@ -408,6 +409,7 @@
@@ -520,12 +522,48 @@ const showPdfReader = ref(false) } .book-block { - padding: 1.5rem; + padding: 1.25rem; border-radius: 0.75rem; border: 1px solid hsl(var(--color-text) / 0.08); background: hsl(var(--color-surface)); } +/* Monnaie libre card */ +.g1-card { + position: relative; + overflow: hidden; + background: linear-gradient( + 135deg, + hsl(var(--color-surface)) 60%, + hsl(var(--color-primary) / 0.06) 100% + ); + border-color: hsl(var(--color-primary) / 0.14); +} + +.g1-card:hover { + border-color: hsl(var(--color-primary) / 0.3); +} + +.g1-watermark { + position: absolute; + right: -0.25rem; + top: 50%; + transform: translateY(-50%); + font-family: var(--font-display); + font-weight: 900; + font-size: 5.5rem; + line-height: 1; + color: hsl(var(--color-primary) / 0.07); + pointer-events: none; + user-select: none; + letter-spacing: -0.02em; + transition: color 0.2s; +} + +.g1-card:hover .g1-watermark { + color: hsl(var(--color-primary) / 0.11); +} + /* Shadok illustrations */ .shadok { position: absolute; diff --git a/app/pages/economique/monnaie-libre.vue b/app/pages/economique/monnaie-libre.vue index 42f4284..302adbe 100644 --- a/app/pages/economique/monnaie-libre.vue +++ b/app/pages/economique/monnaie-libre.vue @@ -1,33 +1,79 @@ diff --git a/app/pages/evenement.vue b/app/pages/evenement.vue index 8640668..a547649 100644 --- a/app/pages/evenement.vue +++ b/app/pages/evenement.vue @@ -330,15 +330,106 @@
+ + +

{{ content?.kicker }}

{{ content?.title }}

-

+

+ {{ evtContent.subtitle }} +

+

{{ content?.description }}

+ + +
+

+ « {{ evtContent.leitmotiv }} » +

+

+ {{ evtContent.tagline }} +

+ +
+ En gestation + +
+ + +
+
+ + +
+

Trois axes d'émancipation

+

« je subis — ou je m'affranchis »

+
+
+
+
+
+

+ {{ axe.label }} +

+
    +
  • +
    + {{ item }} +
  • +
+
+
+
+ + +
+

Espaces & programme

+

Chorégraphie séquencée de plénières, ateliers et espaces permanents

+
+
+
+
+
+
+

{{ esp.label }}

+

{{ esp.desc }}

+
+
+
+
+ + +
+

Format & lieu

+
+
+
+
+
+
+

{{ cfg.label }}

+

{{ cfg.detail }}

+
+
+
+
+ +
+
@@ -555,4 +647,187 @@ useHead({ display: none; } } + +/* ── Logo SVG ── */ +.evt-logo-wrap { + width: 4.5rem; + height: 4.5rem; + display: flex; + align-items: center; + justify-content: center; + color: hsl(var(--color-primary)); + filter: drop-shadow(0 0 14px hsl(var(--color-primary) / 0.25)); +} + +.evt-logo { + width: 100%; + height: 100%; +} + +/* ── Badge gestation hero ── */ +.evt-gestation-badge { + display: inline-flex; + align-items: center; + gap: 0.35rem; + padding: 0.25rem 0.75rem; + border-radius: 9999px; + background: hsl(var(--color-accent) / 0.12); + border: 1px solid hsl(var(--color-accent) / 0.25); + color: hsl(var(--color-accent)); + font-size: 0.75rem; + font-weight: 600; + font-family: var(--font-mono); + letter-spacing: 0.04em; +} + +/* ── Section contenus événement ── */ +.evt-content { + background: hsl(var(--color-bg)); +} + +.evt-section-title { + font-family: var(--font-display); + font-size: clamp(1.25rem, 3vw, 1.75rem); + font-weight: 800; + color: hsl(var(--color-text)); + margin-bottom: 0.25rem; +} + +.evt-section-sub { + font-family: var(--font-mono); + font-size: 0.8rem; + letter-spacing: 0.06em; + text-transform: uppercase; + color: hsl(var(--color-primary)); + margin-bottom: 1.5rem; +} + +/* ── Axes ── */ +.axes-grid { + display: grid; + gap: 1rem; + grid-template-columns: 1fr; +} + +@media (min-width: 640px) { + .axes-grid { grid-template-columns: repeat(3, 1fr); } +} + +.axe-card { + padding: 1.5rem; + border-radius: 16px; + background: hsl(var(--color-surface)); + border: 1px solid hsl(var(--color-text) / 0.07); + transition: border-color 0.2s, box-shadow 0.2s; +} + +.axe-card:hover { + border-color: hsl(var(--color-primary) / 0.25); + box-shadow: 0 4px 24px hsl(var(--color-primary) / 0.06); +} + +.axe-icon { + display: flex; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + border-radius: 0.625rem; + background: hsl(var(--color-primary) / 0.1); + color: hsl(var(--color-primary)); + margin-bottom: 1rem; +} + +.axe-list { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.axe-list li { + display: flex; + align-items: flex-start; + gap: 0.5rem; + font-size: 0.82rem; + line-height: 1.5; + color: hsl(var(--color-text-muted)); +} + +/* ── Espaces ── */ +.espaces-grid { + display: grid; + gap: 0.75rem; + grid-template-columns: 1fr; +} + +@media (min-width: 640px) { + .espaces-grid { grid-template-columns: repeat(2, 1fr); } +} + +@media (min-width: 1024px) { + .espaces-grid { grid-template-columns: repeat(3, 1fr); } +} + +.espace-card { + display: flex; + align-items: flex-start; + gap: 0.875rem; + padding: 1rem 1.25rem; + border-radius: 12px; + background: hsl(var(--color-surface)); + border: 1px solid hsl(var(--color-text) / 0.06); + transition: border-color 0.15s; +} + +.espace-card:hover { + border-color: hsl(var(--color-accent) / 0.25); +} + +.espace-icon { + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + border-radius: 0.5rem; + background: hsl(var(--color-accent) / 0.1); + color: hsl(var(--color-accent)); + flex-shrink: 0; +} + +/* ── Config ── */ +.config-grid { + display: grid; + gap: 0.75rem; + grid-template-columns: repeat(2, 1fr); +} + +@media (min-width: 640px) { + .config-grid { grid-template-columns: repeat(4, 1fr); } +} + +.config-card { + display: flex; + align-items: flex-start; + gap: 0.75rem; + padding: 1rem; + border-radius: 12px; + background: hsl(var(--color-surface)); + border: 1px solid hsl(var(--color-text) / 0.06); +} + +.config-icon { + display: flex; + align-items: center; + justify-content: center; + width: 1.875rem; + height: 1.875rem; + border-radius: 0.5rem; + background: hsl(var(--color-primary) / 0.1); + color: hsl(var(--color-primary)); + flex-shrink: 0; +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 3fb3959..ce94fe5 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -14,7 +14,7 @@ services: ports: - 3000 volumes: - - ./data:/src/data + - ../data:/src/data - ./public:/src/public restart: always labels: diff --git a/public/images/Librodrome-Logo.png b/public/images/Librodrome-Logo.png new file mode 100644 index 0000000..6126a3b Binary files /dev/null and b/public/images/Librodrome-Logo.png differ diff --git a/public/images/librodrome-logo.svg b/public/images/librodrome-logo.svg new file mode 100644 index 0000000..0221591 --- /dev/null +++ b/public/images/librodrome-logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/public/pdf/250115 Le Librodrome - Genèse.pdf b/public/pdf/250115 Le Librodrome - Genèse.pdf new file mode 100644 index 0000000..4fac777 Binary files /dev/null and b/public/pdf/250115 Le Librodrome - Genèse.pdf differ diff --git a/site/pages/evenement.yml b/site/pages/evenement.yml index f87069c..89e7485 100644 --- a/site/pages/evenement.yml +++ b/site/pages/evenement.yml @@ -1,5 +1,69 @@ -kicker: Bientôt -title: En gestation -description: Cette rubrique est en cours de préparation. meta: - title: Évènement + title: Le Librodrome — L'événement + +kicker: Performance d'émancipation civile +title: Le Librodrome +subtitle: "Une paece — performance artistique d'émancipation civile et économique" +leitmotiv: Construire une autonomie collective. +tagline: Rendre possible. Passer la seconde. +gestation: true + +description: > + Synergies entre collectifs, associations et coopératives — autour de trois axes : + numérique, économique, politique. « Je subis ou je m'affranchis. » + +axes: + - icon: cpu + label: Numérique + items: + - Affranchissement GAFAM — logiciels libres, Linux, migration + - Cloud local décentralisé — Nextcloud, IPFS, Matrix, PeerTube + - IA collective locale — Mistral, UPlanet + + - icon: coins + label: Économique + items: + - Monnaie libre (June Ğ1) vs monnaie-dette + - Économie du don — amorcer les filières, couvrir besoins et plaisirs + - Productions versatiles — énergie, alimentaire, agricole + + - icon: landmark + label: Politique + items: + - Autonomie d'un bassin de vie — accessible et reproductible + - "Pragmatique : on parle chiffres, terrain, zéro étiquette" + - Feuilles de route et graphe des synergies + +espaces: + - icon: cpu + label: Salle des machines + desc: Install Linux, on-boarding June Ğ1 et cryptos, FabLab ouvert, visios + - icon: shopping-bag + label: "Ğ(marché)" + desc: Expérience laboratoire in vivo — liberté de choisir sa monnaie, construction collective d'échelles de valeurs relatives + - icon: users + label: Ateliers & feuilles de route + desc: Animateurs initiés, préparés en amont — cartographies, synergies, restitutions collectives + - icon: music-2 + label: Scène musicale & théâtrale + desc: Performances, concerts, lectures — chill out en préau + - icon: utensils + label: Buvette & restauration + desc: Lié au Ğ(marché) — expérience de l'économie du don en direct + - icon: gamepad-2 + label: Géconomicus + desc: "Jeu économique — 3 parties dont 1 sans monnaie, 15 joueurs, 3 animateurs, spectateurs" + +config: + - icon: calendar + label: Ven → Sam → Dim + detail: "5 jours, 4 nuits (+ jeudi install & répétitions + lundi after)" + - icon: users + label: 100 à 200 personnes + detail: Public 2 jours — junistes 3 jours + - icon: map-pin + label: Lieu privé — Drôme + detail: Événement sur invitation, lieu en cours de négociation + - icon: wifi + label: Fibre + LAN wifi + detail: Salle des machines, salle de conf, salles de production, campement 40-60 tentes