fix: légende en popup mobile + manifest PWA sans screenshots

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gwadaking
2026-04-14 17:34:26 -04:00
parent 8114103117
commit 547e0e8437
4 changed files with 153 additions and 19 deletions

View File

@@ -23,13 +23,5 @@
"purpose": "any maskable" "purpose": "any maskable"
} }
], ],
"screenshots": [ "categories": ["navigation", "weather"]
{
"src": "/assets/logo-radarsargasses971.png",
"sizes": "512x512",
"type": "image/png",
"form_factor": "narrow",
"label": "Carte radar sargasses Guadeloupe"
}
]
} }

View File

@@ -1,9 +1,9 @@
// Service Worker — Sargasse-Sentry // Service Worker — Sargasse-Sentry
// fetch handler requis par Chrome pour le critère d'installabilité PWA // fetch handler requis par Chrome pour le critère d'installabilité PWA
self.addEventListener('fetch', (event) => { // Fetch handler vide — requis par Chrome pour l'installabilité PWA.
// Pass-through : on ne met rien en cache pour l'instant (app data-driven, pas offline) // Pas de mise en cache : les données sont temps-réel.
event.respondWith(fetch(event.request)); // On ne fait PAS de respondWith pour éviter les erreurs sur les tiles cross-origin.
}); self.addEventListener('fetch', () => {});
self.addEventListener('push', (event) => { self.addEventListener('push', (event) => {
if (!event.data) return; if (!event.data) return;

View File

@@ -1,3 +1,4 @@
/* ── Légende — desktop : toujours visible ── */
.legend { .legend {
position: absolute; position: absolute;
bottom: 110px; bottom: 110px;
@@ -13,14 +14,30 @@
box-shadow: 4px 4px 0px #333; box-shadow: 4px 4px 0px #333;
} }
.legend__header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 2px;
}
.legend__title { .legend__title {
font-family: 'Fredoka One', cursive; font-family: 'Fredoka One', cursive;
font-size: 13px; font-size: 13px;
color: #1a1a2e; color: #1a1a2e;
margin-bottom: 2px;
letter-spacing: 0.03em; letter-spacing: 0.03em;
} }
/* Croix cachée sur desktop */
.legend__close {
display: none;
}
/* Bouton toggle caché sur desktop */
.legend__toggle {
display: none;
}
.legend__item { .legend__item {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -62,6 +79,99 @@
.legend__dot--medium { background: #f59e0b; } .legend__dot--medium { background: #f59e0b; }
.legend__dot--high { background: #ef4444; } .legend__dot--high { background: #ef4444; }
/* ── Mobile ── */
@media (max-width: 480px) { @media (max-width: 480px) {
.legend { bottom: auto; top: 68px; left: 10px; } /* Bouton toggle flottant en bas à gauche */
.legend__toggle {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
bottom: max(60px, calc(60px + env(safe-area-inset-bottom)));
left: max(16px, calc(16px + env(safe-area-inset-left)));
width: 36px;
height: 36px;
background: #fffbf0;
border: 2.5px solid #333;
border-radius: 50%;
font-size: 16px;
cursor: pointer;
box-shadow: 3px 3px 0px #333;
z-index: 15;
transition: transform .1s, box-shadow .1s;
}
.legend__toggle:hover {
transform: translate(-2px, -2px);
box-shadow: 5px 5px 0px #333;
}
/* Backdrop semi-transparent */
.legend__backdrop {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.25);
z-index: 19;
}
/* Légende cachée par défaut sur mobile */
.legend {
position: fixed;
bottom: max(20px, calc(20px + env(safe-area-inset-bottom)));
left: max(16px, calc(16px + env(safe-area-inset-left)));
right: max(16px, calc(16px + env(safe-area-inset-right)));
/* centré horizontalement */
width: auto;
border-radius: 20px;
padding: 16px 18px 18px;
gap: 10px;
z-index: 20;
box-shadow: 5px 5px 0px #333;
/* Caché par défaut */
opacity: 0;
pointer-events: none;
transform: translateY(12px);
transition: opacity .2s ease, transform .2s ease;
}
.legend--open {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
}
/* Croix visible sur mobile */
.legend__close {
display: flex;
align-items: center;
justify-content: center;
background: none;
border: 2px solid #333;
border-radius: 6px;
width: 24px;
height: 24px;
font-size: 12px;
font-weight: bold;
cursor: pointer;
color: #333;
box-shadow: 1px 1px 0 #333;
}
.legend__title {
font-size: 15px;
}
.legend__item {
font-size: 14px;
gap: 10px;
}
.legend__swatch {
width: 20px;
height: 13px;
}
.legend__dot {
width: 14px;
height: 14px;
}
} }

View File

@@ -1,9 +1,9 @@
import { useState } from 'react';
import './Legend.css'; import './Legend.css';
export default function Legend() { function LegendContent() {
return ( return (
<aside className="legend" aria-label="Légende"> <>
<p className="legend__title">Légende</p>
<div className="legend__item"> <div className="legend__item">
<span className="legend__swatch legend__swatch--obs-s2" /> <span className="legend__swatch legend__swatch--obs-s2" />
<span>Sargasses (S2 confirmé)</span> <span>Sargasses (S2 confirmé)</span>
@@ -29,6 +29,38 @@ export default function Legend() {
<span className="legend__dot legend__dot--high" /> <span className="legend__dot legend__dot--high" />
<span>Impact</span> <span>Impact</span>
</div> </div>
</aside> </>
);
}
export default function Legend() {
const [open, setOpen] = useState(false);
return (
<>
{/* Bouton visible uniquement sur mobile */}
<button
className="legend__toggle"
onClick={() => setOpen(o => !o)}
aria-expanded={open}
aria-label="Afficher la légende"
>
</button>
{/* Backdrop mobile quand ouvert */}
{open && (
<div className="legend__backdrop" onClick={() => setOpen(false)} aria-hidden="true" />
)}
<aside className={`legend${open ? ' legend--open' : ''}`} aria-label="Légende">
<div className="legend__header">
<p className="legend__title">Légende</p>
{/* Croix de fermeture — mobile uniquement */}
<button className="legend__close" onClick={() => setOpen(false)} aria-label="Fermer"></button>
</div>
<LegendContent />
</aside>
</>
); );
} }