Files
librodrome/app/pages/evenement.vue
T
YvvandClaude Opus 5.5 28a6daf382 identité 6 : la règle f mesurée au-dessus du dessin, les chapitres posés sur leurs filets, les coins arrondis dégagés
Règle f, selon la précision de DA du 03/11 après 17h35 : au-dessus d'un oiseau perché, le vide
se mesure du haut de son dessin jusqu'à la plus basse ligne de texte ou au plus bas bloc qui
passe au-dessus de sa largeur peinte. Les lignes de son propre titre comptent, et l'en-tête
collant aussi en haut de page. Quinze perchés en défaut sur bb8fad9 changent de pose, sans
sortir de la liste fermée :
- accueil :
  - le DJ se tient derrière le pupitre de la console, seule sa tête dépasse ;
  - l'accordéoniste passe en S, visible à partir de 1200 px ;
  - la factrice passe à 76 px ;
  - la lectrice sort 20 px plus bas ;
- au téléphone, l'oiseau de l'intitulé est un oiseau plat : codeuse, maraîchère, potier, et le
  cycliste livreur sur productions collectives ;
- authentification, tarifs de l'eau, commande : en marge droite, sur l'arête haute de la carte ;
- en musique : le danseur passe en S ;
- évènement :
  - l'acrobate se tient avant la devise ;
  - le régisseur passe en S, posé sur l'arête des cartes ;
  - le clown passe en M ;
  - le marionnettiste se tient sur le filet du pied de page (option 1 d'orch). Son décalage
    est tiré de --seal-block, le bloc du sceau défini dans le layout ;
- chapitres : le calligraphe se tient sur le filet du titre, le typographe sur celui de la
  navigation, le cartonnier en marge des boutons. Plus aucune hauteur en %.

Règle g, rectangle du bloc (décision d'orch) : le porteur de serveur et l'administrateur réseau
sortent de la découpe des coins arrondis.

La liste fermée (docs/da-oiseaux.md) reçoit les précisions d'orch :
- e vaut pour un oiseau « libre » dont le centre sort de son bloc ;
- g se mesure sur le rectangle du bloc ;
- un oiseau derrière une carte reste « derrière ».

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:24:44 +01:00

352 lines
12 KiB
Vue

<template>
<div class="relative overflow-hidden section-padding min-h-[70vh] flex items-center justify-center">
<div class="container-content relative z-10 text-center">
<!-- The stage of the hero: a tightrope walker and a drummer, at different heights -->
<UiOiseauPose nom="funambule" pose="libre" left="5%" bottom="6%" :w="176" :op="0.2" />
<UiOiseauPose nom="batteur" pose="libre" right="6%" bottom="34%" :w="116" retourne ton="accent" />
<!-- Logo SVG vectoriel — inline pour currentColor -->
<div class="evt-logo-wrap mx-auto mb-6" aria-hidden="true">
<UiSectionSign class="evt-logo" />
</div>
<p class="mb-3 font-mono text-sm tracking-widest text-accent uppercase">{{ content?.kicker }}</p>
<h1 class="page-title relative font-display font-extrabold tracking-tight" style="color: hsl(var(--color-text))">
<!-- The trapeze artist at the end of the title, on its baseline (rule e, docs/da-oiseaux.md) -->
{{ content?.title }}<UiOiseauPose nom="trapeziste" pose="perche" bout left="16px" :w="96" ton="accent" :seuil="1200" />
</h1>
<p v-if="evtContent?.format" class="evt-format font-display">
{{ evtContent.format }}
</p>
<p v-if="evtContent?.subtitle" class="mt-2 text-base italic" style="color: hsl(var(--color-text-muted))">
{{ evtContent.subtitle }}
</p>
<p class="mt-4 text-lg leading-relaxed max-w-xl mx-auto" style="color: hsl(var(--color-text-muted))">
{{ content?.description }}
</p>
<!-- Leitmotiv -->
<div v-if="evtContent?.leitmotiv" class="mt-8 flex flex-col items-center gap-3">
<p class="font-display text-xl font-bold" style="color: hsl(var(--color-text))">
« {{ evtContent.leitmotiv }} »
</p>
<!-- The acrobat before the tagline, on its line: the tagline is narrower than the leitmotiv,
28 px keep it out from under the leitmotiv, and above it the description ends higher
(rule f, DA 03/11 after 17h35). By « Format & lieu », the stage manager stands alone -->
<p v-if="evtContent?.tagline" class="relative font-mono text-sm tracking-widest uppercase" style="color: hsl(var(--color-primary))">
{{ evtContent.tagline }}
<UiOiseauPose nom="acrobate" pose="perche" right="calc(100% + 28px)" bottom="0px" :w="72" />
</p>
<span v-if="evtContent?.gestation" class="evt-gestation-badge">
<div class="i-lucide-flask-conical h-3.5 w-3.5" />
En gestation
</span>
</div>
</div>
</div>
<!-- ══ Contenu événement ══ -->
<section v-if="evtContent?.axes || evtContent?.espaces || evtContent?.config" class="evt-content relative section-padding">
<!-- The puppeteer stands on the footer's top rule, from 1200 px: under « Espaces & programme »
the axes cards leave 100 px, half what it needs (rule f), and each row of cards holds one
bird (rule c). The only bird of the page out of its block (orch, 03/11, option 1). Its
offset is the seal's block of the layout (--seal-block), between this section and the
footer; the bird check verifies it stands on the rule -->
<UiOiseauPose nom="marionnettiste" pose="perche" left="18%" bottom="calc(-1 * var(--seal-block))" :w="112" retourne :seuil="1200" />
<div class="container-content flex flex-col gap-14">
<!-- 3 axes -->
<div v-if="evtContent?.axes">
<h2 class="evt-section-title relative">
<!-- The clown at the end of its title, on its baseline (rule e). M: between 768 and
1199 px the four birds shown would all be S otherwise (rule a) -->
Trois axes d'émancipation<UiOiseauPose nom="clown" pose="perche" bout left="14px" :w="108" retourne ton="accent" />
</h2>
<p class="evt-section-sub">« je subis — ou je m'affranchis »</p>
<div class="axes-grid">
<div v-for="(axe, i) in evtContent.axes" :key="i" class="axe-card">
<UiOiseauPose v-for="o in OISEAUX_CARTE[axe.label] ?? []" :key="`${o.nom}-${o.pose}`" v-bind="o" />
<div class="axe-icon">
<div :class="`i-lucide-${axe.icon} h-5 w-5`" />
</div>
<h3 class="font-display text-lg font-bold mb-3" style="color: hsl(var(--color-text))">
{{ axe.label }}
</h3>
<ul class="axe-list">
<li v-for="(item, j) in axe.items" :key="j">
<div class="i-lucide-arrow-right h-3.5 w-3.5 shrink-0 mt-0.5" style="color: hsl(var(--color-primary))" />
<span>{{ item }}</span>
</li>
</ul>
</div>
</div>
</div>
<!-- Espaces permanents -->
<div v-if="evtContent?.espaces">
<h2 class="evt-section-title relative">
Espaces & programme
</h2>
<p class="evt-section-sub">Chorégraphie séquencée de plénières, ateliers et espaces permanents</p>
<div class="espaces-grid">
<div v-for="(esp, i) in evtContent.espaces" :key="i" class="espace-card">
<UiOiseauPose v-for="o in OISEAUX_CARTE[esp.label] ?? []" :key="`${o.nom}-${o.pose}`" v-bind="o" />
<div class="espace-icon">
<div :class="`i-lucide-${esp.icon} h-4 w-4`" />
</div>
<div>
<p class="font-semibold text-sm" style="color: hsl(var(--color-text))">{{ esp.label }}</p>
<p class="text-xs mt-0.5 leading-relaxed" style="color: hsl(var(--color-text-muted))">{{ esp.desc }}</p>
</div>
</div>
</div>
</div>
<!-- Config -->
<div v-if="evtContent?.config">
<h2 class="evt-section-title relative">
Format & lieu
<!-- S at 72 px, feet on the cards' top edge (the title's 0.25rem margin under it): the
espaces cards above leave 106 px at 768 px, and a perched bird keeps a void of its own
height above it (rule f) -->
<UiOiseauPose nom="regisseur" pose="perche" right="24%" bottom="-0.25rem" :w="72" retourne />
</h2>
<div class="config-grid">
<div v-for="(cfg, i) in evtContent.config" :key="i" class="config-card">
<UiOiseauPose v-for="o in OISEAUX_CARTE[cfg.label] ?? []" :key="`${o.nom}-${o.pose}`" v-bind="o" />
<div class="config-icon">
<div :class="`i-lucide-${cfg.icon} h-4 w-4`" />
</div>
<div>
<p class="font-semibold text-sm" style="color: hsl(var(--color-text))">{{ cfg.label }}</p>
<p class="text-xs mt-0.5" style="color: hsl(var(--color-text-muted))">{{ cfg.detail }}</p>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import type { OiseauPlace } from '~/utils/oiseauPose'
definePageMeta({
layout: 'default',
})
const { data: content } = await usePageContent('evenement')
const evtContent = computed(() => content.value as Record<string, any> | null)
// Birds standing on the cards, by card label: never two on the same row
const OISEAUX_CARTE: Record<string, OiseauPlace[]> = {
'Économique': [{ nom: 'jongleur', pose: 'perche', right: '22px', w: 76 }],
'Ğ(marché)': [{ nom: 'cracheur-de-feu', pose: 'perche', right: '18px', w: 76, ton: 'accent', seuil: 1200 }],
}
useSeoPage({
title: evtContent.value?.meta?.title ?? 'Évènement — Le Librodrome',
description: evtContent.value?.description as string ?? 'Prochains événements du Librodrome : rencontres, lectures et ateliers autour de l\'économie du don.',
})
</script>
<style scoped>
.evt-format {
margin-top: 0.35rem;
font-weight: 600;
font-size: clamp(1.25rem, 3vw, 1.75rem);
letter-spacing: -0.02em;
color: hsl(var(--axis-cit));
}
.page-title {
font-size: clamp(2.5rem, 6vw, 3.5rem);
}
/* ── Logo SVG ── */
.evt-logo-wrap {
width: 4.5rem;
height: 4.5rem;
display: flex;
align-items: center;
justify-content: center;
color: hsl(var(--color-primary));
filter: drop-shadow(0 6px 14px hsl(var(--color-primary) / 0.25));
}
.evt-logo {
height: 100%;
width: auto;
}
/* ── Badge gestation hero ── */
.evt-gestation-badge {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
background: hsl(var(--color-accent) / 0.12);
border: 1px solid hsl(var(--color-accent) / 0.25);
color: hsl(var(--color-accent));
font-size: 0.75rem;
font-weight: 600;
font-family: var(--font-mono);
letter-spacing: 0.04em;
}
/* ── Section contenus événement ── */
.evt-content {
background: hsl(var(--color-bg));
}
.evt-section-title {
font-family: var(--font-display);
font-size: clamp(1.25rem, 3vw, 1.75rem);
font-weight: 800;
color: hsl(var(--color-text));
margin-bottom: 0.25rem;
}
.evt-section-sub {
font-family: var(--font-mono);
font-size: 0.8rem;
letter-spacing: 0.06em;
text-transform: uppercase;
color: hsl(var(--color-primary));
margin-bottom: 1.5rem;
}
/* ── Axes ── */
.axes-grid {
display: grid;
gap: 1rem;
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.axes-grid { grid-template-columns: repeat(3, 1fr); }
}
.axe-card {
position: relative;
padding: 1.5rem;
border-radius: 16px;
background: hsl(var(--color-surface));
border: 1px solid hsl(var(--color-text) / 0.07);
transition: border-color 0.2s, box-shadow 0.2s;
}
.axe-card:hover {
border-color: hsl(var(--color-primary) / 0.25);
box-shadow: 0 4px 24px hsl(var(--color-primary) / 0.06);
}
.axe-icon {
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
border-radius: 0.625rem;
background: hsl(var(--color-primary) / 0.1);
color: hsl(var(--color-primary));
margin-bottom: 1rem;
}
.axe-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.axe-list li {
display: flex;
align-items: flex-start;
gap: 0.5rem;
font-size: 0.82rem;
line-height: 1.5;
color: hsl(var(--color-text-muted));
}
/* ── Espaces ── */
.espaces-grid {
display: grid;
gap: 0.75rem;
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.espaces-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.espaces-grid { grid-template-columns: repeat(3, 1fr); }
}
.espace-card {
position: relative;
display: flex;
align-items: flex-start;
gap: 0.875rem;
padding: 1rem 1.25rem;
border-radius: 12px;
background: hsl(var(--color-surface));
border: 1px solid hsl(var(--color-text) / 0.06);
transition: border-color 0.15s;
}
.espace-card:hover {
border-color: hsl(var(--color-accent) / 0.25);
}
.espace-icon {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 0.5rem;
background: hsl(var(--color-accent) / 0.1);
color: hsl(var(--color-accent));
flex-shrink: 0;
}
/* ── Config ── */
.config-grid {
display: grid;
gap: 0.75rem;
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) {
.config-grid { grid-template-columns: repeat(4, 1fr); }
}
.config-card {
position: relative;
display: flex;
align-items: flex-start;
gap: 0.75rem;
padding: 1rem;
border-radius: 12px;
background: hsl(var(--color-surface));
border: 1px solid hsl(var(--color-text) / 0.06);
}
.config-icon {
display: flex;
align-items: center;
justify-content: center;
width: 1.875rem;
height: 1.875rem;
border-radius: 0.5rem;
background: hsl(var(--color-primary) / 0.1);
color: hsl(var(--color-primary));
flex-shrink: 0;
}
</style>