feat: migre le site vers SvelteKit (Svelte 5, statique, zéro tiers)

- Rebuild complet SvelteKit 2 + Svelte 5 runes + TypeScript, adapter-static
- Images self-hébergées optimisées au build (vite-imagetools), fonts Archivo/Inter
  en woff2 local — BunnyCDN et Google Fonts supprimés (corrige les 403 d'images)
- Tokens charte OKI, thème sombre par défaut / clair opt-in, zéro emoji (set SVG)
- Motion : KineticText (stagger syncopé gwoka), ScrollProgressBar, View Transitions
- Village SVG isométrique pour les services hébergés + fallback accessible
- PWA (manifest + SW hors-ligne), 404 en KA, CSP nettoyée (.htaccess + _headers)
- Lighthouse mobile : 91/100/100/100 — JS initial 67 Ko gzip
This commit is contained in:
sucupira
2026-07-21 08:00:16 -04:00
parent d0fc7207f2
commit d0d80a105e
175 changed files with 15603 additions and 5911 deletions
+118
View File
@@ -0,0 +1,118 @@
<script lang="ts">
import type { Bundle, Locale } from '$lib/i18n';
import { splitLeadingEmoji } from './pictos';
let { t }: { t: Bundle; locale?: Locale } = $props();
</script>
<section class="hero">
<div class="hero-content container">
<h1>ORGANISATION KA</h1>
<h2 class="hero-subtitle">INTERNATIONALE</h2>
<p class="hero-tagline">{t.site.tagline}</p>
<div class="hero-tags">
{#each t.hero.tags as rawTag (rawTag)}
{@const tag = splitLeadingEmoji(rawTag)}
<span class="tag">
{#if tag.icon}
<svg class="icon" aria-hidden="true"><use href="/icons.svg#{tag.icon}" /></svg>
{/if}
{tag.text}
</span>
{/each}
</div>
<p class="hero-description">{t.site.description}</p>
<div class="cta-buttons">
<a href="#solutions" class="btn btn-solid">{t.hero.cta_primary}</a>
<a href="#mission" class="btn">{t.hero.cta_secondary}</a>
</div>
</div>
</section>
<style>
.hero {
padding: 9rem 0 5rem;
min-height: 100vh;
display: flex;
align-items: center;
position: relative;
overflow: hidden;
border-bottom: 1px solid var(--line);
}
.hero::before {
content: '';
position: absolute;
top: 0;
right: -5%;
width: 55%;
height: 100%;
background: url('/images/logo-512x512.png') center / contain no-repeat;
opacity: 0.05;
pointer-events: none;
}
.hero-content {
position: relative;
z-index: 2;
width: 100%;
}
h1 {
font-size: clamp(2.2rem, 6vw, 4rem);
font-weight: 900;
margin-bottom: 0.4rem;
line-height: 1.05;
}
.hero-subtitle {
font-size: clamp(1.4rem, 4vw, 2.2rem);
font-weight: 700;
margin-bottom: 1.25rem;
color: var(--or-oki);
}
.hero-tagline {
font-size: 1.4rem;
margin-bottom: 1.5rem;
color: var(--or-oki);
font-weight: 600;
}
.hero-description {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.85;
max-width: 680px;
}
.hero-tags {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
margin-bottom: 2rem;
}
.hero-tags .tag {
display: inline-flex;
align-items: center;
gap: 0.4rem;
}
.cta-buttons {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
@media (max-width: 768px) {
.cta-buttons {
flex-direction: column;
}
.cta-buttons .btn {
width: 100%;
text-align: center;
}
}
</style>