From 97ba6dd04c556a9cb4bd0460f81e90fb1204d2df Mon Sep 17 00:00:00 2001 From: Yvv Date: Tue, 3 Mar 2026 03:49:07 +0100 Subject: [PATCH] =?UTF-8?q?Redesign=20accueil=20:=20grille=203=20axes,=20h?= =?UTF-8?q?ero=20fade/swipe,=20pages=20gestation=20et=20d=C3=A9cision?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Hero : animation fade-in/fade-out + swipe (useTypewriter composable + TypewriterText) - 3 axes : Autonomie numérique, économique, citoyenne (AxisBlock + AxisGrid) - Pages gestation avec présentations (wishBounty, trustWallet, Cloud libre) - Page /decision : plateforme Décision collective (lien Glibredecision) - Bloc événement distinct en bas des axes - Nav : Numérique / Économique / Citoyenne / Événement - Dark theme éclairci (bg 7→10%, surface 12→14%) - Suppression BookSection + GrateWizardTeaser (remplacés par AxisGrid) Co-Authored-By: Claude Opus 4.6 --- app/app.config.ts | 12 +- app/assets/css/main.css | 6 +- app/components/home/AxisBlock.vue | 231 ++++++++++++++++++++++ app/components/home/AxisGrid.vue | 145 ++++++++++++++ app/components/home/BookSection.vue | 135 ------------- app/components/home/GrateWizardTeaser.vue | 110 ----------- app/components/home/HeroSection.vue | 64 +++--- app/components/home/HomeMessages.vue | 10 +- app/components/home/TypewriterText.vue | 195 ++++++++++++++++++ app/composables/useTypewriter.ts | 108 ++++++++++ app/pages/decision.vue | 104 ++++++++++ app/pages/gestation/[slug].vue | 94 +++++++++ app/pages/index.vue | 4 +- site/pages/home.yml | 169 ++++++++++------ 14 files changed, 1028 insertions(+), 359 deletions(-) create mode 100644 app/components/home/AxisBlock.vue create mode 100644 app/components/home/AxisGrid.vue delete mode 100644 app/components/home/BookSection.vue delete mode 100644 app/components/home/GrateWizardTeaser.vue create mode 100644 app/components/home/TypewriterText.vue create mode 100644 app/composables/useTypewriter.ts create mode 100644 app/pages/decision.vue create mode 100644 app/pages/gestation/[slug].vue diff --git a/app/app.config.ts b/app/app.config.ts index d6b85d3..287443a 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -7,11 +7,10 @@ export default defineAppConfig({ header: { height: '4rem', nav: [ - { label: 'Autonomie', to: '/autonomie' }, - { label: 'Modèle éco', to: '/modele-eco' }, - { label: 'En musique', to: '/en-musique' }, - { label: 'Évènement', to: '/evenement' }, - { label: 'À propos', to: '/a-propos' }, + { label: 'Numérique', to: '/#numerique' }, + { label: 'Économique', to: '/#economique' }, + { label: 'Citoyenne', to: '/#citoyenne' }, + { label: 'Événement', to: '/evenement' }, ], }, footer: { @@ -27,4 +26,7 @@ export default defineAppConfig({ height: 720, }, }, + libredecision: { + url: import.meta.dev ? 'http://localhost:3002' : 'https://decision.laplank.org', + }, }) diff --git a/app/assets/css/main.css b/app/assets/css/main.css index a120d51..595b7f9 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -5,9 +5,9 @@ :root { --color-primary: 18 80% 45%; --color-accent: 32 85% 50%; - --color-bg: 20 10% 7%; - --color-surface: 20 10% 12%; - --color-surface-light: 20 8% 17%; + --color-bg: 20 10% 10%; + --color-surface: 20 10% 14%; + --color-surface-light: 20 8% 20%; --color-text: 0 0% 100%; --color-text-muted: 0 0% 65%; diff --git a/app/components/home/AxisBlock.vue b/app/components/home/AxisBlock.vue new file mode 100644 index 0000000..b3deee7 --- /dev/null +++ b/app/components/home/AxisBlock.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/app/components/home/AxisGrid.vue b/app/components/home/AxisGrid.vue new file mode 100644 index 0000000..a33322b --- /dev/null +++ b/app/components/home/AxisGrid.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/app/components/home/BookSection.vue b/app/components/home/BookSection.vue deleted file mode 100644 index 5249837..0000000 --- a/app/components/home/BookSection.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - diff --git a/app/components/home/GrateWizardTeaser.vue b/app/components/home/GrateWizardTeaser.vue deleted file mode 100644 index 02c16d4..0000000 --- a/app/components/home/GrateWizardTeaser.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - - - diff --git a/app/components/home/HeroSection.vue b/app/components/home/HeroSection.vue index bd34e3a..3961021 100644 --- a/app/components/home/HeroSection.vue +++ b/app/components/home/HeroSection.vue @@ -1,5 +1,5 @@ diff --git a/app/composables/useTypewriter.ts b/app/composables/useTypewriter.ts new file mode 100644 index 0000000..117f659 --- /dev/null +++ b/app/composables/useTypewriter.ts @@ -0,0 +1,108 @@ +export interface TypewriterSentence { + text: string + style?: 'title' | 'citation' | 'text' + stays?: boolean + separator?: boolean +} + +interface SequenceOptions { + holdMs?: number + gapMs?: number +} + +export function useTypewriter(sentences: TypewriterSentence[], options: SequenceOptions = {}) { + const { + holdMs = 2400, + gapMs = 300, + } = options + + const currentIndex = ref(-1) + const showActive = ref(false) + const lockedSentences = ref([]) + const isComplete = ref(false) + + let holdTimer: ReturnType | null = null + + const currentSentence = computed(() => + currentIndex.value >= 0 && currentIndex.value < sentences.length + ? sentences[currentIndex.value] + : null, + ) + + function clearTimer() { + if (holdTimer) { + clearTimeout(holdTimer) + holdTimer = null + } + } + + function showNext() { + const nextIdx = currentIndex.value + 1 + if (nextIdx >= sentences.length) { + isComplete.value = true + return + } + + currentIndex.value = nextIdx + const sentence = sentences[nextIdx] + + if (sentence.separator) { + lockedSentences.value = [...lockedSentences.value, { text: '', separator: true }] + } + + showActive.value = true + } + + /** Called by component via @after-enter on Transition */ + function onEntered() { + holdTimer = setTimeout(() => { + showActive.value = false + }, holdMs) + } + + /** Called by component via @after-leave on Transition */ + function onLeft() { + const sentence = sentences[currentIndex.value] + if (sentence?.stays) { + lockedSentences.value = [...lockedSentences.value, { ...sentence }] + } + setTimeout(showNext, gapMs) + } + + function start() { + showNext() + } + + function skipToEnd() { + clearTimer() + showActive.value = false + + const locked: TypewriterSentence[] = [] + for (const sentence of sentences) { + if (sentence.separator) { + locked.push({ text: '', separator: true }) + } + if (sentence.stays) { + locked.push({ ...sentence }) + } + } + + lockedSentences.value = locked + currentIndex.value = sentences.length - 1 + isComplete.value = true + } + + onUnmounted(clearTimer) + + return { + currentIndex: readonly(currentIndex), + currentSentence, + showActive, + lockedSentences: readonly(lockedSentences), + isComplete: readonly(isComplete), + onEntered, + onLeft, + start, + skipToEnd, + } +} diff --git a/app/pages/decision.vue b/app/pages/decision.vue new file mode 100644 index 0000000..3a96de3 --- /dev/null +++ b/app/pages/decision.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/app/pages/gestation/[slug].vue b/app/pages/gestation/[slug].vue new file mode 100644 index 0000000..2b65003 --- /dev/null +++ b/app/pages/gestation/[slug].vue @@ -0,0 +1,94 @@ + + + + + diff --git a/app/pages/index.vue b/app/pages/index.vue index 503ed5b..06eaeec 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -1,8 +1,8 @@