6a80cbc34f
Suite à l'analyse du vrai CSS d'unabyss.com (root tokens complets) : leur système est bien plus granulaire que le nôtre (8 niveaux de texte, opacités pré-mélangées en tokens, vocabulaire de lueur dorée à plusieurs usages). Emprunt de la STRUCTURE, pas des valeurs : - --ink-dim / --ink-ghost : deux niveaux de texte supplémentaires pour les métadonnées (coordonnées GPS) et le très discret, sans casser les 2 niveaux existants (--ink / --ink-soft) - --gold-wash-subtle / --gold-wash : fonds teintés or pré-mélangés, remplacent les oklch(...) ad hoc dispersés dans les composants - --glow-soft / --glow-strong : vocabulaire de lueur distinct d'une ombre générique — douce sur le titre du hero et la date du prochain lever, forte sur l'onglet actif (Science, Dogon) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
82 lines
2.2 KiB
Svelte
82 lines
2.2 KiB
Svelte
<script>
|
|
import { onMount, onDestroy } from "svelte";
|
|
import L from "leaflet";
|
|
import "leaflet/dist/leaflet.css";
|
|
|
|
let { sites, locale } = $props();
|
|
|
|
let mapContainer = $state();
|
|
let map;
|
|
|
|
function markerIcon(active) {
|
|
return L.divIcon({
|
|
className: "site-marker" + (active ? " site-marker-active" : ""),
|
|
iconSize: active ? [22, 22] : [16, 16],
|
|
iconAnchor: active ? [11, 11] : [8, 8],
|
|
});
|
|
}
|
|
|
|
onMount(() => {
|
|
map = L.map(mapContainer, {
|
|
scrollWheelZoom: false,
|
|
});
|
|
|
|
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
maxZoom: 18,
|
|
}).addTo(map);
|
|
|
|
const markers = sites.map((site) => {
|
|
const marker = L.marker([site.lat, site.lon], { icon: markerIcon(false) }).addTo(map);
|
|
const desc = site[`description_${locale}`] ?? site.description_fr;
|
|
marker.bindPopup(
|
|
`<strong>${site.name}</strong><br>${desc}<br><small style="color: var(--ink-dim)">${site.lat}°N, ${site.lon}°O — ${site.alt} m</small>`
|
|
);
|
|
marker.on("popupopen", () => marker.setIcon(markerIcon(true)));
|
|
marker.on("popupclose", () => marker.setIcon(markerIcon(false)));
|
|
return marker;
|
|
});
|
|
|
|
const group = L.featureGroup(markers);
|
|
map.fitBounds(group.getBounds().pad(0.2));
|
|
});
|
|
|
|
onDestroy(() => {
|
|
map?.remove();
|
|
});
|
|
</script>
|
|
|
|
<div class="observation-map">
|
|
<div bind:this={mapContainer} class="leaflet-container-host" role="group" aria-label="Carte des sites d'observation de Sirius en Guadeloupe"></div>
|
|
</div>
|
|
|
|
<style>
|
|
.leaflet-container-host {
|
|
width: 100%;
|
|
height: 22rem;
|
|
border-radius: var(--radius-md);
|
|
overflow: hidden;
|
|
}
|
|
|
|
:global(.site-marker) {
|
|
background: var(--gold-surface);
|
|
border: 2px solid oklch(20% 0.03 265);
|
|
border-radius: 50%;
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
:global(.site-marker-active) {
|
|
background: var(--caribbean-teal);
|
|
}
|
|
|
|
:global(.leaflet-popup-content-wrapper) {
|
|
background: var(--surface-raised);
|
|
color: var(--ink);
|
|
border-radius: var(--radius-sm);
|
|
}
|
|
|
|
:global(.leaflet-popup-tip) {
|
|
background: var(--surface-raised);
|
|
}
|
|
</style>
|