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:
@@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user