/* =============================================================================
 *  TOP TRANSLATE — sélecteur de langue du site public
 *
 *  Six styles, un seul balisage. Tout est préfixé `.gmlt-sw` et passe par des
 *  propriétés personnalisées : le composant ne peut pas déteindre sur le thème,
 *  et le thème peut le recolorer sans toucher à ce fichier.
 *
 *  Plan :
 *    1. Jetons (charte REDORZO, thèmes clair/sombre)
 *    2. Socle commun — remise à zéro locale, liens, drapeaux, icônes
 *    3. Positions flottantes
 *    4. minimal
 *    5. pill
 *    6. dropdown
 *    7. flags
 *    8. globe
 *    9. aurora
 *   10. Accessibilité, mouvement réduit, contraste, impression, RTL, mobile
 * ========================================================================== */

/* ------------------------------------------------------------------ 1. jetons */

.gmlt-sw {
  /* Charte REDORZO — les mêmes couleurs que la console d'administration et que
     le site : le client doit reconnaître d'un coup d'œil qui a fait ce
     composant. */
  --g1: #4F6BFF;
  --g2: #22D3EE;
  --brand: #6366F1;
  --brand-strong: #4F46E5;
  --grad: linear-gradient(100deg, var(--g1), var(--g2));

  --sw-bg: #FFFFFF;
  --sw-bg-2: #F1F3FA;
  --sw-text: #101828;
  --sw-text-2: #4A5568;
  /* #8A93A6 ne tenait pas : 3,09 sur blanc et 2,78 sur une pastille, pour du
     texte de 12 px que le VISITEUR du site client doit lire — le compteur de
     langues du panneau, le libellé du champ de recherche, et la mention
     « Traduit par TOP TRANSLATE ». C'est le même défaut que `--text-3` dans la
     console, sur la surface la plus vue du produit. #5F697D donne 5,52 et 4,98.
     Le ton sombre, lui, tenait déjà (4,88) et ne bouge pas. */
  --sw-text-3: #5F697D;
  --sw-border: #E7E9F3;
  --sw-border-2: #D8DCEB;
  --sw-ring: rgba(99, 102, 241, .35);
  --sw-shadow: 0 8px 24px -10px rgba(16, 24, 40, .22);
  --sw-shadow-lg: 0 24px 60px -20px rgba(16, 24, 40, .34);
  --sw-glow: 0 14px 34px -12px rgba(79, 107, 255, .55);

  --sw-radius: 12px;
  --sw-font: inherit;
  --sw-size: .875rem;
  --sw-gap: 6px;
  /* Marge des styles flottants. `env(safe-area-inset-*)` : sur iPhone, sans
     cela, le composant se loge sous la barre de gestes et devient intouchable. */
  --sw-inset: 18px;
  --sw-z: 9990;

  font-family: var(--sw-font);
  font-size: var(--sw-size);
  line-height: 1;
  color: var(--sw-text);
  -webkit-font-smoothing: antialiased;
}

/* Thème sombre : suivi du système en `auto`, forcé en `dark`. Deux blocs plutôt
   qu'un, parce qu'un réglage explicite doit l'emporter sur la préférence du
   système — c'est le client qui connaît son propre thème. */
@media (prefers-color-scheme: dark) {
  .gmlt-sw[data-theme="auto"] {
    --sw-bg: #111A31;
    --sw-bg-2: #16203A;
    --sw-text: #EAF0FF;
    --sw-text-2: #AEB9D6;
    --sw-text-3: #7C88A6;
    --sw-border: #212C48;
    --sw-border-2: #2C3960;
    --brand: #8E97FF;
    --brand-strong: #A5B0FF;
    --sw-ring: rgba(142, 151, 255, .5);
    --sw-shadow: 0 10px 30px -12px rgba(0, 0, 0, .6);
    --sw-shadow-lg: 0 26px 64px -20px rgba(0, 0, 0, .72);
  }
}

/* Palette sombre, appliquée quand le composant PORTE `data-theme="dark"`.

   ── HISTOIRE DE CETTE RÈGLE, ET POURQUOI ELLE A MAIGRI (VIS-10 → SW-04) ─────

   Elle a porté un second sélecteur, `.toptr[data-theme="dark"] .sw-stage .gmlt-sw`,
   ajouté par VIS-10 : dans la console passée en sombre, l'aperçu rendait le
   composant en palette CLAIRE — texte foncé sur scène sombre — et 11 libellés sur
   14 tombaient sous le seuil de contraste, plusieurs à 1,03, c'est-à-dire
   invisibles. C'est le « sur fonds il y a des trucs qui disparaissent » signalé
   par le client.

   Le correctif marchait, et il mentait. Sa spécificité (0,4,0) écrasait celle du
   choix du client (0,2,0) : la console imposait donc sa palette à TOUS les
   aperçus, y compris à un client ayant explicitement demandé « Toujours clair ».
   Sur un écran dont l'unique rôle est de montrer le réglage choisi.

   Et il laissait un cas entier dehors, que rien en CSS ne pouvait rattraper : un
   composant en `auto` suit `@media (prefers-color-scheme: dark)`, c'est-à-dire le
   système de L'ADMINISTRATEUR. Console en clair + machine en sombre donnait un
   composant sombre sur scène claire, sans qu'aucun sélecteur puisse le savoir.

   LE THÈME DE L'APERÇU EST DONC RÉSOLU PAR LE SERVEUR, dans
   `TOPTR_UI::preview_theme()`, et passé à `render()`. Le composant ne porte plus
   jamais `auto` dans la console : la préférence système ne peut plus s'y inviter,
   le choix du client est rendu tel quel, et la scène reçoit la classe assortie
   (`sw-stage--light` / `--dark`, dans `admin-toptr.css`).

   On supprime donc le sélecteur de console plutôt que de le corriger. Une règle
   qui ne peut plus matcher n'est pas neutre : elle décrit un mécanisme qui
   n'existe plus, et le prochain à la lire y croira. */
.gmlt-sw[data-theme="dark"] {
  --sw-bg: #111A31;
  --sw-bg-2: #16203A;
  --sw-text: #EAF0FF;
  --sw-text-2: #AEB9D6;
  --sw-text-3: #7C88A6;
  --sw-border: #212C48;
  --sw-border-2: #2C3960;
  --brand: #8E97FF;
  --brand-strong: #A5B0FF;
  --sw-ring: rgba(142, 151, 255, .5);
  --sw-shadow: 0 10px 30px -12px rgba(0, 0, 0, .6);
  --sw-shadow-lg: 0 26px 64px -20px rgba(0, 0, 0, .72);
}

/* --------------------------------------------------------- 2. socle commun */

/* Remise à zéro LOCALE. Les thèmes WordPress imposent des marges, des
   soulignements et des `text-transform` aux liens ; sans ces lignes, le
   composant est différent sur chaque site — et c'est le premier motif de ticket
   sur ce genre de module. */
.gmlt-sw *,
.gmlt-sw *::before,
.gmlt-sw *::after { box-sizing: border-box; }

.gmlt-sw nav,
.gmlt-sw a,
.gmlt-sw button,
.gmlt-sw span,
.gmlt-sw div,
.gmlt-sw input {
  margin: 0;
  padding: 0;
  font-family: inherit;
  letter-spacing: normal;
  text-transform: none;
}

.gmlt-sw a {
  display: inline-flex;
  align-items: center;
  gap: var(--sw-gap);
  color: inherit;
  text-decoration: none;
  box-shadow: none;
  border: 0;
  background: none;
  white-space: nowrap;
  cursor: pointer;
}

.gmlt-sw a:hover,
.gmlt-sw a:focus { text-decoration: none; }

.gmlt-sw button {
  display: inline-flex;
  align-items: center;
  gap: var(--sw-gap);
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.gmlt-sw [hidden] { display: none !important; }

/* Drapeaux. `object-fit` n'a pas cours sur un SVG en ligne : c'est
   `preserveAspectRatio="…slice"`, posé dans le balisage, qui recadre. Le trait
   de contour évite qu'un drapeau à fond blanc (Pologne, Japon) disparaisse sur
   un panneau blanc. */
.gmlt-sw .gmlt-flag {
  display: block;
  flex: none;
  width: 1.35em;
  height: .9em;
  border-radius: 2.5px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}

.gmlt-sw .gmlt-ic {
  display: block;
  flex: none;
  width: 1.05em;
  height: 1.05em;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.gmlt-sw .gmlt-chev { transition: transform .22s cubic-bezier(.4, 0, .2, 1); }
.gmlt-sw [aria-expanded="true"] .gmlt-chev { transform: rotate(180deg); }

/* La coche n'existe que dans les panneaux. Elle est présente dans TOUS les liens
   pour n'avoir qu'un seul balisage : les styles qui n'en veulent pas la
   masquent. */
.gmlt-sw .gmlt-check { display: none; }

.gmlt-sw .gmlt-code {
  font-size: .78em;
  letter-spacing: .06em;
  color: var(--sw-text-3);
  font-variant-numeric: tabular-nums;
}

.gmlt-sw .gmlt-lab { min-width: 0; }

/* ---------------------------------------------------- 3. positions flottantes */

/* LE STYLE `dropdown` NE FLOTTAIT PAS, ET C'EST PASSÉ INAPERÇU DEPUIS TOUJOURS.

   `.gmlt-sw[data-style="dropdown"]` pose `position: relative` — il en a besoin,
   son panneau est en `position: absolute`. Cette règle a la MÊME spécificité que
   `.gmlt-sw.is-float` (0,2,0) et vient plus loin dans le fichier : elle gagnait.
   Le composant gardait donc sa classe flottante, ses règles `pos-*`, et restait
   dans le flux. Pire, `bottom`/`right` appliqués à une boîte relative la
   DÉCALENT au lieu de la placer : mesuré `x = -18` sur bureau et `x = -12` sur
   téléphone, c'est-à-dire un sélecteur amputé sur le bord gauche de l'écran, sur
   tous les sites qui ont choisi ce design.

   Et c'est celui que la console recommande dès qu'il y a plus de cinq langues.

   ON NE DÉPLACE PAS LA RÈGLE, ON LA REND PLUS SPÉCIFIQUE. Compter sur l'ordre du
   fichier remettrait le même piège au premier style ajouté après ce bloc. Le
   sélecteur d'attribut `[data-style]` porte la règle à (0,3,0) : elle l'emporte
   sur toute règle propre à un design, quelle que soit sa position.

   `position: fixed` établit un bloc conteneur pour les descendants absolus, tout
   comme `relative` : le panneau du `dropdown` continue de se placer sous son
   bouton. Vérifié au navigateur. */
.gmlt-sw.is-float,
.gmlt-sw.is-float[data-style] {
  position: fixed;
  z-index: var(--sw-z);
}

.gmlt-sw.pos-bottom-right { bottom: calc(var(--sw-inset) + env(safe-area-inset-bottom, 0px)); right: calc(var(--sw-inset) + env(safe-area-inset-right, 0px)); }
.gmlt-sw.pos-bottom-left  { bottom: calc(var(--sw-inset) + env(safe-area-inset-bottom, 0px)); left: calc(var(--sw-inset) + env(safe-area-inset-left, 0px)); }
.gmlt-sw.pos-top-right    { top: calc(var(--sw-inset) + env(safe-area-inset-top, 0px)); right: calc(var(--sw-inset) + env(safe-area-inset-right, 0px)); }
.gmlt-sw.pos-top-left     { top: calc(var(--sw-inset) + env(safe-area-inset-top, 0px)); left: calc(var(--sw-inset) + env(safe-area-inset-left, 0px)); }

.gmlt-sw.pos-bottom-center {
  bottom: calc(var(--sw-inset) + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
}

/* La barre d'administration de WordPress fait 32 px (46 px en dessous de 783 px)
   et se superpose au composant placé en haut. Sans ce décalage, l'administrateur
   connecté voit son propre sélecteur à moitié caché — et croit à un bug. */
.admin-bar .gmlt-sw.pos-top-right,
.admin-bar .gmlt-sw.pos-top-left { top: calc(var(--sw-inset) + 32px); }

@media (max-width: 782px) {
  .admin-bar .gmlt-sw.pos-top-right,
  .admin-bar .gmlt-sw.pos-top-left { top: calc(var(--sw-inset) + 46px); }
}

/* ----------------------------------------------------------------- 4. minimal */

.gmlt-sw .gmlt-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* VIS-08 — `.62` D'OPACITÉ SUR UNE COULEUR DÉJÀ ATTÉNUÉE, ET C'EST UN DÉFAUT DE
   LISIBILITÉ SUR LE SITE DU CLIENT, PAS SEULEMENT DANS L'APERÇU.
   `--sw-text-2` est déjà un gris de second plan ; le multiplier par .62 amenait les
   langues non actives sous le seuil de contraste que réclame WCAG pour du texte —
   or ce sont les seuls liens qui mènent aux versions traduites. `.82` conserve
   entièrement la hiérarchie (l'active reste à 1, en gras, soulignée) et rend les
   autres franchement lisibles.

   Le soulignement passe à 2px : à 1.5px et à l'échelle réduite de la vignette, il
   se lisait comme un filet parasite plutôt que comme la marque de la langue
   courante — c'est le « truc bizarre » signalé par le client. */
/* .82 était encore une atténuation de trop PAR-DESSUS un ton déjà secondaire :
   mesuré 4,41 en clair, sous le seuil. .88 donne 5,08, et la hiérarchie ne
   reposait de toute façon pas sur ce dixième — l'active est à 1, en gras, et
   soulignée. */
.gmlt-sw[data-style="minimal"] .gmlt-i {
  color: var(--sw-text-2);
  opacity: .88;
  padding: 2px 1px;
  border-bottom: 2px solid transparent;
  transition: opacity .18s, color .18s, border-color .18s;
}

.gmlt-sw[data-style="minimal"] .gmlt-i:hover { opacity: 1; color: var(--sw-text); }

.gmlt-sw[data-style="minimal"] .gmlt-i.is-active {
  opacity: 1;
  color: var(--sw-text);
  font-weight: 600;
  border-bottom-color: var(--brand);
}

.gmlt-sw[data-style="minimal"] .gmlt-sep {
  /* UN TON DÉJÀ SECONDAIRE, MULTIPLIÉ PAR UNE OPACITÉ : mesuré 1,57 sur blanc et
     2,00 en sombre, c'est-à-dire un séparateur qu'on ne voit pas. Il échouait donc
     à la seule chose qu'on lui demande — séparer. Troisième fois que ce motif
     apparaît dans cet audit : on n'atténue qu'une fois — ici, plus du tout.

     À .85 il remontait à 4,00 et 3,89, donc toujours courts. On aurait pu plaider
     l'exemption « décoratif » de la règle : un point médian entre deux liens ne
     porte aucune information. Plaider une exemption pour garder un défaut n'est
     pas la même chose que ne pas avoir de défaut, et ça ne coûtait rien de le
     corriger. Sans opacité : 5,52 en clair, 4,88 en sombre. Il reste plus discret
     que les langues qu'il sépare, qui portent `--sw-text-2` et `--sw-text`. */
  color: var(--sw-text-3);
  user-select: none;
}

/* Flottant, `minimal` a quand même besoin d'un fond : posé sur une photo, du
   texte nu serait illisible. */
.gmlt-sw[data-style="minimal"].is-float {
  background: var(--sw-bg);
  border: 1px solid var(--sw-border);
  border-radius: 999px;
  padding: 9px 15px;
  box-shadow: var(--sw-shadow);
}

/* -------------------------------------------------------------------- 5. pill */

/* Quatre langues aux noms complets — « Français English Español Deutsch » —
   dépassent 390 px de large : la page entière se mettait à défiler
   horizontalement sur téléphone, symptôme que tout le monde remarque et que
   personne n'attribue au sélecteur.
   Le défilement est donc confiné ICI, sur la racine. La piste, elle, garde sa
   largeur intrinsèque : c'est indispensable, car le curseur se positionne en
   pourcentage de la piste — la rendre défilante fausserait son calcul. */
/* ── CE QUI TIENT À 30 LANGUES, ET CE QUI NE TIENT PAS ──────────────────────
   Mesuré le 07/08/2026, page de 1180 px, noms natifs, de 2 à 30 langues :

     dropdown · globe · aurora   taille CONSTANTE — un bouton, un panneau
     codes · minimal · flags     passent à la ligne (h 20 → 76)
     pill                        défile EN INTERNE, la page ne bouge pas
     underline · prism           LA PAGE DÉBORDAIT de 1915 et 2036 px

   Les deux derniers poussaient une barre de défilement horizontale sur TOUTE la
   page du client — pas sur le composant, sur la page. C'est un défaut quoi qu'en
   dise la console, et il commençait dès 12 langues (+10 et +68 px).

   On leur donne le traitement de `pill`, déjà éprouvé ici : le débordement reste
   À L'INTÉRIEUR du composant. Toutes les langues restent atteignables — un
   plafonnement en aurait rendu certaines inaccessibles, ce qui est pire qu'une
   barre de défilement. */
.gmlt-sw[data-style="underline"],
.gmlt-sw[data-style="prism"] {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.gmlt-sw[data-style="underline"]::-webkit-scrollbar,
.gmlt-sw[data-style="prism"]::-webkit-scrollbar { display: none; }

.gmlt-sw[data-style="pill"] {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* De la place pour le halo du curseur, qu'un conteneur défilant rognerait. */
  padding: 3px;
  margin: -3px;
  scrollbar-width: none;
}

.gmlt-sw[data-style="pill"]::-webkit-scrollbar { display: none; }

.gmlt-sw[data-style="pill"] .gmlt-seg {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  padding: 4px;
  background: var(--sw-bg-2);
  border: 1px solid var(--sw-border);
  border-radius: 999px;
  box-shadow: var(--sw-shadow);
  isolation: isolate;
}

/* Le curseur. Sa largeur vaut 1/n de la piste et sa position vient de l'index
   actif, tous deux écrits par PHP dans `--gmlt-n` / `--gmlt-active` : le
   composant est donc juste dès le premier octet de HTML, sans attendre le
   moindre script. */
.gmlt-sw[data-style="pill"] .gmlt-thumb {
  position: absolute;
  z-index: -1;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / var(--gmlt-n, 2));
  transform: translateX(calc(100% * var(--gmlt-active, 0)));
  background: var(--grad);
  border-radius: 999px;
  box-shadow: var(--sw-glow);
  transition: transform .32s cubic-bezier(.34, 1.4, .5, 1);
}

.gmlt-sw[data-style="pill"] .gmlt-i {
  justify-content: center;
  flex: 1 1 0;
  min-width: 0;
  padding: 8px 14px;
  border-radius: 999px;
  color: var(--sw-text-2);
  font-weight: 500;
  transition: color .2s;
}

.gmlt-sw[data-style="pill"] .gmlt-i:hover { color: var(--sw-text); }

/* CE COMMENTAIRE DISAIT L'INVERSE DE LA MESURE, ET LE CODE LE SUIVAIT.
   Il affirmait que le blanc était « le seul couple qui tienne le contraste sur
   toute la longueur du dégradé ». Mesuré sur les pixels réellement affichés,
   c'est le contraire : le blanc donne 4,30 sur le bleu et 1,81 sur le cyan — la
   pastille active du sélecteur, celle que voit le VISITEUR du site client, était
   sous le seuil sur toute sa moitié droite. L'encre fait 10,5 sur ce même cyan.
   On garde donc le dégradé de la marque intact et on retourne l'étiquette. */
.gmlt-sw[data-style="pill"] .gmlt-i.is-active {
  color: #0B1020;
  font-weight: 600;
}

.gmlt-sw[data-style="pill"] .gmlt-i.is-active .gmlt-code { color: rgba(11, 16, 32, .78); }
.gmlt-sw[data-style="pill"] .gmlt-i.is-active .gmlt-flag { box-shadow: 0 0 0 1px rgba(11, 16, 32, .45); }

/* ---------------------------------------------------------------- 6. dropdown */

.gmlt-sw[data-style="dropdown"] { position: relative; display: inline-block; }

.gmlt-sw[data-style="dropdown"] .gmlt-btn {
  padding: 9px 13px;
  background: var(--sw-bg);
  border: 1px solid var(--sw-border-2);
  border-radius: var(--sw-radius);
  color: var(--sw-text);
  font-weight: 500;
  box-shadow: var(--sw-shadow);
  transition: border-color .18s, transform .18s, box-shadow .2s;
}

.gmlt-sw[data-style="dropdown"] .gmlt-btn:hover {
  border-color: var(--brand);
  transform: translateY(-1px);
}

.gmlt-sw[data-style="dropdown"] .gmlt-panel {
  position: absolute;
  z-index: 2;
  top: calc(100% + 8px);
  left: 0;
  min-width: 100%;
  width: max-content;
  max-width: min(280px, calc(100vw - 32px));
  /* La liste défile au-delà d'une dizaine de langues. Sans plafond, trente
     langues produisent un panneau plus haut que l'écran, dont le bas est
     inatteignable. */
  max-height: min(60vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
  background: var(--sw-bg);
  border: 1px solid var(--sw-border);
  border-radius: 14px;
  box-shadow: var(--sw-shadow-lg);
  animation: gmlt-pop .18s cubic-bezier(.2, .9, .3, 1);
}

/* Le panneau s'ouvre du côté où il y a la place. Sans ces règles, un sélecteur
   posé en bas de page ouvrirait vers le bas, hors de l'écran. */
.gmlt-sw[data-style="dropdown"].pos-bottom-right .gmlt-panel,
.gmlt-sw[data-style="dropdown"].pos-bottom-left .gmlt-panel,
.gmlt-sw[data-style="dropdown"].pos-bottom-center .gmlt-panel {
  top: auto;
  bottom: calc(100% + 8px);
  animation-name: gmlt-pop-up;
}

.gmlt-sw[data-style="dropdown"].pos-bottom-right .gmlt-panel,
.gmlt-sw[data-style="dropdown"].pos-top-right .gmlt-panel { left: auto; right: 0; }

.gmlt-sw[data-style="dropdown"] .gmlt-opt {
  width: 100%;
  padding: 9px 10px;
  border-radius: 9px;
  color: var(--sw-text-2);
  transition: background .15s, color .15s;
}

.gmlt-sw[data-style="dropdown"] .gmlt-opt:hover,
.gmlt-sw[data-style="dropdown"] .gmlt-opt:focus-visible {
  background: var(--sw-bg-2);
  color: var(--sw-text);
}

.gmlt-sw[data-style="dropdown"] .gmlt-opt.is-active { color: var(--sw-text); font-weight: 600; }

.gmlt-sw[data-style="dropdown"] .gmlt-opt .gmlt-lab {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gmlt-sw[data-style="dropdown"] .gmlt-opt .gmlt-flag { width: 1.5em; height: 1em; }

.gmlt-sw[data-style="dropdown"] .gmlt-opt.is-active .gmlt-check {
  display: block;
  width: .95em;
  height: .95em;
  color: var(--brand);
}

@keyframes gmlt-pop {
  from { opacity: 0; transform: translateY(-6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

@keyframes gmlt-pop-up {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------- 7. flags */

.gmlt-sw[data-style="flags"] .gmlt-chips { gap: 7px; }

.gmlt-sw[data-style="flags"] .gmlt-chip {
  padding: 5px;
  border-radius: 9px;
  border: 1px solid transparent;
  background: transparent;
  transition: transform .18s cubic-bezier(.34, 1.4, .5, 1), border-color .18s, background .18s;
}

.gmlt-sw[data-style="flags"] .gmlt-chip .gmlt-flag {
  width: 1.9em;
  height: 1.27em;
  border-radius: 4px;
  /* Les langues non actives sont légèrement retirées : sans cela, six drapeaux
     saturés se disputent l'attention et l'on ne voit plus lequel est en cours. */
  filter: saturate(.62);
  opacity: .78;
  transition: filter .18s, opacity .18s;
}

.gmlt-sw[data-style="flags"] .gmlt-chip:hover { transform: translateY(-2px); background: var(--sw-bg-2); }
.gmlt-sw[data-style="flags"] .gmlt-chip:hover .gmlt-flag { filter: none; opacity: 1; }

.gmlt-sw[data-style="flags"] .gmlt-chip.is-active {
  background: var(--grad);
  box-shadow: var(--sw-glow);
}

.gmlt-sw[data-style="flags"] .gmlt-chip.is-active .gmlt-flag {
  filter: none;
  opacity: 1;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .6);
}

.gmlt-sw[data-style="flags"].is-float {
  background: var(--sw-bg);
  border: 1px solid var(--sw-border);
  border-radius: 14px;
  padding: 6px;
  box-shadow: var(--sw-shadow);
}

/* ------------------------------------------------------------------- 8. globe */

.gmlt-sw[data-style="globe"] {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 10px;
}

.gmlt-sw[data-style="globe"].pos-top-right,
.gmlt-sw[data-style="globe"].pos-top-left { flex-direction: column; }

.gmlt-sw[data-style="globe"] .gmlt-fab {
  position: relative;
  justify-content: center;
  width: 54px;
  height: 54px;
  padding: 0;
  border-radius: 50%;
  background: var(--grad);
  color: #FFFFFF;
  box-shadow: var(--sw-glow);
  transition: transform .22s cubic-bezier(.34, 1.4, .5, 1);
}

.gmlt-sw[data-style="globe"] .gmlt-fab:hover { transform: scale(1.06); }
.gmlt-sw[data-style="globe"] .gmlt-fab:active { transform: scale(.96); }
.gmlt-sw[data-style="globe"] .gmlt-fab .gmlt-ic { width: 21px; height: 21px; }

/* Le code de la langue en cours, en pastille sur le bouton : on sait dans
   quelle langue on est SANS avoir à ouvrir. */
.gmlt-sw[data-style="globe"] .gmlt-fab-code {
  position: absolute;
  right: -3px;
  bottom: -3px;
  min-width: 22px;
  padding: 3px 5px;
  border-radius: 999px;
  background: var(--sw-bg);
  color: var(--brand-strong);
  border: 1.5px solid var(--sw-bg);
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-align: center;
  box-shadow: var(--sw-shadow);
}

/* Halo qui pulse doucement : assez pour attirer l'œil une fois, pas assez pour
   gêner la lecture. Sur `transform` et `opacity` seulement, donc sans
   repeinture. */
.gmlt-sw[data-style="globe"] .gmlt-fab-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--grad);
  opacity: .45;
  animation: gmlt-pulse 2.8s cubic-bezier(.4, 0, .2, 1) infinite;
  pointer-events: none;
}

@keyframes gmlt-pulse {
  0%        { transform: scale(1);    opacity: .45; }
  70%, 100% { transform: scale(1.75); opacity: 0; }
}

.gmlt-sw[data-style="globe"] .gmlt-orbit {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 8px;
}

.gmlt-sw[data-style="globe"].pos-top-right .gmlt-orbit,
.gmlt-sw[data-style="globe"].pos-top-left .gmlt-orbit { flex-direction: column; }

.gmlt-sw[data-style="globe"] .gmlt-orb {
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border-radius: 50%;
  background: var(--sw-bg);
  border: 1px solid var(--sw-border);
  box-shadow: var(--sw-shadow);
  /* Chaque pastille entre avec son propre retard (`--gmlt-d`, écrit par PHP) :
     l'œil suit le déploiement au lieu de subir six apparitions simultanées. */
  animation: gmlt-rise .34s cubic-bezier(.34, 1.4, .5, 1) both;
  animation-delay: var(--gmlt-d, 0ms);
  transition: transform .18s cubic-bezier(.34, 1.4, .5, 1), border-color .18s;
}

.gmlt-sw[data-style="globe"] .gmlt-orb:hover { transform: scale(1.1); border-color: var(--brand); }
.gmlt-sw[data-style="globe"] .gmlt-orb .gmlt-flag { width: 1.7em; height: 1.14em; border-radius: 3px; }

.gmlt-sw[data-style="globe"] .gmlt-orb.is-active {
  border-color: transparent;
  background: var(--grad);
  box-shadow: var(--sw-glow);
}

@keyframes gmlt-rise {
  from { opacity: 0; transform: translateY(14px) scale(.5); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ 9. aurora */

.gmlt-sw[data-style="aurora"] {
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 12px;
}

.gmlt-sw[data-style="aurora"].pos-top-right,
.gmlt-sw[data-style="aurora"].pos-top-left { flex-direction: column; }
.gmlt-sw[data-style="aurora"].pos-bottom-left,
.gmlt-sw[data-style="aurora"].pos-top-left { align-items: flex-start; }
.gmlt-sw[data-style="aurora"].pos-bottom-center { align-items: center; }

.gmlt-sw[data-style="aurora"] .gmlt-cap {
  position: relative;
  padding: 0;
  border-radius: 999px;
  overflow: hidden;
  isolation: isolate;
  box-shadow: var(--sw-glow), 0 0 0 1px rgba(255, 255, 255, .16) inset;
  transition: transform .22s cubic-bezier(.34, 1.4, .5, 1), box-shadow .25s;
}

.gmlt-sw[data-style="aurora"] .gmlt-cap:hover { transform: translateY(-2px) scale(1.02); }
.gmlt-sw[data-style="aurora"] .gmlt-cap:active { transform: scale(.98); }

/* L'AURORE.
   Une seule couche, un dégradé conique, animée par `rotate` — donc composée par
   le processeur graphique, sans repeinture ni recalcul de mise en page. La
   version évidente (`background-position` animé) repeint la surface à chaque
   image : sur un téléphone d'entrée de gamme, elle fait tomber la page à trente
   images par seconde. Une aurore qui fait ramer le site serait un très mauvais
   argument de vente. */
.gmlt-sw[data-style="aurora"] .gmlt-aurora {
  position: absolute;
  z-index: -1;
  /* Plus large que la capsule : en tournant, un carré doit couvrir le rectangle
     à tout instant, sinon les coins se vident à 45°. */
  inset: -60%;
  background: conic-gradient(from 0deg, #4F6BFF, #22D3EE, #8B5CF6, #4F6BFF);
  animation: gmlt-spin 7s linear infinite;
  will-change: transform;
}

@keyframes gmlt-spin {
  to { transform: rotate(1turn); }
}

.gmlt-sw[data-style="aurora"] .gmlt-cap-in {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 17px;
  color: #FFFFFF;
  font-weight: 600;
  /* Voile sombre translucide : l'aurore reste visible dessous, mais le texte
     blanc garde son contraste quand le cyan clair passe derrière. Sans lui, le
     libellé disparaît une seconde toutes les sept. */
  background: rgba(11, 16, 32, .40);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.gmlt-sw[data-style="aurora"] .gmlt-cap-in .gmlt-flag {
  width: 1.5em;
  height: 1em;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .5);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-card {
  width: min(300px, calc(100vw - 32px));
  padding: 8px;
  background: var(--sw-bg);
  border: 1px solid var(--sw-border);
  border-radius: 18px;
  box-shadow: var(--sw-shadow-lg);
  animation: gmlt-card .26s cubic-bezier(.2, .9, .3, 1);
  transform-origin: bottom right;
}

.gmlt-sw[data-style="aurora"].pos-bottom-left .gmlt-au-card,
.gmlt-sw[data-style="aurora"].pos-top-left .gmlt-au-card { transform-origin: bottom left; }
.gmlt-sw[data-style="aurora"].pos-top-right .gmlt-au-card { transform-origin: top right; }
.gmlt-sw[data-style="aurora"].pos-top-left .gmlt-au-card { transform-origin: top left; }

@keyframes gmlt-card {
  from { opacity: 0; transform: scale(.9) translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.gmlt-sw[data-style="aurora"] .gmlt-au-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px 10px;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-title {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sw-text-3);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-count {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--sw-bg-2);
  color: var(--sw-text-3);
  font-size: .68rem;
  font-weight: 600;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 2px 8px;
  padding: 9px 11px;
  background: var(--sw-bg-2);
  border: 1px solid var(--sw-border);
  border-radius: 11px;
  color: var(--sw-text-3);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-search:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--sw-ring);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: none;
  color: var(--sw-text);
  font-size: .86rem;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-input::-webkit-search-cancel-button { -webkit-appearance: none; }

.gmlt-sw[data-style="aurora"] .gmlt-au-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: min(52vh, 300px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-item {
  padding: 9px 10px;
  border-radius: 10px;
  color: var(--sw-text-2);
  animation: gmlt-slide .3s cubic-bezier(.2, .9, .3, 1) both;
  animation-delay: var(--gmlt-d, 0ms);
  transition: background .15s, color .15s, transform .15s;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-item:hover,
.gmlt-sw[data-style="aurora"] .gmlt-au-item:focus-visible {
  background: var(--sw-bg-2);
  color: var(--sw-text);
  transform: translateX(2px);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-item .gmlt-lab {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gmlt-sw[data-style="aurora"] .gmlt-au-item .gmlt-flag { width: 1.5em; height: 1em; }

.gmlt-sw[data-style="aurora"] .gmlt-au-item.is-active {
  color: var(--sw-text);
  font-weight: 600;
  background: linear-gradient(100deg, rgba(79, 107, 255, .13), rgba(34, 211, 238, .13));
}

.gmlt-sw[data-style="aurora"] .gmlt-au-item.is-active .gmlt-check {
  display: block;
  width: .95em;
  height: .95em;
  color: var(--brand);
}

@keyframes gmlt-slide {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: none; }
}

.gmlt-sw[data-style="aurora"] .gmlt-au-empty,
.gmlt-sw[data-style="aurora"] .gmlt-au-foot {
  text-align: center;
  font-size: .68rem;
  color: var(--sw-text-3);
}

.gmlt-sw[data-style="aurora"] .gmlt-au-empty { padding: 16px 10px; }

.gmlt-sw[data-style="aurora"] .gmlt-au-foot {
  margin-top: 6px;
  padding: 9px 10px 4px;
  border-top: 1px solid var(--sw-border);
  letter-spacing: .04em;
}

/* ------------------------------------------------------------------ 9b. codes */

/* `EN FR ES`, et rien d'autre. Le style le plus discret du catalogue : ni fond,
   ni bordure, ni ombre. Il occupe la place de trois mots.

   LES CODES SONT ESPACÉS, PAS SÉPARÉS. Un `·` entre eux aurait ajouté un
   troisième ton à gérer — c'est exactement ce que `minimal` a payé deux fois
   (VIS-08, puis SW-01 sur `.gmlt-sep`, mesuré à 1,57). L'espace suffit à séparer
   trois jetons de deux lettres ; il ne peut pas être sous le seuil de contraste,
   puisqu'il n'a pas de couleur. */
.gmlt-sw[data-style="codes"] .gmlt-codes { gap: 4px; }

.gmlt-sw[data-style="codes"] .gmlt-cc {
  padding: 4px 6px;
  border-radius: 6px;
  color: var(--sw-text-2);
  font-size: .8125em;
  font-weight: 600;
  /* Le chasse en majuscules : deux lettres serrées se lisent comme un mot, pas
     comme un code. */
  letter-spacing: .07em;
  transition: color .18s, background-color .18s;
}

.gmlt-sw[data-style="codes"] .gmlt-cc:hover { color: var(--sw-text); }

.gmlt-sw[data-style="codes"] .gmlt-cc.is-active {
  color: var(--brand-strong);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}

/* REPLI POUR LES NAVIGATEURS SANS `color-mix()` — Safari 15 et Firefox ESR 102,
   encore servis. Sans lui, `background` reste invalide et l'active ne se
   distingue QUE par sa couleur de texte : c'est une distinction par la couleur
   seule, ce que WCAG 1.4.1 refuse, et le style perd sa seule indication d'état.
   La déclaration ci-dessus, plus loin dans la cascade, gagne là où elle est
   comprise. */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
  .gmlt-sw[data-style="codes"] .gmlt-cc.is-active {
    background: var(--sw-bg-2);
    box-shadow: inset 0 0 0 1px var(--sw-border-2);
  }
}

/* --------------------------------------------------------------- 9c. underline */

/* Les noms côte à côte, un trait de marque qui glisse sous l'actif. */
.gmlt-sw[data-style="underline"] .gmlt-ul {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  padding-bottom: 4px;
}

.gmlt-sw[data-style="underline"] .gmlt-i {
  justify-content: center;
  flex: 1 1 0;
  min-width: 0;
  padding: 6px 12px;
  color: var(--sw-text-2);
  font-weight: 500;
  transition: color .2s;
}

.gmlt-sw[data-style="underline"] .gmlt-i:hover { color: var(--sw-text); }
.gmlt-sw[data-style="underline"] .gmlt-i.is-active { color: var(--sw-text); font-weight: 600; }

/* LE TRAIT REPREND LE CALCUL DU CURSEUR DE `pill`, à l'identique : largeur
   `100% / n`, décalage `100% × index`, tous deux écrits par PHP dans
   `--gmlt-n` / `--gmlt-active`. Le composant est donc juste dès le premier octet
   de HTML, sans attendre le moindre script — et si ce calcul se révèle faux un
   jour, il est faux au même endroit pour les deux styles. Une seconde formule
   aurait été une seconde chose à corriger, et une seule des deux l'aurait été. */
.gmlt-sw[data-style="underline"] .gmlt-bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: calc(100% / var(--gmlt-n, 2));
  transform: translateX(calc(100% * var(--gmlt-active, 0)));
  background: var(--grad);
  border-radius: 2px;
  transition: transform .32s cubic-bezier(.34, 1.4, .5, 1);
}

/* ------------------------------------------------------------------ 9d. prism */

/* La pièce de démonstration posée AU FIL DU TEXTE — là où `aurora` est toujours
   flottante. Un contour irisé qui tourne lentement autour d'une capsule sobre.

   POURQUOI UN `@property` ET PAS UNE ANIMATION DE `background`. Un dégradé n'est
   pas une valeur interpolable : animer `background` le fait SAUTER d'une image
   clé à l'autre. En déclarant l'angle comme une propriété typée `<angle>`, c'est
   un NOMBRE qui s'anime, et le dégradé se recalcule à chaque image, en douceur.

   Surtout, c'est la seule chose qui bouge. Pas de `box-shadow` animée, pas de
   `filter`, aucune propriété qui déclenche une mise en page : le composant ne
   coûte rien au défilement de la page du client. Une animation de sélecteur de
   langue qui fait tomber les images par seconde d'un site marchand serait un
   défaut vendu comme une fonctionnalité. */
@property --gmlt-ang {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.gmlt-sw[data-style="prism"] .gmlt-prism {
  position: relative;
  display: inline-flex;
  padding: 2px;
  border-radius: 999px;
  isolation: isolate;
}

.gmlt-sw[data-style="prism"] .gmlt-prism-ring {
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  background: conic-gradient(from var(--gmlt-ang),
    var(--g1), var(--brand-strong), #22D3EE, var(--g2), var(--g1));
  animation: gmlt-prism-spin 7s linear infinite;
}

@keyframes gmlt-prism-spin { to { --gmlt-ang: 360deg; } }

/*
 * REPLI QUAND `@property` N'EST PAS CONNU — Firefox l'a acquis en 128, et l'ESR
 * en service ne l'a pas. Là-bas `--gmlt-ang` reste une chaîne, `conic-gradient`
 * la refuse, et le contour DISPARAÎT : la capsule perdrait son seul trait
 * distinctif et se confondrait avec `pill`.
 *
 * On sert donc un dégradé linéaire fixe, sans animation. Le style reste
 * reconnaissable et immobile, ce qui est très exactement ce que voit déjà un
 * visiteur ayant demandé moins d'animation.
 */
@supports not (background: conic-gradient(from var(--gmlt-ang), red, blue)) {
  .gmlt-sw[data-style="prism"] .gmlt-prism-ring {
    background: var(--grad);
    animation: none;
  }
}

.gmlt-sw[data-style="prism"] .gmlt-prism-in {
  display: inline-flex;
  align-items: stretch;
  padding: 3px;
  background: var(--sw-bg);
  border-radius: 999px;
}

.gmlt-sw[data-style="prism"] .gmlt-i {
  justify-content: center;
  padding: 7px 14px;
  border-radius: 999px;
  color: var(--sw-text-2);
  font-weight: 500;
  transition: color .2s, background-color .2s;
}

.gmlt-sw[data-style="prism"] .gmlt-i:hover { color: var(--sw-text); }

.gmlt-sw[data-style="prism"] .gmlt-i.is-active {
  color: var(--sw-text);
  background: var(--sw-bg-2);
  font-weight: 600;
}

/* ------------------------------------- 10. accessibilité et cas particuliers */

/* Un anneau visible AU CLAVIER seulement. `:focus-visible` et non `:focus` :
   sinon chaque clic à la souris laisse un anneau, que les thèmes finissent par
   supprimer globalement — et le composant devient inutilisable au clavier. */
.gmlt-sw a:focus-visible,
.gmlt-sw button:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* Cible tactile : 44 px est le minimum recommandé. Les styles compacts
   l'atteignent par un pseudo-élément, sans grossir visuellement. */
@media (pointer: coarse) {
  .gmlt-sw[data-style="minimal"] .gmlt-i,
  .gmlt-sw[data-style="flags"] .gmlt-chip { position: relative; }

  .gmlt-sw[data-style="minimal"] .gmlt-i::after,
  .gmlt-sw[data-style="flags"] .gmlt-chip::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* Mouvement réduit : on ne supprime pas les transitions, on les rend
   instantanées. Supprimer `transition` ferait SAUTER le curseur du style
   `pill` ; le mettre à 1 ms le fait simplement arriver tout de suite. */
@media (prefers-reduced-motion: reduce) {
  .gmlt-sw *,
  .gmlt-sw *::before,
  .gmlt-sw *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }

  /* L'aurore tournerait à 1 ms par tour : stroboscope. On l'arrête net et on
     garde le dégradé, qui reste beau immobile. */
  .gmlt-sw .gmlt-aurora { animation: none !important; transform: rotate(35deg); }

  /* Même raison pour le contour de `prism` : la règle générique ci-dessus le
     ramènerait à 1 ms par tour, c'est-à-dire à un scintillement — pire que
     l'animation d'origine pour qui a demandé moins de mouvement. On l'arrête, et
     le dégradé conique reste, figé sur son angle initial. */
  .gmlt-sw .gmlt-prism-ring { animation: none !important; }
  .gmlt-sw .gmlt-fab-ring { display: none; }
}

/* Contraste renforcé : bordures nettes, pas de transparence décorative. */
@media (prefers-contrast: more) {
  .gmlt-sw .gmlt-btn,
  .gmlt-sw .gmlt-panel,
  .gmlt-sw .gmlt-au-card,
  .gmlt-sw .gmlt-seg { border-color: var(--sw-text-2); }

  .gmlt-sw[data-style="flags"] .gmlt-chip .gmlt-flag { filter: none; opacity: 1; }
  .gmlt-sw[data-style="aurora"] .gmlt-cap-in { background: rgba(11, 16, 32, .72); }
}

/* Sur papier, un sélecteur de langue ne veut rien dire. */
@media print { .gmlt-sw.is-float { display: none; } }

/* Sens d'écriture. Un site en arabe ou en hébreu inverse sa mise en page ; le
   composant doit suivre, sinon il se retrouve du mauvais côté de l'écran. */
[dir="rtl"] .gmlt-sw[data-style="pill"] .gmlt-thumb {
  left: auto;
  right: 4px;
  transform: translateX(calc(-100% * var(--gmlt-active, 0)));
}

[dir="rtl"] .gmlt-sw[data-style="aurora"] .gmlt-au-item:hover { transform: translateX(-2px); }

/* Petit écran : les composants au fil du texte reviennent à la ligne, les
   flottants se resserrent contre le bord. */
@media (max-width: 480px) {
  .gmlt-sw { --sw-inset: 12px; }
  .gmlt-sw[data-style="pill"] .gmlt-i { padding: 8px 10px; }
  .gmlt-sw[data-style="globe"] .gmlt-fab { width: 50px; height: 50px; }
}
