From a6f359559be9c1c3c5ca1be7acad3f02a25e7512 Mon Sep 17 00:00:00 2001 From: sucupira Date: Tue, 21 Jul 2026 12:42:02 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20passe=20exp=C3=A9rience=20=E2=80=94=20m?= =?UTF-8?q?otion=20system=20niveau=20Awwwards=20(DOM/SVG,=20z=C3=A9ro=20We?= =?UTF-8?q?bGL)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - IntroLoader : cérémonie d'entrée (flag-bar, monogramme, titrage), 1re visite, skippable - Lenis au layout (ticker GSAP, imports dynamiques) + ancres interceptées - Hero : titrage oversized en masques, filets drapeau en parallaxe, sortie scrubée (scroll-driven CSS) - Reveal syncopé gwoka (use:reveal) sur 83 éléments, flag chips, icônes pop - Marquee kréyòl (tagline + valeurs), pause au survol - Hover craft : boutons à balayage or, nav soulignée + section active, pochettes DJANGOKAM en wipe clip-path + tilt 3D (use:tilt) avec reflet or - Gate unique prefers-reduced-motion partout ; contenu complet sans JS - Lighthouse mobile 91/100/100/100 — JS initial 69 Ko gzip (budget 170 Ko) --- package-lock.json | 34 ++- package.json | 3 +- src/lib/components/Nav.svelte | 54 ++++- src/lib/components/motion/FlagChip.svelte | 53 +++++ src/lib/components/motion/IntroLoader.svelte | 216 ++++++++++++++++++ src/lib/components/motion/Marquee.svelte | 104 +++++++++ src/lib/components/sections/Clients.svelte | 13 +- src/lib/components/sections/Contact.svelte | 12 +- src/lib/components/sections/Djangokam.svelte | 108 +++++++-- src/lib/components/sections/Engagement.svelte | 9 +- src/lib/components/sections/Faq.svelte | 7 +- src/lib/components/sections/Fediverse.svelte | 2 + src/lib/components/sections/Hero.svelte | 169 +++++++++++++- src/lib/components/sections/Hosting.svelte | 13 +- .../components/sections/HostingVillage.svelte | 5 +- src/lib/components/sections/Mission.svelte | 9 +- src/lib/components/sections/Partners.svelte | 7 +- src/lib/components/sections/Projects.svelte | 15 +- src/lib/components/sections/Publics.svelte | 11 +- src/lib/motion/reveal.ts | 42 ++++ src/lib/motion/scroll.ts | 43 ++++ src/lib/motion/tilt.ts | 42 ++++ src/lib/styles/base.css | 69 +++++- src/routes/+layout.svelte | 30 +++ src/routes/+page.svelte | 2 + src/routes/en/+page.svelte | 2 + static/theme.js | 10 + 27 files changed, 1018 insertions(+), 66 deletions(-) create mode 100644 src/lib/components/motion/FlagChip.svelte create mode 100644 src/lib/components/motion/IntroLoader.svelte create mode 100644 src/lib/components/motion/Marquee.svelte create mode 100644 src/lib/motion/reveal.ts create mode 100644 src/lib/motion/scroll.ts create mode 100644 src/lib/motion/tilt.ts diff --git a/package-lock.json b/package-lock.json index 89e00e9..772c7f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "@fontsource/archivo": "^5.3.0", "@fontsource/inter": "^5.3.0", - "gsap": "^3.15.0" + "gsap": "^3.15.0", + "lenis": "^1.3.25" }, "devDependencies": { "@sveltejs/adapter-static": "^3.0.10", @@ -5046,6 +5047,37 @@ "node": ">=6" } }, + "node_modules/lenis": { + "version": "1.3.25", + "resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.25.tgz", + "integrity": "sha512-mOKxayErlaONK8fm4LN3XNd99Qu4plTpn9h9qf8wxzjGrJDzuD84FYzZ81HCd6ZsWp++VWVwOzL286Pf2s2u4A==", + "license": "MIT", + "workspaces": [ + "packages/*", + "playground", + "playground/*" + ], + "funding": { + "type": "github", + "url": "https://github.com/sponsors/darkroomengineering" + }, + "peerDependencies": { + "@nuxt/kit": ">=3.0.0", + "react": ">=17.0.0", + "vue": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "react": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", diff --git a/package.json b/package.json index 04ffc78..2672f44 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "dependencies": { "@fontsource/archivo": "^5.3.0", "@fontsource/inter": "^5.3.0", - "gsap": "^3.15.0" + "gsap": "^3.15.0", + "lenis": "^1.3.25" } } diff --git a/src/lib/components/Nav.svelte b/src/lib/components/Nav.svelte index 0111873..0419132 100644 --- a/src/lib/components/Nav.svelte +++ b/src/lib/components/Nav.svelte @@ -1,16 +1,40 @@ + + + + diff --git a/src/lib/components/motion/IntroLoader.svelte b/src/lib/components/motion/IntroLoader.svelte new file mode 100644 index 0000000..ec911aa --- /dev/null +++ b/src/lib/components/motion/IntroLoader.svelte @@ -0,0 +1,216 @@ + + + + + diff --git a/src/lib/components/motion/Marquee.svelte b/src/lib/components/motion/Marquee.svelte new file mode 100644 index 0000000..861a921 --- /dev/null +++ b/src/lib/components/motion/Marquee.svelte @@ -0,0 +1,104 @@ + + + + + diff --git a/src/lib/components/sections/Clients.svelte b/src/lib/components/sections/Clients.svelte index 2ee4b14..fdfe02d 100644 --- a/src/lib/components/sections/Clients.svelte +++ b/src/lib/components/sections/Clients.svelte @@ -1,7 +1,9 @@
+

{t.faq.section_subtitle}

- {#each t.faq.items as item (item.question)} -
+ {#each t.faq.items as item, i (item.question)} +
{item.question} diff --git a/src/lib/components/sections/Fediverse.svelte b/src/lib/components/sections/Fediverse.svelte index 0777542..d76c67e 100644 --- a/src/lib/components/sections/Fediverse.svelte +++ b/src/lib/components/sections/Fediverse.svelte @@ -1,4 +1,5 @@
+
-

ORGANISATION KA

-

INTERNATIONALE

+

+ ORGANISATION + KA +

+

+ INTERNATIONALE +

{t.site.tagline}

{#each t.hero.tags as rawTag (rawTag)} @@ -40,8 +50,13 @@ border-bottom: 1px solid var(--line); } - .hero::before { - content: ''; + .hero-bg { + position: absolute; + inset: 0; + pointer-events: none; + } + + .hero-watermark { position: absolute; top: 0; right: -5%; @@ -49,29 +64,110 @@ height: 100%; background: url('/images/logo-512x512.png') center / contain no-repeat; opacity: 0.05; - pointer-events: none; + will-change: transform; + } + + /* Filets drapeau en diagonale, très basse opacité (profondeur) */ + .hero-stripes { + position: absolute; + left: -50%; + width: 200%; + background: linear-gradient( + to right, + transparent 0 10%, + var(--or-oki) 10% 40%, + var(--vert-oki) 40% 65%, + var(--rouge-oki) 65% 85%, + transparent 85% 100% + ); + transform: rotate(-12deg); + will-change: transform; + } + + .hero-stripes.s1 { + top: 22%; + height: 3px; + opacity: 0.1; + } + + .hero-stripes.s2 { + bottom: 18%; + height: 2px; + opacity: 0.07; } .hero-content { position: relative; z-index: 2; width: 100%; + will-change: transform, opacity; } h1 { - font-size: clamp(2.2rem, 6vw, 4rem); + font-size: clamp(3rem, 9vw, 7rem); font-weight: 900; margin-bottom: 0.4rem; - line-height: 1.05; + line-height: 0.95; } .hero-subtitle { - font-size: clamp(1.4rem, 4vw, 2.2rem); + font-size: clamp(1.6rem, 4.5vw, 3rem); font-weight: 700; margin-bottom: 1.25rem; color: var(--or-oki); } + /* Reveal masqué au chargement (pattern titrage des sites primés) : + uniquement si JS actif et motion autorisée — sinon texte visible */ + .mask { + display: inline-block; + overflow: hidden; + vertical-align: bottom; + } + + .w { + display: inline-block; + will-change: transform; + } + + @media (prefers-reduced-motion: no-preference) { + :global(html.js) .w { + transform: translateY(110%); + animation: word-rise var(--dur-phrase) var(--ease-ka) forwards; + } + + :global(html.js) .w1 { + animation-delay: 150ms; + } + + :global(html.js) .w2 { + animation-delay: 270ms; + } + + :global(html.js) .w3 { + animation-delay: 510ms; + } + + /* Si la cérémonie d'intro joue, le titrage attend sa sortie */ + :global(html.js.intro-pending) .w1 { + animation-delay: 1400ms; + } + + :global(html.js.intro-pending) .w2 { + animation-delay: 1520ms; + } + + :global(html.js.intro-pending) .w3 { + animation-delay: 1760ms; + } + } + + @keyframes word-rise { + to { + transform: translateY(0); + } + } + .hero-tagline { font-size: 1.4rem; margin-bottom: 1.5rem; @@ -82,7 +178,7 @@ .hero-description { font-size: 1.2rem; margin-bottom: 2rem; - opacity: 0.85; + color: var(--muted); max-width: 680px; } @@ -105,6 +201,61 @@ flex-wrap: wrap; } + /* Parallaxe et sortie scrubée : scroll-driven animations natives, + enhancement progressif — sans support, le hero reste statique */ + @supports (animation-timeline: scroll()) { + @media (prefers-reduced-motion: no-preference) { + .hero-watermark { + animation: wm-drift linear both; + animation-timeline: scroll(root); + animation-range: 0 100vh; + } + + .hero-stripes.s1 { + animation: s1-drift linear both; + animation-timeline: scroll(root); + animation-range: 0 100vh; + } + + .hero-stripes.s2 { + animation: s2-drift linear both; + animation-timeline: scroll(root); + animation-range: 0 100vh; + } + + .hero-content { + animation: hero-exit linear both; + animation-timeline: scroll(root); + animation-range: 0 75vh; + } + } + } + + @keyframes wm-drift { + to { + transform: translateY(14%) scale(1.06); + } + } + + @keyframes s1-drift { + to { + transform: rotate(-12deg) translateX(-8%); + } + } + + @keyframes s2-drift { + to { + transform: rotate(-12deg) translateX(6%); + } + } + + @keyframes hero-exit { + to { + transform: translateY(-8vh); + opacity: 0.2; + } + } + @media (max-width: 768px) { .cta-buttons { flex-direction: column; diff --git a/src/lib/components/sections/Hosting.svelte b/src/lib/components/sections/Hosting.svelte index e35c50b..4f46ce7 100644 --- a/src/lib/components/sections/Hosting.svelte +++ b/src/lib/components/sections/Hosting.svelte @@ -1,12 +1,15 @@
+

{t.hosting.section_subtitle}

-
+

{t.hosting.banner_title}

{t.hosting.banner_text}

@@ -33,8 +36,8 @@

{t.hosting.offerings_title}

- {#each t.hosting.offer_cards as card (card.title)} -
+ {#each t.hosting.offer_cards as card, i (card.title)} +

{card.title}

{#if card.intro}

{card.intro}

@@ -50,7 +53,7 @@
-
+

{t.hosting.note_title}

{t.hosting.note_intro}

    @@ -60,7 +63,7 @@
-
+

{t.hosting.why_title}

{t.hosting.why_text}

{t.hosting.why_cta} → diff --git a/src/lib/components/sections/HostingVillage.svelte b/src/lib/components/sections/HostingVillage.svelte index b1e8f1b..77dfbe6 100644 --- a/src/lib/components/sections/HostingVillage.svelte +++ b/src/lib/components/sections/HostingVillage.svelte @@ -1,5 +1,6 @@ +