# Explore Togo — zoom par région sur la carte

Complément à la section A1 du brief phase 2. Le fichier `togo-carte-regions.svg` a été régénéré : il contient tout ce qu'il faut, il remplace la version précédente.

---

## 1. Le comportement attendu

Au clic sur une région, celle-ci s'agrandit jusqu'à occuper la scène, les quatre autres s'effacent, les marqueurs de sites se déploient avec leur nom, et la silhouette entière du pays se replie en minicarte dans un coin. Retour à la vue pays en cliquant la minicarte, la touche Échap, ou le bouton de retour du panneau.

---

## 2. Pourquoi ça change la mise en page — à lire avant de coder

Le Togo entier a un ratio de 1:2,53. Une région seule est presque carrée :

| Région | Ratio |
| --- | --- |
| Savanes | 1:1,10 |
| Kara | 1:1,17 |
| Centrale | 1:1,11 |
| Plateaux | 1:1,64 |
| Maritime | 1:0,76 |

Conséquence directe : **si la scène reste une colonne étroite, le zoom ne sert à rien.** Dans un cadre de 400 × 1000, la Kara ne peut grandir que de 1,47× avant de toucher les bords. Dans une scène large de 1200 × 640, elle atteint 2,10× alors que la vue pays était à 0,57× — soit un agrandissement réel de 3,7×. C'est là que l'effet se produit.

**L'architecture correcte :**

- La scène SVG occupe **toute la largeur de la section**, pas une colonne. Desktop : `viewBox="0 0 1200 640"`. Mobile : `viewBox="0 0 390 560"`.
- Le panneau de contenu est **superposé** en position absolue au-dessus de la scène, pas placé dans une colonne de grille à côté d'elle.
- La taille du SVG ne change jamais. Seule la transformation du groupe `#tg-scene` bouge. Rien n'est animé en dehors de `transform` et `opacity`.
- La vue pays cadre le pays dans le tiers gauche de la scène ; la vue région cadre la région sur environ 60 % de la largeur. Le panneau occupe l'espace restant dans les deux cas.

Le `viewBox` du fichier livré vaut `0 0 402.7 1020` pour qu'il reste consultable seul. **Le remplacer par celui de la scène à l'intégration.** La géométrie interne ne change pas, c'est la transformation qui fait tout le travail.

---

## 3. Ce que contient le fichier régénéré

| Élément | Détail |
| --- | --- |
| `#tg-scene` | Groupe englobant régions, libellés, circuit, marqueurs et grappes. C'est lui qu'on transforme. Transition de 420 ms déjà posée. |
| `path.tg-region` | Porte désormais `data-bbox="x y largeur hauteur"`, la boîte englobante réelle en coordonnées de scène. |
| `g.tg-pin-wrap` | Chaque marqueur est enveloppé, avec `data-x` et `data-y`. Permet la contre-échelle. |
| `text.tg-pin-label` | Nom du site, opacité 0 par défaut, visible quand `#tg-scene` porte `is-zoom`. |
| `g.tg-grappe` | Même enveloppe, mêmes attributs. |
| `#tg-minicarte` | Silhouette du pays en 56 px, en haut à droite. Reprend `#tg-regions` par `<use>`, donc elle reflète automatiquement l'état des régions. Opacité 0, visible avec `is-visible`. |
| `.is-hors-focus` | Régions à 12 % d'opacité, marqueurs masqués. |

Le fichier est en `width="100%"` sans hauteur fixe : c'est la mise en page hôte qui décide.

---

## 4. La fonction de cadrage

```js
const FACTEUR = 0.9;

function cadrer(bbox, rect) {
  const [bx, by, bw, bh] = bbox;
  const s  = Math.min(rect.w / bw, rect.h / bh) * FACTEUR;
  const tx = rect.x + rect.w / 2 - s * (bx + bw / 2);
  const ty = rect.y + rect.h / 2 - s * (by + bh / 2);
  return { s, tx, ty };
}

function appliquer({ s, tx, ty }) {
  scene.style.transform = `translate(${tx}px, ${ty}px) scale(${s})`;
  scene.querySelectorAll('.tg-pin-wrap, .tg-grappe').forEach(el => {
    el.style.transform =
      `translate(${el.dataset.x}px, ${el.dataset.y}px) scale(${1 / s})`;
  });
}
```

La contre-échelle des marqueurs est indispensable : sans elle, les cornes passent de 19 px à 40 px au zoom. Les libellés et les cercles de grappe sont dans la même enveloppe, ils sont traités du même coup.

Les bordures de région restent fines à tous les niveaux grâce à `vector-effect="non-scaling-stroke"`, déjà présent.

**Rectangles de cadrage** — desktop, scène 1200 × 640 :

```js
const RECT_PAYS   = { x: 0, y: 0, w: 420,  h: 640 };
const RECT_REGION = { x: 0, y: 0, w: 700,  h: 640 };
```

Mobile, scène 390 × 560 : le pays occupe `{x:0, y:0, w:390, h:560}` et la région `{x:0, y:0, w:390, h:420}`, le panneau remontant en feuille depuis le bas.

Les boîtes englobantes de chaque région figurent dans `togo-sites-coordonnees.json`, champ `regions[].bbox`, et sur chaque `path` en `data-bbox`.

---

## 5. Séquence au clic

1. `#tg-scene` reçoit `is-zoom`.
2. La région cliquée reçoit `aria-pressed="true"`, les quatre autres reçoivent `is-hors-focus`.
3. Les marqueurs et grappes des autres régions reçoivent `is-hors-focus`.
4. Les grappes de la région active se déploient automatiquement : il y a désormais la place, et c'est tout l'intérêt du zoom. Grappe masquée, marqueurs membres visibles avec leur nom.
5. La transformation calculée par `cadrer(bbox, RECT_REGION)` est appliquée.
6. `#tg-minicarte` reçoit `is-visible`.
7. Le panneau bascule sur la liste des sites de la région, avec un bouton de retour en haut.

Retour : on retire toutes ces classes et on applique `cadrer(BBOX_PAYS, RECT_PAYS)`, où `BBOX_PAYS` vaut `[0, 0, 402.7, 1020]`.

Trois voies de retour, toutes obligatoires : clic sur la minicarte, touche Échap, bouton du panneau. Une vue zoomée sans sortie évidente est un piège.

---

## 6. Points de vigilance

**Les libellés de site ne s'affichent que pour les marqueurs visibles.** Ceux qui appartiennent à une grappe non déployée gardent leur opacité à 0, sinon les noms se chevauchent autour de Kpalimé et de Lomé.

**Le libellé de région disparaît au zoom.** Le nom est déjà dans le panneau ; le garder au centre de la forme le fait entrer en collision avec les marqueurs. Retirer `is-actif` et masquer `text.tg-label` quand `is-zoom` est actif.

**Le tour automatique se désactive définitivement** dès qu'une région a été zoomée dans la session.

**Sous `prefers-reduced-motion: reduce`**, le zoom reste — c'est une navigation, pas une décoration — mais sans transition : l'état final s'applique immédiatement. La règle est déjà dans le fichier.

**Sur mobile**, prévoir aussi le balayage vers le bas pour refermer, en plus des trois voies de retour.

**Ne pas ajouter de zoom libre à la molette ni de déplacement au glisser.** Le zoom est discret, région par région. Une carte librement navigable demande une bibliothèque, casse le cadrage et n'apporte rien ici.
