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,50 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
# Redirect HTTP to HTTPS, including behind reverse proxies
|
||||
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteCond %{HTTP:X-Forwarded-Proto} !https
|
||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
</IfModule>
|
||||
|
||||
# Page 404 designée (statique, autonome)
|
||||
ErrorDocument 404 /404.html
|
||||
|
||||
<IfModule mod_headers.c>
|
||||
# Force HTTPS for one year
|
||||
Header always set Strict-Transport-Security "max-age=31536000"
|
||||
|
||||
# Prevent MIME sniffing
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
|
||||
# Prevent clickjacking (also enforced via CSP frame-ancestors)
|
||||
Header always set X-Frame-Options "DENY"
|
||||
|
||||
# Control referrer leakage
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
|
||||
# Restrict browser features
|
||||
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=()"
|
||||
|
||||
# Content Security Policy (no unsafe-inline/unsafe-eval in script-src)
|
||||
# Toutes les ressources sont auto-hebergees : aucun domaine tiers.
|
||||
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'"
|
||||
</IfModule>
|
||||
|
||||
# Cache long pour les polices et images optimisees au build
|
||||
<IfModule mod_expires.c>
|
||||
ExpiresActive On
|
||||
ExpiresByType font/woff2 "access plus 1 year"
|
||||
ExpiresByType image/avif "access plus 1 month"
|
||||
ExpiresByType image/webp "access plus 1 month"
|
||||
</IfModule>
|
||||
|
||||
# Assets fingerprintes par Vite : cache immutable d'un an
|
||||
<IfModule mod_headers.c>
|
||||
<LocationMatch "^/_app/">
|
||||
Header set Cache-Control "public, max-age=31536000, immutable"
|
||||
</LocationMatch>
|
||||
<LocationMatch "^/fonts/">
|
||||
Header set Cache-Control "public, max-age=31536000, immutable"
|
||||
</LocationMatch>
|
||||
</IfModule>
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<meta name="theme-color" content="#0D0D0D" />
|
||||
<title>404 — Paj la rivé périyòd… · ORGANISATION KA INTERNATIONALE</title>
|
||||
<link rel="icon" href="/favicon.ico" sizes="48x48" />
|
||||
<link rel="icon" href="/images/logo-512x512.png" type="image/png" />
|
||||
<link rel="stylesheet" href="/fonts/fonts.css" />
|
||||
<style>
|
||||
/* 404 autonome — tokens OKI recopiés (charte §2), aucune dépendance JS */
|
||||
:root {
|
||||
--noir-oki: #0d0d0d;
|
||||
--blanc-creme: #fff8e7;
|
||||
--line: rgba(255, 255, 255, 0.1);
|
||||
--or-oki: #fdb813;
|
||||
--or-clair: #ffe066;
|
||||
--vert-oki: #00d66c;
|
||||
--rouge-oki: #ff1654;
|
||||
--font-display: 'Archivo', 'Arial Black', sans-serif;
|
||||
--font-body: 'Inter', system-ui, sans-serif;
|
||||
--radius-sm: 3px;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: var(--noir-oki);
|
||||
color: var(--blanc-creme);
|
||||
min-height: 100vh;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* Flag-bar — 6 px, 4 segments francs, arrêts nets (charte §2.4) */
|
||||
.flag-bar {
|
||||
height: 6px;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#0d0d0d 0 25%,
|
||||
#fdb813 25% 50%,
|
||||
#00d66c 50% 75%,
|
||||
#ff1654 75% 100%
|
||||
);
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
padding: 4rem 2rem;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.ka-drum {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
color: var(--or-oki);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 900;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.01em;
|
||||
line-height: 1.1;
|
||||
font-size: clamp(4rem, 15vw, 8rem);
|
||||
color: var(--blanc-creme);
|
||||
}
|
||||
|
||||
.ka {
|
||||
font-size: 1.25rem;
|
||||
color: var(--or-oki);
|
||||
}
|
||||
|
||||
.fr {
|
||||
max-width: 52ch;
|
||||
color: color-mix(in srgb, var(--blanc-creme) 70%, transparent);
|
||||
}
|
||||
|
||||
/* Bouton or : bordure 2 px, angles nets (charte §2.2) */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: 2px solid var(--or-oki);
|
||||
border-radius: var(--radius-sm);
|
||||
background: transparent;
|
||||
color: var(--or-oki);
|
||||
text-decoration: none;
|
||||
transition:
|
||||
background 120ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
color 120ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
transform 120ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--or-oki);
|
||||
color: var(--noir-oki);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn:focus-visible {
|
||||
outline: 2px solid var(--or-oki);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 1.5rem 2rem;
|
||||
border-top: 1px solid var(--line);
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
color: color-mix(in srgb, var(--blanc-creme) 70%, transparent);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flag-bar" aria-hidden="true"></div>
|
||||
<main>
|
||||
<!-- Tambour ka : fût conique + sangles croisées, stroke 2 px, angles nets (charte §4) -->
|
||||
<svg
|
||||
class="ka-drum"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="square"
|
||||
stroke-linejoin="miter"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M6 4 H18" />
|
||||
<path d="M6 4 L4 20" />
|
||||
<path d="M18 4 L20 20" />
|
||||
<path d="M4 20 H20" />
|
||||
<path d="M6 4 L20 20" />
|
||||
<path d="M18 4 L4 20" />
|
||||
</svg>
|
||||
<h1>404</h1>
|
||||
<p class="ka" lang="gcf">« Paj la rivé périyòd… »</p>
|
||||
<p class="fr">La page que vous cherchez n'existe pas ou a été déplacée. La route continue ailleurs.</p>
|
||||
<a class="btn" href="/">Retour à l'accueil</a>
|
||||
</main>
|
||||
<footer>ORGANISATION KA INTERNATIONALE · o-k-i.net</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
Strict-Transport-Security: max-age=31536000
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: DENY
|
||||
Referrer-Policy: strict-origin-when-cross-origin
|
||||
Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=()
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'
|
||||
|
||||
/_app/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/fonts/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
/assets/press/*
|
||||
Cache-Control: public, max-age=2592000
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
/* Archivo — display (titres + boutons), graisses 600-900 */
|
||||
@font-face {
|
||||
font-family: 'Archivo';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url('/fonts/archivo-latin-600-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Archivo';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('/fonts/archivo-latin-700-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Archivo';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url('/fonts/archivo-latin-800-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Archivo';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url('/fonts/archivo-latin-900-normal.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* Inter — corps de texte, graisses 400-800 */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('/fonts/inter-latin-400-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('/fonts/inter-latin-500-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url('/fonts/inter-latin-600-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('/fonts/inter-latin-700-normal.woff2') format('woff2');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url('/fonts/inter-latin-800-normal.woff2') format('woff2');
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Set iconographique OKI — charte §4 : viewBox 24×24, stroke 2 px, angles nets, currentColor -->
|
||||
<symbol id="ka" viewBox="0 0 24 24">
|
||||
<!-- tambour ka : collerette hexagonale, fût conique, sangles en zigzag -->
|
||||
<path d="M4 7 L20 7 L22 9 L20 11 L4 11 L2 9 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M4 11 L7 21 L17 21 L20 11" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M8 11 L10.5 16 L9 21 M16 11 L13.5 16 L15 21" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="lambi" viewBox="0 0 24 24">
|
||||
<!-- conque lambi : dome en spirale, lèvre angulaire -->
|
||||
<path d="M4 14 C4 8 9 4 14 4 C18 4 21 7 21 11 L17 14 L20 18 L13 20 C8 21 4 18 4 14 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M11 14 C11 12.5 13.5 12.5 13.5 14 C13.5 16 9.5 16 9.5 13 C9.5 9.5 14 8.5 16 10.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="zetwal" viewBox="0 0 24 24">
|
||||
<!-- étoile 4 branches -->
|
||||
<path d="M12 3 L14.5 9.5 L21 12 L14.5 14.5 L12 21 L9.5 14.5 L3 12 L9.5 9.5 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="mawon" viewBox="0 0 24 24">
|
||||
<!-- brisure de chaîne : deux demi-maillons octogonaux, connexion rompue -->
|
||||
<path d="M9 7 L5 7 L3 9 L3 15 L5 17 L9 17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M15 7 L19 7 L21 9 L21 15 L19 17 L15 17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M12 9.5 L12 11 M12 13 L12 14.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="lakanmou" viewBox="0 0 24 24">
|
||||
<!-- flamme : contour angulaire à base courbe, languette interne -->
|
||||
<path d="M12 3 L15 8 L18 12 C19 15 18 18 15.5 20 L12 21 L8.5 20 C6 18 5 15 6 12 L9 8 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M12 12 L14 14.5 C14.3 16.5 13 18 12 18 C11 18 9.7 16.5 10 14.5 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="jaden" viewBox="0 0 24 24">
|
||||
<!-- pousse : tige et deux feuilles angulaires en cerf-volant -->
|
||||
<path d="M12 21 L12 10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M12 13 L3 5 L6 12 L10 16 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M12 13 L21 5 L18 12 L14 16 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="kannen" viewBox="0 0 24 24">
|
||||
<!-- canne à sucre : tige segmentée, trois lames au sommet -->
|
||||
<path d="M10 21 L10 6 L14 6 L14 21 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M10 17 L14 17 M10 13 L14 13 M10 9 L14 9" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M10 6 L5 3 M14 6 L19 3 M12 6 L12 2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="lanme" viewBox="0 0 24 24">
|
||||
<!-- vague angulaire : trois lignes brisées superposées -->
|
||||
<path d="M2 8 L7 4 L12 8 L17 4 L22 8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M2 14 L7 10 L12 14 L17 10 L22 14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M2 20 L7 16 L12 20 L17 16 L22 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="glo" viewBox="0 0 24 24">
|
||||
<!-- poing levé géométrique : bloc poing + avant-bras, doigts segmentés, pouce -->
|
||||
<path d="M8 20 L8 15 L6 15 L6 6 L8 4 L18 4 L18 15 L16 15 L16 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M6 9 L18 9" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M9 4 L9 9 M12 4 L12 9 M15 4 L15 9 M6 12 L10 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="kle" viewBox="0 0 24 24">
|
||||
<!-- cadenas ouvert : corps rectangulaire, anse angulaire levée -->
|
||||
<path d="M5 11 L19 11 L19 21 L5 21 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M8 11 L8 6 L10 4 L14 4 L16 6 L16 8" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M12 14.5 L12 17.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="pawol" viewBox="0 0 24 24">
|
||||
<!-- bulle de parole angulaire : rectangle à queue, deux lignes de texte -->
|
||||
<path d="M3 4 L21 4 L21 15 L13 15 L8 20 L8 15 L3 15 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M7 8 L17 8 M7 11.5 L13 11.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
<symbol id="mizik-note" viewBox="0 0 24 24">
|
||||
<!-- double croche : deux tiges reliées par un croc, têtes en losange -->
|
||||
<path d="M9 6 L9 19 M19 4 L19 17 M9 6 L19 4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M9 16.5 L11.5 19 L9 21.5 L6.5 19 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
<path d="M19 14.5 L21.5 17 L19 19.5 L16.5 17 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,15 @@
|
||||
(function() {
|
||||
// Redirection automatique selon la langue du navigateur, sauf choix explicite déjà mémorisé
|
||||
var pref = localStorage.getItem('oki-lang-pref');
|
||||
if (pref) return;
|
||||
|
||||
var browserLang = (navigator.language || navigator.userLanguage || '').toLowerCase();
|
||||
var wantsEnglish = browserLang.indexOf('en') === 0;
|
||||
var currentLocale = document.documentElement.dataset.locale || 'fr';
|
||||
|
||||
if (wantsEnglish && currentLocale !== 'en') {
|
||||
window.location.replace('/en/' + window.location.hash);
|
||||
} else if (!wantsEnglish && currentLocale === 'en') {
|
||||
window.location.replace('/' + window.location.hash);
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "ORGANISATION KA INTERNATIONALE",
|
||||
"short_name": "OKI",
|
||||
"description": "Studio web militant caribéen — des solutions numériques libres pour les organisations engagées.",
|
||||
"lang": "fr",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#0D0D0D",
|
||||
"background_color": "#0D0D0D",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/logo-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/images/logo-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/favicon.ico",
|
||||
"sizes": "48x48",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Enregistrement du service worker — chemins absolus (le site a des routes imbriquées /en/, /dons/…).
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/sw.js', { scope: '/' });
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://o-k-i.net/sitemap.xml
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://o-k-i.net/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/en/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/presse/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/en/press/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/dons/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/en/donate/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/mentions-legales/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.3</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://o-k-i.net/en/legal-notice/</loc>
|
||||
<lastmod>2026-07-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.3</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
@@ -0,0 +1,17 @@
|
||||
(function() {
|
||||
// Récupérer le thème stocké ou détecter le thème système
|
||||
const storedTheme = localStorage.getItem('oki-theme');
|
||||
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
let theme = storedTheme;
|
||||
|
||||
// Si pas de préférence stockée, utiliser le thème système
|
||||
if (!storedTheme) {
|
||||
theme = systemPrefersDark ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
// Appliquer le thème immédiatement
|
||||
if (theme === 'light') {
|
||||
document.documentElement.classList.add('light-theme');
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user