feat(design): refonte hi-fi (tokens, pills glyphes, dark mode, accueil)
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m30s
All checks were successful
Deploy info-canicule / deploy (push) Successful in 1m30s
Adopte le design system livré par Claude Design (Info Canicule.html) : palette --paper/--brand/--ink + ramp vigilance, Public Sans + Manrope, header sticky blurred avec toggle clair/sombre, pills vigilance avec glyphes ●▲◆■ (a11y daltonisme), home restructurée (hero, stat tiles, map + sidebar avec recherche département, liste filtrable, CTA conseils). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a8830a4f34
commit
72b3785499
7 changed files with 1003 additions and 250 deletions
|
|
@ -23,6 +23,9 @@ const fullOgImage = ogImage.startsWith('http') ? ogImage : `${SITE}${ogImage}`;
|
|||
const umamiId = process.env.UMAMI_WEBSITE_ID;
|
||||
const umamiSrc = process.env.UMAMI_SRC ?? 'https://analytics.nocleus.com/script.js';
|
||||
|
||||
const path = Astro.url.pathname;
|
||||
const isActive = (p: string) => (p === '/' ? path === '/' : path.startsWith(p));
|
||||
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@graph': [
|
||||
|
|
@ -44,7 +47,7 @@ const jsonLd = {
|
|||
'@type': 'Service',
|
||||
'@id': `${SITE}/#service`,
|
||||
name: 'Info Canicule',
|
||||
serviceType: 'Service d\'information météorologique grand public',
|
||||
serviceType: "Service d'information météorologique grand public",
|
||||
areaServed: { '@type': 'Country', name: 'France' },
|
||||
audience: { '@type': 'PeopleAudience', audienceType: 'Grand public, personnes fragiles' },
|
||||
provider: {
|
||||
|
|
@ -69,7 +72,7 @@ const jsonLd = {
|
|||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="description" content={description} />
|
||||
{noindex ? <meta name="robots" content="noindex, nofollow" /> : <meta name="robots" content="index, follow, max-image-preview:large" />}
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
|
@ -90,68 +93,234 @@ const jsonLd = {
|
|||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={fullOgImage} />
|
||||
|
||||
<meta name="theme-color" content="#ea580c" />
|
||||
<meta name="theme-color" content="#fdfaf2" media="(prefers-color-scheme: light)" />
|
||||
<meta name="theme-color" content="#14110d" media="(prefers-color-scheme: dark)" />
|
||||
<meta name="format-detection" content="telephone=yes" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&family=Manrope:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
||||
|
||||
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
|
||||
|
||||
{/* Avoid flash of light theme on dark-preferring devices */}
|
||||
<script is:inline>
|
||||
(function () {
|
||||
try {
|
||||
var saved = localStorage.getItem('ic-theme');
|
||||
var mql = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
var theme = saved || (mql.matches ? 'dark' : 'light');
|
||||
if (theme === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} catch (_) {}
|
||||
})();
|
||||
</script>
|
||||
|
||||
{umamiId && (
|
||||
<script defer src={umamiSrc} data-website-id={umamiId} data-do-not-track="true"></script>
|
||||
)}
|
||||
</head>
|
||||
<body class="min-h-screen flex flex-col">
|
||||
<header class="border-b border-slate-200 bg-white">
|
||||
<div class="container-tight flex flex-wrap items-center justify-between gap-3 py-4">
|
||||
<a href="/" class="flex items-center gap-2 no-underline">
|
||||
<img src="/favicon.svg" alt="" width="32" height="32" class="h-8 w-8" />
|
||||
<span class="text-lg font-bold text-canicule-700">Info Canicule</span>
|
||||
<body class="flex flex-col" style="min-height: 100dvh;">
|
||||
<a href="#main" class="skip-link">Aller au contenu principal</a>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container-tight flex items-center justify-between gap-3 py-3.5">
|
||||
<a href="/" class="inline-flex items-center gap-2.5 font-display text-[1.1rem] font-extrabold no-underline" style="color: var(--ink);">
|
||||
<svg width="28" height="28" viewBox="0 0 32 32" aria-hidden="true">
|
||||
<circle cx="16" cy="16" r="14" fill="var(--sun)" />
|
||||
<circle cx="16" cy="16" r="11" fill="var(--brand)" />
|
||||
<path d="M16 7 C12 11 12 16 16 21 C20 16 20 11 16 7 Z" fill="#fff" />
|
||||
</svg>
|
||||
<span>Info Canicule</span>
|
||||
</a>
|
||||
<nav class="flex flex-wrap items-center gap-x-5 gap-y-1 text-sm font-medium text-slate-600">
|
||||
<a href="/">Carte</a>
|
||||
<a href="/conseils">Conseils</a>
|
||||
<a href="/a-propos">À propos</a>
|
||||
<a href="/soutenir" class="text-canicule-700">☕ Soutenir</a>
|
||||
|
||||
<nav id="nav-main" class="nav-links flex items-center gap-1" aria-label="Navigation principale">
|
||||
<a href="/" class:list={['nav-link', isActive('/') && 'is-active']}>Carte</a>
|
||||
<a href="/conseils" class:list={['nav-link', isActive('/conseils') && 'is-active']}>Conseils</a>
|
||||
<a href="/a-propos" class:list={['nav-link', isActive('/a-propos') && 'is-active']}>À propos</a>
|
||||
<a href="/soutenir" class:list={['nav-link', isActive('/soutenir') && 'is-active']} style="color: var(--brand-deep);">☕ Soutenir</a>
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
id="theme-toggle"
|
||||
type="button"
|
||||
class="icon-btn"
|
||||
aria-label="Basculer entre mode clair et mode sombre"
|
||||
title="Basculer mode clair / sombre"
|
||||
>
|
||||
<svg id="theme-icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4" />
|
||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
|
||||
</svg>
|
||||
<svg id="theme-icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="display:none;">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
id="nav-toggle"
|
||||
type="button"
|
||||
class="icon-btn"
|
||||
data-mobile-only
|
||||
aria-label="Ouvrir le menu"
|
||||
aria-expanded="false"
|
||||
aria-controls="nav-main"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<line x1="3" y1="6" x2="21" y2="6" />
|
||||
<line x1="3" y1="12" x2="21" y2="12" />
|
||||
<line x1="3" y1="18" x2="21" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="flex-1">
|
||||
|
||||
<main id="main" class="flex-1">
|
||||
<slot />
|
||||
</main>
|
||||
<footer class="border-t border-slate-200 bg-white">
|
||||
<div class="container-tight py-6 text-sm text-slate-500">
|
||||
<div class="grid gap-4 sm:grid-cols-3">
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container-tight py-8">
|
||||
<div class="grid gap-8" style="grid-template-columns: 1.4fr 1fr 1fr 1fr;">
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<img src="/favicon.svg" alt="" width="28" height="28" class="h-7 w-7" />
|
||||
<p class="font-semibold text-slate-700">Info Canicule</p>
|
||||
</div>
|
||||
<p class="mt-1 text-xs">
|
||||
<a href="/" class="inline-flex items-center gap-2.5 font-display text-[1.05rem] font-extrabold no-underline" style="color: var(--ink);">
|
||||
<svg width="24" height="24" viewBox="0 0 32 32" aria-hidden="true">
|
||||
<circle cx="16" cy="16" r="14" fill="var(--sun)" />
|
||||
<circle cx="16" cy="16" r="11" fill="var(--brand)" />
|
||||
<path d="M16 7 C12 11 12 16 16 21 C20 16 20 11 16 7 Z" fill="#fff" />
|
||||
</svg>
|
||||
Info Canicule
|
||||
</a>
|
||||
<p class="mt-2 text-sm" style="color: var(--ink-soft); max-width: 36ch;">
|
||||
Service d'information publique gratuit, sans publicité, non lucratif.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-semibold text-slate-700">Liens</p>
|
||||
<ul class="mt-1 space-y-0.5">
|
||||
<li><a href="/a-propos">À propos</a></li>
|
||||
<li><a href="/mentions-legales">Mentions légales</a></li>
|
||||
<li><a href="/dependances">Dépendances</a></li>
|
||||
<li><a href="/soutenir">☕ Soutenir sur Ko-fi</a></li>
|
||||
<h4>Le site</h4>
|
||||
<ul class="flex flex-col gap-2 text-sm">
|
||||
<li><a href="/a-propos" style="color: var(--ink-2);">À propos</a></li>
|
||||
<li><a href="/conseils" style="color: var(--ink-2);">Conseils par phénomène</a></li>
|
||||
<li><a href="/soutenir" style="color: var(--ink-2);">☕ Soutenir le projet</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-semibold text-slate-700">Données</p>
|
||||
<p class="mt-1 text-xs">
|
||||
<a href="https://meteo.data.gouv.fr/" rel="noopener">Météo France</a>
|
||||
— <a href="https://www.etalab.gouv.fr/licence-ouverte-open-licence/" rel="noopener">Licence Ouverte 2.0</a>.
|
||||
En urgence : <a href="tel:112" class="text-canicule-700 font-semibold">112</a>.
|
||||
</p>
|
||||
<h4>Mentions</h4>
|
||||
<ul class="flex flex-col gap-2 text-sm">
|
||||
<li><a href="/mentions-legales" style="color: var(--ink-2);">Mentions légales</a></li>
|
||||
<li><a href="/dependances" style="color: var(--ink-2);">Dépendances</a></li>
|
||||
<li><a href={`${SITE}/sitemap-index.xml`} style="color: var(--ink-2);">Plan du site</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Données</h4>
|
||||
<ul class="flex flex-col gap-2 text-sm">
|
||||
<li>
|
||||
<a href="https://meteo.data.gouv.fr/" rel="noopener" style="color: var(--ink-2);">Météo France (open data)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.etalab.gouv.fr/licence-ouverte-open-licence/" rel="noopener" style="color: var(--ink-2);">Licence Ouverte 2.0</a>
|
||||
</li>
|
||||
<li>
|
||||
En urgence : <a href="tel:112" style="color: var(--brand-deep); font-weight: 600;">112</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-4 text-xs text-slate-400">
|
||||
Édité à titre personnel, sans but lucratif —
|
||||
<a href="/mentions-legales" class="text-canicule-700">mentions légales</a>.
|
||||
</p>
|
||||
<div class="mt-7 flex flex-wrap items-center justify-between gap-3 border-t pt-5 text-xs" style="border-color: var(--line); color: var(--ink-soft);">
|
||||
<span>Édité à titre personnel, sans but lucratif.</span>
|
||||
<span>
|
||||
Données officielles · <a href="https://vigilance.meteofrance.fr/" rel="noopener" style="color: var(--brand-deep);">vigilance.meteofrance.fr</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
/* Header nav links */
|
||||
.nav-link {
|
||||
color: var(--ink-2);
|
||||
padding: 8px 14px;
|
||||
border-radius: var(--r-md);
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
.nav-link:hover { background: var(--paper-warm); color: var(--ink); border-bottom: none; }
|
||||
.nav-link.is-active { color: var(--ink); background: var(--paper-warm); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.nav-links {
|
||||
display: none !important;
|
||||
}
|
||||
.nav-links.open {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
position: fixed;
|
||||
inset: 60px 0 auto 0;
|
||||
background: var(--paper-2);
|
||||
padding: 12px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
box-shadow: var(--sh-3);
|
||||
gap: 4px;
|
||||
z-index: 49;
|
||||
}
|
||||
.nav-links.open .nav-link { width: 100%; padding: 14px 18px; }
|
||||
}
|
||||
|
||||
[data-mobile-only] { display: none !important; }
|
||||
@media (max-width: 720px) {
|
||||
[data-mobile-only] { display: inline-flex !important; }
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.site-footer > div > div:first-child { grid-template-columns: 1fr 1fr !important; }
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.site-footer .grid { grid-template-columns: 1fr 1fr !important; }
|
||||
}
|
||||
@media (max-width: 540px) {
|
||||
.site-footer .grid { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script is:inline>
|
||||
(function () {
|
||||
var root = document.documentElement;
|
||||
var toggle = document.getElementById('theme-toggle');
|
||||
var iconSun = document.getElementById('theme-icon-sun');
|
||||
var iconMoon = document.getElementById('theme-icon-moon');
|
||||
function syncIcons() {
|
||||
var dark = root.getAttribute('data-theme') === 'dark';
|
||||
if (iconSun) iconSun.style.display = dark ? 'none' : '';
|
||||
if (iconMoon) iconMoon.style.display = dark ? '' : 'none';
|
||||
}
|
||||
syncIcons();
|
||||
if (toggle) {
|
||||
toggle.addEventListener('click', function () {
|
||||
var dark = root.getAttribute('data-theme') === 'dark';
|
||||
if (dark) { root.removeAttribute('data-theme'); }
|
||||
else { root.setAttribute('data-theme', 'dark'); }
|
||||
try { localStorage.setItem('ic-theme', dark ? 'light' : 'dark'); } catch (_) {}
|
||||
syncIcons();
|
||||
});
|
||||
}
|
||||
var navToggle = document.getElementById('nav-toggle');
|
||||
var nav = document.getElementById('nav-main');
|
||||
if (navToggle && nav) {
|
||||
navToggle.addEventListener('click', function () {
|
||||
var open = nav.classList.toggle('open');
|
||||
navToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
||||
});
|
||||
nav.addEventListener('click', function (e) {
|
||||
if (e.target && e.target.tagName === 'A') {
|
||||
nav.classList.remove('open');
|
||||
navToggle.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue