/* ============================================================================
   ÉLÉMENT « bouton » — la pièce la plus posée de tous nos sites.
   ----------------------------------------------------------------------------
   PRIX : 3,5 Ko minifiés, 1,2 Ko livrés sur le réseau (gzip), mesurés le
   16/09/2026. Zéro JavaScript, zéro dépendance, zéro image.
   COÛT MACHINE : nul au repos. Au survol, une transformation et une opacité,
   toutes deux composées par le GPU : jamais de `width` ni de `left` animés.
   REPLI : c'est du CSS seul. Sans JavaScript, tout fonctionne. Sous
   `prefers-reduced-motion`, les mouvements tombent, les changements de couleur
   restent (un bouton doit toujours répondre à la main).
   LA FAUTE QU'IL ÉVITE : chaque site du parc réécrivait ses boutons, avec ses
   couleurs en dur et son propre focus, souvent absent. Le catalogue le notait
   « ○ réécrits partout ».

   RELEVÉ, PAS INVENTÉ. Le geste de la pastille qui s'étend et de la flèche qui
   avance vient de `mines/uiverse/Buttons-0x-Sarthak` (MIT). Chez lui, la pièce
   porte #552da8, Montserrat, 50px de rayon et 18px de texte : posée chez un
   couvreur, elle reste violette. Ici, elle ne décide plus rien.

   TROIS NIVEAUX DE PERSONNALISATION, et c'est tout l'objet du fichier :
     1. LA MARQUE   couleurs, polices, rayons, durées : tout vient de tokens.css,
                    donc du JSON de charte du client. Rien n'est écrit en dur.
     2. LA FORME    les réglages `--btn-*` ci-dessous. On les pose UNE fois par
                    client (dans sa feuille) et toute la pièce change d'allure :
                    un artisan veut des angles droits et aucun mouvement, un
                    restaurant veut des pilules et une pastille qui glisse.
     3. L'USAGE     les classes de ton, de taille et de largeur, posées bouton
                    par bouton dans la page.
   ========================================================================== */

:root {
  /* ---- Les réglages de FORME. À écraser par client, jamais dans les pages.
     ATTENTION, PIÈGE PAYÉ LE 16/09/2026 : une variable déclarée ICI qui référence
     une autre variable est résolue ICI, une fois pour toutes. `--btn-fond:
     var(--accent)` posé sur `:root` gelait le bleu de Forge, et le panneau d'un
     autre client redéfinissant `--accent` restait bleu. Donc ce bloc ne contient
     que des valeurs LITTÉRALES ; tout ce qui pointe vers la charte est résolu au
     point d'usage, plus bas, où la charte locale est visible. */
  --btn-hauteur: 46px;                    /* la hauteur de frappe au doigt */
  --btn-espace-x: 22px;                   /* le blanc à gauche et à droite */
  --btn-graisse: 500;
  --btn-casse: none;                      /* `uppercase` pour une marque sèche */
  --btn-tracking: 0;
  --btn-mouvement: 1;                     /* 0 = rien ne bouge, 1 = normal */
  --btn-course: 2px;                      /* de combien il se soulève */
  --btn-trait: 1px;                       /* l'épaisseur du filet des variantes */
}

/* Les crochets de COULEUR ne sont pas déclarés ici : `--btn-fond`, `--btn-texte`
   et `--btn-fond-survol` s'écrivent sur le client QUAND on veut sortir de la
   charte, et sinon la pièce lit `--accent` là où elle est posée. On s'en sert
   quand une charte ne tient pas le contraste dans un mode : mesuré le
   16/09/2026, le blanc sur `--accent` en mode sombre (#5E6AFF) donne 4,22:1,
   sous la limite de 4,5, alors que `--accent-haut` (#5462FF, déjà dans la
   charte) donne 4,60. La pièce ne choisit pas, elle rend le choix possible. */

/* ---------------------------------------------------------------- la base */
.btn {
  /* `inline-flex` pour que l'icône et le texte restent alignés quelle que
     soit la hauteur, et `isolation` pour que la pastille reste dessous. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  isolation: isolate;
  position: relative;
  overflow: hidden;
  min-height: var(--btn-hauteur);
  padding: 0 var(--btn-espace-x);
  border: var(--btn-trait) solid transparent;
  border-radius: var(--btn-rayon, var(--forme-rayon-controle, 10px));
  font-family: var(--typo-labeur-famille, system-ui), sans-serif;
  font-size: 15px;
  font-weight: var(--btn-graisse);
  /* 1,15 et non 1 : avec `overflow:hidden` et une casse en capitales, une
     interligne de 1 ROGNE LES ACCENTS. « VOIR LES RÉALISATIONS » s'affichait
     « REALISATIONS » sur la charte Terre et Création, le 16/09/2026. Un défaut
     qu'aucune bibliothèque anglophone ne peut voir. */
  line-height: 1.15;
  letter-spacing: var(--btn-tracking);
  text-transform: var(--btn-casse);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  background: var(--btn-fond, var(--accent, #4C59FF));
  color: var(--btn-texte, var(--accent-texte, #fff));
  --duree: var(--btn-duree, var(--mouvement-duree-court, .18s));
  --courbe: var(--btn-courbe, var(--mouvement-courbe, cubic-bezier(.22,.61,.36,1)));
  transition: transform var(--duree) var(--courbe),
              background-color var(--duree) var(--courbe),
              border-color var(--duree) var(--courbe),
              color var(--duree) var(--courbe);
}

/* Le clavier d'abord : un bouton qu'on ne voit pas au focus est cassé, et
   c'est le défaut que le parc répétait site après site. */
.btn:focus-visible {
  outline: 2px solid var(--accent, #4C59FF);
  outline-offset: 3px;
}

.btn:hover { background: var(--btn-fond-survol, var(--accent-haut, var(--accent, #4C59FF))); }
.btn:hover:not(:disabled) { transform: translateY(calc(var(--btn-course) * -1 * var(--btn-mouvement))); }
.btn:active:not(:disabled) { transform: translateY(0); }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}

/* ------------------------------------------------------------- les TONS */
/* Second : le même bouton, en creux. Il porte le trait de la charte. */
.btn--second {
  background: transparent;
  color: var(--texte, #0B0C10);
  border-color: var(--trait-fort, #818AB2);
}
.btn--second:hover {
  background: var(--surface, #FAFBFD);
  border-color: var(--texte, #0B0C10);
}

/* Fantôme : ni fond ni filet, pour les actions secondaires d'une barre. */
.btn--fantome {
  background: transparent;
  color: var(--texte-2, #616C9F);
}
.btn--fantome:hover {
  background: var(--surface, #FAFBFD);
  color: var(--texte, #0B0C10);
}

/* Lien : la même mécanique de focus, mais l'allure d'un lien de texte. */
.btn--lien {
  /* Pas de pastille ici, donc rien à rogner : on rend sa place aux accents. */
  overflow: visible;
  background: transparent;
  color: var(--accent, #4C59FF);
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 2px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.btn--lien:hover { background: transparent; color: var(--accent-bas, var(--accent, #4C59FF)); }

/* Danger : pour une suppression. La charte fournit sa couleur, pas la pièce. */
.btn--danger { background: var(--ko, #E06070); color: var(--ko-texte, #fff); }

/* ----------------------------------------------------------- les TAILLES */
.btn--compact { --btn-hauteur: 36px; --btn-espace-x: 14px; font-size: 13.5px; }
.btn--large   { --btn-hauteur: 56px; --btn-espace-x: 30px; font-size: 16.5px; }
.btn--plein   { display: flex; width: 100%; }

/* Icône seule : carré parfait, et le libellé reste lisible aux lecteurs
   d'écran par `aria-label`, jamais par un titre survolé. */
.btn--icone { padding: 0; width: var(--btn-hauteur); }
.btn svg { width: 1.1em; height: 1.1em; flex: none; }

/* -------------------------------------------------- le geste, en option */
/* La pastille qui s'étend et la flèche qui avance, relevées chez Uiverse.
   Elles s'ajoutent, elles ne sont jamais imposées : `.btn--glisse`. */
.btn--glisse::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--accent-bas, #3B46D9);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform calc(var(--duree, .18s) * 2.4) var(--courbe, ease);
}
.btn--glisse:hover::before { transform: scaleX(var(--btn-mouvement)); transform-origin: left center; }
.btn--glisse .fleche { transition: transform calc(var(--duree, .18s) * 2) var(--courbe, ease); }
.btn--glisse:hover .fleche { transform: translateX(calc(4px * var(--btn-mouvement))); }

/* ------------------------------------------------------------- l'attente */
/* `aria-busy` plutôt qu'une classe : l'information part aussi au lecteur
   d'écran, et le bouton garde sa largeur pour que la page ne saute pas. */
.btn[aria-busy="true"] { color: transparent; pointer-events: none; }
.btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  width: 1.05em;
  height: 1.05em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--btn-texte, var(--accent-texte, #fff));
  animation: btn-tourne .7s linear infinite;
}
.btn--second[aria-busy="true"]::after,
.btn--fantome[aria-busy="true"]::after { color: var(--texte, #0B0C10); }
@keyframes btn-tourne { to { transform: rotate(1turn); } }

/* --------------------------------------------------------- le mouvement */
/* Réglage de la charte à zéro : plus rien ne bouge, tout reste lisible. */
@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn--glisse::before,
  .btn--glisse .fleche { transition-duration: .01ms; }
  .btn:hover:not(:disabled) { transform: none; }
  .btn[aria-busy="true"]::after { animation-duration: 2.4s; }
}


/* ── CORRECTIF DU 16/09/2026, à remonter au socle ──────────────────────────
   `.btn--lien` se dessine sans hauteur : mesuré en production, 174 x 17 px sur
   iPhone, sous le minimum tactile de 44 px. Un lien qui déclenche la même
   action qu'un bouton se frappe comme un bouton. */
.btn--lien {
  min-height: 44px;
  padding-block: 0;
  align-items: center;
}
