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:
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let bar: HTMLDivElement;
|
||||
let progress = $state(0);
|
||||
|
||||
onMount(() => {
|
||||
let ticking = false;
|
||||
|
||||
function update() {
|
||||
ticking = false;
|
||||
const scrollable = document.documentElement.scrollHeight - window.innerHeight;
|
||||
progress = scrollable > 0 ? Math.min(window.scrollY / scrollable, 1) : 0;
|
||||
// Écriture DOM directe : jamais d'état réactif par frame (playbook §3)
|
||||
bar.style.transform = `scaleX(${progress})`;
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
if (!ticking) {
|
||||
ticking = true;
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
window.addEventListener('resize', onScroll, { passive: true });
|
||||
return () => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('resize', onScroll);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="scroll-progress"
|
||||
role="progressbar"
|
||||
aria-label="Progression de lecture"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
aria-valuenow={Math.round(progress * 100)}
|
||||
bind:this={bar}
|
||||
></div>
|
||||
|
||||
<style>
|
||||
.scroll-progress {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
z-index: 1001;
|
||||
background: linear-gradient(to right, var(--or-oki), var(--vert-oki));
|
||||
transform: scaleX(0);
|
||||
transform-origin: left;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.scroll-progress {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user