/* ============================================================
   g00dtime Design System — Shared UI Components
   Dépend de: tokens.css + thème actif (/app/css/<theme>.css)
   Usage: .gt-btn, .gt-input, .gt-card, .gt-tabs, .gt-badge…
   ============================================================ */

/* ──────────────────────────────────────────
   BOUTONS (.gt-btn)
────────────────────────────────────────── */

.gt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--font-md);
  font-weight: var(--fw-semibold);
  font-family: inherit;
  line-height: 1;
  border: none;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  background: color-mix(in srgb, var(--surface-3, #2a2d35) 80%, var(--surface-1, #0f1012));
  color: var(--text, #e8eaf6);
  transition:
    opacity var(--t-fast),
    transform var(--t-fast),
    box-shadow var(--t-base),
    background var(--t-base);
}

.gt-btn:hover:not(:disabled) {
  opacity: var(--opacity-hover);
}

.gt-btn:active:not(:disabled) {
  transform: scale(var(--scale-press));
}

/* `display: inline-flex` plus haut l'emporte sur le `display: none` que la
   feuille du navigateur attache à l'attribut `hidden` : sans cette règle, un
   `btn.hidden = true` ne masque rien du tout, et le bouton reste cliquable.
   Une dizaine de vues se sont écrit leur propre `#mon-bouton[hidden]` faute de
   celle-ci (cf. `clip/style.css`). */
.gt-btn[hidden] { display: none; }

.gt-btn:disabled,
.gt-btn[disabled] {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  pointer-events: none;
}

/* Variante primaire */
.gt-btn--primary {
  background: var(--primary, #4ea3ff);
  color: var(--on-primary, #fff);
  box-shadow: var(--shadow-glow);
}

.gt-btn--primary:hover:not(:disabled) {
  opacity: var(--opacity-hover);
  box-shadow: var(--shadow-2);
}

/* Variante danger */
.gt-btn--danger {
  background: var(--danger, #ef4444);
  color: var(--on-danger, #fff);
}

/* Variante succès */
.gt-btn--success {
  background: var(--success, #4fdda4);
  color: var(--on-success, #0a1f18);
}

/* Variante warning */
.gt-btn--warn {
  background: var(--warning, #ffc857);
  color: var(--on-warning, #1a1200);
}

/* Variante ghost (contour) */
.gt-btn--ghost {
  background: transparent;
  border: 1.5px solid var(--border, rgba(255,255,255,0.12));
  color: var(--text, #e8eaf6);
}

.gt-btn--ghost:hover:not(:disabled) {
  background: color-mix(in srgb, var(--primary, #4ea3ff) 12%, transparent);
  border-color: var(--primary, #4ea3ff);
  color: var(--primary-fg, var(--primary, #4ea3ff));
  opacity: 1;
}

/* Variante icône (carré/rond, taille fixe) */
.gt-btn--icon {
  padding: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-circle);
  flex-shrink: 0;
}

.gt-btn--icon.gt-btn--sm {
  width: 32px;
  height: 32px;
}

.gt-btn--icon.gt-btn--lg {
  width: 48px;
  height: 48px;
}

/* Tailles */
.gt-btn--sm {
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-sm);
}

.gt-btn--lg {
  padding: var(--space-3) var(--space-5);
  font-size: var(--font-base);
}

/* Full width */
.gt-btn--full {
  width: 100%;
}

/* ──────────────────────────────────────────
   EN-TÊTE DE MODULE (.gt-page-header)

   La barre de titre de TOUT module, natif comme monté en iframe : titre à
   gauche, boutons ronds à droite. Passer d'un module à l'autre ne doit rien
   changer au rendu de cette barre — c'est la seule raison d'être du composant,
   et la raison pour laquelle ses mesures sont des tokens (`--header-h`,
   `--control-circle`) plutôt que des valeurs recopiées.

   La spec vient de la topbar de journal, qui était la meilleure des huit
   implémentations concurrentes : les sept autres (photos, météo, horloge,
   focus, clip, et les deux modules qui n'avaient pas d'en-tête du tout) s'y
   alignent, pas l'inverse.
────────────────────────────────────────── */

.gt-page-header {
  position: sticky;
  top: 0;
  z-index: 100;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  /* L'encoche iOS mange le haut d'une barre collante : elle s'ajoute à la
     hauteur au lieu de la rogner. `--safe-top` et pas `env()` : dans une
     iframe du dashboard le shell a déjà décalé le contenu sous l'encoche, et
     WebKit y répète pourtant la valeur du document parent (cf. tokens.css). */
  min-height: calc(var(--header-h) + var(--safe-top));
  padding: 0 var(--space-4);
  padding-top: var(--safe-top);
  background: color-mix(in srgb, var(--surface-2) 84%, transparent);
  backdrop-filter: saturate(1.2) blur(18px);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
}

/* Groupe d'éléments alignés — un à gauche, un à droite. */
.gt-page-header__group {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.gt-page-header__title {
  margin: 0;
  font-size: var(--font-xl);
  font-weight: var(--fw-semibold);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Bouton d'en-tête : toujours un cercle, toujours la même taille. Sert aussi
   au retour arrière — un chevron dans le même cercle, pas un bouton à part. */
.gt-page-header__action {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-circle);
  height: var(--control-circle);
  padding: 0;
  border-radius: var(--radius-circle);
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
  background: color-mix(in srgb, var(--surface-3) 76%, transparent);
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  /* Une action d'en-tête est parfois un `<a>` — la navigation croisée de
     profile, contacts et notification en est faite. Le rendu ne doit pas
     dépendre de la balise. */
  text-decoration: none;
  transition:
    background var(--t-base),
    border-color var(--t-base),
    opacity var(--t-fast),
    transform var(--t-fast);
}

/* Les modules déclarent leurs SVG à des tailles qui allaient de 15 à 20 px.
   La taille est imposée ici, sinon « identique » ne tient pas.

   Le TRAIT est imposé ici pour la même raison, et depuis le 2026-08-14. Deux
   catalogues alimentent cette barre : `gt_icon()` (PHP), dont les SVG portent
   `fill="none" stroke="currentColor"` en attributs, et `icons.js` (JS), dont
   les SVG n'en portent aucun — c'est la barre latérale qui les habille, dans
   `dashboard.css`. Tant que le seul bouton injecté était l'engrenage, dont le
   tracé était recopié en dur AVEC ses attributs, la différence ne se voyait
   pas. Le passage par `header-actions.js`, qui lit `icons.js`, l'a révélée :
   le « ? » et l'engrenage sont sortis en aplat noir, faute de `fill: none`.

   Poser la règle sur le composant plutôt que de rajouter des attributs dans le
   catalogue JS : une icône ne devrait pas avoir à savoir où elle est posée, et
   c'est le bouton qui décide de son rendu. Les enfants qui déclarent leur
   propre `fill` (les points de l'icône `drag`, par exemple) gardent le leur —
   un attribut de présentation sur l'élément l'emporte sur une valeur héritée. */
.gt-page-header__action > svg {
  width: var(--icon-action);
  height: var(--icon-action);
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.gt-page-header__action:hover:not(:disabled) {
  background: color-mix(in srgb, var(--surface-4) 84%, transparent);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
}

.gt-page-header__action:active:not(:disabled) {
  transform: scale(var(--scale-press));
}

.gt-page-header__action:disabled,
.gt-page-header__action[disabled] {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  pointer-events: none;
}

/* L'action principale du module. Aplat et survol par opacité, jamais de
   dégradé : `--primary` → `--accent` n'a aucune encre lisible en clair,
   nature et cafe (§7). */
.gt-page-header__action--primary {
  background: var(--primary);
  color: var(--on-primary);
  border-color: transparent;
  box-shadow: var(--shadow-glow);
}

.gt-page-header__action--primary:hover:not(:disabled) {
  background: var(--primary);
  border-color: transparent;
  opacity: var(--opacity-hover);
}

/* Compteur posé sur un bouton d'en-tête (non-lus). L'anneau le détache du
   fond du bouton quel que soit le thème. */
.gt-page-header__badge {
  position: absolute;
  top: 0;
  inset-inline-end: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--badge-dot);
  height: var(--badge-dot);
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--danger);
  color: var(--on-danger);
  font-size: var(--font-2xs);
  font-weight: var(--fw-bold);
  line-height: 1;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--surface-2) 90%, transparent);
}

/* ──────────────────────────────────────────
   INPUTS / SELECT / TEXTAREA (.gt-input, .gt-select, .gt-textarea)
────────────────────────────────────────── */

.gt-input,
.gt-select,
.gt-textarea {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1.5px solid var(--border, rgba(255,255,255,0.12));
  background: color-mix(in srgb, var(--surface-1, #0f1012) 80%, var(--surface-3, #2a2d35));
  color: var(--text, #e8eaf6);
  font-size: var(--font-md);
  font-family: inherit;
  line-height: var(--leading-snug);
  transition:
    border-color var(--t-fast),
    box-shadow var(--t-fast);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.gt-input::placeholder,
.gt-textarea::placeholder {
  color: var(--text-muted, rgba(232,234,246,0.4));
}

.gt-input:focus,
.gt-select:focus,
.gt-textarea:focus {
  border-color: var(--primary, #4ea3ff);
  box-shadow: var(--shadow-focus);
}

.gt-input:disabled,
.gt-select:disabled,
.gt-textarea:disabled {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
}

.gt-textarea {
  resize: vertical;
  min-height: 80px;
}

.gt-select {
  cursor: pointer;
  padding-inline-end: var(--space-6);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='7' viewBox='0 0 12 7'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}

/* ──────────────────────────────────────────
   LABEL DE FORMULAIRE (.gt-label)
────────────────────────────────────────── */

.gt-label {
  display: block;
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted, rgba(232,234,246,0.55));
  margin-bottom: var(--space-1);
  letter-spacing: 0.01em;
}

/* Groupe label + input */
.gt-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* ──────────────────────────────────────────
   CARDS (.gt-card)
────────────────────────────────────────── */

.gt-card {
  background: var(--surface-2, #161a1f);
  border: 1px solid var(--border, rgba(255,255,255,0.08));
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-1);
}

.gt-card--elevated {
  background: var(--surface-3, #1e2328);
  box-shadow: var(--shadow-2);
}

/* ──────────────────────────────────────────
   ONGLETS (.gt-tabs + .gt-tab)
────────────────────────────────────────── */

.gt-tabs {
  display: flex;
  gap: var(--space-1);
  background: var(--surface-2, #161a1f);
  border-radius: var(--radius-pill);
  padding: var(--space-1);
}

.gt-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  font-family: inherit;
  color: var(--text-muted, rgba(232,234,246,0.55));
  cursor: pointer;
  border: none;
  background: none;
  transition: all var(--t-base);
  user-select: none;
  white-space: nowrap;
}

.gt-tab:hover:not(.gt-tab--active) {
  color: var(--text, #e8eaf6);
  background: color-mix(in srgb, var(--surface-4, #2a2d35) 60%, transparent);
}

.gt-tab--active,
.gt-tab[aria-selected="true"] {
  background: var(--primary, #4ea3ff);
  color: var(--on-primary, #fff);
  box-shadow: var(--shadow-1);
}

/* Ruban d'onglets d'un module, posé juste sous `.gt-page-header` : centré,
   borné en largeur, détaché du fond. C'est la deuxième moitié du « haut d'un
   module » — un en-tête identique au-dessus de quatre rangées d'onglets
   différentes ne donne toujours pas deux modules qui se ressemblent. */
.gt-tabs--page {
  box-sizing: border-box;
  width: min(760px, 100% - var(--space-6));
  margin: var(--space-3) auto 0;
  border: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
  background: color-mix(in srgb, var(--surface-2) 82%, transparent);
  box-shadow: var(--shadow-1);
}

.gt-tabs--page .gt-tab {
  padding: var(--space-3) var(--space-4);
}

/* Au-delà de trois ou quatre onglets, ils ne tiennent plus à parts égales
   (kilobye en a sept) : le ruban défile au lieu de compresser les libellés. */
.gt-tabs--scroll {
  overflow-x: auto;
  scrollbar-width: none;
}

.gt-tabs--scroll::-webkit-scrollbar {
  display: none;
}

.gt-tabs--scroll .gt-tab {
  flex: 0 0 auto;
}

/* Sur mobile le ruban se resserre sur la marge du contenu. */
@media (max-width: 600px) {
  .gt-tabs--page {
    width: min(760px, 100% - var(--space-5));
  }
}

/* ──────────────────────────────────────────
   BADGES (.gt-badge)
────────────────────────────────────────── */

.gt-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  font-size: var(--font-2xs);
  font-weight: var(--fw-bold);
  line-height: 1;
  background: var(--danger, #ef4444);
  color: var(--on-danger, #fff);
  flex-shrink: 0;
}

.gt-badge--primary {
  background: var(--primary, #4ea3ff);
  color: var(--on-primary, #fff);
}

.gt-badge--success {
  background: var(--success, #4fdda4);
  color: var(--on-success, #0a1f18);
}

.gt-badge--neutral {
  background: var(--surface-4, #2a2d35);
  color: var(--text-muted, rgba(232,234,246,0.55));
}

/* ──────────────────────────────────────────
   TOGGLE (checkbox switch) (.gt-toggle)
────────────────────────────────────────── */

.gt-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
}

.gt-toggle input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.gt-toggle__track {
  position: relative;
  width: 40px;
  height: 22px;
  border-radius: var(--radius-pill);
  background: var(--surface-4, #2a2d35);
  border: 1.5px solid var(--border, rgba(255,255,255,0.12));
  transition: background var(--t-base), border-color var(--t-base);
  flex-shrink: 0;
}

.gt-toggle__track::after {
  content: '';
  position: absolute;
  top: 2px;
  inset-inline-start: 2px;
  width: 14px;
  height: 14px;
  border-radius: var(--radius-circle);
  background: var(--text-muted, rgba(232,234,246,0.5));
  transition: transform var(--t-base), background var(--t-base);
}

.gt-toggle input:checked + .gt-toggle__track {
  background: var(--primary, #4ea3ff);
  border-color: var(--primary, #4ea3ff);
}

.gt-toggle input:checked + .gt-toggle__track::after {
  transform: translateX(18px);
  background: var(--on-primary, #fff);
}

.gt-toggle__label {
  font-size: var(--font-sm);
  color: var(--text, #e8eaf6);
}

/* ──────────────────────────────────────────
   TITRES DE SECTION (.gt-section-title)
────────────────────────────────────────── */

.gt-section-title {
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  color: var(--text-muted, rgba(232,234,246,0.45));
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 var(--space-2);
}

/* ──────────────────────────────────────────
   ÉTAT VIDE (.gt-empty-state)
────────────────────────────────────────── */

.gt-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-7) var(--space-5);
  color: var(--text-muted, rgba(232,234,246,0.4));
  text-align: center;
}

.gt-empty-state__icon {
  font-size: 2.5rem;
  opacity: 0.5;
}

.gt-empty-state__text {
  font-size: var(--font-sm);
  line-height: var(--leading-normal);
}

/* ──────────────────────────────────────────
   DIVIDER (.gt-divider)
────────────────────────────────────────── */

.gt-divider {
  border: none;
  border-top: 1px solid var(--border, rgba(255,255,255,0.08));
  margin: var(--space-4) 0;
}

/* ──────────────────────────────────────────
   CHIP / TAG (.gt-chip)
────────────────────────────────────────── */

.gt-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  font-size: var(--font-xs);
  font-weight: var(--fw-medium);
  background: color-mix(in srgb, var(--primary, #4ea3ff) 15%, transparent);
  color: var(--primary-fg, var(--primary, #4ea3ff));
  border: 1px solid color-mix(in srgb, var(--primary, #4ea3ff) 30%, transparent);
}

/* ──────────────────────────────────────────
   TOAST / NOTIFICATION (.gt-toast)
────────────────────────────────────────── */

.gt-toast {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  background: var(--surface-4, #2a2d35);
  color: var(--text, #e8eaf6);
  box-shadow: var(--shadow-2);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
}

/*
 * ── `[hidden]` et `display` : la mine, et sa désamorce générale ──────────────
 *
 * `[hidden]` ne vaut `display: none` que par la feuille du NAVIGATEUR. Toute
 * règle d'auteur qui déclare `display` la bat, quelle que soit sa place dans le
 * fichier : un composant qui pose `display: flex` sur sa classe ignore
 * silencieusement `el.hidden = true`.
 *
 * La note existait pour `.gt-btn`, puis pour `.gt-toast` — et n'a jamais été
 * généralisée. Le 2026-08-30, l'agent UX a mesuré ce que ça coûtait dans
 * `radio` : CINQ conteneurs affichés alors qu'ils portaient `hidden`, dont le
 * bandeau du lecteur, visible au premier chargement avec un nom vide et un
 * bouton « Arrêter » qui n'arrêtait rien. Tout le pilotage des vues du module
 * (`el.list.hidden = …`, `filters.hidden = …`) était inerte.
 *
 * La règle est donc posée ici pour TOUS les composants qui déclarent un
 * `display`, et pas une neuvième fois dans un module. Un élément qui porte
 * `hidden` est caché : il n'y a pas de cas où l'on veut l'inverse.
 */
.gt-toast[hidden],
.gt-empty-state[hidden],
.gt-tabs[hidden],
.gt-chip[hidden],
.gt-badge[hidden],
.gt-field[hidden] { display: none; }

.gt-toast--success { background: var(--success, #4fdda4); color: var(--on-success, #0a1f18); }
.gt-toast--danger  { background: var(--danger, #ef4444);  color: var(--on-danger, #fff); }
.gt-toast--warn    { background: var(--warning, #ffc857); color: var(--on-warning, #1a1200); }

/* ──────────────────────────────────────────
   AIDE D'UN MODULE (.gt-help)

   Le panneau de lecture de l'aide, rendu par le shell et par lui seul — un
   calque dessiné dans une iframe ne sort pas de l'iframe, même en top layer.

   C'est le premier `<dialog>` de l'application, délibérément : il donne le top
   layer (aucune échelle de `z-index` à inventer, et `tokens.css` n'en a
   aucune), Échap, le piège à focus, l'arrière-plan `inert` et le focus rendu
   au bouton « ? » à la fermeture — sans une ligne de JavaScript.

   Feuille LATÉRALE, pas modale centrée : on lit l'aide en regardant le module,
   et une modale centrée cache précisément ce qu'elle explique.
────────────────────────────────────────── */

.gt-help {
  /* `<dialog>` est centré par défaut (`margin: auto`) : on le colle au bord. */
  margin: 0 0 0 auto;
  inline-size: min(420px, 100vw);
  max-inline-size: 100vw;
  block-size: 100dvh;
  max-block-size: 100dvh;

  padding: 0;
  border: none;
  border-inline-start: 1px solid var(--border, rgba(255,255,255,0.1));
  background: var(--surface-2);
  color: var(--text);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}

.gt-help::backdrop {
  background: var(--overlay-bg);
}

.gt-help__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  block-size: var(--header-h);
  padding-inline: var(--space-4);
  border-block-end: 1px solid var(--border, rgba(255,255,255,0.1));
}

.gt-help__title {
  margin: 0;
  font-size: var(--font-lg);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.gt-help__close {
  inline-size: var(--control-circle);
  block-size: var(--control-circle);
  border: none;
  border-radius: var(--radius-circle);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--font-xl);
  line-height: 1;
  cursor: pointer;
}

.gt-help__close:hover { background: var(--surface-3); color: var(--text); }

.gt-help__body {
  block-size: calc(100% - var(--header-h));
  overflow-y: auto;
  padding: var(--space-5) var(--space-4) var(--space-7);
}

.gt-help__loading {
  padding: var(--space-5);
  color: var(--text-muted);
  font-size: var(--font-sm);
}

.gt-help__summary {
  font-size: var(--font-lg);
  line-height: var(--leading-normal);
  color: var(--text);
  margin: 0 0 var(--space-5);
}

.gt-help__section { margin-block-end: var(--space-5); }

.gt-help__section h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--font-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

/* `pre-line` : les contenus d'aide séparent leurs paragraphes par un `\n\n`,
   et HTML avale les sauts de ligne. Sans cette ligne, chaque aide du dépôt se
   lisait d'un seul bloc — le retour à la ligne était écrit, jamais rendu. Le
   sanitiseur n'admettant que `**gras**` et `` `code` ``, la mise en forme ne
   peut venir que d'ici. `pre-line` et non `pre-wrap` : on garde les sauts de
   ligne, on ne garde pas l'indentation du fichier PHP. */
.gt-help__summary,
.gt-help__privacy p,
.gt-help__section p {
  white-space: pre-line;
}

.gt-help__section p {
  margin: 0;
  color: var(--text-muted);
  line-height: var(--leading-normal);
}

/* Le repli de langue s'annonce, il ne s'excuse pas : ton d'information, pas
   d'alerte. Une aide non traduite n'est pas une erreur de l'utilisateur. */
.gt-help__notice {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: var(--leading-snug);
}

/* La section qui justifie tout le reste : le seul endroit où la promesse
   d'habask se vérifie au moment où l'on utilise le module. Un filet, pas une
   couleur d'alerte — elle informe, elle n'avertit pas. */
.gt-help__privacy {
  border-inline-start: 3px solid var(--accent);
  padding-inline-start: var(--space-4);
}

.gt-help__shortcuts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  align-items: baseline;
  margin: 0;
}

.gt-help__shortcuts dt { margin: 0; }
.gt-help__shortcuts dd { margin: 0; color: var(--text-muted); font-size: var(--font-sm); }

.gt-help kbd {
  font-family: ui-monospace, monospace;
  font-size: var(--font-sm);
  padding-inline: var(--space-1);
  border: 1px solid var(--border, rgba(255,255,255,0.1));
  border-radius: var(--radius-sm);
  background: var(--surface-3);
  color: var(--text);
}

.gt-help code {
  font-family: ui-monospace, monospace;
  font-size: 0.95em;
  color: var(--text);
}

/* Sous 768 px, feuille BASSE : sur un téléphone, une feuille latérale de
   420 px est la page entière, et arriver par le bas est le geste attendu.
   `dvh` et non `vh` — la barre d'URL d'iOS fausse `vh`, leçon déjà payée
   dans `files.php`. */
@media (max-width: 768px) {
  .gt-help {
    margin: auto 0 0;
    inline-size: 100vw;
    block-size: auto;
    max-block-size: 85dvh;
    border-inline-start: none;
    border-start-start-radius: var(--radius-xl);
    border-start-end-radius: var(--radius-xl);
  }

  .gt-help__body {
    block-size: auto;
    max-block-size: calc(85dvh - var(--header-h));
    padding-block-end: calc(var(--space-7) + var(--safe-bottom, 0px));
  }
}

/* ──────────────────────────────────────────
   PROJECTEUR (.gt-spotlight) — le calque qui désigne

   Un seul SVG plein écran, un seul `<path>` en `fill-rule="evenodd"` : le
   rectangle du viewport MOINS un rectangle arrondi sur la cible.

   Pas quatre `<div>` positionnés (quatre fois la même arithmétique, et des
   coins carrés). Pas `box-shadow: 0 0 0 9999px` (pas de rayon honnête sur le
   trou, et un dépassement qui déclenche des barres de défilement). Un seul
   élément, un trou arrondi et anticrénelé, une seule chose à animer.
────────────────────────────────────────── */

.gt-spotlight {
  position: fixed;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  /* Sous le `<dialog>`, qui est en top layer et donc hors de toute échelle. */
  z-index: 900;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base) ease;
}

.gt-spotlight.is-visible { opacity: 1; }

/*
 * Le voile capte les clics, le trou non — c'est la conséquence directe du
 * `evenodd` : la zone évidée n'appartient pas au tracé, donc `pointer-events`
 * ne s'y applique pas. Le contrôle mis en lumière reste cliquable quand
 * l'étape invite à le faire.
 */
.gt-spotlight__veil {
  fill: var(--overlay-bg);
  pointer-events: auto;
  transition: d var(--t-base) ease;
}

/*
 * `reduce_motion` : le trou SAUTE d'une étape à l'autre au lieu de glisser.
 * `prefers-reduced-motion` couvre le réglage système ; `[data-motion="on"]`
 * couvre le réglage habask, que `a11y.js` pose sur `<html>` (`root.dataset.motion`)
 * et propage aux iframes par `gt:a11y`. Les deux sont nécessaires : l'un
 * n'implique pas l'autre, et c'est justement pourquoi le réglage existe.
 */
@media (prefers-reduced-motion: reduce) {
  .gt-spotlight,
  .gt-spotlight__veil { transition: none; }
}

:root[data-motion="on"] .gt-spotlight,
:root[data-motion="on"] .gt-spotlight__veil { transition: none; }

/* ── Le panneau en mode visite ─────────────────────────────────────────── */

/*
 * Pendant une visite, le panneau se fait petit : il commente ce que le
 * projecteur montre, il ne le cache pas. Il perd donc sa pleine hauteur et se
 * range en bas — au-dessus du voile, mais hors du chemin du regard.
 */
.gt-help--tour {
  block-size: auto;
  max-block-size: 45dvh;
  margin-block: auto var(--space-5);
  margin-inline: auto var(--space-5);
  border-radius: var(--radius-xl);
  border-inline-start: none;
}

.gt-help--tour .gt-help__body {
  block-size: auto;
  max-block-size: calc(45dvh - var(--header-h) - 64px);
  padding-block-end: var(--space-4);
}

.gt-help__step-count {
  margin: 0 0 var(--space-2);
  font-size: var(--font-xs);
  color: var(--text-muted);
  letter-spacing: var(--tracking-wide);
}

.gt-help__foot {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-block-start: 1px solid var(--border, rgba(255,255,255,0.1));
}

.gt-help__foot .gt-btn { flex: 1; }

@media (max-width: 768px) {
  .gt-help--tour {
    margin-inline: var(--space-3);
    margin-block-end: calc(var(--space-3) + var(--safe-bottom, 0px));
    inline-size: auto;
  }
}

/*
 * Variante « point » de la pastille d'en-tête (lot E de D36).
 *
 * La pastille de base porte un COMPTE (les non-lus de la messagerie) ; celle-ci
 * ne porte rien. Elle dit « il y a ici quelque chose que tu n'as pas encore
 * ouvert », et un chiffre laisserait croire à des messages en attente.
 *
 * Couleur d'accent et non `--danger` : découvrir l'aide d'un module n'est pas
 * une urgence, et une pastille rouge sur un « ? » se lirait comme une alerte.
 */
.gt-page-header__badge--dot {
  min-width: var(--badge-dot);
  padding: 0;
  background: var(--accent);
  border: 2px solid var(--surface-1);
}
