      #coffee-map {
        /* Largeur max et marge verticale : variables publiques (voir
           `--coffee-map-max-width`/`--coffee-map-margin-block` plus bas)
           plutôt que des littéraux, pour qu'un thème hôte puisse afficher
           la carte pleine largeur, collée à ce qui l'entoure, sans
           surcharger ces propriétés elles-mêmes. Défauts inchangés (960px,
           2rem) : le dev harness s'affiche à l'identique. */
        max-width: var(--coffee-map-max-width);
        /* `2rem auto` plutôt que le `0 auto` d'origine : `font-family`,
           `margin`, et `background` vivaient auparavant sur `body` — un
           sélecteur global qui, une fois ce CSS extrait tel quel vers
           tcc-theme (voir scripts/sync-to-theme.sh), aurait écrasé le
           `body` du thème Ghost pendant l'affichage de cette page. Les
           trois propriétés sont maintenant scopées ici, sur le conteneur
           racine de la carte lui-même — `2rem` reprend la valeur
           verticale de l'ancien `margin: 2rem` de `body` (l'espacement
           haut/bas voulu autour de la carte), combinée à l'`auto`
           horizontal déjà présent ici pour le centrage dans `max-width`. */
        margin: var(--coffee-map-margin-block) auto;
        font-family: var(--coffee-map-font-body);
        /* Couleur de texte "par défaut" : aujourd'hui un no-op visuel
           total (voir --coffee-map-text plus bas) — chaque élément qui
           affiche réellement du texte pose déjà sa propre couleur
           explicite (accent ou text-muted) plus bas dans cette feuille,
           donc rien n'hérite de celle-ci pour l'instant. Posée ici quand
           même : c'est le point d'accroche public si un futur ajout de
           contenu ne pose pas sa propre couleur, ET la valeur que voit
           un thème hôte qui inspecterait `#coffee-map` pour comprendre
           le contrat de theming. */
        color: var(--coffee-map-text);
        background: #faf6f0;
        /* Le panneau de détail (.country-popup) est positionné en absolu
           par rapport à ce conteneur : il lui faut donc une position
           autre que "static" pour servir de repère. */
        position: relative;
        /* Marge de bord partagée par TOUS les éléments flottants ancrés
           aux coins de la carte — popup (`top`/`right`), légende
           (`bottom`/`left`), liste (`left`/`bottom` de secours) — une
           SEULE valeur, pour qu'aucun ne puisse diverger des autres. En
           rem, comme le reste de cette feuille de style : countryList.js
           la lit via `getComputedStyle` (elle a besoin d'un nombre en px
           pour ses calculs de positionnement) et la convertit lui-même,
           puisqu'une variable CSS ne se résout PAS en px via
           `getComputedStyle` — elle renvoie la valeur telle qu'écrite
           ("1rem", pas "16px"). PAS une variable de theming publique
           (pas de préfixe `--coffee-map-`) : c'est un détail de mise en
           page interne, sans intérêt pour un thème hôte. */
        --map-edge-margin: 1rem;
        /* Fond de survol partagé par TOUS les boutons/items cliquables
           des éléments flottants (fermeture du popup, bascule de
           recherche, item de résultat). PAS une variable de theming
           publique non plus, pour la même raison que `--map-edge-margin`
           ci-dessus — voir les variables `--coffee-map-*` ci-dessous
           pour ce qui EST exposé à un thème hôte. */
        --map-hover-bg: #faf6f0;

        /* ====================================================================
           Variables PUBLIQUES de theming (--coffee-map-*) — voir
           docs/ARCHITECTURE.md et docs/INTEGRATION.md pour le contrat
           complet, et docs/theme-bridge-example.css pour un exemple
           concret de pont depuis un thème hôte. tcc-map n'a AUCUNE
           connaissance d'un thème précis (tcc-theme ou autre) : un
           thème hôte qui veut adapter l'apparence de la carte pose ses
           propres valeurs sur CES variables (sur #coffee-map ou un de
           ses ancêtres), plutôt que ce fichier ne référence les design
           tokens d'un thème particulier.

           Les valeurs ci-dessous sont les DÉFAUTS : elles reproduisent
           EXACTEMENT le rendu actuel tant qu'aucun pont n'est posé —
           c'est ce qui garantit que le dev harness (index.html lui-même,
           qui ne pose aucun pont) continue de s'afficher à l'identique. */
        --coffee-map-accent: #5c3a1e;
        /* Non utilisée nulle part dans cette feuille aujourd'hui (aucun
           second accent dans l'UI actuelle) — exposée quand même pour
           qu'un thème hôte qui EN a un puisse la poser sans attendre
           qu'un futur composant tcc-map en ait besoin en premier. Même
           valeur que l'accent principal par défaut : pas de second ton
           de marque à inventer ici. */
        --coffee-map-accent-secondary: #5c3a1e;
        --coffee-map-text: #2b2b2b;
        --coffee-map-text-muted: #444;
        /* Fond des éléments FLOTTANTS (popup, légende, bouton toggle,
           panneau de recherche) — délibérément DISTINCT du fond de la
           carte elle-même (`background: #faf6f0` ci-dessus, qui reste un
           détail visuel de ce conteneur, pas une variable publique) :
           les deux valent la même couleur par coïncidence historique
           (voir git blame), pas parce qu'ils partagent un sens. */
        --coffee-map-bg: #ffffff;
        --coffee-map-border: #e8e8e8;
        --coffee-map-font-heading: system-ui, sans-serif;
        --coffee-map-font-body: system-ui, sans-serif;
        /* Angles droits par défaut (décision propriétaire du 2026-10-09, suit
           la maquette Penpot) : popup, légende, champ de recherche, résultats. */
        --coffee-map-radius-sm: 0;
        --coffee-map-radius-pill: 9999px;
        /* Ombre partagée par les 4 éléments flottants (popup, légende,
           bascule de liste, panneau de liste) — une SEULE valeur, pour
           qu'aucun ne puisse diverger des autres (anciennement
           `--map-shadow`, renommée ici pour rejoindre le contrat public
           `--coffee-map-*`). */
        --coffee-map-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        /* Mise en page du conteneur lui-même (les deux seules variables
           publiques qui ne sont pas de l'apparence) : 960px reprend
           `config.width`, la largeur de référence du viewBox SVG — la
           carte reste nette au-delà (SVG), ce plafond n'est qu'un choix
           de présentation standalone. `none` côté hôte = pleine largeur
           du parent ; le ratio 960:520 du viewBox fixe alors la hauteur. */
        --coffee-map-max-width: 960px;
        --coffee-map-margin-block: 2rem;
        /* Taille du popup de détail (panneau ancré en haut à droite, AU-DESSUS
           du breakpoint bottom-sheet de 480px — sous ce breakpoint, la
           règle mobile plus bas pose sa propre largeur et ignore ces
           variables). Défauts = rendu actuel : 260px plafonnés à 40% de la
           carte, hauteur selon le contenu, texte à 1rem (le nom et la
           valeur sont en `em` de cette taille, donc 1.1rem / 0.9rem comme
           avant). Un hôte qui affiche la carte en grand (plein écran) peut
           en faire un grand panneau latéral. */
        --coffee-map-popup-width: min(260px, 40%);
        --coffee-map-popup-height: auto;
        --coffee-map-popup-font-size: 1rem;
        /* `1` = le zoom sur un pays se cale dans la zone LAISSÉE LIBRE à
           gauche du popup, au lieu du centre de toute la carte (voir
           `computeZoomFrame`, interaction.js). Utile seulement quand le
           popup est assez large pour masquer le pays zoomé ; défaut `0`
           = zoom centré sur toute la carte, comme avant. Lue en JS via
           `getComputedStyle` au moment du clic. */
        --coffee-map-zoom-beside-popup: 0;
      }
      .country {
        transition: fill 0.15s ease;
      }
      .country--tier1 {
        cursor: pointer;
        /* On anime "filter" et "stroke-width" en douceur, comme le zoom
           qui est déjà animé côté JS (interaction.js) — même esprit,
           rien d'instantané. */
        transition: filter 0.15s ease, stroke-width 0.15s ease;
      }
      /* On limite cette règle aux dispositifs qui ont un VRAI survol —
         souris/trackpad, pas un doigt — exactement le même critère que
         `main.js` utilise en JS pour n'activer hover.js que sur ces
         dispositifs (`matchMedia('(hover: hover) and (pointer: fine)')`).
         Sans ce filtre, taper du doigt sur un pays Tier 1 sur mobile
         "armait" ce :hover, qui restait visuellement collé (surbrillance,
         contour épaissi) après le tap — aucun `mouseleave` ne survient
         jamais sur un écran tactile pour le faire disparaître. */
      @media (hover: hover) and (pointer: fine) {
        /* filter: brightness() éclaircit la couleur EXISTANTE d'un pays
           (qu'elle soit dorée clair ou brun foncé selon colorScale.js)
           sans avoir besoin de connaître cette couleur à l'avance —
           contrairement à une couleur fixe en `background`, ça marche
           pour tout le dégradé. On épaissit aussi légèrement le contour
           pour un effet "ce pays est actif" plus net. */
        .country--tier1:hover {
          filter: brightness(1.15);
          stroke-width: 1.5;
        }
      }
      .map-background {
        cursor: default;
      }

      /* Tooltip qui suit la souris au survol d'un pays Tier 1 (voir
         hover.js). `pointer-events: none` est essentiel : sans ça, le
         tooltip se placerait sous le curseur et intercepterait lui-même
         les événements de souris, coupant le survol du pays en dessous
         (clignotement). */
      .country-tooltip {
        position: absolute;
        top: 0;
        left: 0;
        pointer-events: none;
        /* Fond volontairement laissé en dur : c'est un scrim sombre
           propre à ce tooltip (pas "le fond" d'un élément flottant au
           sens de --coffee-map-bg), sans variable publique équivalente
           dans le contrat de theming actuel. `color`, en revanche,
           réutilise --coffee-map-bg — le même ton clair que les boîtes
           flottantes, ici comme couleur de TEXTE lisible sur ce fond
           sombre plutôt que comme fond. */
        background: rgba(30, 20, 10, 0.85);
        color: var(--coffee-map-bg);
        font-size: 0.8rem;
        padding: 0.25rem 0.6rem;
        /* border-radius laissé en dur (4px) : plus fin que
           --coffee-map-radius-sm (boîtes plus grandes), pas
           couvert par les deux variables de rayon exposées. */
        border-radius: 4px;
        white-space: nowrap;
      }
      .country-tooltip[hidden] {
        display: none;
      }

      /* Panneau de détail affiché au clic sur un pays Tier 1. Positionné
         en haut à droite de la carte, par-dessus le SVG. */
      .country-popup {
        position: absolute;
        top: var(--map-edge-margin);
        right: var(--map-edge-margin);
        width: var(--coffee-map-popup-width);
        height: var(--coffee-map-popup-height);
        /* Filet de sécurité si un hôte fixe une hauteur plus petite que le
           contenu : le panneau défile au lieu de déborder. Sans effet
           avec la hauteur par défaut (`auto`). */
        overflow-y: auto;
        font-size: var(--coffee-map-popup-font-size);
        background: var(--coffee-map-bg);
        border-radius: var(--coffee-map-radius-sm);
        box-shadow: var(--coffee-map-shadow);
        /* En `em` (= rem avec la taille de texte par défaut) : l'espace
           intérieur suit `--coffee-map-popup-font-size` quand un hôte
           agrandit le texte, au lieu de rester à l'étroit autour. */
        padding: 1em 1.25em;
        /* Filet de sécurité permanent, pas seulement pour le mobile : si
           le contenu (nom de pays, valeur) change un jour et contient un
           mot plus long que la largeur du panneau, ce mot se coupe au
           lieu de déborder hors de la boîte blanche. */
        overflow-wrap: break-word;
      }
      .country-popup[hidden] {
        display: none;
      }
      /* Bouton icône seul (flèche "arrow_back", voir interaction.js) —
         plus de texte "← Back" à afficher, d'où l'`aria-label` posé en JS
         pour l'équivalent accessible. Boîte 32x32 (`width`/`height`
         ci-dessous) + petite marge négative pour la nudger visuellement
         vers le coin du popup malgré le padding du panneau : même
         principe que la zone de tap agrandie de `.country-list__toggle`,
         en plus modeste puisqu'ici le padding du panneau (1rem/1.25rem)
         offre déjà de la marge autour. */
      .country-popup__close {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        margin: -0.25rem 0 0.5rem -0.25rem;
        background: none;
        border: none;
        /* Laissé en dur (6px) : plus fin que --coffee-map-radius-sm
           (8px, boîtes plus grandes), pas couvert par les deux variables
           de rayon exposées — même choix que .country-tooltip. */
        border-radius: 6px;
        padding: 0;
        /* `--coffee-map-accent` (défaut `#5c3a1e`) : intentionnellement
           la MÊME valeur que `config.colorRange[1]` (config.js), le brun
           le plus foncé du dégradé de la carte — pas une coïncidence.
           Réutilisée telle quelle plus bas (`.country-popup__name-link`,
           icône de `.country-list__toggle`) pour que tous les accents de
           l'UI restent cohérents entre eux ET avec la carte, PAR DÉFAUT
           — un thème hôte qui pose sa propre `--coffee-map-accent` fait
           donc varier les trois en même temps, mais découple
           délibérément cet accent UI de la carte elle-même (dont les
           couleurs restent pilotées par `config.colorRange`, indépendant
           de ce contrat CSS). */
        color: var(--coffee-map-accent);
        cursor: pointer;
      }
      .country-popup__close:hover {
        background: var(--map-hover-bg);
      }
      .country-popup__name {
        /* 0.5rem à la taille par défaut, exprimé en `em` de ce titre
           (1.1em) pour suivre lui aussi la taille du texte. */
        margin: 0 0 calc(0.5em / 1.1);
        /* En `em` de `--coffee-map-popup-font-size` (posée sur le panneau) :
           1.1em = 1.1rem avec la valeur par défaut, rendu inchangé. */
        font-size: 1.1em;
        /* Seul "titre" de ce composant (le nom du pays) — voir
           --coffee-map-font-heading, défaut identique à
           --coffee-map-font-body donc aucun changement visuel tant
           qu'un thème hôte ne différencie pas explicitement les deux. */
        font-family: var(--coffee-map-font-heading);
      }
      /* Le nom du pays EST le lien vers son guide (voir interaction.js) —
         plus de bouton "Read our guide →" séparé. `inline-flex` aligne le
         texte et l'icône "external link" sur une ligne, `flex-wrap` en
         filet de sécurité si jamais un nom de pays plus long devait
         passer à la ligne. `--coffee-map-accent` (voir le commentaire sur
         `.country-popup__close` plus haut) + soulignement au survol :
         seul lien texte du popup, le bouton de fermeture étant
         maintenant une icône seule (voir juste au-dessus). `currentColor`
         sur l'icône (voir `EXTERNAL_LINK_ICON_SVG`, interaction.js) suit
         automatiquement cette même couleur, pas besoin de la répéter. */
      .country-popup__name-link {
        display: inline-flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.3rem;
        color: var(--coffee-map-accent);
        text-decoration: none;
      }
      .country-popup__name-link:hover {
        text-decoration: underline;
      }
      .country-popup__external-icon {
        flex-shrink: 0;
      }
      .country-popup__value {
        margin: 0;
        font-size: 0.9em;
        color: var(--coffee-map-text-muted);
      }

      /* Légende du dégradé de couleur, en bas à gauche — coin opposé au
         popup (en haut à droite), sous le champ de recherche (en haut à
         gauche). Même style de boîte que le popup (fond blanc, angles
         droits, ombre légère) pour rester cohérent visuellement.

         Barre HORIZONTALE à toutes les largeurs (maquette Penpot : 240px
         de large), avec des repères chiffrés en dessous, posés en JS à
         partir de l'échelle réelle de la carte (legend.js). Chaque repère
         porte sa position sur la barre dans `--tick-pos` (0 à 1), calculée
         sur l'axe LOGARITHMIQUE de la carte. Le dégradé CSS est linéaire
         entre les deux couleurs, ce qui correspond à la carte : elle
         interpole en RGB linéairement, mais sur le log de la production. */
      .country-legend {
        position: absolute;
        bottom: var(--map-edge-margin);
        left: var(--map-edge-margin);
        box-sizing: border-box;
        width: 240px;
        max-width: calc(100% - 2 * var(--map-edge-margin));
        padding: 12px 20px 8px;
        background: var(--coffee-map-bg);
        border-radius: var(--coffee-map-radius-sm);
        box-shadow: var(--coffee-map-shadow);
        font-size: 1.1rem;
        color: var(--coffee-map-text-muted);
      }
      .country-legend__gradient {
        height: 10px;
        border-radius: 4px;
        /* `--legend-color-low`/`--legend-color-high` sont posées en JS
           (legend.js) à partir de config.colorRange : faible à gauche,
           élevé à droite. */
        background: linear-gradient(to right, var(--legend-color-low), var(--legend-color-high));
      }
      .country-legend__ticks {
        position: relative;
        height: 1.6em;
        margin-top: 4px;
      }
      .country-legend__tick {
        position: absolute;
        top: 0;
        left: calc(var(--tick-pos) * 100%);
        transform: translateX(-50%);
        padding-top: 5px;
        white-space: nowrap;
        font-weight: 600;
      }
      /* Petit trait de graduation sous la barre, à l'aplomb du repère. */
      .country-legend__tick::before {
        content: '';
        position: absolute;
        top: 0;
        left: 50%;
        width: 1px;
        height: 4px;
        background: currentColor;
      }
      .country-legend__tick[hidden] {
        display: none;
      }
      /* Les deux BORNES s'alignent sur les extrémités de la barre (gauche et
         droite) plutôt que d'être centrées : leur libellé ne dépasse pas de
         la boîte. */
      .country-legend__tick--first {
        transform: none;
      }
      .country-legend__tick--first::before {
        left: 0;
      }
      .country-legend__tick--last {
        transform: translateX(-100%);
      }
      .country-legend__tick--last::before {
        left: auto;
        right: 0;
      }
      /* MOINS de 768px : légende réduite pour libérer la carte (décision du
         2026-10-09, tailles exactes à valider). Les libellés qui ne tiennent
         pas côte à côte sont masqués par legend.js
         (`pruneOverlappingTicks`) ; les bornes sont gardées en priorité. */
      @media (max-width: 767px) {
        .country-legend {
          width: 160px;
          padding: 8px 12px 6px;
          font-size: 0.9rem;
        }
        .country-legend__gradient {
          height: 8px;
        }
        .country-legend__ticks {
          margin-top: 3px;
        }
        .country-legend__tick {
          padding-top: 4px;
        }
      }

      /* Le popup peut devenir sensiblement plus haut que sa hauteur
         "confortable" (~180px) tant que sa largeur n'a pas atteint son
         plafond de 260px — ce qui n'arrive qu'à partir d'environ 714px de
         large (260px = 40% du conteneur). En dessous de ce seuil, un
         texte de popup un peu long peut s'enrouler sur plusieurs lignes
         et grandir suffisamment pour chevaucher une légende verticale de
         ~150px ancrée en bas. Plutôt que de calculer un seuil pixel-perfect
         fragile, on réutilise le même mécanisme que pour le très petit
         écran : `:has()` détecte que `.country-popup` est visible et
         masque temporairement la légende tant que c'est le cas — quelle
         que soit sa hauteur exacte, il ne peut plus y avoir chevauchement.
         Elle réapparaît dès que le popup se referme.

         `.country-list` (la loupe) est masqué en même temps, pour la même
         raison : sous 480px le popup devient une "bottom sheet" fixée en
         bas de l'ÉCRAN (voir plus bas), qui chevaucherait ce groupe
         bas-gauche sans ce garde-fou. */
      @media (max-width: 720px) {
        #coffee-map:has(.country-popup:not([hidden])) .country-legend,
        #coffee-map:has(.country-popup:not([hidden])) .country-list {
          display: none;
        }
      }

      @media (max-width: 480px) {
        /* Sous ce breakpoint, le popup passe d'un panneau ancré à côté du
           pays cliqué à une "bottom sheet" : fixée en bas de l'ÉCRAN
           (position: fixed, pas juste du conteneur de la carte), pleine
           largeur moins les marges. Ancré au pays, il devait rétrécir à
           ~40% du conteneur pour ne pas déborder à droite — trop étroit
           pour son contenu, qui s'enroulait sur de nombreuses lignes et
           devenait plus haut que la carte elle-même. */
        .country-popup {
          position: fixed;
          top: auto;
          right: 1rem;
          bottom: 1rem;
          left: 1rem;
          width: auto;
        }
      }

      /* Recherche des 10 pays Tier 1 (voir countryList.js pour le pourquoi :
         les plus petits pays ont une cible de tap de 1.6 à 3.6px sur la
         carte elle-même sur mobile — quasi impossible à toucher
         précisément). DEUX MODES, mêmes éléments DOM, séparés à 768px de
         large (la même condition que `FIELD_MODE_QUERY` dans
         countryList.js) :

         - MOINS de 768px (portrait ou paysage) : LOUPE, comportement
           d'origine. Bouton icône seul empilé juste au-dessus de la légende,
           en bas à GAUCHE (coin opposé au popup, qui occupe le haut droite).
           `bottom: var(--map-edge-margin)` n'est qu'un filet de sécurité : la
           vraie valeur est posée en JS (`alignAboveLegend`), qui mesure la
           hauteur RÉELLE de la légende. Un clic ouvre la boîte (champ +
           résultats) vers le HAUT, ou vers le bas si le haut manque de place.
         - 768px et PLUS : champ de saisie TOUJOURS VISIBLE en haut à gauche
           (maquette Penpot : 240×44), à `--map-edge-margin` des bords ; la
           liste de résultats s'ouvre vers le BAS sous le champ. */
      .country-list {
        position: absolute;
        bottom: var(--map-edge-margin);
        left: var(--map-edge-margin);
      }
      .country-list__toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        /* Cible de tap WCAG 2.5.5 (44x44px minimum) malgré la disparition
           du label texte. La LARGEUR est posée en JS (`alignAboveLegend`)
           pour matcher celle de la légende juste en dessous ; `min-width`
           n'est qu'un filet de sécurité. */
        min-width: 44px;
        min-height: 44px;
        background: var(--coffee-map-bg);
        border: none;
        border-radius: var(--coffee-map-radius-sm);
        box-shadow: var(--coffee-map-shadow);
        padding: 0.5rem;
        color: var(--coffee-map-accent);
        cursor: pointer;
      }
      .country-list__toggle:hover {
        background: var(--map-hover-bg);
      }
      /* MODE LOUPE : boîte (champ + résultats) en absolu par rapport à
         `.country-list`, vers le HAUT par défaut. countryList.js pose à
         chaque ouverture son PROPRE `style.maxHeight` (inline, prioritaire
         sur les 320px "confortables" ci-dessous), plafonné à l'espace réel
         disponible dans ce sens, sans jamais descendre sous la hauteur du
         champ + padding (`overflow: hidden` couperait sinon le champ
         lui-même). `border-box` : le padding est inclus dans cette hauteur. */
      .country-list__box {
        position: absolute;
        left: 0;
        bottom: calc(100% + 0.5rem);
        box-sizing: border-box;
        width: 220px;
        padding: 0.5rem;
        background: var(--coffee-map-bg);
        border-radius: var(--coffee-map-radius-sm);
        box-shadow: var(--coffee-map-shadow);
        max-height: 320px;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        gap: 0.4rem;
      }
      .country-list__box--open-down {
        bottom: auto;
        top: calc(100% + 0.5rem);
      }
      .country-list__box[hidden] {
        display: none;
      }
      /* Liste de résultats. Mode loupe : simple bloc dans la boîte (c'est
         `.country-list__results` qui défile). `min-height: 0` : sans ça, un
         enfant flex garde sa taille de CONTENU comme plancher. */
      .country-list__panel {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
      }
      .country-list__panel[hidden] {
        display: none;
      }
      /* Champ de saisie, mode loupe : même style de "champ" que les items. */
      .country-list__search {
        flex-shrink: 0;
        box-sizing: border-box;
        width: 100%;
        padding: 0.5rem 0.6rem;
        border: 1px solid var(--coffee-map-border);
        border-radius: var(--coffee-map-radius-sm);
        font: inherit;
        font-size: 0.85rem;
        color: var(--coffee-map-text-muted);
      }
      @media (min-width: 768px) {
        .country-list {
          top: var(--map-edge-margin);
          bottom: auto;
          width: 240px;
          max-width: calc(100% - 2 * var(--map-edge-margin));
        }
        .country-list__toggle {
          display: none;
        }
        /* La boîte n'est plus un dropdown : un simple conteneur du champ et
           de sa liste, toujours visible (countryList.js la garde non cachée). */
        .country-list__box {
          position: relative;
          bottom: auto;
          width: auto;
          padding: 0;
          background: none;
          border-radius: 0;
          box-shadow: none;
          max-height: none;
          overflow: visible;
          display: block;
        }
        /* Champ : boîte flottante comme le popup (fond blanc, ombre, angles
           droits), sans bordure. 44px de haut = cible de tap WCAG 2.5.5.
           Focus visible par un contour d'accent (une ombre seule ne se voit
           pas sur fond blanc). */
        .country-list__search {
          display: block;
          height: 44px;
          padding: 0 20px;
          border: none;
          background: var(--coffee-map-bg);
          box-shadow: var(--coffee-map-shadow);
          font-size: 1.3rem;
          color: var(--coffee-map-text);
        }
        .country-list__search::placeholder {
          color: var(--coffee-map-text-muted);
          opacity: 1;
        }
        .country-list__search:focus-visible {
          outline: 2px solid var(--coffee-map-accent);
          outline-offset: 0;
        }
        /* Liste sous le champ, même style de boîte que le popup. Son
           `max-height` est posé en JS à chaque ouverture, plafonné à
           l'espace réellement disponible sous le champ. */
        .country-list__panel {
          position: absolute;
          left: 0;
          right: 0;
          top: calc(100% + 0.5rem);
          box-sizing: border-box;
          padding: 0.5rem;
          background: var(--coffee-map-bg);
          border-radius: var(--coffee-map-radius-sm);
          box-shadow: var(--coffee-map-shadow);
          max-height: 320px;
          overflow: hidden;
        }
        .country-list__panel[hidden] {
          display: none;
        }
      }
      /* `-webkit-search-cancel-button` : le bouton "effacer" natif que
         Chrome/Safari ajoutent aux `<input type="search">` hérite déjà de
         `cursor: pointer` par défaut, pas besoin de le retoucher ici — pas
         de règle superflue. */
      .country-list__results {
        list-style: none;
        margin: 0;
        padding: 0;
        /* `min-height: 0` : sans ça, un enfant flex garde sa taille de
           CONTENU comme plancher (défaut `min-height: auto`), ce qui
           empêchait cette liste de rétrécir en dessous de la hauteur de
           ses 10 items — la rendant incapable de scroller à l'intérieur
           du `max-height` fixé sur `.country-list__panel` (le parent
           flex). */
        min-height: 0;
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        gap: 0.4rem;
      }
      .country-list__results[hidden] {
        display: none;
      }
      .country-list__empty {
        margin: 0;
        padding: 0.5rem 0.25rem;
        font-size: 0.8rem;
        /* Laissé en dur (`#777`, plus clair que --coffee-map-text-muted
           `#444`) : un ton "vide/discret" distinct de la couleur de texte
           atténué déjà utilisée ailleurs (valeur du popup, légende, champ
           de recherche) — pas de second niveau de "muted" dans le
           contrat public actuel, pour ne pas dupliquer
           --coffee-map-text-muted avec une valeur légèrement différente. */
        color: #777;
        text-align: center;
      }
      .country-list__empty[hidden] {
        display: none;
      }
      /* Bordure, coins, police de chaque item de résultat. (Le champ de
         saisie a son propre style plus haut : boîte flottante, sans
         bordure.) */
      .country-list__item {
        border: 1px solid var(--coffee-map-border);
        border-radius: var(--coffee-map-radius-sm);
        font: inherit;
        font-size: 1.2rem;
        color: var(--coffee-map-text-muted);
      }
      .country-list__item {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        width: 100%;
        box-sizing: border-box;
        background: none;
        padding: 0.5rem 0.75rem;
        text-align: left;
        cursor: pointer;
        /* Recommandation WCAG 2.5.5 pour une cible de tap confortable —
           exactement ce que la carte ne peut pas offrir aux petits pays,
           raison d'être de cette liste. `box-sizing: border-box` ci-dessus
           garantit que le padding est INCLUS dans ces 44px, pas ajouté
           par-dessus. */
        min-height: 44px;
      }
      .country-list__item:hover {
        background: var(--map-hover-bg);
      }
      .country-list__badge {
        width: 14px;
        height: 14px;
        /* `--coffee-map-radius-pill` (défaut `9999px`) rend un cercle
           parfait exactement comme `50%` sur une boîte carrée — tout
           rayon supérieur à la moitié du plus petit côté est plafonné
           par la spec CSS, donc aucun changement visuel par rapport à
           l'ancien `50%` en dur. */
        border-radius: var(--coffee-map-radius-pill);
        flex-shrink: 0;
        /* La couleur réelle est posée en JS (countryList.js), à partir de
           colorScale — la même échelle que celle qui peint les pays sur
           la carte, pas une approximation. */
      }
