Restructuration sections, contenu administrable, shadoks, palette été
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Structure par section : /numerique, /economique, /citoyenne (plus de /gestation) - Chaque section a index + sous-pages avec contenu YAML administrable - API content supporte les chemins imbriqués ([...path]) - Admin : liste des pages + éditeur par section - Page /economique : monnaie libre (picto Ğ1), modèle éco, productions collectives, commande livre - Page /citoyenne : decision (CTA Glibredecision), tarifs-eau (CTA SejeteralO) - BookActions : composant partagé (player, PDF, chapitres, commande) sur home, eco et modele-eco - GrateWizard remonté dans la section économique de la home - Palette été par défaut, choix persisté en localStorage - Fix lisibilité été (text-white/65 + variables CSS) - Shadoks thématiques sur toutes les pages (8-10 par page, métiers variés) - Redirections 301 : /gestation/*, /modele-eco/*, /decision, /lire/* - README, CONTRIBUTING, CLAUDE.md mis à jour Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
58
CLAUDE.md
58
CLAUDE.md
@@ -14,26 +14,36 @@ Site vitrine du projet Le Librodrome — livre + chansons sur l'économie du don
|
||||
|
||||
```
|
||||
app/
|
||||
pages/ # Routes : index, lire/, ecouter/, autonomie, evenement, gratewizard, a-propos, admin/
|
||||
components/ # admin, book, content, home, layout, player, song, ui
|
||||
composables/ # useAudioPlayer, useBookData, useGrateWizard, usePlaylist, usePageContent, useSiteContent...
|
||||
assets/css/ # main.css (UnoCSS)
|
||||
data/
|
||||
pages/ # Contenu YAML par page (home, lire, ecouter, autonomie, evenement...)
|
||||
site.yml # Config globale du site
|
||||
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)
|
||||
components/
|
||||
book/Actions.vue # Boutons partagés livre (player, PDF, chapitres, commande)
|
||||
home/ # BookSection, AxisBlock, AxisGrid, HeroSection, Messages
|
||||
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 par section (numerique/, economique/, citoyenne/)
|
||||
site.yml # Config globale (nav, footer, GrateWizard)
|
||||
bookplayer.config.yml # Config player/chapitres
|
||||
server/
|
||||
api/ # Endpoints API (admin, health)
|
||||
middleware/ # Auth middleware
|
||||
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
|
||||
docker/
|
||||
Dockerfile # Build multi-stage (dev + prod)
|
||||
docker-compose.yml # Production (Traefik)
|
||||
docker-compose.dev.yml # Dev Docker
|
||||
Dockerfile, docker-compose.yml, docker-compose.dev.yml
|
||||
```
|
||||
|
||||
## Ports dev (CRITIQUE)
|
||||
|
||||
Chaque projet a un port fixe pour éviter les conflits Nuxt auto-increment :
|
||||
|
||||
| Projet | Port | Config |
|
||||
|--------|------|--------|
|
||||
| **librodrome** | **3000** | `nuxt.config.ts` → `devServer.port: 3000` |
|
||||
@@ -41,32 +51,32 @@ Chaque projet a un port fixe pour éviter les conflits Nuxt auto-increment :
|
||||
| **SejeteralO frontend** | **3009** | `frontend/nuxt.config.ts` → `devServer.port: 3009` |
|
||||
| **SejeteralO backend** | **8000** | Makefile → `uvicorn --port 8000` |
|
||||
|
||||
Script de gestion : `/home/yvv/Documents/PROD/DEV/dev-ports.sh` (status/kill/clean/start)
|
||||
|
||||
**Ne jamais changer ces ports.** Si un port est occupé, tuer le process parasite plutôt que laisser Nuxt auto-incrémenter.
|
||||
**Ne jamais changer ces ports.**
|
||||
|
||||
## Intégration GrateWizard
|
||||
|
||||
- URL dev configurée dans `app/app.config.ts` → `localhost:3001`
|
||||
- URL dev : `app/app.config.ts` → `localhost:3001`
|
||||
- URL prod : `https://gratewizard.axiom-team.fr`
|
||||
- Ouverture en popup via `composables/useGrateWizard.ts`
|
||||
- GrateWizard est un projet Next.js séparé (`/home/yvv/Documents/PROD/DEV/GrateWizard`)
|
||||
- Bloc GrateWizard dans la section économique de la home
|
||||
|
||||
## Contenu
|
||||
## Contenu administrable
|
||||
|
||||
Le contenu des pages est dans `data/pages/*.yml` et chargé via `composables/usePageContent.ts`. Le contenu riche (articles) utilise Nuxt Content avec des fichiers Markdown.
|
||||
- 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)
|
||||
|
||||
## Commandes
|
||||
|
||||
```bash
|
||||
pnpm dev # Dev server sur :3000
|
||||
pnpm build # Build production
|
||||
pnpm generate # Génération statique
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
- Langue du site : français
|
||||
- Commits en français, style concis
|
||||
- CSS via UnoCSS (utility-first), pas de framework CSS externe
|
||||
- CSS via UnoCSS (utility-first) + variables CSS palettes
|
||||
- Composants Vue SFC avec `<script setup lang="ts">`
|
||||
- Shadoks SVG inline thématiques sur chaque page (hidden mobile)
|
||||
|
||||
77
CONTRIBUTING.md
Normal file
77
CONTRIBUTING.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Contributing — Le Librodrome
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
app/
|
||||
pages/
|
||||
numerique/ # Section autonomie numérique
|
||||
index.vue # Vue d'ensemble (3 piliers)
|
||||
[slug].vue # Détail pilier (contenu YAML)
|
||||
economique/ # Section autonomie économique
|
||||
index.vue # Vue d'ensemble (monnaie libre, livre, productions)
|
||||
monnaie-libre.vue
|
||||
commande.vue # Commande du livre (Bookelis + librairie)
|
||||
productions-collectives.vue
|
||||
modele-eco/
|
||||
index.vue # Couverture livre + sommaire chapitres
|
||||
[slug].vue # Lecteur de chapitre (Nuxt Content)
|
||||
citoyenne/ # Section autonomie citoyenne
|
||||
index.vue # Vue d'ensemble (decision, tarifs-eau)
|
||||
[slug].vue # Détail (contenu YAML)
|
||||
en-musique/ # Player audio
|
||||
evenement.vue
|
||||
admin/ # Back-office protégé
|
||||
pages/
|
||||
index.vue # Liste toutes les pages YAML
|
||||
[...path].vue # Éditeur YAML (supporte les sous-dossiers)
|
||||
components/
|
||||
book/Actions.vue # Boutons partagés du livre (player, PDF, chapitres, commande)
|
||||
home/BookSection.vue # Bloc couverture + CTAs (utilise BookActions)
|
||||
home/AxisBlock.vue # Bloc axe sur la home (supporte actions lien via `to`)
|
||||
home/AxisGrid.vue # Grille 3 axes + GrateWizard
|
||||
stores/palette.ts # 4 palettes saisonnières (été par défaut)
|
||||
```
|
||||
|
||||
## Contenu YAML
|
||||
|
||||
API : `GET /api/content/pages/{path}` — supporte les chemins imbriqués (`numerique/logiciel-libre`).
|
||||
|
||||
Admin : `PUT /api/admin/content/pages/{path}` + `GET /api/admin/content/pages` (liste).
|
||||
|
||||
Les fichiers YAML sont dans `site/pages/`, organisés en sous-dossiers par section.
|
||||
|
||||
## Palettes
|
||||
|
||||
4 palettes dans `stores/palette.ts` : automne, hiver, printemps, été.
|
||||
- Défaut : **été** (premier visiteur)
|
||||
- Persisté en `localStorage('palette')` pour les visites suivantes
|
||||
- CSS : variables `--color-primary`, `--color-accent`, etc. + classe `.palette-light`/`.palette-dark`
|
||||
- Overrides light mode dans `main.css` (`.palette-light .text-white` → couleur adaptive)
|
||||
|
||||
## Shadoks
|
||||
|
||||
Illustrations SVG inline sur chaque page, thématiques par section :
|
||||
- Numérique : métiers tech/industrie (codeuse, électricien, soudeuse...)
|
||||
- Économique : artisanat/agriculture (boulangère, potier, forgeron...)
|
||||
- Citoyenne : navigation/justice/théâtre (capitaine, avocate, comédien...)
|
||||
- Modèle éco : livre/édition (typographe, calligraphe, conteuse...)
|
||||
- Événement : spectacle (funambule, accordéoniste, jongleur...)
|
||||
|
||||
Règles : corps compact, longues pattes, grands pieds plats, bec pointu, postures variées.
|
||||
CSS : `position: absolute`, `pointer-events: none`, `opacity 0.18-0.28`, animation float, `display: none` sur mobile.
|
||||
|
||||
## Redirections
|
||||
|
||||
`server/middleware/redirects.ts` :
|
||||
- `/gestation/*` → section appropriée
|
||||
- `/modele-eco/*` → `/economique/modele-eco/*`
|
||||
- `/decision` → `/citoyenne/decision`
|
||||
- `/lire/*` → `/economique/modele-eco/*`
|
||||
- `/ecouter/*` → `/en-musique/*`
|
||||
|
||||
## Conventions
|
||||
|
||||
- Commits en français, concis
|
||||
- Build prod vérifié avant push (`PORT=3099 node .output/server/index.mjs`)
|
||||
- Port dev : 3000 (fixe, jamais de fallback)
|
||||
118
README.md
118
README.md
@@ -1,75 +1,63 @@
|
||||
# Nuxt Minimal Starter
|
||||
# Le Librodrome
|
||||
|
||||
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||
Site vitrine du projet Le Librodrome — livre + chansons sur l'économie du don.
|
||||
|
||||
## Setup
|
||||
## Navigation
|
||||
|
||||
Make sure to install dependencies:
|
||||
Le site est organisé en 3 grandes sections :
|
||||
|
||||
| Section | Route | Contenu |
|
||||
|---------|-------|---------|
|
||||
| **Numérique** | `/numerique` | Autonomie numérique : logiciel libre, authentification WoT, cloud libre |
|
||||
| **Économique** | `/economique` | Création monétaire, monnaie libre, modèle économique (livre + chapitres), productions collectives |
|
||||
| **Citoyenne** | `/citoyenne` | Décision collective (Glibredecision), tarifs de l'eau (SejeteralO) |
|
||||
|
||||
Autres pages : `/en-musique` (player audio), `/evenement`, `/a-propos`, `/messages`.
|
||||
|
||||
Chaque section a une page index et des sous-pages de détail (`/numerique/logiciel-libre`, `/economique/modele-eco`, etc.).
|
||||
|
||||
## Le livre
|
||||
|
||||
- **Lire** : lecteur PDF intégré, chapitres Markdown sous `/economique/modele-eco/[slug]`
|
||||
- **Écouter** : player audio avec 9 morceaux sous `/en-musique`
|
||||
- **Commander** : page `/economique/commande` (Bookelis + librairie)
|
||||
|
||||
## Stack
|
||||
|
||||
- **Nuxt 4** (Vue 3, TypeScript, Nitro)
|
||||
- **UnoCSS** (utility-first) + palettes saisonnières (été par défaut)
|
||||
- **Nuxt Content** pour les chapitres du livre
|
||||
- **Pinia** pour l'état (palette, player)
|
||||
- **pnpm** comme package manager
|
||||
|
||||
## Contenu administrable
|
||||
|
||||
Le contenu des pages est dans `site/pages/` en YAML, organisé par section :
|
||||
|
||||
```
|
||||
site/pages/
|
||||
home.yml # Page d'accueil
|
||||
numerique.yml # Index numérique
|
||||
numerique/*.yml # Sous-pages
|
||||
economique.yml # Index économique
|
||||
economique/*.yml # Sous-pages (modele-eco, monnaie-libre, commande...)
|
||||
citoyenne.yml # Index citoyenne
|
||||
citoyenne/*.yml # Sous-pages (decision, tarifs-eau)
|
||||
en-musique.yml, evenement.yml, gratewizard.yml
|
||||
```
|
||||
|
||||
Administration via `/admin/pages` (éditeur YAML, authentifié).
|
||||
|
||||
## Développement
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
pnpm dev # Dev server sur :3000
|
||||
pnpm build # Build production
|
||||
```
|
||||
|
||||
## Development Server
|
||||
Port réservé : **3000** (ne pas changer).
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
## Déploiement
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
|
||||
# pnpm
|
||||
pnpm build
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||
Docker + Traefik, CI via Woodpecker. Domaine : `librodrome.org`.
|
||||
|
||||
@@ -104,6 +104,7 @@ a {
|
||||
.palette-light .text-white\/45 { color: hsl(var(--color-text) / 0.52) !important; }
|
||||
.palette-light .text-white\/50 { color: hsl(var(--color-text) / 0.58) !important; }
|
||||
.palette-light .text-white\/60 { color: hsl(var(--color-text) / 0.68) !important; }
|
||||
.palette-light .text-white\/65 { color: hsl(var(--color-text) / 0.73) !important; }
|
||||
.palette-light .text-white\/70 { color: hsl(var(--color-text) / 0.78) !important; }
|
||||
.palette-light .text-white\/80 { color: hsl(var(--color-text) / 0.88) !important; }
|
||||
.palette-light .text-white\/85 { color: hsl(var(--color-text) / 0.92) !important; }
|
||||
|
||||
@@ -23,13 +23,25 @@
|
||||
</NuxtLink>
|
||||
|
||||
<p class="sidebar-section">Pages</p>
|
||||
<NuxtLink to="/admin/pages" class="sidebar-link" exact-active-class="sidebar-link--active">
|
||||
<div class="i-lucide-file-text h-4 w-4" />
|
||||
Toutes les pages
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/pages/home" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-home h-4 w-4" />
|
||||
Accueil
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/pages/modele-eco" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-book-open h-4 w-4" />
|
||||
Modèle éco
|
||||
<NuxtLink to="/admin/pages/numerique" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-monitor h-4 w-4" />
|
||||
Numérique
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/pages/economique" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-coins h-4 w-4" />
|
||||
Économique
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/pages/citoyenne" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-landmark h-4 w-4" />
|
||||
Citoyenne
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/pages/en-musique" class="sidebar-link" active-class="sidebar-link--active">
|
||||
<div class="i-lucide-headphones h-4 w-4" />
|
||||
|
||||
33
app/components/book/Actions.vue
Normal file
33
app/components/book/Actions.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="mt-8 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:gap-4">
|
||||
<UiBaseButton @click="$emit('open-player')">
|
||||
<div class="i-lucide-play mr-2 h-5 w-5" />
|
||||
Présentation musicale
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="accent" @click="$emit('open-pdf')">
|
||||
<div class="i-lucide-book-open mr-2 h-5 w-5" />
|
||||
Lire le livre
|
||||
</UiBaseButton>
|
||||
<UiBaseButton v-if="showChapters" variant="ghost" to="/economique/modele-eco">
|
||||
<div class="i-lucide-list mr-2 h-5 w-5" />
|
||||
Présentation des chapitres
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="ghost" to="/economique/commande">
|
||||
<div class="i-lucide-shopping-bag mr-2 h-5 w-5" />
|
||||
Commandez le livre
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
withDefaults(defineProps<{
|
||||
showChapters?: boolean
|
||||
}>(), {
|
||||
showChapters: true,
|
||||
})
|
||||
|
||||
defineEmits<{
|
||||
'open-player': []
|
||||
'open-pdf': []
|
||||
}>()
|
||||
</script>
|
||||
@@ -6,7 +6,7 @@
|
||||
<ul class="flex flex-col gap-1">
|
||||
<li v-for="chapter in chapters" :key="chapter.path">
|
||||
<NuxtLink
|
||||
:to="`/modele-eco/${chapter.stem?.split('/').pop()}`"
|
||||
:to="`/economique/modele-eco/${chapter.stem?.split('/').pop()}`"
|
||||
class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors hover:bg-white/5"
|
||||
active-class="bg-primary/10 text-primary font-medium"
|
||||
>
|
||||
|
||||
@@ -56,15 +56,17 @@
|
||||
</div>
|
||||
<!-- Secondary row -->
|
||||
<div v-if="secondaryActions(item.actions).length" class="axis-actions-secondary">
|
||||
<button
|
||||
<component
|
||||
:is="action.to ? resolveComponent('NuxtLink') : 'button'"
|
||||
v-for="action in secondaryActions(item.actions)"
|
||||
:key="action.id"
|
||||
:key="action.label"
|
||||
:to="action.to"
|
||||
class="axis-action-btn axis-action-btn--secondary"
|
||||
@click.stop="handleAction(action.id)"
|
||||
@click.stop="!action.to && handleAction(action.id)"
|
||||
>
|
||||
<div :class="iconClass(action.icon)" class="h-3.5 w-3.5" />
|
||||
{{ action.label }}
|
||||
</button>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,6 +81,7 @@ interface AxisAction {
|
||||
icon: string
|
||||
highlight?: boolean
|
||||
secondary?: boolean
|
||||
to?: string
|
||||
}
|
||||
|
||||
interface AxisItem {
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
@open-pdf="$emit('open-pdf')"
|
||||
@launch-gratewizard="launchGW"
|
||||
/>
|
||||
|
||||
<!-- Bloc GrateWizard — dans la section économique -->
|
||||
<button v-if="gw" class="gw-block mt-4" @click="launchGW">
|
||||
<div class="gw-icon">
|
||||
<div class="i-lucide-sparkles h-5 w-5" />
|
||||
</div>
|
||||
<div class="gw-text">
|
||||
<h3 class="font-display text-base font-bold text-white sm:text-lg">
|
||||
{{ gw.title }}
|
||||
</h3>
|
||||
<p class="text-white/55 text-xs sm:text-sm mt-0.5">
|
||||
{{ gw.subtitle }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="gw-arrow">
|
||||
<div class="i-lucide-arrow-up-right h-4 w-4" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</UiScrollReveal>
|
||||
|
||||
@@ -40,26 +58,6 @@
|
||||
</div>
|
||||
</UiScrollReveal>
|
||||
|
||||
<!-- Bloc GrateWizard -->
|
||||
<UiScrollReveal v-if="gw" :delay="250">
|
||||
<button class="gw-block" @click="launchGW">
|
||||
<div class="gw-icon">
|
||||
<div class="i-lucide-sparkles h-7 w-7" />
|
||||
</div>
|
||||
<div class="gw-text">
|
||||
<h2 class="font-display text-xl font-bold text-white sm:text-2xl">
|
||||
{{ gw.title }}
|
||||
</h2>
|
||||
<p class="text-white/55 text-sm sm:text-base mt-0.5">
|
||||
{{ gw.subtitle }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="gw-arrow">
|
||||
<div class="i-lucide-arrow-up-right h-5 w-5" />
|
||||
</div>
|
||||
</button>
|
||||
</UiScrollReveal>
|
||||
|
||||
<!-- Bloc Événement -->
|
||||
<UiScrollReveal v-if="evenement" :delay="350">
|
||||
<NuxtLink :to="evenement.to" class="event-block">
|
||||
@@ -160,10 +158,10 @@ function launchGW() {
|
||||
.gw-block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.25rem;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
padding: 1.75rem 2rem;
|
||||
border-radius: 1rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, hsl(280 50% 20% / 0.35), hsl(260 40% 15% / 0.25));
|
||||
box-shadow: 0 0 40px hsl(280 60% 50% / 0.06), inset 0 1px 0 hsl(280 60% 70% / 0.08);
|
||||
@@ -187,9 +185,9 @@ function launchGW() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
border-radius: 0.875rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.625rem;
|
||||
background: hsl(280 60% 55% / 0.18);
|
||||
color: hsl(280 60% 72%);
|
||||
flex-shrink: 0;
|
||||
@@ -205,8 +203,8 @@ function launchGW() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
background: hsl(280 60% 55% / 0.1);
|
||||
color: hsl(280 60% 65%);
|
||||
|
||||
@@ -5,23 +5,6 @@
|
||||
<!-- Book cover -->
|
||||
<UiScrollReveal>
|
||||
<div class="book-cover-wrapper relative">
|
||||
<!-- Shadok pumper -->
|
||||
<svg class="shadok-pumper" viewBox="0 0 200 240" fill="none" aria-hidden="true">
|
||||
<ellipse cx="100" cy="130" rx="55" ry="65" fill="currentColor" opacity="0.9"/>
|
||||
<ellipse cx="100" cy="60" rx="30" ry="28" fill="currentColor" opacity="0.85"/>
|
||||
<circle cx="88" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="112" cy="54" r="6" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="90" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="114" cy="53" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||
<polygon points="100,68 115,78 85,78" fill="currentColor" opacity="0.6"/>
|
||||
<line x1="80" y1="192" x2="70" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||
<line x1="120" y1="192" x2="130" y2="230" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.7"/>
|
||||
<line x1="70" y1="230" x2="55" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||
<line x1="130" y1="230" x2="145" y2="232" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
|
||||
<line x1="155" y1="110" x2="190" y2="90" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="190" y1="90" x2="190" y2="120" stroke="currentColor" stroke-width="4" stroke-linecap="round" opacity="0.6"/>
|
||||
<rect x="180" y="118" width="18" height="40" rx="3" fill="currentColor" opacity="0.4"/>
|
||||
</svg>
|
||||
<div class="book-cover-3d">
|
||||
<img
|
||||
:src="content?.book.coverImage"
|
||||
@@ -48,16 +31,11 @@
|
||||
</UiScrollReveal>
|
||||
|
||||
<UiScrollReveal :delay="200">
|
||||
<div class="mt-8 flex flex-col gap-3 sm:flex-row sm:gap-4">
|
||||
<UiBaseButton @click="$emit('open-player')">
|
||||
<div class="i-lucide-play mr-2 h-5 w-5" />
|
||||
{{ content?.book.cta.player }}
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="accent" @click="$emit('open-pdf')">
|
||||
<div class="i-lucide-book-open mr-2 h-5 w-5" />
|
||||
{{ content?.book.cta.pdf }}
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
<BookActions
|
||||
:show-chapters="showChapters"
|
||||
@open-player="$emit('open-player')"
|
||||
@open-pdf="$emit('open-pdf')"
|
||||
/>
|
||||
</UiScrollReveal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,6 +44,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
withDefaults(defineProps<{
|
||||
showChapters?: boolean
|
||||
}>(), {
|
||||
showChapters: true,
|
||||
})
|
||||
|
||||
defineEmits<{
|
||||
'open-player': []
|
||||
'open-pdf': []
|
||||
@@ -111,25 +95,4 @@ const { data: content } = await usePageContent('home')
|
||||
.heading-section {
|
||||
font-size: clamp(1.625rem, 4vw, 2.125rem);
|
||||
}
|
||||
|
||||
.shadok-pumper {
|
||||
position: absolute;
|
||||
right: 3%;
|
||||
bottom: 8%;
|
||||
width: clamp(90px, 12vw, 180px);
|
||||
opacity: 0.28;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float 10s ease-in-out infinite;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@keyframes shadok-float {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-pumper { display: none; }
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
<p class="text-sm text-white/50">Identité, navigation, footer</p>
|
||||
</NuxtLink>
|
||||
|
||||
<NuxtLink to="/admin/pages/home" class="dash-card">
|
||||
<div class="i-lucide-home h-8 w-8 text-primary mb-2" />
|
||||
<NuxtLink to="/admin/pages" class="dash-card">
|
||||
<div class="i-lucide-file-text h-8 w-8 text-primary mb-2" />
|
||||
<h2 class="text-lg font-semibold text-white">Pages</h2>
|
||||
<p class="text-sm text-white/50">Contenus des pages publiques</p>
|
||||
</NuxtLink>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<NuxtLink to="/admin" class="text-sm text-white/40 hover:text-white/60 transition-colors">
|
||||
← Dashboard
|
||||
<NuxtLink to="/admin/pages" class="text-sm text-white/40 hover:text-white/60 transition-colors">
|
||||
← Pages
|
||||
</NuxtLink>
|
||||
<h1 class="font-display text-2xl font-bold text-white mt-1">
|
||||
Page : {{ pageName }}
|
||||
Page : {{ pagePath }}
|
||||
</h1>
|
||||
</div>
|
||||
<AdminSaveButton :saving="saving" :saved="saved" @save="save" />
|
||||
@@ -40,9 +40,12 @@ definePageMeta({
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
const pageName = computed(() => route.params.name as string)
|
||||
const pagePath = computed(() => {
|
||||
const p = route.params.path
|
||||
return Array.isArray(p) ? p.join('/') : p
|
||||
})
|
||||
|
||||
const { data, error } = await useFetch(() => `/api/content/pages/${pageName.value}`)
|
||||
const { data, error } = await useFetch(() => `/api/content/pages/${pagePath.value}`)
|
||||
|
||||
const yamlContent = ref('')
|
||||
|
||||
@@ -60,7 +63,7 @@ async function save() {
|
||||
saved.value = false
|
||||
try {
|
||||
const parsed = yaml.parse(yamlContent.value)
|
||||
await $fetch(`/api/admin/content/pages/${pageName.value}`, {
|
||||
await $fetch(`/api/admin/content/pages/${pagePath.value}`, {
|
||||
method: 'PUT',
|
||||
body: parsed,
|
||||
})
|
||||
97
app/pages/admin/pages/index.vue
Normal file
97
app/pages/admin/pages/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<NuxtLink to="/admin" class="text-sm text-white/40 hover:text-white/60 transition-colors">
|
||||
← Dashboard
|
||||
</NuxtLink>
|
||||
<h1 class="font-display text-2xl font-bold text-white mt-1">Pages</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="pages" class="flex flex-col gap-6">
|
||||
<!-- Root pages -->
|
||||
<div v-if="rootPages.length">
|
||||
<h2 class="font-display text-lg font-semibold text-white/80 mb-3">Pages principales</h2>
|
||||
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<NuxtLink
|
||||
v-for="page in rootPages"
|
||||
:key="page.path"
|
||||
:to="`/admin/pages/${page.path}`"
|
||||
class="page-card"
|
||||
>
|
||||
<div class="i-lucide-file-text h-5 w-5 text-primary mb-1" />
|
||||
<span class="font-mono text-sm text-white">{{ page.label }}</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section pages -->
|
||||
<div v-for="[section, sectionPages] in sections" :key="section">
|
||||
<h2 class="font-display text-lg font-semibold text-white/80 mb-3">
|
||||
<span class="i-lucide-folder h-4 w-4 inline-block mr-1 text-accent" />
|
||||
{{ section }}
|
||||
</h2>
|
||||
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<NuxtLink
|
||||
v-for="page in sectionPages"
|
||||
:key="page.path"
|
||||
:to="`/admin/pages/${page.path}`"
|
||||
class="page-card"
|
||||
>
|
||||
<div class="i-lucide-file-text h-5 w-5 text-primary/60 mb-1" />
|
||||
<span class="font-mono text-sm text-white">{{ page.label }}</span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'admin',
|
||||
middleware: 'admin',
|
||||
})
|
||||
|
||||
interface PageEntry {
|
||||
path: string
|
||||
label: string
|
||||
section?: string
|
||||
}
|
||||
|
||||
const { data: pages } = await useFetch<PageEntry[]>('/api/admin/content/pages')
|
||||
|
||||
const rootPages = computed(() =>
|
||||
(pages.value ?? []).filter(p => !p.section),
|
||||
)
|
||||
|
||||
const sections = computed(() => {
|
||||
const map = new Map<string, PageEntry[]>()
|
||||
for (const p of pages.value ?? []) {
|
||||
if (p.section) {
|
||||
if (!map.has(p.section)) map.set(p.section, [])
|
||||
map.get(p.section)!.push(p)
|
||||
}
|
||||
}
|
||||
return Array.from(map.entries())
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid hsl(20 8% 14%);
|
||||
background: hsl(20 8% 6%);
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.page-card:hover {
|
||||
border-color: hsl(12 76% 48% / 0.3);
|
||||
background: hsl(20 8% 8%);
|
||||
}
|
||||
</style>
|
||||
159
app/pages/citoyenne/[slug].vue
Normal file
159
app/pages/citoyenne/[slug].vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="section-icon mx-auto mb-6">
|
||||
<div :class="`i-lucide-${content?.icon ?? 'landmark'}`" class="h-12 w-12" />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase text-center">
|
||||
{{ content?.kicker }}
|
||||
</p>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold mb-4 text-center" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title ?? slug }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8 text-center" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
|
||||
<!-- Features grid (for decision page) -->
|
||||
<div v-if="content?.features" class="grid gap-4 sm:grid-cols-2 mb-12">
|
||||
<div v-for="feature in content.features" :key="feature.title" class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div :class="`i-lucide-${feature.icon} h-5 w-5`" />
|
||||
</div>
|
||||
<h3 class="font-display font-semibold mb-1" style="color: hsl(var(--color-text))">{{ feature.title }}</h3>
|
||||
<p class="text-sm leading-relaxed" style="color: hsl(var(--color-text-muted))">{{ feature.text }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Project card -->
|
||||
<div v-if="content?.project" class="project-card mb-8">
|
||||
<div class="project-icon">
|
||||
<div class="i-lucide-rocket h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-semibold mb-2" style="color: hsl(var(--color-text))">
|
||||
{{ content.project.name }}
|
||||
</h2>
|
||||
<p style="color: hsl(var(--color-text-muted))" class="leading-relaxed">
|
||||
{{ content.project.text }}
|
||||
</p>
|
||||
<span v-if="content?.gestation" class="gestation-badge mt-3">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Extended content -->
|
||||
<div v-if="content?.content" class="prose-block mb-10">
|
||||
<p class="leading-relaxed whitespace-pre-line" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content.content }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center flex flex-col items-center gap-3 sm:flex-row sm:justify-center">
|
||||
<UiBaseButton v-if="slug === 'decision'" :href="decisionUrl" target="_blank">
|
||||
<div class="i-lucide-external-link mr-2 h-4 w-4" />
|
||||
Ouvrir Glibredecision
|
||||
</UiBaseButton>
|
||||
<UiBaseButton v-if="slug === 'tarifs-eau'" :href="sejeteral0Url" target="_blank">
|
||||
<div class="i-lucide-external-link mr-2 h-4 w-4" />
|
||||
Lancer SejeteralO
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="ghost" to="/citoyenne">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Autonomie citoyenne
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const slug = route.params.slug as string
|
||||
|
||||
const { data: content } = await usePageContent(`citoyenne/${slug}`)
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const decisionUrl = (appConfig.libredecision as { url: string })?.url ?? '#'
|
||||
const sejeteral0Url = (appConfig.sejeteral0 as { url: string })?.url ?? '#'
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? slug,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.section-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
padding: 1.25rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-primary) / 0.15);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.project-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.prose-block {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
</style>
|
||||
631
app/pages/citoyenne/index.vue
Normal file
631
app/pages/citoyenne/index.vue
Normal file
@@ -0,0 +1,631 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- 1. Shadok Capitaine (top-left, profile — at ship's wheel, telescope) -->
|
||||
<svg class="shadok shadok-capitaine" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- ship's wheel -->
|
||||
<circle cx="50" cy="130" r="28" stroke="currentColor" stroke-width="3" fill="none" opacity="0.35"/>
|
||||
<line x1="50" y1="102" x2="50" y2="158" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="22" y1="130" x2="78" y2="130" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="30" y1="110" x2="70" y2="150" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="70" y1="110" x2="30" y2="150" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<!-- wheel spokes knobs -->
|
||||
<circle cx="50" cy="100" r="3" fill="currentColor" opacity="0.4"/>
|
||||
<circle cx="50" cy="160" r="3" fill="currentColor" opacity="0.4"/>
|
||||
<circle cx="20" cy="130" r="3" fill="currentColor" opacity="0.4"/>
|
||||
<circle cx="80" cy="130" r="3" fill="currentColor" opacity="0.4"/>
|
||||
<!-- body (small oval, profile facing right) -->
|
||||
<ellipse cx="85" cy="110" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- head -->
|
||||
<circle cx="92" cy="68" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- captain hat -->
|
||||
<rect x="76" y="52" width="32" height="8" rx="4" fill="currentColor" opacity="0.4"/>
|
||||
<rect x="80" y="46" width="24" height="8" rx="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- hat brim detail -->
|
||||
<ellipse cx="92" cy="60" rx="18" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- eyes (looking right through telescope) -->
|
||||
<circle cx="98" cy="65" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="90" cy="66" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- beak (pointy, profile right) -->
|
||||
<polygon points="108,68 120,65 108,72" fill="currentColor" opacity="0.35"/>
|
||||
<!-- left arm on wheel -->
|
||||
<line x1="65" y1="100" x2="55" y2="115" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- right arm holding telescope -->
|
||||
<line x1="105" y1="95" x2="130" y2="72" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- telescope -->
|
||||
<rect x="128" y="66" width="30" height="7" rx="3.5" fill="currentColor" opacity="0.4"/>
|
||||
<rect x="155" y="64" width="10" height="11" rx="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- left leg (long, forward) -->
|
||||
<line x1="75" y1="135" x2="60" y2="190" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- left foot -->
|
||||
<ellipse cx="55" cy="193" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- right leg (long, back) -->
|
||||
<line x1="92" y1="136" x2="100" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- right foot -->
|
||||
<ellipse cx="103" cy="195" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 2. Shadok Avocate (top-right — robe, scroll, arm up) -->
|
||||
<svg class="shadok shadok-avocate" viewBox="0 0 160 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- body (small oval) -->
|
||||
<ellipse cx="80" cy="115" rx="22" ry="30" fill="currentColor" opacity="0.25"/>
|
||||
<!-- robe/gown flowing -->
|
||||
<path d="M58 100 Q55 145 48 175 L112 175 Q105 145 102 100 Z" fill="currentColor" opacity="0.18"/>
|
||||
<!-- robe collar -->
|
||||
<path d="M68 88 Q80 96 92 88" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.35"/>
|
||||
<!-- head -->
|
||||
<circle cx="80" cy="70" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (looking up-left) -->
|
||||
<circle cx="74" cy="67" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="83" cy="68" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- beak (3/4 view, slight left) -->
|
||||
<polygon points="68,72 56,69 66,76" fill="currentColor" opacity="0.35"/>
|
||||
<!-- left arm up dramatically -->
|
||||
<line x1="60" y1="100" x2="30" y2="55" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- open hand at top -->
|
||||
<line x1="30" y1="55" x2="24" y2="46" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="30" y1="55" x2="28" y2="44" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="30" y1="55" x2="34" y2="46" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- right arm holding scroll -->
|
||||
<line x1="100" y1="102" x2="125" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- scroll document (big) -->
|
||||
<rect x="120" y="72" width="28" height="40" rx="3" fill="currentColor" opacity="0.25"/>
|
||||
<!-- scroll curl top -->
|
||||
<ellipse cx="134" cy="72" rx="14" ry="5" fill="currentColor" opacity="0.2"/>
|
||||
<!-- scroll curl bottom -->
|
||||
<ellipse cx="134" cy="112" rx="12" ry="4" fill="currentColor" opacity="0.2"/>
|
||||
<!-- scroll text lines -->
|
||||
<line x1="126" y1="82" x2="142" y2="82" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<line x1="126" y1="88" x2="140" y2="88" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<line x1="126" y1="94" x2="143" y2="94" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<line x1="126" y1="100" x2="138" y2="100" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<!-- left leg (long) -->
|
||||
<line x1="72" y1="142" x2="62" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="58" cy="198" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- right leg -->
|
||||
<line x1="88" y1="142" x2="95" y2="196" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="99" cy="199" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 3. Shadok Vigie (left — crow's nest, looking far) -->
|
||||
<svg class="shadok shadok-vigie" viewBox="0 0 140 220" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- mast pole -->
|
||||
<line x1="70" y1="90" x2="70" y2="218" stroke="currentColor" stroke-width="4" opacity="0.3"/>
|
||||
<!-- crow's nest platform -->
|
||||
<path d="M38 88 L42 100 L98 100 L102 88 Z" fill="currentColor" opacity="0.25"/>
|
||||
<line x1="36" y1="88" x2="104" y2="88" stroke="currentColor" stroke-width="3" opacity="0.35"/>
|
||||
<!-- nest railing -->
|
||||
<line x1="40" y1="78" x2="40" y2="100" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="100" y1="78" x2="100" y2="100" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="40" y1="78" x2="100" y2="78" stroke="currentColor" stroke-width="2" opacity="0.25"/>
|
||||
<!-- body (small, inside nest) -->
|
||||
<ellipse cx="70" cy="72" rx="20" ry="22" fill="currentColor" opacity="0.25"/>
|
||||
<!-- head -->
|
||||
<circle cx="70" cy="38" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (squinting, looking right far) -->
|
||||
<circle cx="78" cy="35" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="70" cy="36" r="2" fill="currentColor" opacity="0.4"/>
|
||||
<!-- beak (profile right) -->
|
||||
<polygon points="83,38 96,35 84,42" fill="currentColor" opacity="0.35"/>
|
||||
<!-- right hand shielding eyes -->
|
||||
<line x1="88" y1="55" x2="98" y2="35" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="96" y1="33" x2="108" y2="30" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- left arm resting on railing -->
|
||||
<line x1="52" y1="60" x2="42" y2="78" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- legs dangling below nest (long!) -->
|
||||
<line x1="60" y1="98" x2="52" y2="160" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="48" cy="163" rx="8" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="80" y1="98" x2="86" y2="158" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="90" cy="161" rx="8" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 4. Shadok Comedien (right — theater masks, cape, leg lifted) -->
|
||||
<svg class="shadok shadok-comedien" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- dramatic cape -->
|
||||
<path d="M65 85 Q40 120 35 180 L115 180 Q110 120 95 85 Z" fill="currentColor" opacity="0.15"/>
|
||||
<path d="M95 85 Q120 100 135 160 Q130 165 115 180" fill="currentColor" opacity="0.1"/>
|
||||
<!-- body (small oval) -->
|
||||
<ellipse cx="80" cy="105" rx="20" ry="26" fill="currentColor" opacity="0.25"/>
|
||||
<!-- head -->
|
||||
<circle cx="80" cy="62" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (different directions — dramatic!) -->
|
||||
<circle cx="74" cy="59" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="86" cy="61" r="2.5" fill="currentColor" opacity="0.55"/>
|
||||
<!-- beak -->
|
||||
<polygon points="72,66 60,63 70,70" fill="currentColor" opacity="0.35"/>
|
||||
<!-- left arm up holding comedy mask -->
|
||||
<line x1="62" y1="92" x2="32" y2="55" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- comedy mask (big, smiling) -->
|
||||
<circle cx="25" cy="42" r="16" fill="currentColor" opacity="0.2"/>
|
||||
<path d="M17 46 Q25 56 33 46" stroke="currentColor" stroke-width="2" fill="none" opacity="0.4"/>
|
||||
<circle cx="20" cy="38" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="30" cy="38" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- right arm out holding tragedy mask -->
|
||||
<line x1="98" y1="92" x2="135" y2="65" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- tragedy mask (big, frowning) -->
|
||||
<circle cx="145" cy="55" r="16" fill="currentColor" opacity="0.2"/>
|
||||
<path d="M137 62 Q145 54 153 62" stroke="currentColor" stroke-width="2" fill="none" opacity="0.4"/>
|
||||
<circle cx="140" cy="50" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="150" cy="50" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- left leg (long, planted) -->
|
||||
<line x1="72" y1="128" x2="62" y2="190" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="58" cy="193" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- right leg (lifted dramatically!) -->
|
||||
<line x1="88" y1="126" x2="115" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="120" cy="167" rx="8" ry="4" transform="rotate(-25 120 167)" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 5. Shadok Cartographe (bottom-left — sitting, map, compass) -->
|
||||
<svg class="shadok shadok-cartographe" viewBox="0 0 180 190" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- table -->
|
||||
<rect x="20" y="125" width="140" height="6" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="35" y1="131" x2="30" y2="185" stroke="currentColor" stroke-width="3" opacity="0.25"/>
|
||||
<line x1="145" y1="131" x2="150" y2="185" stroke="currentColor" stroke-width="3" opacity="0.25"/>
|
||||
<!-- big map spread on table -->
|
||||
<rect x="30" y="108" width="110" height="18" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<!-- map details -->
|
||||
<path d="M45 112 Q65 108 85 115 Q105 110 125 114" stroke="currentColor" stroke-width="1" fill="none" opacity="0.25"/>
|
||||
<circle cx="75" cy="115" r="3" stroke="currentColor" stroke-width="1" fill="none" opacity="0.2"/>
|
||||
<line x1="95" y1="110" x2="95" y2="122" stroke="currentColor" stroke-width="0.8" opacity="0.2"/>
|
||||
<!-- body (small, hunched over map) -->
|
||||
<ellipse cx="90" cy="88" rx="22" ry="25" fill="currentColor" opacity="0.25" transform="rotate(10 90 88)"/>
|
||||
<!-- head (bent down looking at map) -->
|
||||
<circle cx="78" cy="60" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (looking down at map) -->
|
||||
<circle cx="74" cy="64" r="2" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="83" cy="65" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- beak (pointing down) -->
|
||||
<polygon points="72,70 65,78 78,72" fill="currentColor" opacity="0.35"/>
|
||||
<!-- right arm holding compass tool -->
|
||||
<line x1="110" y1="92" x2="130" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- compass/divider tool (big V shape) -->
|
||||
<line x1="130" y1="105" x2="125" y2="125" stroke="currentColor" stroke-width="2.5" opacity="0.4"/>
|
||||
<line x1="130" y1="105" x2="140" y2="125" stroke="currentColor" stroke-width="2.5" opacity="0.4"/>
|
||||
<circle cx="130" cy="103" r="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- left arm holding magnifying glass -->
|
||||
<line x1="70" y1="90" x2="48" y2="100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- magnifying glass (big) -->
|
||||
<circle cx="38" cy="96" r="12" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.35"/>
|
||||
<line x1="48" y1="103" x2="55" y2="112" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- legs (sitting, bent under table) -->
|
||||
<line x1="78" y1="110" x2="65" y2="145" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="65" y1="145" x2="50" y2="148" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<ellipse cx="45" cy="150" rx="8" ry="3.5" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="100" y1="110" x2="110" y2="145" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="110" y1="145" x2="122" y2="148" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<ellipse cx="127" cy="150" rx="8" ry="3.5" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 6. Shadok Juge (bottom-right — on bench, gavel, wig) -->
|
||||
<svg class="shadok shadok-juge" viewBox="0 0 160 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- elevated bench/podium -->
|
||||
<rect x="30" y="145" width="100" height="55" rx="4" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="25" y="138" width="110" height="10" rx="3" fill="currentColor" opacity="0.28"/>
|
||||
<!-- bench front panel detail -->
|
||||
<rect x="55" y="155" width="50" height="35" rx="3" fill="currentColor" opacity="0.1"/>
|
||||
<!-- body (small, seated) -->
|
||||
<ellipse cx="80" cy="112" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- head -->
|
||||
<circle cx="80" cy="68" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- judge wig (curly puffs) -->
|
||||
<circle cx="66" cy="60" r="6" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="94" cy="60" r="6" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="72" cy="54" r="5" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="88" cy="54" r="5" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="80" cy="52" r="5.5" fill="currentColor" opacity="0.2"/>
|
||||
<!-- wig curls hanging -->
|
||||
<circle cx="63" cy="70" r="4.5" fill="currentColor" opacity="0.15"/>
|
||||
<circle cx="97" cy="70" r="4.5" fill="currentColor" opacity="0.15"/>
|
||||
<!-- eyes (stern, both forward) -->
|
||||
<circle cx="74" cy="66" r="2.5" fill="currentColor" opacity="0.65"/>
|
||||
<circle cx="86" cy="66" r="2.5" fill="currentColor" opacity="0.65"/>
|
||||
<!-- stern eyebrows -->
|
||||
<line x1="71" y1="62" x2="77" y2="63" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="89" y1="63" x2="83" y2="62" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- beak (small, stern) -->
|
||||
<polygon points="80,74 72,78 80,80" fill="currentColor" opacity="0.35"/>
|
||||
<!-- right arm raising gavel -->
|
||||
<line x1="100" y1="98" x2="130" y2="60" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- gavel (big!) -->
|
||||
<rect x="120" y="44" width="26" height="12" rx="4" fill="currentColor" opacity="0.4"/>
|
||||
<line x1="133" y1="56" x2="133" y2="38" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- left arm on bench -->
|
||||
<line x1="60" y1="100" x2="40" y2="130" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- legs (dangling from bench, long) -->
|
||||
<line x1="72" y1="138" x2="62" y2="200" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="58" cy="203" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="88" y1="138" x2="96" y2="198" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="100" cy="201" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 7. Shadok Matelot (center-bottom — pulling rope, leaning back, anchor) -->
|
||||
<svg class="shadok shadok-matelot" viewBox="0 0 160 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- rope going up and off -->
|
||||
<path d="M30 20 Q35 50 55 70 Q65 78 68 85" stroke="currentColor" stroke-width="3" fill="none" opacity="0.3"/>
|
||||
<!-- body (leaning back, tilted) -->
|
||||
<ellipse cx="85" cy="108" rx="20" ry="27" fill="currentColor" opacity="0.25" transform="rotate(-15 85 108)"/>
|
||||
<!-- head -->
|
||||
<circle cx="95" cy="68" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- bandana -->
|
||||
<path d="M80 62 Q95 55 110 62" stroke="currentColor" stroke-width="3" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="108" y1="60" x2="118" y2="55" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="108" y1="62" x2="116" y2="60" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.2"/>
|
||||
<!-- eyes (straining, squinting) -->
|
||||
<circle cx="90" cy="66" r="2" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="100" cy="65" r="2.5" fill="currentColor" opacity="0.55"/>
|
||||
<!-- beak -->
|
||||
<polygon points="104,70 115,67 105,74" fill="currentColor" opacity="0.35"/>
|
||||
<!-- both arms pulling rope -->
|
||||
<line x1="68" y1="95" x2="55" y2="78" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="75" y1="98" x2="62" y2="82" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- left leg (long, bracing forward) -->
|
||||
<line x1="72" y1="130" x2="48" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="43" cy="188" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- right leg (long, back) -->
|
||||
<line x1="92" y1="132" x2="110" y2="188" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="114" cy="191" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- anchor nearby -->
|
||||
<line x1="135" y1="140" x2="135" y2="185" stroke="currentColor" stroke-width="3" opacity="0.3"/>
|
||||
<circle cx="135" cy="138" r="5" stroke="currentColor" stroke-width="2" fill="none" opacity="0.25"/>
|
||||
<path d="M120 180 Q135 195 150 180" stroke="currentColor" stroke-width="3" fill="none" opacity="0.3"/>
|
||||
<line x1="120" y1="180" x2="117" y2="174" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="150" y1="180" x2="153" y2="174" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- 8. Shadok Mime (right — pushing invisible wall, striped shirt, beret) -->
|
||||
<svg class="shadok shadok-mime" viewBox="0 0 150 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<!-- body (small oval) -->
|
||||
<ellipse cx="70" cy="112" rx="22" ry="28" fill="currentColor" opacity="0.2"/>
|
||||
<!-- striped shirt lines -->
|
||||
<line x1="52" y1="96" x2="88" y2="96" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="50" y1="102" x2="90" y2="102" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="50" y1="108" x2="90" y2="108" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="50" y1="114" x2="90" y2="114" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="52" y1="120" x2="88" y2="120" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="54" y1="126" x2="86" y2="126" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<!-- head (white face = lighter) -->
|
||||
<circle cx="75" cy="65" r="16" fill="currentColor" opacity="0.2"/>
|
||||
<!-- white face highlight -->
|
||||
<circle cx="75" cy="65" r="13" fill="currentColor" opacity="0.08"/>
|
||||
<!-- beret -->
|
||||
<ellipse cx="75" cy="50" rx="18" ry="6" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="75" cy="46" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<!-- eyes (expressive, wide) -->
|
||||
<circle cx="69" cy="62" r="3" fill="currentColor" opacity="0.55"/>
|
||||
<circle cx="81" cy="62" r="3" fill="currentColor" opacity="0.55"/>
|
||||
<!-- raised eyebrows (surprised) -->
|
||||
<path d="M66 57 Q69 54 72 57" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.4"/>
|
||||
<path d="M78 57 Q81 54 84 57" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.4"/>
|
||||
<!-- beak (small) -->
|
||||
<polygon points="75,72 68,76 75,78" fill="currentColor" opacity="0.3"/>
|
||||
<!-- both arms pushing against invisible wall (to the right) -->
|
||||
<line x1="90" y1="100" x2="125" y2="85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="90" y1="115" x2="125" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- flat hands pressed against wall -->
|
||||
<rect x="124" y="78" width="12" height="15" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="124" y="103" width="12" height="15" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- invisible wall hint (faint line) -->
|
||||
<line x1="138" y1="50" x2="138" y2="180" stroke="currentColor" stroke-width="1" stroke-dasharray="4 6" opacity="0.12"/>
|
||||
<!-- left leg (long, leaning forward) -->
|
||||
<line x1="60" y1="138" x2="45" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="40" cy="198" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- right leg (long, back) -->
|
||||
<line x1="80" y1="138" x2="95" y2="194" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="99" cy="197" rx="9" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl leading-relaxed" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl flex flex-col gap-6">
|
||||
<!-- Decision collective -->
|
||||
<div class="item-card">
|
||||
<NuxtLink to="/citoyenne/decision" class="item-body group">
|
||||
<div class="item-header">
|
||||
<div class="item-icon">
|
||||
<div class="i-lucide-gavel h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
|
||||
Décision collective
|
||||
</h2>
|
||||
</div>
|
||||
<p class="leading-relaxed mt-3" style="color: hsl(var(--color-text-muted))">
|
||||
Se donner les moyens de la décision collective.
|
||||
</p>
|
||||
<div class="mt-3 inline-flex items-center gap-1 text-sm text-primary group-hover:text-primary/80 transition-colors">
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</div>
|
||||
</NuxtLink>
|
||||
<div class="item-actions">
|
||||
<a :href="decisionUrl" target="_blank" rel="noopener" class="action-btn action-btn--primary">
|
||||
<div class="i-lucide-external-link h-3.5 w-3.5" />
|
||||
Ouvrir Glibredecision
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tarifs de l'eau -->
|
||||
<div class="item-card">
|
||||
<NuxtLink to="/citoyenne/tarifs-eau" class="item-body group">
|
||||
<div class="item-header">
|
||||
<div class="item-icon">
|
||||
<div class="i-lucide-droplets h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
|
||||
Tarifs de l'eau
|
||||
</h2>
|
||||
<span class="gestation-badge">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
<p class="leading-relaxed mt-3" style="color: hsl(var(--color-text-muted))">
|
||||
Application pour obtenir justice sociale et incitation dynamique à la réduction.
|
||||
Permet de confier la décision à la population des communes.
|
||||
</p>
|
||||
<div class="mt-3 inline-flex items-center gap-1 text-sm text-primary group-hover:text-primary/80 transition-colors">
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</div>
|
||||
</NuxtLink>
|
||||
<div class="item-actions">
|
||||
<a :href="sejeteral0Url" target="_blank" rel="noopener" class="action-btn action-btn--primary">
|
||||
<div class="i-lucide-external-link h-3.5 w-3.5" />
|
||||
Lancer SejeteralO
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('citoyenne')
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const decisionUrl = (appConfig.libredecision as { url: string })?.url ?? '#'
|
||||
const sejeteral0Url = (appConfig.sejeteral0 as { url: string })?.url ?? '#'
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Autonomie citoyenne',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
.item-card {
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
transition: border-color 0.2s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-card:hover {
|
||||
border-color: hsl(var(--color-primary) / 0.2);
|
||||
}
|
||||
|
||||
.item-body {
|
||||
display: block;
|
||||
padding: 1.5rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.15);
|
||||
color: hsl(var(--color-primary));
|
||||
box-shadow: 0 0 12px hsl(var(--color-primary) / 0.12);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
margin-left: auto;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.375rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-top: 1px solid hsl(var(--color-text) / 0.06);
|
||||
background: hsl(var(--color-bg) / 0.4);
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
padding: 0.375rem 0.75rem;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.action-btn--primary {
|
||||
color: hsl(var(--color-primary));
|
||||
background: hsl(var(--color-primary) / 0.12);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.25);
|
||||
}
|
||||
|
||||
.action-btn--primary:hover {
|
||||
background: hsl(var(--color-primary) / 0.2);
|
||||
border-color: hsl(var(--color-primary) / 0.4);
|
||||
}
|
||||
|
||||
/* Shadok illustrations */
|
||||
.shadok {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.shadok-capitaine {
|
||||
top: 2%;
|
||||
left: 2%;
|
||||
color: hsl(var(--color-primary));
|
||||
opacity: 0.22;
|
||||
animation: shadok-float-1 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-avocate {
|
||||
top: 1%;
|
||||
right: 2%;
|
||||
color: hsl(var(--color-accent));
|
||||
opacity: 0.2;
|
||||
animation: shadok-float-2 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-vigie {
|
||||
left: 2%;
|
||||
top: 38%;
|
||||
color: hsl(var(--color-primary));
|
||||
opacity: 0.24;
|
||||
animation: shadok-float-3 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-comedien {
|
||||
right: 3%;
|
||||
top: 35%;
|
||||
color: hsl(var(--color-accent));
|
||||
opacity: 0.2;
|
||||
animation: shadok-float-4 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-cartographe {
|
||||
bottom: 10%;
|
||||
left: 1%;
|
||||
color: hsl(var(--color-accent));
|
||||
opacity: 0.22;
|
||||
animation: shadok-float-5 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-juge {
|
||||
bottom: 6%;
|
||||
right: 1%;
|
||||
color: hsl(var(--color-primary));
|
||||
opacity: 0.24;
|
||||
animation: shadok-float-6 9.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-matelot {
|
||||
bottom: 2%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: hsl(var(--color-primary));
|
||||
opacity: 0.18;
|
||||
animation: shadok-float-7 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-mime {
|
||||
right: 2%;
|
||||
top: 55%;
|
||||
color: hsl(var(--color-accent));
|
||||
opacity: 0.28;
|
||||
animation: shadok-float-8 10.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-1 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-2 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-3 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-7px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-4 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-9px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-5 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-6px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-6 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-7 {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-7px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-8 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,104 +0,0 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<!-- Header -->
|
||||
<div class="text-center mb-12">
|
||||
<div class="decision-icon mx-auto mb-6">
|
||||
<div class="i-lucide-gavel h-10 w-10" />
|
||||
</div>
|
||||
<h1 class="font-display text-4xl font-bold text-white mb-4">Plateforme Décision</h1>
|
||||
<p class="text-lg text-white/60 leading-relaxed">
|
||||
Se donner les moyens de la décision collective.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<div class="grid gap-4 sm:grid-cols-2 mb-12">
|
||||
<div v-for="feature in features" :key="feature.title" class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div :class="`i-lucide-${feature.icon} h-5 w-5`" />
|
||||
</div>
|
||||
<h3 class="font-display font-semibold text-white mb-1">{{ feature.title }}</h3>
|
||||
<p class="text-sm text-white/50 leading-relaxed">{{ feature.text }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA -->
|
||||
<div class="text-center flex flex-col items-center gap-3 sm:flex-row sm:justify-center">
|
||||
<UiBaseButton :href="decisionUrl" target="_blank">
|
||||
<div class="i-lucide-external-link mr-2 h-4 w-4" />
|
||||
Ouvrir Glibredecision
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="ghost" to="/">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Retour à l'accueil
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
useHead({ title: 'Décision collective' })
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const decisionUrl = (appConfig.libredecision as { url: string }).url
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: 'vote',
|
||||
title: 'Décisions on-chain',
|
||||
text: 'Des décisions transparentes et vérifiables, inscrites sur la blockchain.',
|
||||
},
|
||||
{
|
||||
icon: 'scroll-text',
|
||||
title: 'Les Mandats',
|
||||
text: 'Formaliser et suivre les mandats confiés aux personnes désignées.',
|
||||
},
|
||||
{
|
||||
icon: 'scroll-text',
|
||||
title: 'Documents de référence',
|
||||
text: 'Les textes fondateurs et documents qui encadrent la prise de décision.',
|
||||
},
|
||||
{
|
||||
icon: 'git-branch',
|
||||
title: 'Les Protocoles',
|
||||
text: 'Les règles et processus qui structurent la décision collective.',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.decision-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
padding: 1.25rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
453
app/pages/economique/commande.vue
Normal file
453
app/pages/economique/commande.vue
Normal file
@@ -0,0 +1,453 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok 1 : Libraire — behind counter, 3/4 view, glasses, recommending a book -->
|
||||
<svg class="shadok-libraire" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Body (small oval) -->
|
||||
<ellipse cx="75" cy="95" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head -->
|
||||
<circle cx="75" cy="58" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes looking right (recommending) -->
|
||||
<circle cx="80" cy="55" r="2" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="86" cy="54" r="2" fill="currentColor" opacity="0.6"/>
|
||||
<!-- Glasses on beak -->
|
||||
<circle cx="80" cy="55" r="5" stroke="currentColor" stroke-width="1.2" fill="none" opacity="0.4"/>
|
||||
<circle cx="86" cy="54" r="5" stroke="currentColor" stroke-width="1.2" fill="none" opacity="0.4"/>
|
||||
<line x1="85" y1="55" x2="81" y2="54" stroke="currentColor" stroke-width="1" opacity="0.3"/>
|
||||
<!-- Beak (pointy, triangular) -->
|
||||
<polygon points="90,58 102,55 90,52" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arm holding book out to customer -->
|
||||
<line x1="97" y1="88" x2="125" y2="78" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Book in hand (big, detailed) -->
|
||||
<rect x="120" y="70" width="18" height="24" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<rect x="122" y="73" width="14" height="3" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="129" y1="70" x2="129" y2="94" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<!-- Other arm resting on counter -->
|
||||
<line x1="53" y1="90" x2="35" y2="108" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Counter (big) -->
|
||||
<rect x="10" y="120" width="140" height="10" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="15" y="130" width="130" height="6" rx="1" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Stack of books on counter -->
|
||||
<rect x="25" y="105" width="22" height="15" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="28" y="98" width="18" height="7" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="30" y="93" width="14" height="5" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Legs (long!) -->
|
||||
<line x1="65" y1="123" x2="55" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="85" y1="123" x2="95" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="50" cy="188" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="100" cy="188" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok 2 : Factrice — running profile, letter carrier bag, letters flying, cap -->
|
||||
<svg class="shadok-factrice" viewBox="0 0 180 200" fill="none" aria-hidden="true">
|
||||
<!-- Body (small oval, leaning forward) -->
|
||||
<ellipse cx="80" cy="80" rx="20" ry="26" fill="currentColor" opacity="0.25" transform="rotate(-15 80 80)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="95" cy="48" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Cap -->
|
||||
<rect x="82" y="34" width="28" height="7" rx="3" fill="currentColor" opacity="0.4"/>
|
||||
<rect x="106" y="36" width="10" height="5" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (determined, looking forward) -->
|
||||
<circle cx="101" cy="46" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="106" cy="45" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<!-- Beak (pointy, profile) -->
|
||||
<polygon points="110,48 125,44 110,42" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Carrier bag (big, on shoulder) -->
|
||||
<rect x="55" y="62" width="28" height="35" rx="4" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="60" y1="62" x2="75" y2="55" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- Letters flying out of bag -->
|
||||
<rect x="42" y="55" width="12" height="9" rx="1" fill="currentColor" opacity="0.2" transform="rotate(-20 48 59)"/>
|
||||
<rect x="35" y="45" width="10" height="7" rx="1" fill="currentColor" opacity="0.15" transform="rotate(-35 40 48)"/>
|
||||
<rect x="48" y="42" width="11" height="8" rx="1" fill="currentColor" opacity="0.18" transform="rotate(10 53 46)"/>
|
||||
<!-- Arm swinging back -->
|
||||
<line x1="65" y1="72" x2="45" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Running legs (long strides!) -->
|
||||
<line x1="72" y1="106" x2="40" y2="170" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="88" y1="106" x2="130" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="35" cy="174" rx="11" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="135" cy="168" rx="11" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok 3 : Cartonnier — assembling cardboard box, tape gun, flat boxes nearby -->
|
||||
<svg class="shadok-cartonnier" viewBox="0 0 170 220" fill="none" aria-hidden="true">
|
||||
<!-- Body (small, leaning over work) -->
|
||||
<ellipse cx="70" cy="100" rx="22" ry="27" fill="currentColor" opacity="0.25" transform="rotate(8 70 100)"/>
|
||||
<!-- Head (looking down at box) -->
|
||||
<circle cx="78" cy="65" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (focused, looking down) -->
|
||||
<circle cx="83" cy="67" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="88" cy="68" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<!-- Beak pointing down -->
|
||||
<polygon points="88,72 98,78 86,76" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arm holding tape gun -->
|
||||
<line x1="90" y1="95" x2="130" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Tape gun (big, detailed) -->
|
||||
<circle cx="138" cy="102" r="8" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="132" y="99" width="18" height="6" rx="1" fill="currentColor" opacity="0.35"/>
|
||||
<polygon points="150,100 158,102 150,104" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Other arm holding box flap -->
|
||||
<line x1="50" y1="92" x2="35" y2="118" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Box being assembled (big, 3D perspective) -->
|
||||
<rect x="25" y="118" width="45" height="35" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<polygon points="25,118 15,108 60,108 70,118" fill="currentColor" opacity="0.15"/>
|
||||
<polygon points="70,118 60,108 60,143 70,153" fill="currentColor" opacity="0.12"/>
|
||||
<!-- Flap open -->
|
||||
<polygon points="25,118 15,108 15,98 25,108" fill="currentColor" opacity="0.18"/>
|
||||
<!-- Flat boxes nearby -->
|
||||
<rect x="90" y="145" width="35" height="4" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="88" y="150" width="38" height="4" rx="1" fill="currentColor" opacity="0.15"/>
|
||||
<rect x="92" y="155" width="32" height="4" rx="1" fill="currentColor" opacity="0.12"/>
|
||||
<!-- Legs (long!) -->
|
||||
<line x1="60" y1="127" x2="48" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="80" y1="127" x2="92" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="43" cy="196" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="97" cy="196" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok 4 : Cycliste livreur — on bicycle, package on rack, profile leaning forward -->
|
||||
<svg class="shadok-cycliste" viewBox="0 0 180 200" fill="none" aria-hidden="true">
|
||||
<!-- Back wheel -->
|
||||
<circle cx="35" cy="160" r="22" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.25"/>
|
||||
<circle cx="35" cy="160" r="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Front wheel -->
|
||||
<circle cx="145" cy="160" r="22" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.25"/>
|
||||
<circle cx="145" cy="160" r="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Frame -->
|
||||
<line x1="35" y1="160" x2="80" y2="120" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="80" y1="120" x2="120" y2="120" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="120" y1="120" x2="145" y2="160" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="35" y1="160" x2="80" y2="140" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.2"/>
|
||||
<line x1="80" y1="140" x2="120" y2="120" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.2"/>
|
||||
<!-- Handlebars -->
|
||||
<line x1="120" y1="120" x2="130" y2="105" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="125" y1="105" x2="135" y2="105" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- Saddle -->
|
||||
<rect x="72" y="116" width="16" height="5" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Package on rear rack (big!) -->
|
||||
<rect x="15" y="125" width="30" height="22" rx="3" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="30" y1="125" x2="30" y2="147" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<line x1="15" y1="136" x2="45" y2="136" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<!-- Rear rack -->
|
||||
<line x1="35" y1="147" x2="35" y2="155" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="15" y1="147" x2="55" y2="147" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- Body (small, leaning forward on bike) -->
|
||||
<ellipse cx="90" cy="100" rx="18" ry="24" fill="currentColor" opacity="0.25" transform="rotate(-20 90 100)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="108" cy="68" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (focused ahead) -->
|
||||
<circle cx="115" cy="65" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="120" cy="64" r="1.8" fill="currentColor" opacity="0.6"/>
|
||||
<!-- Beak -->
|
||||
<polygon points="122,68 134,64 122,62" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arms to handlebars -->
|
||||
<line x1="100" y1="90" x2="130" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Legs pedaling -->
|
||||
<line x1="82" y1="118" x2="72" y2="145" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="88" y1="120" x2="95" y2="148" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Feet on pedals -->
|
||||
<ellipse cx="70" cy="148" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="97" cy="150" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok 5 : Lectrice satisfaite — sitting in armchair, open book, wrapping paper on floor -->
|
||||
<svg class="shadok-lectrice" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Armchair (big!) -->
|
||||
<path d="M20 100 Q20 80 35 80 L115 80 Q130 80 130 100 L130 150 L20 150 Z" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Armrests -->
|
||||
<rect x="10" y="90" width="16" height="55" rx="6" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="124" y="90" width="16" height="55" rx="6" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Chair legs -->
|
||||
<line x1="25" y1="150" x2="22" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.2"/>
|
||||
<line x1="125" y1="150" x2="128" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.2"/>
|
||||
<!-- Body (sitting, small) -->
|
||||
<ellipse cx="75" cy="120" rx="20" ry="25" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head (tilted, reading happily) -->
|
||||
<circle cx="75" cy="82" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Happy eyes (curved) -->
|
||||
<path d="M66 79 Q69 76 72 79" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.5"/>
|
||||
<path d="M80 78 Q83 75 86 78" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.5"/>
|
||||
<!-- Small smile -->
|
||||
<path d="M70 88 Q75 93 80 88" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Beak (small, happy) -->
|
||||
<polygon points="88,83 98,80 88,78" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Arms holding open book -->
|
||||
<line x1="55" y1="112" x2="40" y2="125" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="95" y1="112" x2="110" y2="125" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Open book (big, in lap) -->
|
||||
<rect x="38" y="125" width="28" height="20" rx="1" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="66" y="125" width="28" height="20" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<line x1="66" y1="125" x2="66" y2="145" stroke="currentColor" stroke-width="1.5" opacity="0.35"/>
|
||||
<!-- Text lines on book pages -->
|
||||
<line x1="42" y1="131" x2="62" y2="131" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<line x1="42" y1="135" x2="60" y2="135" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<line x1="70" y1="131" x2="90" y2="131" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<line x1="70" y1="135" x2="88" y2="135" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<!-- Legs (long, dangling from chair) -->
|
||||
<line x1="62" y1="145" x2="50" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="88" y1="145" x2="100" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="45" cy="198" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="105" cy="198" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Wrapping paper on floor -->
|
||||
<path d="M30 175 Q45 170 55 178 Q60 182 50 185" stroke="currentColor" stroke-width="1.5" fill="currentColor" opacity="0.12"/>
|
||||
<path d="M100 180 Q115 172 125 180 Q120 188 108 185" stroke="currentColor" stroke-width="1.5" fill="currentColor" opacity="0.1"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok 6 : Empileur — balancing tower of books on head, arms out, worried eyes -->
|
||||
<svg class="shadok-empileur" viewBox="0 0 140 220" fill="none" aria-hidden="true">
|
||||
<!-- Precarious tower of books on head (big, detailed!) -->
|
||||
<rect x="48" y="8" width="24" height="7" rx="1" fill="currentColor" opacity="0.2" transform="rotate(3 60 11)"/>
|
||||
<rect x="46" y="16" width="28" height="7" rx="1" fill="currentColor" opacity="0.25" transform="rotate(-2 60 19)"/>
|
||||
<rect x="44" y="24" width="32" height="7" rx="1" fill="currentColor" opacity="0.2" transform="rotate(4 60 27)"/>
|
||||
<rect x="47" y="32" width="26" height="7" rx="1" fill="currentColor" opacity="0.28" transform="rotate(-3 60 35)"/>
|
||||
<rect x="50" y="40" width="22" height="6" rx="1" fill="currentColor" opacity="0.22" transform="rotate(2 61 43)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="65" cy="58" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Worried eyes (looking up at books) -->
|
||||
<circle cx="60" cy="54" r="2.2" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="70" cy="54" r="2.2" fill="currentColor" opacity="0.6"/>
|
||||
<!-- Tiny worried pupils (looking up) -->
|
||||
<circle cx="60" cy="53" r="1" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="70" cy="53" r="1" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Worried eyebrows -->
|
||||
<line x1="56" y1="50" x2="63" y2="51" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="74" y1="51" x2="67" y2="50" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Beak (slightly open, worried) -->
|
||||
<polygon points="74,60 86,57 74,55" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="76" y1="58" x2="83" y2="58" stroke="currentColor" stroke-width="0.8" opacity="0.2"/>
|
||||
<!-- Body (small oval, upright, tense) -->
|
||||
<ellipse cx="65" cy="95" rx="20" ry="26" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Arms out wide for balance -->
|
||||
<line x1="45" y1="88" x2="10" y2="82" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="85" y1="88" x2="120" y2="82" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Hands (small circles at arm ends) -->
|
||||
<circle cx="8" cy="82" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="122" cy="82" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Legs (long!) -->
|
||||
<line x1="55" y1="121" x2="45" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="75" y1="121" x2="85" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="40" cy="196" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="90" cy="196" rx="10" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="section-icon mx-auto mb-6">
|
||||
<div class="i-lucide-shopping-bag h-12 w-12" />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase text-center">
|
||||
{{ content?.kicker }}
|
||||
</p>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold mb-4 text-center" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-10 text-center" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
|
||||
<!-- Bookelis CTA -->
|
||||
<div class="cta-block mb-8">
|
||||
<div class="cta-icon">
|
||||
<div class="i-lucide-globe h-5 w-5" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h2 class="font-display text-lg font-semibold mb-1" style="color: hsl(var(--color-text))">
|
||||
Commander en ligne
|
||||
</h2>
|
||||
<p class="text-sm mb-3" style="color: hsl(var(--color-text-muted))">
|
||||
Impression à la demande, livraison chez vous.
|
||||
</p>
|
||||
<a
|
||||
:href="content?.bookelis?.url"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="order-btn"
|
||||
>
|
||||
<div class="i-lucide-external-link h-4 w-4" />
|
||||
{{ content?.bookelis?.label }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Librairie -->
|
||||
<div class="cta-block mb-10">
|
||||
<div class="cta-icon cta-icon--accent">
|
||||
<div class="i-lucide-store h-5 w-5" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h2 class="font-display text-lg font-semibold mb-2" style="color: hsl(var(--color-text))">
|
||||
{{ content?.librairie?.title }}
|
||||
</h2>
|
||||
<p class="leading-relaxed whitespace-pre-line" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.librairie?.text }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<UiBaseButton variant="ghost" to="/economique">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Autonomie économique
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { data: content } = await usePageContent('economique/commande')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Commander le livre',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.section-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.cta-block {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.cta-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.12);
|
||||
color: hsl(var(--color-primary));
|
||||
flex-shrink: 0;
|
||||
margin-top: 0.125rem;
|
||||
}
|
||||
|
||||
.cta-icon--accent {
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
}
|
||||
|
||||
.order-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
background: hsl(var(--color-primary));
|
||||
color: white;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.order-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px hsl(var(--color-primary) / 0.3);
|
||||
}
|
||||
|
||||
.shadok-libraire {
|
||||
position: absolute;
|
||||
left: 2%;
|
||||
top: 5%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-1 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-factrice {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
top: 4%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.24;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-2 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-cartonnier {
|
||||
position: absolute;
|
||||
left: 3%;
|
||||
top: 45%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-3 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-cycliste {
|
||||
position: absolute;
|
||||
left: 3%;
|
||||
bottom: 8%;
|
||||
width: clamp(75px, 10vw, 140px);
|
||||
opacity: 0.18;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-4 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-lectrice {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
bottom: 10%;
|
||||
width: clamp(70px, 10vw, 135px);
|
||||
opacity: 0.28;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-5 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-empileur {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 2%;
|
||||
transform: translateX(-50%);
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-6 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-1 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
|
||||
@keyframes shadok-float-2 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-10px) rotate(2deg); } }
|
||||
@keyframes shadok-float-3 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-12px) rotate(-1deg); } }
|
||||
@keyframes shadok-float-4 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px) rotate(1deg); } }
|
||||
@keyframes shadok-float-5 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
|
||||
@keyframes shadok-float-6 { 0%, 100% { transform: translateX(-50%) translateY(0); } 50% { transform: translateX(-50%) translateY(-9px); } }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-libraire,
|
||||
.shadok-factrice,
|
||||
.shadok-cartonnier,
|
||||
.shadok-cycliste,
|
||||
.shadok-lectrice,
|
||||
.shadok-empileur { display: none; }
|
||||
}
|
||||
</style>
|
||||
647
app/pages/economique/index.vue
Normal file
647
app/pages/economique/index.vue
Normal file
@@ -0,0 +1,647 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok boulangère (top-left, walking profile, carrying bread tray) -->
|
||||
<svg class="shadok shadok-boulangere" viewBox="0 0 160 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body tilted forward walking -->
|
||||
<ellipse cx="85" cy="105" rx="22" ry="28" fill="currentColor" opacity="0.25" transform="rotate(-8 85 105)" />
|
||||
<!-- head -->
|
||||
<circle cx="80" cy="65" r="16" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes looking forward -->
|
||||
<circle cx="88" cy="62" r="2" fill="currentColor" />
|
||||
<circle cx="88" cy="68" r="1.5" fill="currentColor" />
|
||||
<!-- beak pointing right -->
|
||||
<path d="M94 64 L108 62 L94 68" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arms up holding tray -->
|
||||
<line x1="75" y1="88" x2="60" y2="42" stroke-width="3" />
|
||||
<line x1="95" y1="88" x2="110" y2="42" stroke-width="3" />
|
||||
<!-- big bread tray -->
|
||||
<rect x="48" y="32" width="74" height="12" rx="3" fill="currentColor" opacity="0.25" />
|
||||
<!-- bread loaves on tray -->
|
||||
<ellipse cx="62" cy="30" rx="10" ry="6" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="85" cy="28" rx="11" ry="7" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="108" cy="30" rx="9" ry="6" fill="currentColor" opacity="0.3" />
|
||||
<!-- score marks on loaves -->
|
||||
<line x1="58" y1="28" x2="60" y2="32" opacity="0.4" />
|
||||
<line x1="64" y1="27" x2="66" y2="31" opacity="0.4" />
|
||||
<line x1="82" y1="26" x2="84" y2="30" opacity="0.4" />
|
||||
<line x1="88" y1="25" x2="90" y2="29" opacity="0.4" />
|
||||
<!-- flour apron -->
|
||||
<path d="M70 95 Q85 92 100 95 L97 125 Q85 128 73 125 Z" fill="currentColor" opacity="0.1" />
|
||||
<!-- flour dots -->
|
||||
<circle cx="78" cy="100" r="1" fill="currentColor" opacity="0.3" />
|
||||
<circle cx="92" cy="108" r="1.2" fill="currentColor" opacity="0.25" />
|
||||
<circle cx="83" cy="115" r="0.8" fill="currentColor" opacity="0.3" />
|
||||
<!-- long legs walking stride -->
|
||||
<line x1="78" y1="132" x2="58" y2="185" stroke-width="3" />
|
||||
<line x1="92" y1="132" x2="112" y2="180" stroke-width="3" />
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="52" cy="188" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="118" cy="183" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok potier (top-right, sitting at wheel) -->
|
||||
<svg class="shadok shadok-potier" viewBox="0 0 170 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body sitting, slightly hunched -->
|
||||
<ellipse cx="70" cy="100" rx="23" ry="26" fill="currentColor" opacity="0.25" transform="rotate(5 70 100)" />
|
||||
<!-- head looking down at wheel -->
|
||||
<circle cx="65" cy="65" r="15" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes looking down -->
|
||||
<circle cx="60" cy="68" r="2" fill="currentColor" />
|
||||
<circle cx="72" cy="70" r="1.8" fill="currentColor" />
|
||||
<!-- beak pointing down-right -->
|
||||
<path d="M68 76 L80 82 L66 82" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arms reaching to vase -->
|
||||
<line x1="50" y1="92" x2="110" y2="115" stroke-width="3" />
|
||||
<line x1="90" y1="90" x2="120" y2="110" stroke-width="3" />
|
||||
<!-- hands on vase -->
|
||||
<circle cx="112" cy="113" r="4" fill="currentColor" opacity="0.2" />
|
||||
<circle cx="122" cy="108" r="4" fill="currentColor" opacity="0.2" />
|
||||
<!-- vase being shaped -->
|
||||
<path d="M108 95 Q102 108 106 125 Q115 135 124 125 Q128 108 122 95" fill="currentColor" opacity="0.2" stroke="currentColor" stroke-width="2" />
|
||||
<!-- vase opening -->
|
||||
<ellipse cx="115" cy="95" rx="8" ry="3" fill="currentColor" opacity="0.15" />
|
||||
<!-- pottery wheel -->
|
||||
<ellipse cx="115" cy="140" rx="28" ry="8" fill="currentColor" opacity="0.2" />
|
||||
<line x1="115" y1="148" x2="115" y2="170" stroke-width="3" />
|
||||
<line x1="100" y1="170" x2="130" y2="170" stroke-width="3" />
|
||||
<!-- spinning motion lines -->
|
||||
<path d="M88 138 Q85 135 88 132" fill="none" opacity="0.35" />
|
||||
<path d="M142 138 Q145 135 142 132" fill="none" opacity="0.35" />
|
||||
<path d="M90 145 Q86 143 90 140" fill="none" opacity="0.25" />
|
||||
<!-- legs folded sitting -->
|
||||
<line x1="60" y1="124" x2="40" y2="165" stroke-width="3" />
|
||||
<line x1="80" y1="124" x2="75" y2="170" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="34" cy="168" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="70" cy="173" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok apicultrice (left, 40% down, with smoker and bees) -->
|
||||
<svg class="shadok shadok-apicultrice" viewBox="0 0 160 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body upright -->
|
||||
<ellipse cx="75" cy="110" rx="20" ry="27" fill="currentColor" opacity="0.25" />
|
||||
<!-- head -->
|
||||
<circle cx="75" cy="70" r="15" fill="currentColor" opacity="0.3" />
|
||||
<!-- beekeeping hat brim -->
|
||||
<ellipse cx="75" cy="56" rx="22" ry="5" fill="currentColor" opacity="0.2" />
|
||||
<!-- hat top -->
|
||||
<path d="M58 56 Q58 42 75 40 Q92 42 92 56" fill="currentColor" opacity="0.15" />
|
||||
<!-- veil hanging down -->
|
||||
<path d="M53 56 L53 82 Q75 88 97 82 L97 56" fill="none" stroke-dasharray="3 2" opacity="0.3" />
|
||||
<!-- eyes behind veil -->
|
||||
<circle cx="70" cy="68" r="2" fill="currentColor" />
|
||||
<circle cx="82" cy="66" r="1.8" fill="currentColor" />
|
||||
<!-- beak -->
|
||||
<path d="M80 74 L94 72 L82 78" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arm left holding smoker -->
|
||||
<line x1="56" y1="100" x2="28" y2="85" stroke-width="3" />
|
||||
<!-- smoker device (big) -->
|
||||
<rect x="10" y="72" width="22" height="20" rx="4" fill="currentColor" opacity="0.25" />
|
||||
<path d="M14 72 L14 62 Q21 58 28 62 L28 72" fill="currentColor" opacity="0.15" />
|
||||
<!-- smoke puffs -->
|
||||
<circle cx="18" cy="55" r="5" fill="currentColor" opacity="0.12" />
|
||||
<circle cx="24" cy="48" r="4" fill="currentColor" opacity="0.08" />
|
||||
<circle cx="16" cy="42" r="3" fill="currentColor" opacity="0.06" />
|
||||
<!-- arm right -->
|
||||
<line x1="94" y1="100" x2="110" y2="90" stroke-width="3" />
|
||||
<!-- buzzing bees (small detailed dots) -->
|
||||
<circle cx="120" cy="60" r="2.5" fill="currentColor" opacity="0.35" />
|
||||
<line x1="118" y1="58" x2="115" y2="56" opacity="0.3" />
|
||||
<line x1="122" y1="58" x2="125" y2="55" opacity="0.3" />
|
||||
<circle cx="135" cy="75" r="2" fill="currentColor" opacity="0.3" />
|
||||
<line x1="133" y1="73" x2="131" y2="71" opacity="0.25" />
|
||||
<line x1="137" y1="73" x2="139" y2="71" opacity="0.25" />
|
||||
<circle cx="110" cy="48" r="2.2" fill="currentColor" opacity="0.25" />
|
||||
<line x1="108" y1="46" x2="106" y2="44" opacity="0.2" />
|
||||
<line x1="112" y1="46" x2="114" y2="43" opacity="0.2" />
|
||||
<circle cx="140" cy="55" r="1.8" fill="currentColor" opacity="0.2" />
|
||||
<circle cx="128" cy="42" r="2" fill="currentColor" opacity="0.22" />
|
||||
<!-- long legs -->
|
||||
<line x1="66" y1="136" x2="55" y2="192" stroke-width="3" />
|
||||
<line x1="84" y1="136" x2="95" y2="192" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="49" cy="195" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="101" cy="195" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok forgeron (right, 35%, swinging hammer on anvil) -->
|
||||
<svg class="shadok shadok-forgeron" viewBox="0 0 180 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body leaning forward, muscular feel -->
|
||||
<ellipse cx="90" cy="105" rx="24" ry="30" fill="currentColor" opacity="0.3" transform="rotate(-12 90 105)" />
|
||||
<!-- head in profile -->
|
||||
<circle cx="100" cy="65" r="16" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes focused, intense -->
|
||||
<circle cx="108" cy="62" r="2.5" fill="currentColor" />
|
||||
<circle cx="108" cy="70" r="2" fill="currentColor" />
|
||||
<!-- beak pointing right -->
|
||||
<path d="M114 65 L130 62 L114 70" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- big arm swinging hammer UP -->
|
||||
<line x1="72" y1="90" x2="40" y2="40" stroke-width="3.5" />
|
||||
<!-- hammer head (big!) -->
|
||||
<rect x="22" y="22" width="38" height="18" rx="3" fill="currentColor" opacity="0.3" />
|
||||
<!-- hammer handle end -->
|
||||
<line x1="40" y1="40" x2="42" y2="30" stroke-width="4" />
|
||||
<!-- other arm resting on anvil -->
|
||||
<line x1="110" y1="92" x2="140" y2="130" stroke-width="3" />
|
||||
<!-- anvil (big detailed) -->
|
||||
<path d="M120 135 L160 135 L168 145 L112 145 Z" fill="currentColor" opacity="0.25" />
|
||||
<rect x="128" y="145" width="24" height="20" fill="currentColor" opacity="0.2" />
|
||||
<rect x="122" y="165" width="36" height="6" rx="2" fill="currentColor" opacity="0.25" />
|
||||
<!-- hot metal on anvil -->
|
||||
<rect x="132" y="130" width="20" height="5" rx="1" fill="currentColor" opacity="0.35" />
|
||||
<!-- sparks flying -->
|
||||
<line x1="138" y1="128" x2="132" y2="118" opacity="0.4" />
|
||||
<line x1="145" y1="126" x2="150" y2="116" opacity="0.35" />
|
||||
<line x1="152" y1="128" x2="160" y2="120" opacity="0.3" />
|
||||
<circle cx="130" cy="115" r="1.5" fill="currentColor" opacity="0.35" />
|
||||
<circle cx="155" cy="112" r="1.2" fill="currentColor" opacity="0.3" />
|
||||
<circle cx="162" cy="118" r="1" fill="currentColor" opacity="0.25" />
|
||||
<!-- long legs wide stance -->
|
||||
<line x1="78" y1="133" x2="55" y2="190" stroke-width="3" />
|
||||
<line x1="100" y1="133" x2="120" y2="192" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="48" cy="193" rx="13" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="127" cy="195" rx="13" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok maraîchère (bottom-left, pushing wheelbarrow) -->
|
||||
<svg class="shadok shadok-maraichere" viewBox="0 0 180 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body leaning forward pushing -->
|
||||
<ellipse cx="120" cy="95" rx="21" ry="26" fill="currentColor" opacity="0.25" transform="rotate(-20 120 95)" />
|
||||
<!-- head tilted forward -->
|
||||
<circle cx="130" cy="58" r="14" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes looking down at path -->
|
||||
<circle cx="136" cy="56" r="2" fill="currentColor" />
|
||||
<circle cx="136" cy="63" r="1.5" fill="currentColor" />
|
||||
<!-- beak pointing right-down -->
|
||||
<path d="M140 60 L154 64 L140 66" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arms pushing wheelbarrow handles -->
|
||||
<line x1="104" y1="86" x2="72" y2="110" stroke-width="3" />
|
||||
<line x1="108" y1="80" x2="72" y2="100" stroke-width="3" />
|
||||
<!-- wheelbarrow body (big!) -->
|
||||
<path d="M10 80 L70 80 L75 120 L5 120 Z" fill="currentColor" opacity="0.2" />
|
||||
<path d="M10 80 L70 80 L75 120 L5 120 Z" />
|
||||
<!-- wheelbarrow handles -->
|
||||
<line x1="70" y1="90" x2="72" y2="110" stroke-width="3" />
|
||||
<line x1="70" y1="100" x2="72" y2="100" stroke-width="2" />
|
||||
<!-- wheel -->
|
||||
<circle cx="12" cy="128" r="12" fill="currentColor" opacity="0.15" />
|
||||
<circle cx="12" cy="128" r="12" />
|
||||
<circle cx="12" cy="128" r="3" fill="currentColor" opacity="0.3" />
|
||||
<!-- vegetables in wheelbarrow -->
|
||||
<circle cx="22" cy="72" r="7" fill="currentColor" opacity="0.3" />
|
||||
<circle cx="38" cy="70" r="8" fill="currentColor" opacity="0.25" />
|
||||
<circle cx="55" cy="73" r="6" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="30" cy="76" rx="5" ry="8" fill="currentColor" opacity="0.2" transform="rotate(15 30 76)" />
|
||||
<!-- carrot tops -->
|
||||
<line x1="22" y1="66" x2="18" y2="58" opacity="0.35" />
|
||||
<line x1="22" y1="66" x2="25" y2="57" opacity="0.35" />
|
||||
<line x1="55" y1="67" x2="52" y2="60" opacity="0.3" />
|
||||
<line x1="55" y1="67" x2="58" y2="59" opacity="0.3" />
|
||||
<!-- long legs striding -->
|
||||
<line x1="112" y1="118" x2="100" y2="180" stroke-width="3" />
|
||||
<line x1="128" y1="118" x2="150" y2="178" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="94" cy="183" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="156" cy="181" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok tisserand (bottom-right, sitting at loom) -->
|
||||
<svg class="shadok shadok-tisserand" viewBox="0 0 170 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body sitting upright -->
|
||||
<ellipse cx="55" cy="100" rx="20" ry="25" fill="currentColor" opacity="0.25" />
|
||||
<!-- head looking down at loom -->
|
||||
<circle cx="55" cy="65" r="15" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes focused downward -->
|
||||
<circle cx="62" cy="66" r="2" fill="currentColor" />
|
||||
<circle cx="60" cy="72" r="1.5" fill="currentColor" />
|
||||
<!-- beak pointing right-down -->
|
||||
<path d="M66 70 L78 74 L64 76" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arms reaching to loom -->
|
||||
<line x1="72" y1="92" x2="100" y2="80" stroke-width="3" />
|
||||
<line x1="74" y1="100" x2="105" y2="100" stroke-width="3" />
|
||||
<!-- loom frame (big detailed) -->
|
||||
<rect x="95" y="55" width="60" height="80" rx="3" fill="none" />
|
||||
<!-- vertical loom posts -->
|
||||
<line x1="95" y1="55" x2="95" y2="135" stroke-width="3" />
|
||||
<line x1="155" y1="55" x2="155" y2="135" stroke-width="3" />
|
||||
<!-- top beam -->
|
||||
<line x1="95" y1="55" x2="155" y2="55" stroke-width="3" />
|
||||
<!-- warp threads (vertical) -->
|
||||
<line x1="105" y1="55" x2="105" y2="135" opacity="0.3" />
|
||||
<line x1="115" y1="55" x2="115" y2="135" opacity="0.3" />
|
||||
<line x1="125" y1="55" x2="125" y2="135" opacity="0.3" />
|
||||
<line x1="135" y1="55" x2="135" y2="135" opacity="0.3" />
|
||||
<line x1="145" y1="55" x2="145" y2="135" opacity="0.3" />
|
||||
<!-- weft threads (horizontal, partial = work in progress) -->
|
||||
<line x1="95" y1="70" x2="155" y2="70" opacity="0.25" />
|
||||
<line x1="95" y1="80" x2="155" y2="80" opacity="0.25" />
|
||||
<line x1="95" y1="90" x2="145" y2="90" opacity="0.25" />
|
||||
<line x1="95" y1="100" x2="135" y2="100" opacity="0.2" />
|
||||
<!-- shuttle in hand -->
|
||||
<ellipse cx="105" cy="100" rx="8" ry="3" fill="currentColor" opacity="0.3" transform="rotate(-5 105 100)" />
|
||||
<!-- woven fabric area -->
|
||||
<rect x="97" y="62" width="56" height="28" fill="currentColor" opacity="0.08" />
|
||||
<!-- legs folded sitting on stool -->
|
||||
<line x1="45" y1="123" x2="30" y2="178" stroke-width="3" />
|
||||
<line x1="65" y1="123" x2="70" y2="180" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="24" cy="181" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="76" cy="183" rx="11" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<!-- stool -->
|
||||
<rect x="38" y="124" width="30" height="6" rx="2" fill="currentColor" opacity="0.15" />
|
||||
<line x1="42" y1="130" x2="40" y2="148" stroke-width="2" opacity="0.3" />
|
||||
<line x1="64" y1="130" x2="66" y2="148" stroke-width="2" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok berger (center-bottom, walking with sheep) -->
|
||||
<svg class="shadok shadok-berger" viewBox="0 0 180 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body walking, slight lean -->
|
||||
<ellipse cx="85" cy="90" rx="20" ry="26" fill="currentColor" opacity="0.25" transform="rotate(-5 85 90)" />
|
||||
<!-- head 3/4 view -->
|
||||
<circle cx="88" cy="52" r="16" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes looking ahead, slightly different directions -->
|
||||
<circle cx="94" cy="48" r="2" fill="currentColor" />
|
||||
<circle cx="96" cy="56" r="1.8" fill="currentColor" />
|
||||
<!-- beak -->
|
||||
<path d="M100 52 L114 50 L100 56" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arm holding staff -->
|
||||
<line x1="68" y1="82" x2="50" y2="60" stroke-width="3" />
|
||||
<!-- shepherd's crook (big, detailed) -->
|
||||
<line x1="50" y1="60" x2="44" y2="10" stroke-width="3" />
|
||||
<path d="M44 10 Q44 0 54 0 Q62 0 62 10 Q62 18 54 18" fill="none" stroke-width="3" />
|
||||
<!-- other arm relaxed -->
|
||||
<line x1="104" y1="84" x2="118" y2="95" stroke-width="3" />
|
||||
<!-- long legs walking -->
|
||||
<line x1="76" y1="114" x2="60" y2="175" stroke-width="3" />
|
||||
<line x1="94" y1="114" x2="110" y2="172" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="54" cy="178" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="116" cy="175" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<!-- sheep 1 (following) -->
|
||||
<ellipse cx="140" cy="160" rx="14" ry="10" fill="currentColor" opacity="0.18" />
|
||||
<circle cx="150" cy="152" r="6" fill="currentColor" opacity="0.15" />
|
||||
<circle cx="153" cy="150" r="1" fill="currentColor" />
|
||||
<line x1="132" y1="170" x2="132" y2="180" stroke-width="2" opacity="0.3" />
|
||||
<line x1="148" y1="170" x2="148" y2="180" stroke-width="2" opacity="0.3" />
|
||||
<!-- sheep 2 -->
|
||||
<ellipse cx="158" cy="172" rx="12" ry="8" fill="currentColor" opacity="0.14" />
|
||||
<circle cx="166" cy="166" r="5" fill="currentColor" opacity="0.12" />
|
||||
<circle cx="168" cy="164" r="0.8" fill="currentColor" />
|
||||
<line x1="152" y1="180" x2="152" y2="188" stroke-width="1.5" opacity="0.25" />
|
||||
<line x1="164" y1="180" x2="164" y2="188" stroke-width="1.5" opacity="0.25" />
|
||||
<!-- sheep 3 (smaller, behind) -->
|
||||
<ellipse cx="170" cy="178" rx="9" ry="6" fill="currentColor" opacity="0.1" />
|
||||
<circle cx="176" cy="174" r="4" fill="currentColor" opacity="0.08" />
|
||||
<!-- dog at side -->
|
||||
<ellipse cx="125" cy="170" rx="8" ry="5" fill="currentColor" opacity="0.2" />
|
||||
<circle cx="130" cy="164" r="4" fill="currentColor" opacity="0.18" />
|
||||
<circle cx="132" cy="163" r="1" fill="currentColor" />
|
||||
<line x1="118" y1="168" x2="112" y2="165" stroke-width="1.5" opacity="0.3" />
|
||||
<line x1="120" y1="175" x2="120" y2="182" stroke-width="1.5" opacity="0.25" />
|
||||
<line x1="130" y1="175" x2="130" y2="182" stroke-width="1.5" opacity="0.25" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok vigneronne (right, 55%, carrying grape basket) -->
|
||||
<svg class="shadok shadok-vigneronne" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- body seen from 3/4 back, leaning under weight -->
|
||||
<ellipse cx="80" cy="105" rx="22" ry="28" fill="currentColor" opacity="0.25" transform="rotate(10 80 105)" />
|
||||
<!-- head turned slightly -->
|
||||
<circle cx="72" cy="65" r="15" fill="currentColor" opacity="0.3" />
|
||||
<!-- eyes looking to the side -->
|
||||
<circle cx="64" cy="62" r="2" fill="currentColor" />
|
||||
<circle cx="66" cy="69" r="1.5" fill="currentColor" />
|
||||
<!-- beak pointing left -->
|
||||
<path d="M58 65 L44 62 L58 69" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.2" />
|
||||
<!-- arm back holding basket strap -->
|
||||
<line x1="98" y1="92" x2="115" y2="75" stroke-width="3" />
|
||||
<!-- arm front with pruning shears -->
|
||||
<line x1="62" y1="95" x2="38" y2="80" stroke-width="3" />
|
||||
<!-- pruning shears (big) -->
|
||||
<line x1="38" y1="80" x2="26" y2="68" stroke-width="3" />
|
||||
<line x1="38" y1="80" x2="28" y2="78" stroke-width="3" />
|
||||
<circle cx="36" cy="78" r="3" fill="currentColor" opacity="0.2" />
|
||||
<!-- blade shapes -->
|
||||
<path d="M26 68 Q22 72 28 74" fill="none" stroke-width="2" />
|
||||
<path d="M28 78 Q22 76 24 72" fill="none" stroke-width="2" />
|
||||
<!-- big basket on back with grapes -->
|
||||
<path d="M100 60 L130 60 L135 120 L95 120 Z" fill="currentColor" opacity="0.2" />
|
||||
<path d="M100 60 L130 60 L135 120 L95 120 Z" />
|
||||
<!-- basket weave texture -->
|
||||
<line x1="100" y1="75" x2="133" y2="75" opacity="0.2" />
|
||||
<line x1="98" y1="90" x2="134" y2="90" opacity="0.2" />
|
||||
<line x1="97" y1="105" x2="135" y2="105" opacity="0.2" />
|
||||
<!-- grapes overflowing -->
|
||||
<circle cx="108" cy="55" r="4" fill="currentColor" opacity="0.3" />
|
||||
<circle cx="116" cy="53" r="4.5" fill="currentColor" opacity="0.3" />
|
||||
<circle cx="124" cy="55" r="4" fill="currentColor" opacity="0.25" />
|
||||
<circle cx="112" cy="48" r="3.5" fill="currentColor" opacity="0.25" />
|
||||
<circle cx="120" cy="47" r="3.5" fill="currentColor" opacity="0.2" />
|
||||
<circle cx="105" cy="52" r="3" fill="currentColor" opacity="0.2" />
|
||||
<!-- grape stems -->
|
||||
<line x1="115" y1="43" x2="115" y2="36" opacity="0.3" />
|
||||
<line x1="113" y1="36" x2="117" y2="36" opacity="0.3" />
|
||||
<!-- grapevine nearby -->
|
||||
<line x1="148" y1="30" x2="148" y2="130" stroke-width="2" opacity="0.2" />
|
||||
<path d="M148 50 Q158 45 162 55" fill="none" opacity="0.2" />
|
||||
<path d="M148 75 Q160 70 165 80" fill="none" opacity="0.2" />
|
||||
<circle cx="160" cy="58" r="3" fill="currentColor" opacity="0.12" />
|
||||
<circle cx="163" cy="83" r="3" fill="currentColor" opacity="0.1" />
|
||||
<!-- grape leaf -->
|
||||
<path d="M148 90 Q155 85 158 90 Q160 95 155 98 Q150 95 148 90" fill="currentColor" opacity="0.12" />
|
||||
<!-- long legs -->
|
||||
<line x1="70" y1="132" x2="55" y2="192" stroke-width="3" />
|
||||
<line x1="90" y1="132" x2="105" y2="190" stroke-width="3" />
|
||||
<!-- flat feet -->
|
||||
<ellipse cx="49" cy="195" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
<ellipse cx="111" cy="193" rx="12" ry="4" fill="currentColor" opacity="0.3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<!-- Header -->
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl leading-relaxed" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl flex flex-col gap-8">
|
||||
<!-- Monnaie libre -->
|
||||
<NuxtLink to="/economique/monnaie-libre" class="item-card group">
|
||||
<div class="item-header">
|
||||
<div class="item-icon">
|
||||
<span class="g1-icon">Ğ1</span>
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
|
||||
Monnaie libre
|
||||
</h2>
|
||||
</div>
|
||||
<p class="leading-relaxed mt-3" style="color: hsl(var(--color-text-muted))">
|
||||
La Ğ1 (June) : une monnaie co-créée par ses membres, sans dette ni intérêt. Le dividende universel comme base.
|
||||
</p>
|
||||
<div class="mt-3 inline-flex items-center gap-1 text-sm text-primary group-hover:text-primary/80 transition-colors">
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
<!-- Modèle économique — bloc livre -->
|
||||
<div class="book-block">
|
||||
<HomeBookSection
|
||||
@open-player="showBookPlayer = true"
|
||||
@open-pdf="showPdfReader = true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Productions collectives -->
|
||||
<NuxtLink to="/economique/productions-collectives" class="item-card group">
|
||||
<div class="item-header">
|
||||
<div class="item-icon">
|
||||
<div class="i-lucide-users h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
|
||||
Productions collectives
|
||||
</h2>
|
||||
<span class="gestation-badge">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
<p class="leading-relaxed mt-3" style="color: hsl(var(--color-text-muted))">
|
||||
Une plateforme pour faciliter la création d'équipes et la réalisation de productions à l'échelle des bassins de vie. Passer la seconde.
|
||||
</p>
|
||||
<div class="mt-3 inline-flex items-center gap-1 text-sm text-primary group-hover:text-primary/80 transition-colors">
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BookPlayer v-model="showBookPlayer" />
|
||||
<BookPdfReader v-model="showPdfReader" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('economique')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Autonomie économique',
|
||||
})
|
||||
|
||||
const showBookPlayer = ref(false)
|
||||
const showPdfReader = ref(false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
.item-card {
|
||||
display: block;
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
transition: border-color 0.2s, transform 0.12s ease;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.item-card:hover {
|
||||
border-color: hsl(var(--color-primary) / 0.2);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 24px hsl(var(--color-primary) / 0.08);
|
||||
}
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.g1-icon {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.15);
|
||||
color: hsl(var(--color-primary));
|
||||
box-shadow: 0 0 12px hsl(var(--color-primary) / 0.12);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
margin-left: auto;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.book-block {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
/* Shadok illustrations */
|
||||
.shadok {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.shadok-boulangere {
|
||||
top: 1%;
|
||||
left: 2%;
|
||||
opacity: 0.22;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-1 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-potier {
|
||||
top: 1%;
|
||||
right: 2%;
|
||||
opacity: 0.2;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-2 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-apicultrice {
|
||||
left: 2%;
|
||||
top: 40%;
|
||||
opacity: 0.2;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-3 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-forgeron {
|
||||
right: 3%;
|
||||
top: 35%;
|
||||
opacity: 0.24;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-4 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-maraichere {
|
||||
bottom: 14%;
|
||||
left: 1%;
|
||||
opacity: 0.18;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-5 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-tisserand {
|
||||
bottom: 12%;
|
||||
right: 1%;
|
||||
opacity: 0.22;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-6 9.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-berger {
|
||||
bottom: 2%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
opacity: 0.28;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-7 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-vigneronne {
|
||||
right: 2%;
|
||||
top: 55%;
|
||||
opacity: 0.2;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-8 7.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-1 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-2 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-3 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-12px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-4 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-9px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-5 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-11px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-6 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-7 {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-8 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-7px); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -14,7 +14,7 @@
|
||||
<nav class="mt-16 flex items-center justify-between border-t border-white/8 pt-8">
|
||||
<NuxtLink
|
||||
v-if="prevChapter"
|
||||
:to="`/modele-eco/${prevChapter.stem?.split('/').pop()}`"
|
||||
:to="`/economique/modele-eco/${prevChapter.stem?.split('/').pop()}`"
|
||||
class="btn-ghost gap-2"
|
||||
>
|
||||
<div class="i-lucide-arrow-left h-4 w-4" />
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<NuxtLink
|
||||
v-if="nextChapter"
|
||||
:to="`/modele-eco/${nextChapter.stem?.split('/').pop()}`"
|
||||
:to="`/economique/modele-eco/${nextChapter.stem?.split('/').pop()}`"
|
||||
class="btn-ghost gap-2"
|
||||
>
|
||||
<span class="text-sm">{{ nextChapter.title }}</span>
|
||||
562
app/pages/economique/modele-eco/index.vue
Normal file
562
app/pages/economique/modele-eco/index.vue
Normal file
@@ -0,0 +1,562 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok illustrations -->
|
||||
|
||||
<!-- 1. Typographe — placing movable type in composing stick, profile view -->
|
||||
<svg class="shadok shadok-typographe" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- body (small oval, profile facing right) -->
|
||||
<ellipse cx="70" cy="72" rx="22" ry="28" fill="currentColor" opacity="0.28"/>
|
||||
<!-- head -->
|
||||
<circle cx="78" cy="36" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (pointy, profile right) -->
|
||||
<polygon points="94,34 110,38 94,42" fill="currentColor" opacity="0.35"/>
|
||||
<!-- eyes (profile — one visible) -->
|
||||
<circle cx="84" cy="33" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<!-- apron -->
|
||||
<path d="M52 60 L88 60 L85 100 L55 100 Z" fill="currentColor" opacity="0.15"/>
|
||||
<line x1="70" y1="60" x2="70" y2="100" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<!-- arm reaching to composing stick -->
|
||||
<line x1="88" y1="65" x2="120" y2="55" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- other arm holding type block -->
|
||||
<line x1="52" y1="68" x2="35" y2="58" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- composing stick (big, detailed) -->
|
||||
<rect x="110" y="40" width="50" height="14" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="110" y="42" width="50" height="10" rx="1" stroke="currentColor" stroke-width="1" fill="none" opacity="0.25"/>
|
||||
<!-- type blocks in stick -->
|
||||
<rect x="114" y="44" width="6" height="7" rx="0.5" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="122" y="44" width="5" height="7" rx="0.5" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="129" y="44" width="7" height="7" rx="0.5" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="138" y="44" width="5" height="7" rx="0.5" fill="currentColor" opacity="0.22"/>
|
||||
<rect x="145" y="44" width="6" height="7" rx="0.5" fill="currentColor" opacity="0.28"/>
|
||||
<!-- tiny letter on held block -->
|
||||
<rect x="30" y="52" width="8" height="10" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<text x="32" y="60" font-size="6" fill="currentColor" opacity="0.5" font-family="serif">A</text>
|
||||
<!-- long legs -->
|
||||
<line x1="62" y1="98" x2="50" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="78" y1="98" x2="90" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="45" cy="168" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="95" cy="168" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 2. Lectrice — sitting in armchair, legs crossed, book on lap, reading glasses -->
|
||||
<svg class="shadok shadok-lectrice" viewBox="0 0 180 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- armchair back -->
|
||||
<path d="M30 55 Q25 50 28 30 L85 28 Q88 50 83 55" fill="currentColor" opacity="0.12"/>
|
||||
<!-- armchair seat -->
|
||||
<path d="M25 55 L88 55 L92 90 L20 90 Z" fill="currentColor" opacity="0.15"/>
|
||||
<!-- armchair arms -->
|
||||
<rect x="15" y="45" width="12" height="45" rx="5" fill="currentColor" opacity="0.15"/>
|
||||
<rect x="85" y="45" width="12" height="45" rx="5" fill="currentColor" opacity="0.15"/>
|
||||
<!-- body (seated, small) -->
|
||||
<ellipse cx="58" cy="68" rx="20" ry="25" fill="currentColor" opacity="0.28"/>
|
||||
<!-- head -->
|
||||
<circle cx="58" cy="32" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (small, facing right-down toward book) -->
|
||||
<polygon points="70,35 80,40 70,42" fill="currentColor" opacity="0.3"/>
|
||||
<!-- reading glasses -->
|
||||
<circle cx="52" cy="30" r="6" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.4"/>
|
||||
<circle cx="65" cy="30" r="6" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.4"/>
|
||||
<line x1="58" y1="30" x2="59" y2="30" stroke="currentColor" stroke-width="1.5" opacity="0.35"/>
|
||||
<!-- eyes behind glasses (looking down) -->
|
||||
<circle cx="53" cy="31" r="2" fill="currentColor" opacity="0.55"/>
|
||||
<circle cx="64" cy="31" r="2" fill="currentColor" opacity="0.55"/>
|
||||
<!-- arms holding open book on lap -->
|
||||
<line x1="40" y1="60" x2="35" y2="82" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="76" y1="60" x2="80" y2="82" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- open book on lap -->
|
||||
<path d="M32 80 L58 88 L84 80 L84 95 L58 103 L32 95 Z" fill="currentColor" opacity="0.18"/>
|
||||
<line x1="58" y1="88" x2="58" y2="103" stroke="currentColor" stroke-width="1" opacity="0.25"/>
|
||||
<!-- text lines on pages -->
|
||||
<line x1="37" y1="86" x2="54" y2="91" stroke="currentColor" stroke-width="0.7" opacity="0.2"/>
|
||||
<line x1="37" y1="89" x2="54" y2="94" stroke="currentColor" stroke-width="0.7" opacity="0.2"/>
|
||||
<line x1="62" y1="91" x2="79" y2="86" stroke="currentColor" stroke-width="0.7" opacity="0.2"/>
|
||||
<line x1="62" y1="94" x2="79" y2="89" stroke="currentColor" stroke-width="0.7" opacity="0.2"/>
|
||||
<!-- crossed legs (long!) -->
|
||||
<line x1="48" y1="90" x2="30" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="68" y1="90" x2="55" y2="150" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- the crossed leg goes over -->
|
||||
<line x1="55" y1="150" x2="75" y2="140" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.22"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="25" cy="168" rx="11" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="79" cy="142" rx="9" ry="3.5" fill="currentColor" opacity="0.22"/>
|
||||
<!-- cup of tea nearby -->
|
||||
<rect x="130" y="78" width="14" height="16" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<ellipse cx="137" cy="78" rx="7" ry="2.5" fill="currentColor" opacity="0.25"/>
|
||||
<!-- tea handle -->
|
||||
<path d="M144 83 Q152 86 144 92" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.2"/>
|
||||
<!-- steam -->
|
||||
<path d="M134 73 Q132 68 135 64" stroke="currentColor" stroke-width="0.8" fill="none" opacity="0.15"/>
|
||||
<path d="M139 74 Q141 69 138 65" stroke="currentColor" stroke-width="0.8" fill="none" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<!-- 3. Calligraphe — standing at tilted drafting table, large quill, ink flourishes -->
|
||||
<svg class="shadok shadok-calligraphe" viewBox="0 0 180 220" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- drafting table (tilted, big) -->
|
||||
<rect x="75" y="50" width="65" height="85" rx="3" fill="currentColor" opacity="0.12" transform="rotate(-15 108 92)"/>
|
||||
<!-- table legs -->
|
||||
<line x1="85" y1="130" x2="78" y2="195" stroke="currentColor" stroke-width="2.5" opacity="0.18"/>
|
||||
<line x1="140" y1="115" x2="150" y2="195" stroke="currentColor" stroke-width="2.5" opacity="0.18"/>
|
||||
<!-- paper on table -->
|
||||
<rect x="85" y="58" width="48" height="65" rx="1" fill="currentColor" opacity="0.08" transform="rotate(-15 109 90)"/>
|
||||
<!-- ink flourishes on paper -->
|
||||
<path d="M95 80 Q105 70 115 82 Q120 90 110 95" stroke="currentColor" stroke-width="1.2" fill="none" opacity="0.25" transform="rotate(-15 105 85)"/>
|
||||
<path d="M100 95 Q108 88 118 98" stroke="currentColor" stroke-width="0.8" fill="none" opacity="0.2" transform="rotate(-15 109 93)"/>
|
||||
<!-- body (3/4 view, facing table) -->
|
||||
<ellipse cx="55" cy="95" rx="21" ry="27" fill="currentColor" opacity="0.28"/>
|
||||
<!-- head (turned toward table) -->
|
||||
<circle cx="62" cy="58" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak pointing at paper -->
|
||||
<polygon points="75,55 90,52 78,60" fill="currentColor" opacity="0.32"/>
|
||||
<!-- eyes (looking at paper, slightly different directions) -->
|
||||
<circle cx="66" cy="55" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="58" cy="54" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- arm holding large quill -->
|
||||
<line x1="72" y1="85" x2="105" y2="65" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- large quill -->
|
||||
<line x1="105" y1="65" x2="100" y2="80" stroke="currentColor" stroke-width="1.5" opacity="0.35"/>
|
||||
<path d="M105 65 L115 30 Q108 45 100 40 Q105 55 105 65" fill="currentColor" opacity="0.2"/>
|
||||
<!-- other arm resting on table edge -->
|
||||
<line x1="40" y1="88" x2="80" y2="85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- ink trailing from quill tip -->
|
||||
<path d="M100 80 Q95 90 98 100 Q102 108 96 115" stroke="currentColor" stroke-width="0.8" fill="none" opacity="0.2"/>
|
||||
<!-- long legs -->
|
||||
<line x1="45" y1="120" x2="35" y2="190" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="65" y1="120" x2="72" y2="190" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="30" cy="193" rx="11" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="77" cy="193" rx="11" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 4. Relieur — sewing book spine with needle and thread, stack of signatures -->
|
||||
<svg class="shadok shadok-relieur" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- body (leaning forward over work) -->
|
||||
<ellipse cx="85" cy="80" rx="22" ry="26" fill="currentColor" opacity="0.28" transform="rotate(10 85 80)"/>
|
||||
<!-- head (tilted down, focused) -->
|
||||
<circle cx="95" cy="46" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (pointing down at work) -->
|
||||
<polygon points="105,52 115,62 103,58" fill="currentColor" opacity="0.32"/>
|
||||
<!-- eyes (both looking down at different angles) -->
|
||||
<circle cx="92" cy="44" r="2" fill="currentColor" opacity="0.55"/>
|
||||
<circle cx="100" cy="46" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<!-- arm holding needle high -->
|
||||
<line x1="100" y1="70" x2="130" y2="40" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- needle -->
|
||||
<line x1="130" y1="40" x2="135" y2="32" stroke="currentColor" stroke-width="2" opacity="0.45"/>
|
||||
<!-- thread from needle down to book -->
|
||||
<path d="M132 38 Q140 55 125 75 Q115 90 120 100" stroke="currentColor" stroke-width="1" fill="none" stroke-dasharray="4 3" opacity="0.3"/>
|
||||
<!-- other arm holding book spine -->
|
||||
<line x1="68" y1="75" x2="50" y2="95" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- book being bound (open spine view, big) -->
|
||||
<path d="M40 90 L60 85 L60 125 L40 130 Z" fill="currentColor" opacity="0.18"/>
|
||||
<path d="M60 85 L80 90 L80 130 L60 125 Z" fill="currentColor" opacity="0.14"/>
|
||||
<!-- stitching holes along spine -->
|
||||
<circle cx="60" cy="92" r="1.2" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="60" cy="100" r="1.2" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="60" cy="108" r="1.2" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="60" cy="116" r="1.2" fill="currentColor" opacity="0.35"/>
|
||||
<!-- stack of folded signatures nearby -->
|
||||
<rect x="10" y="125" width="30" height="5" rx="1" fill="currentColor" opacity="0.18"/>
|
||||
<rect x="12" y="119" width="28" height="5" rx="1" fill="currentColor" opacity="0.15"/>
|
||||
<rect x="11" y="113" width="29" height="5" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="13" y="107" width="27" height="5" rx="1" fill="currentColor" opacity="0.16"/>
|
||||
<!-- long legs -->
|
||||
<line x1="75" y1="104" x2="65" y2="172" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="95" y1="104" x2="105" y2="172" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="60" cy="175" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="110" cy="175" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 5. Conteuse — on small stage, arms dramatically wide, 3 tiny shadoks below -->
|
||||
<svg class="shadok shadok-conteuse" viewBox="0 0 180 220" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- small stage/box -->
|
||||
<rect x="55" y="110" width="60" height="20" rx="3" fill="currentColor" opacity="0.18"/>
|
||||
<rect x="58" y="108" width="54" height="4" rx="1.5" fill="currentColor" opacity="0.22"/>
|
||||
<!-- body (on stage, upright, dramatic) -->
|
||||
<ellipse cx="85" cy="85" rx="20" ry="26" fill="currentColor" opacity="0.28"/>
|
||||
<!-- head (thrown back slightly) -->
|
||||
<circle cx="85" cy="50" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (open, telling story) -->
|
||||
<polygon points="98,46 112,42 100,52" fill="currentColor" opacity="0.3"/>
|
||||
<polygon points="100,52 112,55 98,54" fill="currentColor" opacity="0.22"/>
|
||||
<!-- wide expressive eyes -->
|
||||
<circle cx="82" cy="46" r="3" fill="currentColor" opacity="0.6"/>
|
||||
<circle cx="92" cy="45" r="2.5" fill="currentColor" opacity="0.55"/>
|
||||
<!-- arms dramatically wide -->
|
||||
<line x1="65" y1="75" x2="15" y2="50" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="105" y1="75" x2="160" y2="50" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- gesture sparkles -->
|
||||
<circle cx="10" cy="45" r="2" fill="currentColor" opacity="0.15"/>
|
||||
<circle cx="165" cy="45" r="2" fill="currentColor" opacity="0.15"/>
|
||||
<circle cx="18" cy="38" r="1.5" fill="currentColor" opacity="0.12"/>
|
||||
<circle cx="157" cy="38" r="1.5" fill="currentColor" opacity="0.12"/>
|
||||
<!-- long legs (standing on stage) -->
|
||||
<line x1="77" y1="108" x2="70" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="93" y1="108" x2="100" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet on stage -->
|
||||
<ellipse cx="67" cy="112" rx="8" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<ellipse cx="103" cy="112" rx="8" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- audience: 3 tiny shadoks below stage -->
|
||||
<!-- tiny shadok 1 (left) -->
|
||||
<ellipse cx="40" cy="165" rx="8" ry="10" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="40" cy="152" r="6" fill="currentColor" opacity="0.22"/>
|
||||
<circle cx="39" cy="151" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<circle cx="42" cy="151" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<polygon points="45,151 50,153 45,155" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="37" y1="175" x2="35" y2="195" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<line x1="43" y1="175" x2="45" y2="195" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<!-- tiny shadok 2 (center) -->
|
||||
<ellipse cx="85" cy="168" rx="8" ry="10" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="85" cy="155" r="6" fill="currentColor" opacity="0.22"/>
|
||||
<circle cx="83" cy="154" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<circle cx="87" cy="154" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<polygon points="90,154 95,156 90,158" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="82" y1="178" x2="80" y2="198" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<line x1="88" y1="178" x2="90" y2="198" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<!-- tiny shadok 3 (right) -->
|
||||
<ellipse cx="130" cy="163" rx="8" ry="10" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="130" cy="150" r="6" fill="currentColor" opacity="0.22"/>
|
||||
<circle cx="128" cy="149" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<circle cx="132" cy="149" r="1" fill="currentColor" opacity="0.45"/>
|
||||
<polygon points="135,149 140,151 135,153" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="127" y1="173" x2="125" y2="193" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<line x1="133" y1="173" x2="135" y2="193" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<!-- 6. Correcteur — leaning forward, magnifying glass over manuscript, red pen -->
|
||||
<svg class="shadok shadok-correcteur" viewBox="0 0 170 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- body (leaning forward heavily) -->
|
||||
<ellipse cx="75" cy="82" rx="21" ry="28" fill="currentColor" opacity="0.28" transform="rotate(20 75 82)"/>
|
||||
<!-- head (craned forward) -->
|
||||
<circle cx="95" cy="48" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (pursed, critical) -->
|
||||
<polygon points="108,45 118,48 108,52" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (squinting, one bigger — peering through glass) -->
|
||||
<circle cx="92" cy="45" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="101" cy="46" r="3" fill="currentColor" opacity="0.6"/>
|
||||
<!-- arm holding magnifying glass -->
|
||||
<line x1="90" y1="72" x2="120" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- magnifying glass (big) -->
|
||||
<circle cx="128" cy="98" r="18" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.3"/>
|
||||
<circle cx="128" cy="98" r="16" fill="currentColor" opacity="0.06"/>
|
||||
<!-- handle -->
|
||||
<line x1="140" y1="112" x2="155" y2="135" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- manuscript under magnifying glass -->
|
||||
<rect x="95" y="115" width="55" height="70" rx="2" fill="currentColor" opacity="0.1"/>
|
||||
<!-- text lines on manuscript -->
|
||||
<line x1="100" y1="125" x2="140" y2="125" stroke="currentColor" stroke-width="0.8" opacity="0.18"/>
|
||||
<line x1="100" y1="132" x2="145" y2="132" stroke="currentColor" stroke-width="0.8" opacity="0.18"/>
|
||||
<line x1="100" y1="139" x2="138" y2="139" stroke="currentColor" stroke-width="0.8" opacity="0.18"/>
|
||||
<line x1="100" y1="146" x2="142" y2="146" stroke="currentColor" stroke-width="0.8" opacity="0.18"/>
|
||||
<line x1="100" y1="153" x2="135" y2="153" stroke="currentColor" stroke-width="0.8" opacity="0.18"/>
|
||||
<!-- crossed-out text (red corrections) -->
|
||||
<line x1="100" y1="132" x2="130" y2="132" stroke="currentColor" stroke-width="1.5" opacity="0.35"/>
|
||||
<line x1="105" y1="146" x2="125" y2="146" stroke="currentColor" stroke-width="1.5" opacity="0.35"/>
|
||||
<!-- other arm holding red pen -->
|
||||
<line x1="58" y1="78" x2="35" y2="100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- red pen -->
|
||||
<line x1="35" y1="100" x2="25" y2="115" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.35"/>
|
||||
<circle cx="24" cy="117" r="1.5" fill="currentColor" opacity="0.4"/>
|
||||
<!-- long legs -->
|
||||
<line x1="65" y1="108" x2="50" y2="178" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="82" y1="105" x2="95" y2="178" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="45" cy="181" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="100" cy="181" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 7. Colporteur — walking profile, books in wooden crate on back, walking stick, hat -->
|
||||
<svg class="shadok shadok-colporteur" viewBox="0 0 160 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- body (profile, walking right, leaning forward under weight) -->
|
||||
<ellipse cx="70" cy="72" rx="20" ry="25" fill="currentColor" opacity="0.28" transform="rotate(15 70 72)"/>
|
||||
<!-- head -->
|
||||
<circle cx="82" cy="38" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- hat (brimmed) -->
|
||||
<ellipse cx="82" cy="26" rx="18" ry="5" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="72" y="16" width="20" height="12" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- beak (profile right) -->
|
||||
<polygon points="94,36 106,40 94,43" fill="currentColor" opacity="0.32"/>
|
||||
<!-- eye (profile — one visible, determined) -->
|
||||
<circle cx="88" cy="35" r="2.5" fill="currentColor" opacity="0.6"/>
|
||||
<!-- wooden crate on back (big, loaded with books) -->
|
||||
<rect x="25" y="35" width="40" height="50" rx="3" stroke="currentColor" stroke-width="2" fill="currentColor" opacity="0.12"/>
|
||||
<!-- strap over shoulder -->
|
||||
<line x1="45" y1="35" x2="78" y2="55" stroke="currentColor" stroke-width="2" opacity="0.25"/>
|
||||
<line x1="65" y1="35" x2="85" y2="60" stroke="currentColor" stroke-width="2" opacity="0.25"/>
|
||||
<!-- books in crate (visible spines) -->
|
||||
<rect x="28" y="38" width="6" height="44" rx="1" fill="currentColor" opacity="0.22"/>
|
||||
<rect x="36" y="40" width="5" height="42" rx="1" fill="currentColor" opacity="0.18"/>
|
||||
<rect x="43" y="37" width="7" height="45" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="52" y="39" width="5" height="43" rx="1" fill="currentColor" opacity="0.16"/>
|
||||
<rect x="58" y="38" width="4" height="44" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<!-- arm forward with walking stick -->
|
||||
<line x1="88" y1="65" x2="115" y2="80" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- walking stick (long) -->
|
||||
<line x1="115" y1="80" x2="125" y2="195" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- other arm back holding strap -->
|
||||
<line x1="55" y1="68" x2="45" y2="55" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- long legs (walking stride) — front leg forward, back leg behind -->
|
||||
<line x1="78" y1="95" x2="100" y2="170" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="62" y1="95" x2="40" y2="170" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet (walking) -->
|
||||
<ellipse cx="105" cy="173" rx="11" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="35" cy="173" rx="10" ry="4" fill="currentColor" opacity="0.22"/>
|
||||
</svg>
|
||||
|
||||
<!-- 8. Illustratrice — at easel, brush in one hand, palette in other, canvas showing a shadok -->
|
||||
<svg class="shadok shadok-illustratrice" viewBox="0 0 180 220" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- easel legs -->
|
||||
<line x1="105" y1="30" x2="85" y2="210" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="145" y1="30" x2="165" y2="210" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<line x1="125" y1="60" x2="125" y2="210" stroke="currentColor" stroke-width="2" opacity="0.18"/>
|
||||
<!-- canvas on easel -->
|
||||
<rect x="95" y="25" width="60" height="75" rx="2" fill="currentColor" opacity="0.08"/>
|
||||
<rect x="95" y="25" width="60" height="75" rx="2" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.2"/>
|
||||
<!-- tiny shadok drawing on canvas! -->
|
||||
<ellipse cx="125" cy="65" rx="8" ry="10" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="125" cy="52" r="6" fill="currentColor" opacity="0.2"/>
|
||||
<polygon points="130,51 136,53 130,55" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="123" cy="51" r="1" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="127" cy="51" r="1" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="121" y1="75" x2="118" y2="88" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="129" y1="75" x2="132" y2="88" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<!-- body (3/4 view, standing back from easel) -->
|
||||
<ellipse cx="55" cy="90" rx="22" ry="28" fill="currentColor" opacity="0.28"/>
|
||||
<!-- head (looking at canvas) -->
|
||||
<circle cx="62" cy="52" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- beak (profile right, toward canvas) -->
|
||||
<polygon points="75,50 88,54 76,56" fill="currentColor" opacity="0.3"/>
|
||||
<!-- eyes (artistic scrutiny, different sizes) -->
|
||||
<circle cx="60" cy="49" r="2" fill="currentColor" opacity="0.55"/>
|
||||
<circle cx="69" cy="50" r="2.8" fill="currentColor" opacity="0.6"/>
|
||||
<!-- arm holding brush toward canvas -->
|
||||
<line x1="73" y1="82" x2="100" y2="60" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- paintbrush -->
|
||||
<line x1="100" y1="60" x2="108" y2="52" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<circle cx="110" cy="50" r="2" fill="currentColor" opacity="0.3"/>
|
||||
<!-- other arm holding palette -->
|
||||
<line x1="38" y1="85" x2="18" y2="95" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- palette (big, with color dots) -->
|
||||
<ellipse cx="12" cy="102" rx="16" ry="12" fill="currentColor" opacity="0.15"/>
|
||||
<!-- thumb hole -->
|
||||
<circle cx="12" cy="108" r="3" fill="currentColor" opacity="0.05"/>
|
||||
<!-- paint dabs on palette -->
|
||||
<circle cx="6" cy="97" r="2.5" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="14" cy="94" r="2" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="21" cy="98" r="2.5" fill="currentColor" opacity="0.28"/>
|
||||
<circle cx="8" cy="104" r="2" fill="currentColor" opacity="0.22"/>
|
||||
<circle cx="18" cy="103" r="2" fill="currentColor" opacity="0.3"/>
|
||||
<!-- long legs -->
|
||||
<line x1="45" y1="116" x2="35" y2="188" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="65" y1="116" x2="75" y2="188" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- big flat feet -->
|
||||
<ellipse cx="30" cy="191" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="80" cy="191" rx="10" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<!-- Page de couverture du livre -->
|
||||
<HomeBookSection
|
||||
class="mb-16"
|
||||
:show-chapters="false"
|
||||
@open-player="showBookPlayer = true"
|
||||
@open-pdf="showPdfReader = true"
|
||||
/>
|
||||
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<ul class="flex flex-col gap-3">
|
||||
<li
|
||||
v-for="chapter in chapters"
|
||||
:key="chapter.path"
|
||||
>
|
||||
<NuxtLink
|
||||
:to="`/economique/modele-eco/${chapter.stem?.split('/').pop()}`"
|
||||
class="card-surface flex items-start gap-4 group"
|
||||
>
|
||||
<span class="font-mono text-2xl font-bold text-primary/30 leading-none mt-1 w-10 text-right flex-shrink-0">
|
||||
{{ String(chapter.order).padStart(2, '0') }}
|
||||
</span>
|
||||
<div class="min-w-0 flex-1">
|
||||
<h2 class="font-display text-lg font-semibold text-white group-hover:text-primary transition-colors">
|
||||
{{ chapter.title }}
|
||||
</h2>
|
||||
<p v-if="chapter.description" class="mt-1 text-sm text-white/50">
|
||||
{{ chapter.description }}
|
||||
</p>
|
||||
<div class="mt-2 flex items-center gap-3">
|
||||
<span v-if="chapter.readingTime" class="text-xs text-white/30">
|
||||
<span class="i-lucide-clock inline-block h-3 w-3 mr-1 align-middle" />
|
||||
{{ chapter.readingTime }}
|
||||
</span>
|
||||
<SongBadges :chapter-slug="chapter.stem?.split('/').pop() ?? ''" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="i-lucide-chevron-right h-5 w-5 text-white/20 group-hover:text-primary/60 transition-colors flex-shrink-0 mt-2" />
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BookPlayer v-model="showBookPlayer" />
|
||||
<BookPdfReader v-model="showPdfReader" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('economique/modele-eco')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Table des matières',
|
||||
})
|
||||
|
||||
const { data: chapters } = await useAsyncData('book-toc', () =>
|
||||
queryCollection('book').order('order', 'ASC').all(),
|
||||
)
|
||||
|
||||
const showBookPlayer = ref(false)
|
||||
const showPdfReader = ref(false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
/* Shadok illustrations — shared */
|
||||
.shadok {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* 1. Typographe — top left */
|
||||
.shadok-typographe {
|
||||
top: 1%;
|
||||
left: 1%;
|
||||
opacity: 0.24;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-1 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 2. Lectrice — top right, sitting */
|
||||
.shadok-lectrice {
|
||||
top: 2%;
|
||||
right: 1%;
|
||||
opacity: 0.22;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-2 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 3. Calligraphe — left, 40% */
|
||||
.shadok-calligraphe {
|
||||
top: 40%;
|
||||
left: 1%;
|
||||
opacity: 0.2;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-3 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 4. Relieur — right, 35% */
|
||||
.shadok-relieur {
|
||||
top: 35%;
|
||||
right: 2%;
|
||||
opacity: 0.24;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-4 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 5. Conteuse — bottom left */
|
||||
.shadok-conteuse {
|
||||
bottom: 6%;
|
||||
left: 1%;
|
||||
opacity: 0.22;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-5 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 6. Correcteur — bottom right, leaning */
|
||||
.shadok-correcteur {
|
||||
bottom: 5%;
|
||||
right: 1%;
|
||||
opacity: 0.2;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-6 9.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 7. Colporteur — center bottom, walking */
|
||||
.shadok-colporteur {
|
||||
bottom: 2%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
opacity: 0.18;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-7 7.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 8. Illustratrice — right, 58% */
|
||||
.shadok-illustratrice {
|
||||
top: 58%;
|
||||
right: 1%;
|
||||
opacity: 0.26;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-8 10.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Float animations — each unique duration and offset */
|
||||
@keyframes shadok-float-1 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
@keyframes shadok-float-2 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
@keyframes shadok-float-3 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-12px); }
|
||||
}
|
||||
@keyframes shadok-float-4 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-9px); }
|
||||
}
|
||||
@keyframes shadok-float-5 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-11px); }
|
||||
}
|
||||
@keyframes shadok-float-6 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-7px); }
|
||||
}
|
||||
@keyframes shadok-float-7 {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-10px); }
|
||||
}
|
||||
@keyframes shadok-float-8 {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
/* Hidden on mobile */
|
||||
@media (max-width: 768px) {
|
||||
.shadok {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
119
app/pages/economique/monnaie-libre.vue
Normal file
119
app/pages/economique/monnaie-libre.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="section-icon mx-auto mb-6">
|
||||
<span v-if="content?.icon === 'g1'" class="g1-icon">Ğ1</span>
|
||||
<div v-else :class="`i-lucide-${content?.icon ?? 'coins'}`" class="h-12 w-12" />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase text-center">
|
||||
{{ content?.kicker }}
|
||||
</p>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold mb-4 text-center" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8 text-center" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
|
||||
<!-- Content -->
|
||||
<div v-if="content?.content" class="prose-block mb-8">
|
||||
<p class="leading-relaxed whitespace-pre-line" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content.content }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- External links -->
|
||||
<div v-if="content?.links" class="flex flex-col gap-3 mb-10">
|
||||
<a
|
||||
v-for="link in content.links"
|
||||
:key="link.href"
|
||||
:href="link.href"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="link-card group"
|
||||
>
|
||||
<div class="link-icon">
|
||||
<div :class="`i-lucide-${link.icon ?? 'external-link'} h-4 w-4`" />
|
||||
</div>
|
||||
<span class="text-sm font-medium" style="color: hsl(var(--color-text))">{{ link.label }}</span>
|
||||
<div class="i-lucide-arrow-up-right h-3.5 w-3.5 ml-auto text-primary/40 group-hover:text-primary transition-colors" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<UiBaseButton variant="ghost" to="/economique">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Autonomie économique
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { data: content } = await usePageContent('economique/monnaie-libre')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Monnaie libre',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.g1-icon {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
font-size: 1.75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.section-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.prose-block {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.link-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid hsl(var(--color-primary) / 0.1);
|
||||
background: hsl(var(--color-surface));
|
||||
text-decoration: none;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.link-card:hover {
|
||||
border-color: hsl(var(--color-primary) / 0.25);
|
||||
}
|
||||
|
||||
.link-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
border-radius: 0.375rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
85
app/pages/economique/productions-collectives.vue
Normal file
85
app/pages/economique/productions-collectives.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="section-icon mx-auto mb-6">
|
||||
<div :class="`i-lucide-${content?.icon ?? 'users'}`" class="h-12 w-12" />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase text-center">
|
||||
{{ content?.kicker }}
|
||||
</p>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold mb-4 text-center" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8 text-center" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
|
||||
<span v-if="content?.gestation" class="gestation-badge mx-auto mb-8">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
|
||||
<!-- Content -->
|
||||
<div v-if="content?.content" class="prose-block mb-10">
|
||||
<p class="leading-relaxed whitespace-pre-line" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content.content }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<UiBaseButton variant="ghost" to="/economique">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Autonomie économique
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { data: content } = await usePageContent('economique/productions-collectives')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Productions collectives',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.section-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.prose-block {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
</style>
|
||||
@@ -1,152 +1,340 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding min-h-[70vh] flex items-center justify-center">
|
||||
<!-- Shadok jongleur: juggling coins (top-left) -->
|
||||
<svg class="shadok-juggler" viewBox="0 0 240 300" fill="none" aria-hidden="true">
|
||||
<!-- 1. Shadok funambule: walking on tightrope (top-left) -->
|
||||
<svg class="shadok-funambule" viewBox="0 0 170 200" fill="none" aria-hidden="true">
|
||||
<!-- Tightrope -->
|
||||
<line x1="5" y1="170" x2="165" y2="170" stroke="currentColor" stroke-width="2" opacity="0.3"/>
|
||||
<!-- Body (small oval, leaning forward) -->
|
||||
<ellipse cx="85" cy="110" rx="20" ry="28" fill="currentColor" opacity="0.25" transform="rotate(-5 85 110)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="88" cy="72" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (focused, looking down-right) -->
|
||||
<circle cx="93" cy="70" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="99" cy="71" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak (pointy, right side) -->
|
||||
<polygon points="103,74 116,72 103,78" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Balancing pole (big, horizontal) -->
|
||||
<line x1="10" y1="92" x2="160" y2="88" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Arms holding pole -->
|
||||
<line x1="67" y1="100" x2="45" y2="92" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="103" y1="98" x2="125" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Left leg (forward, on rope) -->
|
||||
<line x1="78" y1="136" x2="70" y2="170" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="70" cy="172" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Right leg (back, lifted) -->
|
||||
<line x1="92" y1="136" x2="108" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="108" cy="167" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 2. Shadok accordeoniste: playing accordion (top-right, profile) -->
|
||||
<svg class="shadok-accordeoniste" viewBox="0 0 180 210" fill="none" aria-hidden="true">
|
||||
<!-- Body (profile, small) -->
|
||||
<ellipse cx="70" cy="115" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head (profile) -->
|
||||
<circle cx="72" cy="75" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Beret -->
|
||||
<ellipse cx="72" cy="60" rx="18" ry="6" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="72" cy="56" r="4" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Eye (profile, one visible) -->
|
||||
<circle cx="80" cy="73" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak (profile right) -->
|
||||
<polygon points="86,76 98,74 86,80" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Accordion bellows (big, extended right) -->
|
||||
<rect x="92" y="95" width="12" height="45" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="98" y1="98" x2="98" y2="137" stroke="currentColor" stroke-width="0.8" opacity="0.2"/>
|
||||
<rect x="107" y="93" width="8" height="49" rx="2" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="118" y="91" width="8" height="53" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="129" y="89" width="8" height="57" rx="2" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="140" y="87" width="12" height="61" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Keyboard dots on right panel -->
|
||||
<circle cx="146" cy="100" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="146" cy="110" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="146" cy="120" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="146" cy="130" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Left arm on bellows -->
|
||||
<line x1="52" y1="105" x2="92" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Right arm stretched to far end -->
|
||||
<line x1="90" y1="108" x2="140" y2="100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Foot tapping (right lifted) -->
|
||||
<line x1="60" y1="141" x2="52" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="52" cy="197" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="80" y1="141" x2="90" y2="188" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="90" cy="190" rx="8" ry="3" fill="currentColor" opacity="0.3" transform="rotate(-15 90 190)"/>
|
||||
<!-- Music notes -->
|
||||
<text x="155" y="80" fill="currentColor" opacity="0.25" font-size="14">♪</text>
|
||||
<text x="145" y="68" fill="currentColor" opacity="0.2" font-size="11">♫</text>
|
||||
</svg>
|
||||
|
||||
<!-- 3. Shadok jongleur: 4 balls in the air (top-center) -->
|
||||
<svg class="shadok-jongleur" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Body -->
|
||||
<ellipse cx="120" cy="160" rx="38" ry="46" fill="currentColor" opacity="0.85"/>
|
||||
<ellipse cx="80" cy="120" rx="21" ry="27" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head -->
|
||||
<circle cx="120" cy="98" r="24" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Eyes (looking up at coins) -->
|
||||
<circle cx="112" cy="92" r="3.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="130" cy="92" r="3.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="113" cy="91" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="131" cy="91" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Smile -->
|
||||
<path d="M112 108 Q120 114 128 108" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<!-- Arms up (juggling) -->
|
||||
<line x1="85" y1="145" x2="55" y2="105" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="155" y1="145" x2="185" y2="105" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Hands -->
|
||||
<circle cx="55" cy="103" r="4" fill="currentColor" opacity="0.4"/>
|
||||
<circle cx="185" cy="103" r="4" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Juggling coins -->
|
||||
<circle cx="90" cy="55" r="8" fill="currentColor" opacity="0.35"/>
|
||||
<text x="86" y="59" fill="currentColor" opacity="0.5" font-size="10" font-weight="bold">$</text>
|
||||
<circle cx="120" cy="40" r="8" fill="currentColor" opacity="0.3"/>
|
||||
<text x="116" y="44" fill="currentColor" opacity="0.45" font-size="10" font-weight="bold">$</text>
|
||||
<circle cx="150" cy="50" r="8" fill="currentColor" opacity="0.32"/>
|
||||
<text x="146" y="54" fill="currentColor" opacity="0.48" font-size="10" font-weight="bold">$</text>
|
||||
<!-- Legs -->
|
||||
<line x1="105" y1="203" x2="95" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="135" y1="203" x2="145" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<circle cx="80" cy="82" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (looking up, wide) -->
|
||||
<circle cx="74" cy="78" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="86" cy="78" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Mouth open (concentration) -->
|
||||
<ellipse cx="80" cy="92" rx="4" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Beak (small, front view) -->
|
||||
<polygon points="80,86 87,89 80,92" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Arms up wide -->
|
||||
<line x1="60" y1="110" x2="30" y2="75" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="100" y1="110" x2="130" y2="75" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- 4 juggling balls in arc -->
|
||||
<circle cx="40" cy="35" r="8" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="70" cy="18" r="8" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="100" cy="15" r="8" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="128" cy="30" r="8" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Long legs -->
|
||||
<line x1="72" y1="145" x2="60" y2="200" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="60" cy="202" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="88" y1="145" x2="100" y2="200" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="100" cy="202" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok échelle: on a wobbly ladder (top-right) -->
|
||||
<svg class="shadok-ladder" viewBox="0 0 220 320" fill="none" aria-hidden="true">
|
||||
<!-- Ladder (tilting) -->
|
||||
<line x1="80" y1="50" x2="70" y2="300" stroke="currentColor" stroke-width="3" opacity="0.35"/>
|
||||
<line x1="150" y1="50" x2="140" y2="300" stroke="currentColor" stroke-width="3" opacity="0.35"/>
|
||||
<!-- Rungs -->
|
||||
<line x1="82" y1="80" x2="148" y2="80" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="83" y1="120" x2="147" y2="120" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="84" y1="160" x2="146" y2="160" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="85" y1="200" x2="145" y2="200" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<line x1="86" y1="240" x2="144" y2="240" stroke="currentColor" stroke-width="2.5" opacity="0.3"/>
|
||||
<!-- Shadok on top (arms out for balance) -->
|
||||
<ellipse cx="115" cy="68" rx="18" ry="14" fill="currentColor" opacity="0.85"/>
|
||||
<circle cx="115" cy="46" r="14" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Eyes (worried) -->
|
||||
<circle cx="110" cy="43" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="122" cy="43" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="110" cy="44" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="122" cy="44" r="1.2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Worried mouth -->
|
||||
<path d="M108 52 Q115 49 122 52" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Arms out (balancing) -->
|
||||
<line x1="97" y1="62" x2="60" y2="55" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="133" y1="62" x2="170" y2="55" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.6"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok acrobate: doing a cartwheel (center) -->
|
||||
<svg class="shadok-acrobat" viewBox="0 0 260 240" fill="none" aria-hidden="true">
|
||||
<!-- Body (sideways, mid-cartwheel) -->
|
||||
<ellipse cx="130" cy="120" rx="30" ry="38" fill="currentColor" opacity="0.85" transform="rotate(45 130 120)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="155" cy="82" r="20" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Eyes (dizzy/happy) -->
|
||||
<path d="M148 78 Q152 74 156 78" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<path d="M160 78 Q164 74 168 78" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<!-- Smile -->
|
||||
<path d="M150 90 Q158 95 165 90" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Arms (one touching ground, one up) -->
|
||||
<line x1="110" y1="100" x2="80" y2="130" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="150" y1="105" x2="185" y2="70" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Hand on ground -->
|
||||
<circle cx="78" cy="132" r="4" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Legs (splayed in cartwheel) -->
|
||||
<line x1="125" y1="155" x2="100" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="140" y1="150" x2="175" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Motion lines -->
|
||||
<path d="M70 110 Q60 105 55 115" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<path d="M190 60 Q200 55 205 65" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok dormeur: sleeping on a cloud (bottom-left) -->
|
||||
<svg class="shadok-sleeper" viewBox="0 0 260 220" fill="none" aria-hidden="true">
|
||||
<!-- Cloud -->
|
||||
<ellipse cx="130" cy="150" rx="80" ry="25" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="80" cy="140" r="25" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="120" cy="130" r="30" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="165" cy="135" r="22" fill="currentColor" opacity="0.18"/>
|
||||
<circle cx="190" cy="142" r="18" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Shadok body (lying down) -->
|
||||
<ellipse cx="130" cy="125" rx="35" ry="18" fill="currentColor" opacity="0.85"/>
|
||||
<!-- Head (on cloud, sideways) -->
|
||||
<ellipse cx="85" cy="118" rx="18" ry="16" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Closed eyes (sleeping) -->
|
||||
<path d="M76 115 Q80 112 84 115" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<path d="M88 115 Q92 112 96 115" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<!-- Snooze bubbles -->
|
||||
<text x="70" y="100" fill="currentColor" opacity="0.3" font-size="12" font-weight="bold">z</text>
|
||||
<text x="60" y="85" fill="currentColor" opacity="0.25" font-size="16" font-weight="bold">z</text>
|
||||
<text x="48" y="68" fill="currentColor" opacity="0.2" font-size="20" font-weight="bold">z</text>
|
||||
<!-- Legs (curled) -->
|
||||
<path d="M165 125 Q180 130 175 140" stroke="currentColor" stroke-width="3" stroke-linecap="round" fill="none" opacity="0.5"/>
|
||||
<path d="M160 130 Q172 138 168 148" stroke="currentColor" stroke-width="3" stroke-linecap="round" fill="none" opacity="0.5"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok cuisinier: cooking in a cauldron (bottom-right) -->
|
||||
<svg class="shadok-cook" viewBox="0 0 240 300" fill="none" aria-hidden="true">
|
||||
<!-- 4. Shadok cracheur de feu: head tilted back, flame from mouth -->
|
||||
<svg class="shadok-cracheur" viewBox="0 0 170 220" fill="none" aria-hidden="true">
|
||||
<!-- Body -->
|
||||
<ellipse cx="120" cy="145" rx="38" ry="45" fill="currentColor" opacity="0.85"/>
|
||||
<ellipse cx="75" cy="125" rx="22" ry="30" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head (tilted back) -->
|
||||
<circle cx="78" cy="82" r="16" fill="currentColor" opacity="0.3" />
|
||||
<!-- Eyes (looking up) -->
|
||||
<circle cx="73" cy="76" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="83" cy="76" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak (pointing up, open) -->
|
||||
<polygon points="78,66 85,52 72,66" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Flame stream from beak (big, upward-right) -->
|
||||
<path d="M82 54 Q100 25 95 10 Q110 30 120 8 Q115 35 135 15 Q120 42 140 30 Q118 50 130 45" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Torch in left hand -->
|
||||
<line x1="55" y1="115" x2="30" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<rect x="24" y="78" width="8" height="16" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<path d="M28 78 Q28 68 32 72 Q28 65 28 78" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Right arm out for balance -->
|
||||
<line x1="95" y1="112" x2="125" y2="100" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Long legs -->
|
||||
<line x1="66" y1="153" x2="55" y2="210" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="55" cy="212" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="84" y1="153" x2="95" y2="210" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="95" cy="212" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 5. Shadok trapeziste: hanging from trapeze, body in arc -->
|
||||
<svg class="shadok-trapeziste" viewBox="0 0 150 220" fill="none" aria-hidden="true">
|
||||
<!-- Trapeze ropes -->
|
||||
<line x1="40" y1="0" x2="50" y2="40" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="110" y1="0" x2="100" y2="40" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- Trapeze bar -->
|
||||
<line x1="48" y1="40" x2="102" y2="40" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Arms (hanging from bar) -->
|
||||
<line x1="60" y1="42" x2="65" y2="70" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="90" y1="42" x2="85" y2="70" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Body (arched, graceful) -->
|
||||
<ellipse cx="75" cy="95" rx="20" ry="25" fill="currentColor" opacity="0.25" transform="rotate(10 75 95)"/>
|
||||
<!-- Head (below body, looking down) -->
|
||||
<circle cx="78" cy="72" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (excited, looking down) -->
|
||||
<circle cx="74" cy="74" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="84" cy="75" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak (pointing down-right) -->
|
||||
<polygon points="86,78 96,84 86,82" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Legs (pointed, graceful, extending down-right) -->
|
||||
<line x1="80" y1="118" x2="95" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="70" y1="118" x2="82" y2="180" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Pointed feet -->
|
||||
<polygon points="95,175 105,180 95,182" fill="currentColor" opacity="0.3"/>
|
||||
<polygon points="82,180 92,185 82,187" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 6. Shadok batteur: behind drum kit, sticks raised -->
|
||||
<svg class="shadok-batteur" viewBox="0 0 180 210" fill="none" aria-hidden="true">
|
||||
<!-- Snare drum (center, big) -->
|
||||
<ellipse cx="90" cy="165" rx="35" ry="12" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="55" y="155" width="70" height="20" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<ellipse cx="90" cy="155" rx="35" ry="12" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Hi-hat (left) -->
|
||||
<ellipse cx="30" cy="140" rx="18" ry="5" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="30" y1="140" x2="30" y2="185" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<!-- Cymbal (right) -->
|
||||
<ellipse cx="155" cy="120" rx="20" ry="5" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="155" y1="120" x2="155" y2="185" stroke="currentColor" stroke-width="2" opacity="0.2"/>
|
||||
<!-- Body (behind kit) -->
|
||||
<ellipse cx="90" cy="110" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head -->
|
||||
<circle cx="120" cy="85" r="24" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Chef hat -->
|
||||
<ellipse cx="120" cy="62" rx="22" ry="18" fill="currentColor" opacity="0.35"/>
|
||||
<rect x="105" y="68" width="30" height="6" rx="1" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Eyes (focused on cooking) -->
|
||||
<circle cx="112" cy="82" r="3.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="130" cy="82" r="3.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="113" cy="83" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="131" cy="83" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Tongue out (concentrating) -->
|
||||
<path d="M115 96 Q120 100 125 96" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Arm with ladle -->
|
||||
<line x1="155" y1="135" x2="185" y2="175" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Ladle -->
|
||||
<line x1="185" y1="175" x2="175" y2="200" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.5"/>
|
||||
<ellipse cx="175" cy="205" rx="8" ry="5" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Other arm -->
|
||||
<line x1="85" y1="140" x2="60" y2="175" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Legs -->
|
||||
<line x1="105" y1="188" x2="95" y2="250" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="135" y1="188" x2="145" y2="250" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Cauldron -->
|
||||
<path d="M55 220 Q55 260 120 260 Q185 260 185 220" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="120" cy="220" rx="65" ry="12" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="120" cy="220" rx="65" ry="12" stroke="currentColor" stroke-width="2" fill="none" opacity="0.35"/>
|
||||
<!-- Steam -->
|
||||
<path d="M95 210 Q90 195 95 185" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<path d="M120 208 Q118 190 122 180" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<path d="M145 210 Q148 195 143 185" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<circle cx="90" cy="70" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (intense, looking at drums) -->
|
||||
<circle cx="84" cy="68" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="96" cy="69" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak (front, small) -->
|
||||
<polygon points="90,76 97,80 90,82" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Arms raised with drumsticks -->
|
||||
<line x1="70" y1="100" x2="40" y2="65" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="40" y1="65" x2="25" y2="50" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="110" y1="100" x2="140" y2="60" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="140" y1="60" x2="158" y2="48" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Motion lines on sticks -->
|
||||
<path d="M22 52 Q18 48 20 44" stroke="currentColor" stroke-width="1" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<path d="M160 50 Q164 46 162 42" stroke="currentColor" stroke-width="1" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<!-- Legs (tucked behind kit) -->
|
||||
<line x1="80" y1="136" x2="70" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="70" cy="197" rx="7" ry="3" fill="currentColor" opacity="0.25"/>
|
||||
<line x1="100" y1="136" x2="110" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<ellipse cx="110" cy="197" rx="7" ry="3" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 7. Shadok marionnettiste: holding puppet strings -->
|
||||
<svg class="shadok-marionnettiste" viewBox="0 0 160 220" fill="none" aria-hidden="true">
|
||||
<!-- Body -->
|
||||
<ellipse cx="80" cy="75" rx="20" ry="26" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head -->
|
||||
<circle cx="80" cy="40" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (looking down at puppet) -->
|
||||
<circle cx="75" cy="42" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="86" cy="43" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak -->
|
||||
<polygon points="89,44 100,42 89,48" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Arms down holding control bar -->
|
||||
<line x1="62" y1="68" x2="50" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="98" y1="68" x2="110" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Control bar (cross) -->
|
||||
<line x1="40" y1="108" x2="120" y2="108" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="80" y1="98" x2="80" y2="118" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Puppet strings -->
|
||||
<line x1="45" y1="108" x2="55" y2="155" stroke="currentColor" stroke-width="1" opacity="0.25"/>
|
||||
<line x1="80" y1="118" x2="70" y2="158" stroke="currentColor" stroke-width="1" opacity="0.25"/>
|
||||
<line x1="115" y1="108" x2="85" y2="155" stroke="currentColor" stroke-width="1" opacity="0.25"/>
|
||||
<line x1="80" y1="98" x2="70" y2="148" stroke="currentColor" stroke-width="1" opacity="0.25"/>
|
||||
<!-- Mini puppet shadok -->
|
||||
<circle cx="70" cy="155" r="8" fill="currentColor" opacity="0.2"/>
|
||||
<ellipse cx="70" cy="172" rx="10" ry="13" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Puppet eyes -->
|
||||
<circle cx="67" cy="154" r="1" fill="currentColor" opacity="0.4"/>
|
||||
<circle cx="74" cy="154" r="1" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Puppet beak -->
|
||||
<polygon points="76,156 82,155 76,158" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Puppet legs -->
|
||||
<line x1="64" y1="184" x2="58" y2="208" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="76" y1="184" x2="82" y2="208" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- Master shadok legs -->
|
||||
<line x1="72" y1="99" x2="62" y2="155" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="88" y1="99" x2="98" y2="155" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.3"/>
|
||||
<ellipse cx="62" cy="157" rx="7" ry="3" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="98" cy="157" rx="7" ry="3" fill="currentColor" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- 8. Shadok clown: oversized shoes, red nose, squirting flower -->
|
||||
<svg class="shadok-clown" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Body -->
|
||||
<ellipse cx="80" cy="110" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head -->
|
||||
<circle cx="80" cy="70" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Party hat (tall cone) -->
|
||||
<polygon points="80,38 68,62 92,62" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="80" cy="38" r="3" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Big red nose (circle on beak) -->
|
||||
<circle cx="92" cy="74" r="5" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Beak behind nose -->
|
||||
<polygon points="88,72 100,74 88,78" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Eyes (different directions — goofy) -->
|
||||
<circle cx="74" cy="66" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="85" cy="64" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Big goofy grin -->
|
||||
<path d="M72 82 Q80 90 88 82" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Squirting flower on chest -->
|
||||
<circle cx="80" cy="95" r="6" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="80" cy="95" r="2.5" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Water squirt from flower -->
|
||||
<path d="M86 93 Q100 85 105 90" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<circle cx="107" cy="90" r="2" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="112" cy="88" r="1.5" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Arms -->
|
||||
<line x1="60" y1="100" x2="35" y2="90" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="100" y1="100" x2="125" y2="85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Long legs -->
|
||||
<line x1="72" y1="136" x2="50" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="88" y1="136" x2="110" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- OVERSIZED shoes -->
|
||||
<ellipse cx="42" cy="190" rx="18" ry="6" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="118" cy="190" rx="18" ry="6" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- 9. Shadok acrobate: mid-cartwheel, body rotated 90deg -->
|
||||
<svg class="shadok-acrobate" viewBox="0 0 160 200" fill="none" aria-hidden="true">
|
||||
<!-- Body (rotated 90 degrees) -->
|
||||
<ellipse cx="80" cy="100" rx="20" ry="26" fill="currentColor" opacity="0.25" transform="rotate(90 80 100)"/>
|
||||
<!-- Head (at bottom-right, inverted) -->
|
||||
<circle cx="112" cy="100" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes (dizzy, spiral-ish) -->
|
||||
<path d="M108 97 Q110 94 113 97" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<path d="M117 97 Q119 94 122 97" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.4"/>
|
||||
<!-- Beak (pointing right) -->
|
||||
<polygon points="124,102 136,100 124,106" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Limbs in pinwheel pattern -->
|
||||
<!-- Arm up-right -->
|
||||
<line x1="85" y1="80" x2="110" y2="35" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Arm down-left -->
|
||||
<line x1="75" y1="120" x2="50" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Leg up-left (hand on ground) -->
|
||||
<line x1="65" y1="88" x2="25" y2="55" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<circle cx="23" cy="53" r="4" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Leg down-right -->
|
||||
<line x1="95" y1="112" x2="135" y2="150" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="110" cy="33" rx="6" ry="3" fill="currentColor" opacity="0.25" transform="rotate(-60 110 33)"/>
|
||||
<ellipse cx="135" cy="152" rx="6" ry="3" fill="currentColor" opacity="0.25" transform="rotate(40 135 152)"/>
|
||||
<!-- Motion arc -->
|
||||
<path d="M30 40 Q20 50 25 60" stroke="currentColor" stroke-width="1" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
<path d="M140 140 Q148 148 145 158" stroke="currentColor" stroke-width="1" stroke-linecap="round" fill="none" opacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
<!-- 10. Shadok regisseur: headset, clipboard, running -->
|
||||
<svg class="shadok-regisseur" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Body (leaning forward, running) -->
|
||||
<ellipse cx="75" cy="105" rx="20" ry="27" fill="currentColor" opacity="0.25" transform="rotate(-12 75 105)"/>
|
||||
<!-- Head -->
|
||||
<circle cx="80" cy="68" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Headset arc -->
|
||||
<path d="M66 60 Q80 48 94 60" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<!-- Headset earpiece -->
|
||||
<ellipse cx="66" cy="64" rx="4" ry="6" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Headset mic -->
|
||||
<path d="M66 70 Q62 78 70 80" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<!-- Eyes (stressed, one looking forward one sideways) -->
|
||||
<circle cx="76" cy="65" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="87" cy="64" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak -->
|
||||
<polygon points="91,68 104,66 91,72" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Lanyard -->
|
||||
<line x1="80" y1="82" x2="80" y2="100" stroke="currentColor" stroke-width="1.5" opacity="0.25"/>
|
||||
<!-- Badge -->
|
||||
<rect x="74" y="100" width="12" height="15" rx="2" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="76" y="103" width="8" height="3" rx="1" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Right arm pointing forward (with authority) -->
|
||||
<line x1="92" y1="95" x2="135" y2="75" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Pointing finger -->
|
||||
<line x1="135" y1="75" x2="145" y2="70" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Left arm holding clipboard -->
|
||||
<line x1="58" y1="98" x2="38" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Clipboard (big) -->
|
||||
<rect x="22" y="105" width="22" height="30" rx="2" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="28" y="102" width="10" height="5" rx="1" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Clipboard lines -->
|
||||
<line x1="26" y1="114" x2="40" y2="114" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="26" y1="120" x2="38" y2="120" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="26" y1="126" x2="40" y2="126" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<!-- Legs (running stride, long) -->
|
||||
<line x1="68" y1="130" x2="40" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="38" cy="197" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="82" y1="130" x2="115" y2="190" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<ellipse cx="117" cy="192" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content relative z-10 text-center">
|
||||
<p class="mb-3 font-mono text-sm tracking-widest text-accent uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-extrabold tracking-tight text-white">
|
||||
<h1 class="page-title font-display font-extrabold tracking-tight" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 text-lg text-white/50">
|
||||
<p class="mt-4 text-lg" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -170,98 +358,201 @@ useHead({
|
||||
font-size: clamp(2.5rem, 6vw, 3.5rem);
|
||||
}
|
||||
|
||||
.shadok-juggler {
|
||||
/* 1. Funambule — top-left */
|
||||
.shadok-funambule {
|
||||
position: absolute;
|
||||
left: 4%;
|
||||
top: 5%;
|
||||
width: clamp(100px, 14vw, 190px);
|
||||
opacity: 0.3;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.24;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-bounce-juggler 4s ease-in-out infinite;
|
||||
animation: shadok-sway-funambule 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-ladder {
|
||||
/* 2. Accordeoniste — top-right */
|
||||
.shadok-accordeoniste {
|
||||
position: absolute;
|
||||
right: 4%;
|
||||
top: 3%;
|
||||
width: clamp(90px, 12vw, 170px);
|
||||
opacity: 0.28;
|
||||
right: 3%;
|
||||
top: 4%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-wobble-ladder 5s ease-in-out infinite;
|
||||
animation: shadok-bounce-accordeon 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-acrobat {
|
||||
/* 3. Jongleur — top-center */
|
||||
.shadok-jongleur {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 55%;
|
||||
top: 2%;
|
||||
transform: translateX(-50%);
|
||||
width: clamp(100px, 13vw, 180px);
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-spin-acrobat 6s ease-in-out infinite;
|
||||
animation: shadok-float-jongleur 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-sleeper {
|
||||
/* 4. Cracheur de feu — left 5%, 40% */
|
||||
.shadok-cracheur {
|
||||
position: absolute;
|
||||
left: 3%;
|
||||
bottom: 5%;
|
||||
width: clamp(110px, 15vw, 210px);
|
||||
opacity: 0.25;
|
||||
left: 5%;
|
||||
top: 40%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-sleeper 8s ease-in-out infinite;
|
||||
animation: shadok-flicker-cracheur 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-cook {
|
||||
/* 5. Trapeziste — right 3%, 30% */
|
||||
.shadok-trapeziste {
|
||||
position: absolute;
|
||||
right: 3%;
|
||||
top: 30%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-swing-trapeze 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 6. Batteur — left 4%, bottom 15% */
|
||||
.shadok-batteur {
|
||||
position: absolute;
|
||||
left: 4%;
|
||||
bottom: 15%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-pulse-batteur 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 7. Marionnettiste — right 4%, bottom 20% */
|
||||
.shadok-marionnettiste {
|
||||
position: absolute;
|
||||
right: 4%;
|
||||
bottom: 20%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-bob-marionnette 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 8. Clown — bottom-left */
|
||||
.shadok-clown {
|
||||
position: absolute;
|
||||
left: 6%;
|
||||
bottom: 3%;
|
||||
width: clamp(70px, 10vw, 135px);
|
||||
opacity: 0.24;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-wobble-clown 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 9. Acrobate — center-bottom */
|
||||
.shadok-acrobate {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 2%;
|
||||
transform: translateX(-50%);
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.18;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-spin-acrobate 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 10. Regisseur — bottom-right */
|
||||
.shadok-regisseur {
|
||||
position: absolute;
|
||||
right: 3%;
|
||||
bottom: 4%;
|
||||
width: clamp(100px, 14vw, 200px);
|
||||
opacity: 0.3;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-bounce-cook 5s ease-in-out infinite;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-rush-regisseur 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-bounce-juggler {
|
||||
@keyframes shadok-sway-funambule {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
25% { transform: translateY(-5px) rotate(2deg); }
|
||||
75% { transform: translateY(-3px) rotate(-2deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-bounce-accordeon {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
30% { transform: translateY(-12px); }
|
||||
60% { transform: translateY(-6px); }
|
||||
40% { transform: translateY(-8px); }
|
||||
70% { transform: translateY(-3px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-wobble-ladder {
|
||||
@keyframes shadok-float-jongleur {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-flicker-cracheur {
|
||||
0%, 100% { transform: translateY(0) scale(1); }
|
||||
30% { transform: translateY(-4px) scale(1.02); }
|
||||
60% { transform: translateY(-2px) scale(0.99); }
|
||||
}
|
||||
|
||||
@keyframes shadok-swing-trapeze {
|
||||
0%, 100% { transform: rotate(0deg); }
|
||||
25% { transform: rotate(3deg); }
|
||||
75% { transform: rotate(-3deg); }
|
||||
25% { transform: rotate(4deg); }
|
||||
75% { transform: rotate(-4deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-spin-acrobat {
|
||||
@keyframes shadok-pulse-batteur {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
15% { transform: translateY(-4px); }
|
||||
30% { transform: translateY(0); }
|
||||
45% { transform: translateY(-6px); }
|
||||
60% { transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes shadok-bob-marionnette {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-7px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-wobble-clown {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
30% { transform: translateY(-5px) rotate(-3deg); }
|
||||
70% { transform: translateY(-2px) rotate(3deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-spin-acrobate {
|
||||
0% { transform: translateX(-50%) rotate(0deg); }
|
||||
25% { transform: translateX(-50%) rotate(15deg); }
|
||||
50% { transform: translateX(-50%) rotate(0deg); }
|
||||
75% { transform: translateX(-50%) rotate(-15deg); }
|
||||
50% { transform: translateX(-50%) rotate(10deg); }
|
||||
100% { transform: translateX(-50%) rotate(0deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-sleeper {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-6px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-bounce-cook {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
40% { transform: translateY(-10px); }
|
||||
70% { transform: translateY(-4px); }
|
||||
@keyframes shadok-rush-regisseur {
|
||||
0%, 100% { transform: translateX(0) translateY(0); }
|
||||
25% { transform: translateX(3px) translateY(-5px); }
|
||||
50% { transform: translateX(-2px) translateY(-2px); }
|
||||
75% { transform: translateX(2px) translateY(-6px); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-juggler { display: none; }
|
||||
.shadok-ladder { display: none; }
|
||||
.shadok-acrobat { display: none; }
|
||||
.shadok-sleeper { display: none; }
|
||||
.shadok-cook { display: none; }
|
||||
.shadok-funambule,
|
||||
.shadok-accordeoniste,
|
||||
.shadok-jongleur,
|
||||
.shadok-cracheur,
|
||||
.shadok-trapeziste,
|
||||
.shadok-batteur,
|
||||
.shadok-marionnettiste,
|
||||
.shadok-clown,
|
||||
.shadok-acrobate,
|
||||
.shadok-regisseur {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="gestation-icon mx-auto mb-6">
|
||||
<div class="i-lucide-flask-conical h-12 w-12 text-accent" />
|
||||
</div>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold text-white mb-4 text-center">
|
||||
{{ item?.label ?? 'En gestation' }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg text-white/60 leading-relaxed mb-8 text-center">
|
||||
{{ item?.description ?? 'Cette initiative est en cours de préparation.' }}
|
||||
</p>
|
||||
|
||||
<!-- Présentation spécifique -->
|
||||
<div v-if="item?.presentation" class="presentation-card mb-10">
|
||||
<div class="presentation-icon">
|
||||
<div class="i-lucide-rocket h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-semibold text-white mb-2">
|
||||
{{ item.presentation.title }}
|
||||
</h2>
|
||||
<p class="text-white/60 leading-relaxed">
|
||||
{{ item.presentation.text }}
|
||||
</p>
|
||||
<p class="mt-4 text-sm text-white/30 italic">En cours de développement.</p>
|
||||
</div>
|
||||
|
||||
<!-- Bouton SejeteralO pour tarifs-eau -->
|
||||
<div v-if="slug === 'tarifs-eau'" class="text-center mb-10">
|
||||
<UiBaseButton :href="sejeteral0Url" target="_blank">
|
||||
<div class="i-lucide-external-link mr-2 h-4 w-4" />
|
||||
Lancer SejeteralO
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<UiBaseButton variant="ghost" to="/">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Retour à l'accueil
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const slug = route.params.slug as string
|
||||
|
||||
const { data: content } = await usePageContent('home')
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const sejeteral0Url = (appConfig.sejeteral0 as { url: string }).url
|
||||
|
||||
const item = computed(() => {
|
||||
const axes = (content.value as any)?.axes
|
||||
if (!axes) return null
|
||||
for (const axis of Object.values(axes) as any[]) {
|
||||
for (const it of axis.items ?? []) {
|
||||
if (it.to === `/gestation/${slug}`) return it
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: item.value?.label ?? `En gestation — ${slug}`,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gestation-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-accent) / 0.1);
|
||||
border: 1px solid hsl(var(--color-accent) / 0.2);
|
||||
}
|
||||
|
||||
.presentation-card {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-primary) / 0.15);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.presentation-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,212 +0,0 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok reader: character with big glasses reading a book -->
|
||||
<svg class="shadok-reader" viewBox="0 0 240 300" fill="none" aria-hidden="true">
|
||||
<!-- Body -->
|
||||
<ellipse cx="120" cy="170" rx="45" ry="55" fill="currentColor" opacity="0.85"/>
|
||||
<!-- Head -->
|
||||
<circle cx="120" cy="100" r="28" fill="currentColor" opacity="0.8"/>
|
||||
<!-- Big round glasses -->
|
||||
<circle cx="107" cy="94" r="11" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.5"/>
|
||||
<circle cx="133" cy="94" r="11" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.5"/>
|
||||
<line x1="118" y1="94" x2="122" y2="94" stroke="currentColor" stroke-width="2" opacity="0.5"/>
|
||||
<!-- Eyes behind glasses -->
|
||||
<circle cx="108" cy="93" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="134" cy="93" r="2.5" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Arms holding book -->
|
||||
<line x1="78" y1="155" x2="60" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="162" y1="155" x2="180" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- Book (open) -->
|
||||
<rect x="55" y="175" width="55" height="40" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<rect x="110" y="175" width="55" height="40" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="110" y1="175" x2="110" y2="215" stroke="currentColor" stroke-width="2" opacity="0.5"/>
|
||||
<!-- Book lines (text) -->
|
||||
<line x1="65" y1="188" x2="100" y2="188" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<line x1="65" y1="195" x2="95" y2="195" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<line x1="65" y1="202" x2="98" y2="202" stroke="currentColor" stroke-width="1" opacity="0.2"/>
|
||||
<!-- Legs -->
|
||||
<line x1="105" y1="222" x2="95" y2="270" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="135" y1="222" x2="145" y2="270" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok stack: pile of books tilting -->
|
||||
<svg class="shadok-stack" viewBox="0 0 160 220" fill="none" aria-hidden="true">
|
||||
<!-- Bottom book -->
|
||||
<rect x="20" y="170" width="120" height="22" rx="3" fill="currentColor" opacity="0.5" transform="rotate(-2 80 181)"/>
|
||||
<!-- Second book -->
|
||||
<rect x="30" y="145" width="100" height="20" rx="3" fill="currentColor" opacity="0.45" transform="rotate(3 80 155)"/>
|
||||
<!-- Third book -->
|
||||
<rect x="25" y="120" width="110" height="18" rx="3" fill="currentColor" opacity="0.4" transform="rotate(-4 80 129)"/>
|
||||
<!-- Fourth book -->
|
||||
<rect x="35" y="97" width="90" height="18" rx="3" fill="currentColor" opacity="0.35" transform="rotate(5 80 106)"/>
|
||||
<!-- Fifth book (tilting more) -->
|
||||
<rect x="40" y="74" width="80" height="17" rx="3" fill="currentColor" opacity="0.3" transform="rotate(-7 80 82)"/>
|
||||
<!-- Top book (really tilting) -->
|
||||
<rect x="45" y="52" width="70" height="16" rx="3" fill="currentColor" opacity="0.25" transform="rotate(10 80 60)"/>
|
||||
<!-- Tiny Shadok sitting on top -->
|
||||
<ellipse cx="85" cy="42" rx="10" ry="8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="85" cy="30" r="6" fill="currentColor" opacity="0.45"/>
|
||||
<circle cx="87" cy="29" r="1.5" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok scribe: character with quill and inkwell -->
|
||||
<svg class="shadok-scribe" viewBox="0 0 240 280" fill="none" aria-hidden="true">
|
||||
<ellipse cx="120" cy="155" rx="40" ry="48" fill="currentColor" opacity="0.85"/>
|
||||
<circle cx="120" cy="92" r="25" fill="currentColor" opacity="0.8"/>
|
||||
<ellipse cx="120" cy="72" rx="20" ry="8" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="112" cy="90" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="130" cy="90" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="113" cy="91" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="131" cy="91" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<path d="M118 104 Q120 108 122 104" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="160" y1="140" x2="190" y2="170" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="190" y1="170" x2="210" y2="145" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.45"/>
|
||||
<path d="M210 145 Q215 140 212 135 Q208 138 210 145" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="80" y1="148" x2="55" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<path d="M100 200 Q90 230 95 250" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||
<path d="M140 200 Q150 230 145 250" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||||
<rect x="45" y="185" width="20" height="18" rx="3" fill="currentColor" opacity="0.35"/>
|
||||
<ellipse cx="55" cy="185" rx="12" ry="4" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="170" y="175" width="40" height="50" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="178" y1="188" x2="202" y2="188" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="178" y1="195" x2="200" y2="195" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="178" y1="202" x2="198" y2="202" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<!-- Page de couverture du livre -->
|
||||
<HomeBookSection
|
||||
class="mb-16"
|
||||
@open-player="showBookPlayer = true"
|
||||
@open-pdf="showPdfReader = true"
|
||||
/>
|
||||
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight text-white">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl text-white/60">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl">
|
||||
<ul class="flex flex-col gap-3">
|
||||
<li
|
||||
v-for="chapter in chapters"
|
||||
:key="chapter.path"
|
||||
>
|
||||
<NuxtLink
|
||||
:to="`/modele-eco/${chapter.stem?.split('/').pop()}`"
|
||||
class="card-surface flex items-start gap-4 group"
|
||||
>
|
||||
<span class="font-mono text-2xl font-bold text-primary/30 leading-none mt-1 w-10 text-right flex-shrink-0">
|
||||
{{ String(chapter.order).padStart(2, '0') }}
|
||||
</span>
|
||||
<div class="min-w-0 flex-1">
|
||||
<h2 class="font-display text-lg font-semibold text-white group-hover:text-primary transition-colors">
|
||||
{{ chapter.title }}
|
||||
</h2>
|
||||
<p v-if="chapter.description" class="mt-1 text-sm text-white/50">
|
||||
{{ chapter.description }}
|
||||
</p>
|
||||
<div class="mt-2 flex items-center gap-3">
|
||||
<span v-if="chapter.readingTime" class="text-xs text-white/30">
|
||||
<span class="i-lucide-clock inline-block h-3 w-3 mr-1 align-middle" />
|
||||
{{ chapter.readingTime }}
|
||||
</span>
|
||||
<SongBadges :chapter-slug="chapter.stem?.split('/').pop() ?? ''" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="i-lucide-chevron-right h-5 w-5 text-white/20 group-hover:text-primary/60 transition-colors flex-shrink-0 mt-2" />
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BookPlayer v-model="showBookPlayer" />
|
||||
<BookPdfReader v-model="showPdfReader" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('modele-eco')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Table des matières',
|
||||
})
|
||||
|
||||
const { data: chapters } = await useAsyncData('book-toc', () =>
|
||||
queryCollection('book').order('order', 'ASC').all(),
|
||||
)
|
||||
|
||||
const showBookPlayer = ref(false)
|
||||
const showPdfReader = ref(false)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
.shadok-reader {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
top: 3%;
|
||||
width: clamp(110px, 15vw, 220px);
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-reader 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-stack {
|
||||
position: absolute;
|
||||
left: 2%;
|
||||
bottom: 5%;
|
||||
width: clamp(100px, 13vw, 180px);
|
||||
opacity: 0.25;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-stack 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-reader {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-stack {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-8px) rotate(-2deg); }
|
||||
}
|
||||
|
||||
.shadok-scribe {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 3%;
|
||||
transform: translateX(-50%);
|
||||
width: clamp(100px, 13vw, 180px);
|
||||
opacity: 0.25;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-scribe 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-scribe {
|
||||
0%, 100% { transform: translateX(-50%) translateY(0); }
|
||||
50% { transform: translateX(-50%) translateY(-8px); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-reader { display: none; }
|
||||
.shadok-stack { display: none; }
|
||||
.shadok-scribe { display: none; }
|
||||
}
|
||||
</style>
|
||||
@@ -1,232 +0,0 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok jardinier -->
|
||||
<svg class="shadok-jardinier" viewBox="0 0 240 300" fill="none" aria-hidden="true">
|
||||
<ellipse cx="110" cy="160" rx="40" ry="48" fill="currentColor" opacity="0.85"/>
|
||||
<circle cx="110" cy="96" r="25" fill="currentColor" opacity="0.8"/>
|
||||
<ellipse cx="110" cy="78" rx="35" ry="8" fill="currentColor" opacity="0.4"/>
|
||||
<path d="M85 78 Q110 60 135 78" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="102" cy="94" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="120" cy="94" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="103" cy="95" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="121" cy="95" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<path d="M103 106 Q110 111 118 106" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<line x1="70" y1="150" x2="40" y2="170" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<rect x="20" y="165" width="30" height="20" rx="3" fill="currentColor" opacity="0.4"/>
|
||||
<line x1="20" y1="168" x2="10" y2="160" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.4"/>
|
||||
<circle cx="12" cy="165" r="1.5" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="8" cy="170" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="15" cy="172" r="1.5" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="150" y1="150" x2="170" y2="180" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="95" y1="205" x2="85" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="125" y1="205" x2="135" y2="260" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="180" y1="220" x2="180" y2="180" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.4"/>
|
||||
<path d="M180 195 Q195 185 190 175" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<path d="M180 205 Q165 195 168 185" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<path d="M180 185 Q192 172 188 165" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<path d="M170 220 L175 240 L185 240 L190 220 Z" fill="currentColor" opacity="0.35"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok bâtisseur -->
|
||||
<svg class="shadok-batisseur" viewBox="0 0 260 300" fill="none" aria-hidden="true">
|
||||
<ellipse cx="130" cy="150" rx="40" ry="48" fill="currentColor" opacity="0.85"/>
|
||||
<circle cx="130" cy="86" r="25" fill="currentColor" opacity="0.8"/>
|
||||
<ellipse cx="130" cy="68" rx="28" ry="6" fill="currentColor" opacity="0.4"/>
|
||||
<rect x="108" y="60" width="44" height="10" rx="3" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="122" cy="84" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="140" cy="84" r="4" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="123" cy="83" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="141" cy="83" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<path d="M123 96 Q130 101 138 96" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none" opacity="0.3"/>
|
||||
<line x1="170" y1="140" x2="210" y2="120" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<polygon points="210,115 230,110 225,120 210,122" fill="currentColor" opacity="0.45"/>
|
||||
<line x1="210" y1="118" x2="200" y2="125" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="90" y1="145" x2="65" y2="170" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="115" y1="195" x2="105" y2="255" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<line x1="145" y1="195" x2="155" y2="255" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" opacity="0.6"/>
|
||||
<rect x="40" y="200" width="50" height="16" rx="1" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="45" y="183" width="40" height="16" rx="1" fill="currentColor" opacity="0.28"/>
|
||||
<rect x="50" y="166" width="30" height="16" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<line x1="65" y1="200" x2="65" y2="216" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<line x1="55" y1="183" x2="55" y2="199" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight text-white">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl text-white/60 leading-relaxed">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl flex flex-col gap-6">
|
||||
<div
|
||||
v-for="pillar in content?.pillars"
|
||||
:key="pillar.id"
|
||||
class="pillar-card"
|
||||
>
|
||||
<div class="pillar-header">
|
||||
<div class="pillar-icon">
|
||||
<div :class="`i-lucide-${pillar.icon}`" class="h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold text-white">
|
||||
{{ pillar.label }}
|
||||
</h2>
|
||||
<span v-if="pillar.gestation" class="gestation-badge">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="text-white/65 leading-relaxed whitespace-pre-line mt-3">{{ pillar.text }}</p>
|
||||
|
||||
<!-- Project card -->
|
||||
<div v-if="pillar.project" class="project-card mt-4">
|
||||
<div class="project-icon">
|
||||
<div class="i-lucide-rocket h-4 w-4" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-display font-semibold text-white text-sm">{{ pillar.project.name }}</span>
|
||||
<span class="text-white/45 text-sm ml-2">{{ pillar.project.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="pillar.to" class="mt-4">
|
||||
<NuxtLink
|
||||
:to="pillar.to"
|
||||
class="inline-flex items-center gap-1 text-sm text-primary hover:text-primary/80 transition-colors"
|
||||
>
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('numerique')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Autonomie numérique',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
.pillar-card {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.pillar-card:hover {
|
||||
border-color: hsl(var(--color-primary) / 0.2);
|
||||
}
|
||||
|
||||
.pillar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.pillar-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.15);
|
||||
color: hsl(var(--color-primary));
|
||||
box-shadow: 0 0 12px hsl(var(--color-primary) / 0.12);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
margin-left: auto;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.project-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-bg) / 0.5);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.1);
|
||||
}
|
||||
|
||||
.project-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
border-radius: 0.375rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.shadok-jardinier {
|
||||
position: absolute;
|
||||
left: 2%;
|
||||
top: 5%;
|
||||
width: clamp(100px, 14vw, 200px);
|
||||
opacity: 0.28;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-jardinier 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-batisseur {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
bottom: 5%;
|
||||
width: clamp(110px, 15vw, 210px);
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-batisseur 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-jardinier {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-batisseur {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-8px) rotate(1deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-jardinier { display: none; }
|
||||
.shadok-batisseur { display: none; }
|
||||
}
|
||||
</style>
|
||||
124
app/pages/numerique/[slug].vue
Normal file
124
app/pages/numerique/[slug].vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div class="section-padding">
|
||||
<div class="container-content">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<div class="section-icon mx-auto mb-6">
|
||||
<div :class="`i-lucide-${content?.icon ?? 'monitor'}`" class="h-12 w-12" />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase text-center">
|
||||
{{ content?.kicker }}
|
||||
</p>
|
||||
|
||||
<h1 class="font-display text-3xl font-bold mb-4 text-center" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title ?? slug }}
|
||||
</h1>
|
||||
|
||||
<p class="text-lg leading-relaxed mb-8 text-center" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
|
||||
<!-- Project card -->
|
||||
<div v-if="content?.project" class="project-card mb-8">
|
||||
<div class="project-icon">
|
||||
<div class="i-lucide-rocket h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-semibold mb-2" style="color: hsl(var(--color-text))">
|
||||
{{ content.project.name }}
|
||||
</h2>
|
||||
<p style="color: hsl(var(--color-text-muted))" class="leading-relaxed">
|
||||
{{ content.project.text }}
|
||||
</p>
|
||||
<span v-if="content?.gestation" class="gestation-badge mt-3">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Extended content -->
|
||||
<div v-if="content?.content" class="prose-block mb-10">
|
||||
<p class="leading-relaxed whitespace-pre-line" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content.content }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center flex flex-col items-center gap-3 sm:flex-row sm:justify-center">
|
||||
<UiBaseButton v-if="slug === 'tarifs-eau'" :href="sejeteral0Url" target="_blank">
|
||||
<div class="i-lucide-external-link mr-2 h-4 w-4" />
|
||||
Lancer SejeteralO
|
||||
</UiBaseButton>
|
||||
<UiBaseButton variant="ghost" to="/numerique">
|
||||
<div class="i-lucide-arrow-left mr-2 h-4 w-4" />
|
||||
Autonomie numérique
|
||||
</UiBaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const slug = route.params.slug as string
|
||||
|
||||
const { data: content } = await usePageContent(`numerique/${slug}`)
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const sejeteral0Url = (appConfig.sejeteral0 as { url: string })?.url ?? '#'
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? slug,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.section-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 1rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.2);
|
||||
color: hsl(var(--color-primary));
|
||||
}
|
||||
|
||||
.project-card {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-primary) / 0.15);
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
|
||||
.project-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.prose-block {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: hsl(var(--color-surface));
|
||||
}
|
||||
</style>
|
||||
586
app/pages/numerique/index.vue
Normal file
586
app/pages/numerique/index.vue
Normal file
@@ -0,0 +1,586 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden section-padding">
|
||||
<!-- Shadok codeuse — sitting at desk, typing on laptop, glasses -->
|
||||
<svg class="shadok-codeuse" viewBox="0 0 170 200" fill="none" aria-hidden="true">
|
||||
<!-- Desk -->
|
||||
<rect x="15" y="120" width="80" height="5" rx="2" fill="currentColor" opacity="0.3"/>
|
||||
<line x1="25" y1="125" x2="25" y2="165" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="85" y1="125" x2="85" y2="165" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- Laptop on desk -->
|
||||
<rect x="30" y="108" width="50" height="12" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<path d="M35 108 L40 80 L70 80 L75 108" fill="currentColor" opacity="0.28"/>
|
||||
<rect x="42" y="84" width="26" height="18" rx="1" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Code on screen < /> -->
|
||||
<text x="48" y="96" font-size="8" fill="currentColor" opacity="0.4" font-family="monospace"></></text>
|
||||
<!-- Body — seated, tilted forward -->
|
||||
<ellipse cx="110" cy="105" rx="20" ry="26" fill="currentColor" opacity="0.25" transform="rotate(-10 110 105)"/>
|
||||
<!-- Head — looking at screen -->
|
||||
<circle cx="105" cy="68" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Glasses -->
|
||||
<circle cx="100" cy="66" r="5" stroke="currentColor" stroke-width="1.2" fill="none" opacity="0.4"/>
|
||||
<circle cx="111" cy="66" r="5" stroke="currentColor" stroke-width="1.2" fill="none" opacity="0.4"/>
|
||||
<line x1="105" y1="66" x2="106" y2="66" stroke="currentColor" stroke-width="1" opacity="0.35"/>
|
||||
<!-- Eyes behind glasses -->
|
||||
<circle cx="101" cy="66" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="110" cy="65" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak — pointy, looking left -->
|
||||
<polygon points="88,68 82,65 88,72" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arms reaching to laptop -->
|
||||
<line x1="95" y1="95" x2="78" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="125" y1="98" x2="80" y2="115" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Legs — bent, seated -->
|
||||
<line x1="100" y1="128" x2="90" y2="180" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="118" y1="128" x2="125" y2="180" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="88" cy="183" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="127" cy="183" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok electricien — profile view, climbing utility pole, tool belt -->
|
||||
<svg class="shadok-electricien" viewBox="0 0 150 210" fill="none" aria-hidden="true">
|
||||
<!-- Utility pole -->
|
||||
<rect x="68" y="5" width="8" height="200" rx="2" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="50" y1="30" x2="94" y2="30" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="45" y1="55" x2="99" y2="55" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" opacity="0.22"/>
|
||||
<!-- Cables hanging -->
|
||||
<path d="M50 30 Q35 45 30 35" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.2"/>
|
||||
<path d="M94 30 Q110 45 115 35" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.2"/>
|
||||
<path d="M45 55 Q30 68 25 60" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.18"/>
|
||||
<!-- Body — climbing, profile, tilted -->
|
||||
<ellipse cx="95" cy="100" rx="20" ry="25" fill="currentColor" opacity="0.25" transform="rotate(15 95 100)"/>
|
||||
<!-- Head — looking up at cable -->
|
||||
<circle cx="100" cy="65" r="14" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes — looking up -->
|
||||
<circle cx="96" cy="61" r="1.5" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="105" cy="60" r="1.5" fill="currentColor" opacity="0.45"/>
|
||||
<!-- Beak — profile right -->
|
||||
<polygon points="114,63 122,60 114,67" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Hard hat -->
|
||||
<ellipse cx="100" cy="53" rx="16" ry="5" fill="currentColor" opacity="0.3"/>
|
||||
<path d="M88 53 Q100 42 112 53" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Arms — one gripping pole, one holding cable -->
|
||||
<line x1="82" y1="90" x2="74" y2="75" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="108" y1="88" x2="118" y2="60" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Tool belt -->
|
||||
<ellipse cx="95" cy="118" rx="22" ry="4" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="82" y="118" width="6" height="8" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="105" y="118" width="5" height="10" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Legs — climbing, spread on pole -->
|
||||
<line x1="85" y1="122" x2="72" y2="185" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="105" y1="122" x2="76" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet gripping pole -->
|
||||
<ellipse cx="70" cy="188" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="75" cy="178" rx="8" ry="3" fill="currentColor" opacity="0.28"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok soudeuse — welding mask flipped up, torch with sparks, apron -->
|
||||
<svg class="shadok-soudeuse" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Body — upright, slight lean forward -->
|
||||
<ellipse cx="80" cy="110" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Apron -->
|
||||
<path d="M62 95 L60 140 L100 140 L98 95" fill="currentColor" opacity="0.18"/>
|
||||
<line x1="80" y1="95" x2="80" y2="140" stroke="currentColor" stroke-width="1" opacity="0.15"/>
|
||||
<!-- Head -->
|
||||
<circle cx="80" cy="65" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Welding mask flipped up on head -->
|
||||
<rect x="65" y="42" width="30" height="18" rx="4" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="70" y="46" width="20" height="10" rx="2" fill="currentColor" opacity="0.12"/>
|
||||
<!-- Eyes — squinting from bright light -->
|
||||
<line x1="73" y1="64" x2="77" y2="64" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" opacity="0.5"/>
|
||||
<line x1="84" y1="63" x2="88" y2="63" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" opacity="0.45"/>
|
||||
<!-- Beak — small, front-facing -->
|
||||
<polygon points="78,72 80,78 82,72" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Right arm holding torch -->
|
||||
<line x1="100" y1="100" x2="135" y2="85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Welding torch -->
|
||||
<rect x="132" y="78" width="22" height="6" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<line x1="154" y1="81" x2="160" y2="78" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Sparks from torch -->
|
||||
<circle cx="158" cy="75" r="1.5" fill="currentColor" opacity="0.45"/>
|
||||
<circle cx="155" cy="70" r="1" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="160" cy="72" r="1.2" fill="currentColor" opacity="0.4"/>
|
||||
<line x1="157" y1="76" x2="160" y2="68" stroke="currentColor" stroke-width="0.8" opacity="0.3"/>
|
||||
<line x1="155" y1="78" x2="152" y2="71" stroke="currentColor" stroke-width="0.8" opacity="0.25"/>
|
||||
<!-- Left arm down -->
|
||||
<line x1="60" y1="100" x2="45" y2="125" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Legs — standing, spread -->
|
||||
<line x1="70" y1="136" x2="58" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="90" y1="136" x2="102" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Big flat feet -->
|
||||
<ellipse cx="55" cy="198" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="105" cy="198" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok admin réseau — tangled in cables, router at feet, frustrated -->
|
||||
<svg class="shadok-admin-reseau" viewBox="0 0 160 200" fill="none" aria-hidden="true">
|
||||
<!-- Body — upright but struggling -->
|
||||
<ellipse cx="80" cy="95" rx="21" ry="27" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head — tilted, frustrated -->
|
||||
<circle cx="82" cy="52" r="15" fill="currentColor" opacity="0.3" />
|
||||
<!-- Eyes — looking in different directions (frustrated) -->
|
||||
<circle cx="77" cy="50" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="88" cy="48" r="1.8" fill="currentColor" opacity="0.45"/>
|
||||
<!-- Angry eyebrows -->
|
||||
<line x1="74" y1="46" x2="79" y2="47" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="91" y1="44" x2="86" y2="46" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Beak — open, yelling -->
|
||||
<polygon points="73,56 65,55 73,60" fill="currentColor" opacity="0.35"/>
|
||||
<line x1="67" y1="56" x2="66" y2="58" stroke="currentColor" stroke-width="1" opacity="0.3"/>
|
||||
<!-- Cables tangling around body -->
|
||||
<path d="M50 40 Q30 60 55 80 Q80 95 60 115 Q40 130 70 140" stroke="currentColor" stroke-width="2" fill="none" opacity="0.3"/>
|
||||
<path d="M110 45 Q130 65 105 85 Q85 100 110 120 Q125 130 95 145" stroke="currentColor" stroke-width="2" fill="none" opacity="0.28"/>
|
||||
<path d="M75 38 Q95 50 75 70" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.22"/>
|
||||
<!-- Arms — trying to untangle -->
|
||||
<line x1="60" y1="85" x2="40" y2="70" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="100" y1="85" x2="120" y2="68" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Legs -->
|
||||
<line x1="70" y1="120" x2="60" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="90" y1="120" x2="100" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="57" cy="178" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="103" cy="178" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Router box at feet -->
|
||||
<rect x="60" y="168" width="40" height="14" rx="3" fill="currentColor" opacity="0.25"/>
|
||||
<circle cx="70" cy="175" r="1.5" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="78" cy="175" r="1.5" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="86" cy="175" r="1.5" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Antenna on router -->
|
||||
<line x1="92" y1="168" x2="96" y2="155" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" opacity="0.25"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok imprimeuse 3D — watching printer build object layer by layer -->
|
||||
<svg class="shadok-imprimeuse3d" viewBox="0 0 170 210" fill="none" aria-hidden="true">
|
||||
<!-- 3D printer frame -->
|
||||
<rect x="10" y="90" width="65" height="60" rx="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Printer rails -->
|
||||
<line x1="15" y1="95" x2="15" y2="145" stroke="currentColor" stroke-width="1.5" opacity="0.25"/>
|
||||
<line x1="70" y1="95" x2="70" y2="145" stroke="currentColor" stroke-width="1.5" opacity="0.25"/>
|
||||
<!-- Print bed -->
|
||||
<rect x="18" y="135" width="49" height="4" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Object being printed (layered) -->
|
||||
<rect x="32" y="128" width="20" height="7" rx="1" fill="currentColor" opacity="0.3"/>
|
||||
<rect x="34" y="122" width="16" height="6" rx="1" fill="currentColor" opacity="0.25"/>
|
||||
<rect x="36" y="117" width="12" height="5" rx="1" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Extruder head -->
|
||||
<rect x="34" y="110" width="16" height="6" rx="2" fill="currentColor" opacity="0.35"/>
|
||||
<line x1="42" y1="116" x2="42" y2="118" stroke="currentColor" stroke-width="1.5" opacity="0.4"/>
|
||||
<!-- Body — leaning forward, watching intently -->
|
||||
<ellipse cx="120" cy="105" rx="20" ry="25" fill="currentColor" opacity="0.25" transform="rotate(-15 120 105)"/>
|
||||
<!-- Head — looking down at printer -->
|
||||
<circle cx="108" cy="70" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes — both staring down at printer, fascinated -->
|
||||
<circle cx="103" cy="72" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="112" cy="73" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<!-- Beak — pointing down -->
|
||||
<polygon points="100,78 96,82 104,82" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arms — one pointing at printer -->
|
||||
<line x1="105" y1="95" x2="75" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="135" y1="98" x2="150" y2="115" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<!-- Legs — standing, leaning -->
|
||||
<line x1="112" y1="128" x2="105" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="128" y1="128" x2="138" y2="192" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="103" cy="195" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="140" cy="195" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok cryptographe — 3/4 view, cloak, giant key + padlock -->
|
||||
<svg class="shadok-cryptographe" viewBox="0 0 170 210" fill="none" aria-hidden="true">
|
||||
<!-- Mysterious cloak -->
|
||||
<path d="M55 70 Q50 110 45 160 L125 160 Q120 110 115 70" fill="currentColor" opacity="0.15"/>
|
||||
<path d="M45 160 Q40 170 38 180 L132 180 Q130 170 125 160" fill="currentColor" opacity="0.12"/>
|
||||
<!-- Body under cloak -->
|
||||
<ellipse cx="85" cy="105" rx="22" ry="28" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head — 3/4 view, slightly turned -->
|
||||
<circle cx="85" cy="55" r="16" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Hood suggestion -->
|
||||
<path d="M68 50 Q85 35 102 50" fill="currentColor" opacity="0.18"/>
|
||||
<!-- Eyes — mysterious, one slightly larger -->
|
||||
<circle cx="80" cy="53" r="2" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="91" cy="52" r="1.5" fill="currentColor" opacity="0.4"/>
|
||||
<!-- Beak — 3/4 profile -->
|
||||
<polygon points="75,58 67,55 74,62" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Left arm holding giant key -->
|
||||
<line x1="63" y1="95" x2="30" y2="110" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Giant key -->
|
||||
<circle cx="18" cy="108" r="12" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.4"/>
|
||||
<line x1="30" y1="108" x2="55" y2="108" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.35"/>
|
||||
<line x1="48" y1="108" x2="48" y2="118" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="53" y1="108" x2="53" y2="115" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- Right arm holding padlock -->
|
||||
<line x1="107" y1="95" x2="140" y2="85" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Padlock — big -->
|
||||
<rect x="135" y="82" width="28" height="24" rx="4" fill="currentColor" opacity="0.3"/>
|
||||
<path d="M141 82 L141 70 Q149 58 157 70 L157 82" stroke="currentColor" stroke-width="2.5" fill="none" opacity="0.35"/>
|
||||
<circle cx="149" cy="95" r="3" fill="currentColor" opacity="0.2"/>
|
||||
<line x1="149" y1="98" x2="149" y2="103" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<!-- Legs — long, cloak partly covering -->
|
||||
<line x1="75" y1="130" x2="65" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="95" y1="130" x2="108" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="63" cy="198" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="110" cy="198" rx="8" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok droneuse — looking up at flying drone, remote in hands -->
|
||||
<svg class="shadok-droneuse" viewBox="0 0 160 210" fill="none" aria-hidden="true">
|
||||
<!-- Drone above -->
|
||||
<rect x="60" y="12" width="30" height="8" rx="3" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Drone arms -->
|
||||
<line x1="55" y1="16" x2="35" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<line x1="95" y1="16" x2="115" y2="16" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.25"/>
|
||||
<!-- Propellers spinning -->
|
||||
<ellipse cx="35" cy="14" rx="12" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<ellipse cx="115" cy="14" rx="12" ry="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Propeller blur lines -->
|
||||
<line x1="25" y1="12" x2="45" y2="12" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<line x1="105" y1="12" x2="125" y2="12" stroke="currentColor" stroke-width="0.8" opacity="0.15"/>
|
||||
<!-- Drone camera -->
|
||||
<circle cx="75" cy="22" r="3" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Drone legs -->
|
||||
<line x1="62" y1="20" x2="58" y2="28" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<line x1="88" y1="20" x2="92" y2="28" stroke="currentColor" stroke-width="1.5" opacity="0.2"/>
|
||||
<!-- Body — upright, looking up -->
|
||||
<ellipse cx="78" cy="115" rx="20" ry="26" fill="currentColor" opacity="0.25"/>
|
||||
<!-- Head — tilted back looking up -->
|
||||
<circle cx="78" cy="72" r="15" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eyes — looking up at drone -->
|
||||
<circle cx="74" cy="68" r="1.8" fill="currentColor" opacity="0.5"/>
|
||||
<circle cx="83" cy="67" r="1.8" fill="currentColor" opacity="0.45"/>
|
||||
<!-- Beak — pointing up -->
|
||||
<polygon points="76,56 80,50 82,57" fill="currentColor" opacity="0.35"/>
|
||||
<!-- Arms — holding remote control -->
|
||||
<line x1="60" y1="108" x2="50" y2="128" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="96" y1="108" x2="106" y2="128" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Remote control in hands -->
|
||||
<rect x="42" y="126" width="70" height="14" rx="4" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="55" cy="133" r="3" fill="currentColor" opacity="0.2"/>
|
||||
<circle cx="100" cy="133" r="3" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Joysticks -->
|
||||
<line x1="55" y1="130" x2="55" y2="127" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<line x1="100" y1="131" x2="102" y2="128" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" opacity="0.3"/>
|
||||
<!-- Legs — standing -->
|
||||
<line x1="68" y1="138" x2="58" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="88" y1="138" x2="100" y2="195" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Feet -->
|
||||
<ellipse cx="55" cy="198" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="103" cy="198" rx="9" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
</svg>
|
||||
|
||||
<!-- Shadok mécanicienne — lying under machine, legs sticking out, wrench, oil drops -->
|
||||
<svg class="shadok-mecanicienne" viewBox="0 0 180 200" fill="none" aria-hidden="true">
|
||||
<!-- Machine/server box above -->
|
||||
<rect x="5" y="55" width="100" height="50" rx="5" fill="currentColor" opacity="0.2"/>
|
||||
<rect x="12" y="62" width="35" height="12" rx="2" fill="currentColor" opacity="0.15"/>
|
||||
<rect x="12" y="80" width="35" height="12" rx="2" fill="currentColor" opacity="0.15"/>
|
||||
<!-- Machine details -->
|
||||
<circle cx="20" cy="68" r="2" fill="currentColor" opacity="0.3"/>
|
||||
<circle cx="20" cy="86" r="2" fill="currentColor" opacity="0.25"/>
|
||||
<line x1="60" y1="65" x2="90" y2="65" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<line x1="60" y1="72" x2="85" y2="72" stroke="currentColor" stroke-width="1.5" opacity="0.15"/>
|
||||
<!-- Body — lying flat under machine, only partial visible -->
|
||||
<ellipse cx="80" cy="118" rx="25" ry="18" fill="currentColor" opacity="0.22" transform="rotate(90 80 118)"/>
|
||||
<!-- Head under machine (barely visible) -->
|
||||
<circle cx="55" cy="115" r="12" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Arm sticking out with wrench -->
|
||||
<line x1="42" y1="115" x2="15" y2="105" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Wrench -->
|
||||
<path d="M8 100 L15 105 L12 108 L5 103 Z" fill="currentColor" opacity="0.35"/>
|
||||
<circle cx="5" cy="100" r="5" stroke="currentColor" stroke-width="1.5" fill="none" opacity="0.3"/>
|
||||
<!-- Oil drops falling -->
|
||||
<ellipse cx="70" cy="108" rx="2" ry="3" fill="currentColor" opacity="0.3"/>
|
||||
<ellipse cx="85" cy="112" rx="1.5" ry="2.5" fill="currentColor" opacity="0.25"/>
|
||||
<ellipse cx="62" cy="105" rx="1" ry="2" fill="currentColor" opacity="0.2"/>
|
||||
<!-- Legs sticking out from under machine — the signature view -->
|
||||
<line x1="90" y1="125" x2="130" y2="175" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<line x1="95" y1="120" x2="145" y2="165" stroke="currentColor" stroke-width="3" stroke-linecap="round" opacity="0.4"/>
|
||||
<!-- Big feet sticking up -->
|
||||
<ellipse cx="133" cy="178" rx="10" ry="4" fill="currentColor" opacity="0.35" transform="rotate(-25 133 178)"/>
|
||||
<ellipse cx="148" cy="168" rx="10" ry="4" fill="currentColor" opacity="0.35" transform="rotate(-25 148 168)"/>
|
||||
<!-- Beak visible from side -->
|
||||
<polygon points="42,118 35,116 42,122" fill="currentColor" opacity="0.3"/>
|
||||
<!-- Eye visible -->
|
||||
<circle cx="50" cy="113" r="1.5" fill="currentColor" opacity="0.4"/>
|
||||
</svg>
|
||||
|
||||
<div class="container-content">
|
||||
<header class="mb-12 text-center">
|
||||
<p class="mb-2 font-mono text-sm tracking-widest text-primary uppercase">{{ content?.kicker }}</p>
|
||||
<h1 class="page-title font-display font-bold tracking-tight" style="color: hsl(var(--color-text))">
|
||||
{{ content?.title }}
|
||||
</h1>
|
||||
<p class="mt-4 mx-auto max-w-2xl leading-relaxed" style="color: hsl(var(--color-text-muted))">
|
||||
{{ content?.description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="mx-auto max-w-3xl flex flex-col gap-6">
|
||||
<div
|
||||
v-for="pillar in content?.pillars"
|
||||
:key="pillar.id"
|
||||
class="pillar-card"
|
||||
>
|
||||
<div class="pillar-header">
|
||||
<div class="pillar-icon">
|
||||
<div :class="`i-lucide-${pillar.icon}`" class="h-5 w-5" />
|
||||
</div>
|
||||
<h2 class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
|
||||
{{ pillar.label }}
|
||||
</h2>
|
||||
<span v-if="pillar.gestation" class="gestation-badge">
|
||||
<div class="i-lucide-flask-conical h-3 w-3" />
|
||||
En gestation
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="leading-relaxed whitespace-pre-line mt-3" style="color: hsl(var(--color-text-muted))">{{ pillar.text }}</p>
|
||||
|
||||
<!-- Project card -->
|
||||
<div v-if="pillar.project" class="project-card mt-4">
|
||||
<div class="project-icon">
|
||||
<div class="i-lucide-rocket h-4 w-4" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-display font-semibold text-sm" style="color: hsl(var(--color-text))">{{ pillar.project.name }}</span>
|
||||
<span class="text-sm ml-2" style="color: hsl(var(--color-text-muted))">{{ pillar.project.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="pillar.to" class="mt-4">
|
||||
<NuxtLink
|
||||
:to="pillar.to"
|
||||
class="inline-flex items-center gap-1 text-sm text-primary hover:text-primary/80 transition-colors"
|
||||
>
|
||||
En savoir plus
|
||||
<div class="i-lucide-arrow-right h-3.5 w-3.5" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'default',
|
||||
})
|
||||
|
||||
const { data: content } = await usePageContent('numerique')
|
||||
|
||||
useHead({
|
||||
title: content.value?.meta?.title ?? 'Autonomie numérique',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-title {
|
||||
font-size: clamp(2rem, 5vw, 2.75rem);
|
||||
}
|
||||
|
||||
.pillar-card {
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid hsl(var(--color-text) / 0.08);
|
||||
background: hsl(var(--color-surface));
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
.pillar-card:hover {
|
||||
border-color: hsl(var(--color-primary) / 0.2);
|
||||
}
|
||||
|
||||
.pillar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.pillar-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-primary) / 0.15);
|
||||
color: hsl(var(--color-primary));
|
||||
box-shadow: 0 0 12px hsl(var(--color-primary) / 0.12);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.gestation-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
margin-left: auto;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
background: hsl(var(--color-accent) / 0.12);
|
||||
color: hsl(var(--color-accent));
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.project-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
background: hsl(var(--color-bg) / 0.5);
|
||||
border: 1px solid hsl(var(--color-primary) / 0.1);
|
||||
}
|
||||
|
||||
.project-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
border-radius: 0.375rem;
|
||||
background: hsl(var(--color-primary) / 0.1);
|
||||
color: hsl(var(--color-primary));
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.shadok-codeuse {
|
||||
position: absolute;
|
||||
left: 1%;
|
||||
top: 4%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.24;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-codeuse 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-electricien {
|
||||
position: absolute;
|
||||
right: 1%;
|
||||
top: 3%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-electricien 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-soudeuse {
|
||||
position: absolute;
|
||||
left: 3%;
|
||||
top: 40%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-soudeuse 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-admin-reseau {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
top: 35%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-admin-reseau 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-imprimeuse3d {
|
||||
position: absolute;
|
||||
left: 2%;
|
||||
bottom: 8%;
|
||||
width: clamp(70px, 10vw, 135px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-imprimeuse3d 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-cryptographe {
|
||||
position: absolute;
|
||||
right: 1%;
|
||||
bottom: 6%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.18;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-cryptographe 11s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-droneuse {
|
||||
position: absolute;
|
||||
left: 40%;
|
||||
bottom: 2%;
|
||||
width: clamp(70px, 10vw, 130px);
|
||||
opacity: 0.2;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-primary));
|
||||
animation: shadok-float-droneuse 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.shadok-mecanicienne {
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
top: 60%;
|
||||
width: clamp(70px, 10vw, 140px);
|
||||
opacity: 0.22;
|
||||
pointer-events: none;
|
||||
color: hsl(var(--color-accent));
|
||||
animation: shadok-float-mecanicienne 9s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shadok-float-codeuse {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-8px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-electricien {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-10px) rotate(1deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-soudeuse {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-7px) rotate(-0.8deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-admin-reseau {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-9px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-imprimeuse3d {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-11px) rotate(0.5deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-cryptographe {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-8px) rotate(-0.6deg); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-droneuse {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-12px); }
|
||||
}
|
||||
|
||||
@keyframes shadok-float-mecanicienne {
|
||||
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||
50% { transform: translateY(-7px) rotate(1.2deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.shadok-codeuse { display: none; }
|
||||
.shadok-electricien { display: none; }
|
||||
.shadok-soudeuse { display: none; }
|
||||
.shadok-admin-reseau { display: none; }
|
||||
.shadok-imprimeuse3d { display: none; }
|
||||
.shadok-cryptographe { display: none; }
|
||||
.shadok-droneuse { display: none; }
|
||||
.shadok-mecanicienne { display: none; }
|
||||
}
|
||||
</style>
|
||||
@@ -77,7 +77,7 @@ const palettes: Record<PaletteName, PaletteColors> = {
|
||||
|
||||
export const usePaletteStore = defineStore('palette', () => {
|
||||
const currentPalette = ref<PaletteName>(
|
||||
(import.meta.client && localStorage.getItem('palette') as PaletteName) || 'automne',
|
||||
(import.meta.client && localStorage.getItem('palette') as PaletteName) || 'ete',
|
||||
)
|
||||
|
||||
const colors = computed(() => palettes[currentPalette.value])
|
||||
|
||||
39
server/api/admin/content/pages.get.ts
Normal file
39
server/api/admin/content/pages.get.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { readdir, stat } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
|
||||
interface PageEntry {
|
||||
path: string
|
||||
label: string
|
||||
section?: string
|
||||
}
|
||||
|
||||
async function listYamlFiles(dir: string, prefix = ''): Promise<PageEntry[]> {
|
||||
const entries: PageEntry[] = []
|
||||
const items = await readdir(dir)
|
||||
|
||||
for (const item of items) {
|
||||
const fullPath = join(dir, item)
|
||||
const s = await stat(fullPath)
|
||||
|
||||
if (s.isDirectory()) {
|
||||
const subEntries = await listYamlFiles(fullPath, prefix ? `${prefix}/${item}` : item)
|
||||
entries.push(...subEntries)
|
||||
}
|
||||
else if (item.endsWith('.yml')) {
|
||||
const name = item.replace('.yml', '')
|
||||
const path = prefix ? `${prefix}/${name}` : name
|
||||
entries.push({
|
||||
path,
|
||||
label: name,
|
||||
section: prefix || undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
const pagesDir = join(process.cwd(), 'site', 'pages')
|
||||
return await listYamlFiles(pagesDir)
|
||||
})
|
||||
21
server/api/admin/content/pages/[...path].put.ts
Normal file
21
server/api/admin/content/pages/[...path].put.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { mkdir } from 'node:fs/promises'
|
||||
import { join, dirname } from 'node:path'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const path = getRouterParam(event, 'path')
|
||||
|
||||
if (!path || !/^[a-z0-9-/]+$/.test(path)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid page path' })
|
||||
}
|
||||
|
||||
const body = await readBody(event)
|
||||
const relativePath = `pages/${path}.yml`
|
||||
|
||||
// Ensure subdirectory exists
|
||||
const fullPath = join(process.cwd(), 'site', relativePath)
|
||||
await mkdir(dirname(fullPath), { recursive: true })
|
||||
|
||||
await writeYaml(relativePath, body)
|
||||
gitSyncContent(`Mise à jour page ${path}`, [`site/${relativePath}`])
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const name = getRouterParam(event, 'name')
|
||||
|
||||
if (!name || !/^[a-z0-9-]+$/.test(name)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid page name' })
|
||||
}
|
||||
|
||||
const body = await readBody(event)
|
||||
await writeYaml(`pages/${name}.yml`, body)
|
||||
gitSyncContent(`Mise à jour page ${name}`, [`site/pages/${name}.yml`])
|
||||
return { ok: true }
|
||||
})
|
||||
@@ -1,14 +1,14 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const name = getRouterParam(event, 'name')
|
||||
const path = getRouterParam(event, 'path')
|
||||
|
||||
if (!name || !/^[a-z0-9-]+$/.test(name)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid page name' })
|
||||
if (!path || !/^[a-z0-9-/]+$/.test(path)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Invalid page path' })
|
||||
}
|
||||
|
||||
try {
|
||||
return await readYaml(`pages/${name}.yml`)
|
||||
return await readYaml(`pages/${path}.yml`)
|
||||
}
|
||||
catch {
|
||||
throw createError({ statusCode: 404, statusMessage: `Page "${name}" not found` })
|
||||
throw createError({ statusCode: 404, statusMessage: `Page "${path}" not found` })
|
||||
}
|
||||
})
|
||||
@@ -1,9 +1,10 @@
|
||||
export default defineEventHandler((event) => {
|
||||
const path = getRequestURL(event).pathname
|
||||
|
||||
// /lire → /economique/modele-eco
|
||||
if (path.startsWith('/lire')) {
|
||||
const rest = path.slice(5) // remove '/lire'
|
||||
return sendRedirect(event, `/modele-eco${rest || '/'}`, 301)
|
||||
return sendRedirect(event, `/economique/modele-eco${rest || '/'}`, 301)
|
||||
}
|
||||
|
||||
if (path.startsWith('/ecouter')) {
|
||||
@@ -14,4 +15,31 @@ export default defineEventHandler((event) => {
|
||||
if (path === '/autonomie' || path === '/autonomie/') {
|
||||
return sendRedirect(event, '/numerique', 301)
|
||||
}
|
||||
|
||||
if (path === '/decision' || path === '/decision/') {
|
||||
return sendRedirect(event, '/citoyenne/decision', 301)
|
||||
}
|
||||
|
||||
// /modele-eco → /economique/modele-eco
|
||||
if (path.startsWith('/modele-eco')) {
|
||||
const rest = path.slice(11) // remove '/modele-eco'
|
||||
return sendRedirect(event, `/economique/modele-eco${rest || '/'}`, 301)
|
||||
}
|
||||
|
||||
// Redirect old /gestation/* routes to proper sections
|
||||
if (path.startsWith('/gestation/')) {
|
||||
const slug = path.slice(11).replace(/\/$/, '')
|
||||
const numeriquePages = ['logiciel-libre', 'authentification-wot', 'cloud-libre']
|
||||
if (numeriquePages.includes(slug)) {
|
||||
return sendRedirect(event, `/numerique/${slug}`, 301)
|
||||
}
|
||||
if (slug === 'productions-collectives') {
|
||||
return sendRedirect(event, '/economique/productions-collectives', 301)
|
||||
}
|
||||
if (slug === 'tarifs-eau') {
|
||||
return sendRedirect(event, '/citoyenne/tarifs-eau', 301)
|
||||
}
|
||||
// Fallback
|
||||
return sendRedirect(event, '/', 301)
|
||||
}
|
||||
})
|
||||
|
||||
22
site/pages/citoyenne.yml
Normal file
22
site/pages/citoyenne.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
meta:
|
||||
title: Autonomie citoyenne
|
||||
|
||||
kicker: Autonomie citoyenne
|
||||
title: La décision
|
||||
description: >
|
||||
Se donner les moyens de la décision collective. Reprendre la main
|
||||
sur les processus qui structurent notre vie commune — à l'échelle
|
||||
des bassins de vie.
|
||||
|
||||
items:
|
||||
- id: decision
|
||||
label: Décision collective
|
||||
icon: gavel
|
||||
description: Se donner les moyens de la décision collective.
|
||||
to: /citoyenne/decision
|
||||
- id: tarifs-eau
|
||||
label: Tarifs de l'eau
|
||||
icon: droplets
|
||||
description: Application pour obtenir justice sociale et incitation dynamique à la réduction. Permet de confier la décision à la population des communes.
|
||||
to: /citoyenne/tarifs-eau
|
||||
gestation: true
|
||||
21
site/pages/citoyenne/decision.yml
Normal file
21
site/pages/citoyenne/decision.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
meta:
|
||||
title: Décision collective — Autonomie citoyenne
|
||||
|
||||
kicker: Autonomie citoyenne
|
||||
title: Plateforme Décision
|
||||
icon: gavel
|
||||
description: Se donner les moyens de la décision collective.
|
||||
|
||||
features:
|
||||
- icon: vote
|
||||
title: Décisions on-chain
|
||||
text: Des décisions transparentes et vérifiables, inscrites sur la blockchain.
|
||||
- icon: scroll-text
|
||||
title: Les Mandats
|
||||
text: Formaliser et suivre les mandats confiés aux personnes désignées.
|
||||
- icon: scroll-text
|
||||
title: Documents de référence
|
||||
text: Les textes fondateurs et documents qui encadrent la prise de décision.
|
||||
- icon: git-branch
|
||||
title: Les Protocoles
|
||||
text: Les règles et processus qui structurent la décision collective.
|
||||
20
site/pages/citoyenne/tarifs-eau.yml
Normal file
20
site/pages/citoyenne/tarifs-eau.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
meta:
|
||||
title: Tarifs de l'eau — Autonomie citoyenne
|
||||
|
||||
kicker: Autonomie citoyenne
|
||||
title: Tarifs de l'eau
|
||||
icon: droplets
|
||||
gestation: true
|
||||
|
||||
description: >
|
||||
Application pour obtenir justice sociale et incitation dynamique
|
||||
à la réduction. Permet de confier la décision à la population des communes.
|
||||
|
||||
project:
|
||||
name: SejeteralO
|
||||
text: Simulateur de tarification de l'eau — justice sociale et écologie.
|
||||
|
||||
content: >
|
||||
La tarification de l'eau est un levier essentiel de justice sociale
|
||||
et d'incitation à la réduction de la consommation. SejeteralO permet
|
||||
aux communes de simuler et comparer différentes grilles tarifaires.
|
||||
29
site/pages/economique.yml
Normal file
29
site/pages/economique.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
meta:
|
||||
title: Autonomie économique
|
||||
|
||||
kicker: Autonomie économique
|
||||
title: La création monétaire
|
||||
description: >
|
||||
Pour fonctionner autrement, il faut créer une économie qui le permette.
|
||||
Au fondement de toute économie se trouve la création monétaire — son code,
|
||||
ses règles, ses bénéficiaires. Tant que ce code est écrit par d'autres,
|
||||
pour d'autres, aucune autonomie réelle n'est possible.
|
||||
La monnaie libre propose un autre code : symétrique, transparent, co-créé.
|
||||
|
||||
items:
|
||||
- id: monnaie-libre
|
||||
label: Monnaie libre
|
||||
icon: g1
|
||||
description: "La Ğ1 (June) : une monnaie co-créée par ses membres, sans dette ni intérêt. Le dividende universel comme base."
|
||||
to: /economique/monnaie-libre
|
||||
- id: modele-eco
|
||||
label: Économie du don
|
||||
icon: scale
|
||||
description: Un livre et des chansons pour une proposition de modèle économique fondé sur le don.
|
||||
to: /economique/modele-eco
|
||||
- id: productions-collectives
|
||||
label: Productions collectives
|
||||
icon: users
|
||||
description: Une plateforme pour faciliter la création d'équipes et la réalisation de productions à l'échelle des bassins de vie.
|
||||
to: /economique/productions-collectives
|
||||
gestation: true
|
||||
23
site/pages/economique/commande.yml
Normal file
23
site/pages/economique/commande.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
meta:
|
||||
title: Commandez le livre papier
|
||||
|
||||
kicker: Le livre
|
||||
title: Commandez le livre papier
|
||||
icon: shopping-bag
|
||||
|
||||
description: >
|
||||
« Une économie du don — enfin concevable » est disponible en version papier.
|
||||
Vous pouvez le commander en ligne ou le demander en librairie.
|
||||
|
||||
bookelis:
|
||||
label: Commander sur Bookelis
|
||||
url: https://www.bookelis.com/economie/56818-Une-economie-du-don-enfin-concevable.html
|
||||
|
||||
librairie:
|
||||
title: En librairie
|
||||
text: >
|
||||
Le livre est disponible à la commande dans toute librairie jusqu'au printemps 2027.
|
||||
Cette disponibilité dépend d'un abonnement de référencement Hachette,
|
||||
qui permet aux libraires de le trouver dans leur catalogue et de le commander
|
||||
auprès de leur distributeur. Au-delà de cette date, la commande en ligne
|
||||
sur Bookelis reste disponible.
|
||||
33
site/pages/economique/monnaie-libre.yml
Normal file
33
site/pages/economique/monnaie-libre.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
meta:
|
||||
title: Monnaie libre — Autonomie économique
|
||||
|
||||
kicker: Autonomie économique
|
||||
title: Monnaie libre
|
||||
icon: g1
|
||||
|
||||
description: >
|
||||
La Ğ1 (June) est une monnaie co-créée par ses membres, sans dette ni intérêt.
|
||||
Chaque être humain qui y participe co-crée la même part de monnaie —
|
||||
c'est le dividende universel. Un code monétaire symétrique dans le temps
|
||||
et dans l'espace.
|
||||
|
||||
content: >
|
||||
La monnaie libre repose sur la Théorie Relative de la Monnaie (TRM),
|
||||
formulée par Stéphane Laborde. Elle définit les conditions d'une monnaie
|
||||
qui ne privilégie aucune génération ni aucun individu dans sa création.
|
||||
|
||||
La Ğ1 est la première implémentation de cette théorie. Chaque membre
|
||||
certifié par la toile de confiance co-crée quotidiennement un dividende
|
||||
universel — la même quantité relative de monnaie pour tous.
|
||||
|
||||
Ce n'est pas une monnaie complémentaire ni une monnaie locale.
|
||||
C'est une monnaie libre : libre dans son code, libre dans sa création,
|
||||
libre dans son usage.
|
||||
|
||||
links:
|
||||
- label: monnaie-libre.fr
|
||||
href: https://monnaie-libre.fr
|
||||
icon: external-link
|
||||
- label: Théorie Relative de la Monnaie
|
||||
href: https://trm.creationmonetaire.info
|
||||
icon: book-open
|
||||
16
site/pages/economique/productions-collectives.yml
Normal file
16
site/pages/economique/productions-collectives.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
meta:
|
||||
title: Productions collectives — Autonomie citoyenne
|
||||
|
||||
kicker: Autonomie citoyenne
|
||||
title: Productions collectives
|
||||
icon: users
|
||||
gestation: true
|
||||
|
||||
description: >
|
||||
Une plateforme pour faciliter la création d'équipes et la réalisation
|
||||
de productions à l'échelle des bassins de vie.
|
||||
|
||||
content: >
|
||||
Les productions collectives permettent de mutualiser les compétences
|
||||
et les ressources pour réaliser des projets concrets au service
|
||||
du territoire.
|
||||
@@ -1,16 +1,16 @@
|
||||
hero:
|
||||
heading:
|
||||
- "Construire une autonomie collective."
|
||||
- "à l'échelle des bassins de vie"
|
||||
- "Pousser les curseurs"
|
||||
- "Autonomie numérique, économique, citoyenne."
|
||||
- "— s'en donner les moyens —"
|
||||
- Construire une autonomie collective.
|
||||
- à l'échelle des bassins de vie
|
||||
- Pousser les curseurs
|
||||
- Autonomie numérique, économique, citoyenne.
|
||||
- — s'en donner les moyens —
|
||||
citations:
|
||||
- "Il s'agit d'émancipation."
|
||||
- "Les trois dimensions qui nous émancipent sont le numérique, l'économie et le politique."
|
||||
- "Elles peuvent nous asservir tout autant."
|
||||
- "Ce sont les 3 axes de l'espace dans lequel nous naviguons."
|
||||
approach: "Dans chaque dimension, nous adressons ce qui est le plus en amont"
|
||||
- Il s'agit d'émancipation.
|
||||
- Les trois dimensions qui nous émancipent sont le numérique, l'économie et le politique.
|
||||
- Elles peuvent nous asservir tout autant.
|
||||
- Ce sont les 3 axes de l'espace dans lequel nous naviguons.
|
||||
approach: Dans chaque dimension, nous adressons ce qui est le plus en amont
|
||||
axes:
|
||||
- label: numérique
|
||||
value: le code source
|
||||
@@ -18,7 +18,6 @@ hero:
|
||||
value: la création monétaire
|
||||
- label: citoyenne
|
||||
value: la décision
|
||||
|
||||
book:
|
||||
kicker: Modèle économique
|
||||
title: Une économie du don — enfin concevable
|
||||
@@ -29,7 +28,6 @@ book:
|
||||
cta:
|
||||
player: Présentation musicale
|
||||
pdf: Lecture du livre
|
||||
|
||||
axes:
|
||||
numerique:
|
||||
title: Autonomie numérique
|
||||
@@ -37,7 +35,7 @@ axes:
|
||||
items:
|
||||
- label: Logiciel libre
|
||||
description: Maîtriser le code source, c'est maîtriser l'outil. Le logiciel libre est la base de l'autonomie numérique.
|
||||
to: /gestation/logiciel-libre
|
||||
to: /numerique/logiciel-libre
|
||||
gestation: true
|
||||
icon: code-2
|
||||
presentation:
|
||||
@@ -45,7 +43,7 @@ axes:
|
||||
text: Application pour le financement fléché des développements.
|
||||
- label: Authentification — WoT
|
||||
description: Une toile de confiance décentralisée, sans autorité centrale. Chaque identité est certifiée par ses pairs.
|
||||
to: /gestation/authentification-wot
|
||||
to: /numerique/authentification-wot
|
||||
gestation: true
|
||||
icon: share-2
|
||||
presentation:
|
||||
@@ -53,7 +51,7 @@ axes:
|
||||
text: Gestionnaire de confiances.
|
||||
- label: Cloud libre
|
||||
description: Héberger ses propres services pour ne dépendre de personne. Serveurs, noms de domaine, infrastructure.
|
||||
to: /gestation/cloud-libre
|
||||
to: /numerique/cloud-libre
|
||||
gestation: true
|
||||
icon: cloud
|
||||
presentation:
|
||||
@@ -64,12 +62,13 @@ axes:
|
||||
icon: coins
|
||||
items:
|
||||
- label: Monnaie libre
|
||||
description: "La Ğ1 (June) : une monnaie co-créée par ses membres, sans dette ni intérêt. Le dividende universel comme base."
|
||||
href: https://monnaie-libre.fr
|
||||
description: "La Ğ1 (June) : une monnaie co-créée par ses membres, sans dette ni intérêt. Le dividende universel comme
|
||||
base."
|
||||
to: /economique/monnaie-libre
|
||||
icon: g1
|
||||
- label: Économie du don
|
||||
description: Un livre et des chansons pour une proposition de modèle économique fondé sur le don.
|
||||
to: /modele-eco
|
||||
to: /economique/modele-eco
|
||||
icon: scale
|
||||
actions:
|
||||
- id: open-player
|
||||
@@ -77,11 +76,22 @@ axes:
|
||||
icon: play
|
||||
highlight: true
|
||||
- id: open-pdf
|
||||
label: Lecture du livre
|
||||
label: Lire le livre
|
||||
icon: book-open
|
||||
- id: link
|
||||
label: Présentation des chapitres
|
||||
icon: list
|
||||
to: /economique/modele-eco
|
||||
secondary: true
|
||||
- id: link
|
||||
label: Commandez le livre
|
||||
icon: shopping-bag
|
||||
to: /economique/commande
|
||||
secondary: true
|
||||
- label: Productions collectives
|
||||
description: Une plateforme pour faciliter la création d'équipes et la réalisation de productions à l'échelle des bassins de vie.
|
||||
to: /gestation/productions-collectives
|
||||
description: Une plateforme pour faciliter la création d'équipes et la réalisation de productions à l'échelle des
|
||||
bassins de vie.
|
||||
to: /economique/productions-collectives
|
||||
gestation: true
|
||||
icon: users
|
||||
politique:
|
||||
@@ -90,20 +100,19 @@ axes:
|
||||
items:
|
||||
- label: Décision collective
|
||||
description: Se donner les moyens de la décision collective.
|
||||
to: /decision
|
||||
to: /citoyenne/decision
|
||||
icon: gavel
|
||||
- label: Tarifs de l'eau
|
||||
description: Application pour obtenir justice sociale et incitation dynamique à la réduction. Permet de confier la décision à la population des communes.
|
||||
to: /gestation/tarifs-eau
|
||||
description: Application pour obtenir justice sociale et incitation dynamique à la réduction. Permet de confier la
|
||||
décision à la population des communes.
|
||||
to: /citoyenne/tarifs-eau
|
||||
gestation: true
|
||||
icon: droplets
|
||||
|
||||
gratewizard:
|
||||
title: grateWizard
|
||||
subtitle: Le compagnon interactif du livre et du projet
|
||||
subtitle: Un utilitaire pratique pour estimer les valeurs de façon relative
|
||||
description: Explorez le modèle économique, posez vos questions, suivez le fil du raisonnement.
|
||||
icon: sparkles
|
||||
|
||||
evenement:
|
||||
title: Le librodrome,
|
||||
subtitle: c'est également un événement.
|
||||
|
||||
@@ -17,7 +17,7 @@ pillars:
|
||||
name: wishBounty
|
||||
text: Application pour le financement fléché des développements libres.
|
||||
gestation: true
|
||||
to: /gestation/logiciel-libre
|
||||
to: /numerique/logiciel-libre
|
||||
|
||||
- id: authentification-wot
|
||||
label: "Authentification — WoT"
|
||||
@@ -31,7 +31,7 @@ pillars:
|
||||
name: trustWallet
|
||||
text: Gestionnaire de confiances.
|
||||
gestation: true
|
||||
to: /gestation/authentification-wot
|
||||
to: /numerique/authentification-wot
|
||||
|
||||
- id: cloud-libre
|
||||
label: Cloud libre
|
||||
@@ -45,4 +45,4 @@ pillars:
|
||||
name: Bouquet de services
|
||||
text: "Drive, Visio, Forum, Wiki, CMS. IA frugale localisée."
|
||||
gestation: true
|
||||
to: /gestation/cloud-libre
|
||||
to: /numerique/cloud-libre
|
||||
|
||||
22
site/pages/numerique/authentification-wot.yml
Normal file
22
site/pages/numerique/authentification-wot.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
meta:
|
||||
title: Authentification WoT — Autonomie numérique
|
||||
|
||||
kicker: Autonomie numérique
|
||||
title: "Authentification — WoT"
|
||||
icon: share-2
|
||||
gestation: true
|
||||
|
||||
description: >
|
||||
Une toile de confiance décentralisée, sans autorité centrale.
|
||||
Chaque identité est certifiée par ses pairs — pas par un serveur,
|
||||
pas par une entreprise. C'est le fondement de la monnaie libre Ğ1
|
||||
et de toute gouvernance entre égaux.
|
||||
|
||||
project:
|
||||
name: trustWallet
|
||||
text: Gestionnaire de confiances.
|
||||
|
||||
content: >
|
||||
La Web of Trust (toile de confiance) est un mécanisme d'authentification
|
||||
décentralisé où chaque participant certifie l'identité des autres.
|
||||
Aucune autorité centrale n'est nécessaire — la confiance émerge du réseau.
|
||||
22
site/pages/numerique/cloud-libre.yml
Normal file
22
site/pages/numerique/cloud-libre.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
meta:
|
||||
title: Cloud libre — Autonomie numérique
|
||||
|
||||
kicker: Autonomie numérique
|
||||
title: Cloud libre
|
||||
icon: cloud
|
||||
gestation: true
|
||||
|
||||
description: >
|
||||
Héberger ses propres services pour ne dépendre de personne.
|
||||
Serveurs, noms de domaine, infrastructure.
|
||||
Un bouquet de services complet — Drive, Visio, Forum, Wiki, CMS —
|
||||
et demain, une IA frugale localisée.
|
||||
|
||||
project:
|
||||
name: Bouquet de services
|
||||
text: "Drive, Visio, Forum, Wiki, CMS. IA frugale localisée."
|
||||
|
||||
content: >
|
||||
L'auto-hébergement est la clé de voûte de l'autonomie numérique.
|
||||
Il s'agit de maîtriser l'infrastructure sur laquelle reposent nos outils
|
||||
de communication, de stockage et de collaboration.
|
||||
23
site/pages/numerique/logiciel-libre.yml
Normal file
23
site/pages/numerique/logiciel-libre.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
meta:
|
||||
title: Logiciel libre — Autonomie numérique
|
||||
|
||||
kicker: Autonomie numérique
|
||||
title: Logiciel libre
|
||||
icon: code-2
|
||||
gestation: true
|
||||
|
||||
description: >
|
||||
Le logiciel libre n'est pas qu'une question technique.
|
||||
C'est la condition d'existence d'outils qui nous appartiennent —
|
||||
que l'on peut auditer, modifier, partager.
|
||||
Sans logiciel libre, toute promesse de souveraineté numérique est creuse.
|
||||
|
||||
project:
|
||||
name: wishBounty
|
||||
text: Application pour le financement fléché des développements libres.
|
||||
|
||||
content: >
|
||||
Le logiciel libre garantit quatre libertés fondamentales : utiliser, étudier,
|
||||
modifier et redistribuer. Ces libertés sont le socle de toute autonomie numérique.
|
||||
Sans elles, nous sommes dépendants d'éditeurs qui peuvent à tout moment modifier
|
||||
les règles du jeu.
|
||||
@@ -8,9 +8,9 @@ navigation:
|
||||
- label: numérique
|
||||
to: /numerique
|
||||
- label: économique
|
||||
to: /modele-eco
|
||||
to: /economique
|
||||
- label: citoyenne
|
||||
to: /decision
|
||||
to: /citoyenne
|
||||
extra:
|
||||
- label: Événement
|
||||
to: /evenement
|
||||
|
||||
Reference in New Issue
Block a user