/* Socle de composants de la console — spécification 0037, § 6.
 *
 * Chargé APRÈS console.css. Deux règles qui ne se négocient pas :
 *
 *   1. AUCUN ÉCRAN EXISTANT NE CHANGE DE RENDU. Le bloc `:root` ci-dessous ne
 *      définit que des noms NEUFS (`--ardoise`, `--t-14`, `--ton-…`) ; la seule
 *      variable que console.css définit aussi, `--accent`, y a la même valeur
 *      (l'épreuve `jetons-console-accordes.js` le vérifie). Toute règle du
 *      socle vise une classe `s-…` (ou `.onglets.s-onglets`) : jamais un
 *      élément nu, jamais une classe de console.css.
 *   2. console.css pose des règles sur les éléments nus (`button`, `input`,
 *      `label`, `h2`, `table`, `th`, `td`) que la spécificité d'une classe
 *      seule ne bat pas toujours (`button:hover:not(:disabled)` vaut 0,2,1).
 *      Les composants s'écrivent donc `button.s-btn…`, avec assez de
 *      spécificité pour ne rien hériter de la feuille voisine.
 *
 * AUCUN `style=` ET AUCUN `<style>` : la CSP de production (`style-src 'self'`)
 * les refuse. Toute valeur qui varie passe par une classe.
 */

:root {
  /* ------------------------------------------------------------------------
   * JETONS — valeurs RECOPIÉES du portail, jamais importées (la console n'a
   * aucune dépendance de code sur le portail). La source est dite à côté de
   * chaque valeur ; `scripts/epreuves/jetons-console-accordes.js` compare
   * chacune à son fichier d'origine et rougit à la première dérive.
   * ---------------------------------------------------------------------- */

  /* Ardoise : services/portal/app/style/theme.ts, ARDOISE[500], [600], [700]
   * (lignes 598 à 600). Elle remplace `--bleu`, `--bleu-sombre` et `--marine`
   * de console.css — ce n'étaient plus des bleus — à la fin de la refonte. */
  --ardoise:        #293239;
  --ardoise-sombre: #1e242a;
  --ardoise-nuit:   #13171b;
  /* theme.ts:627, `accent` de MARQUE_ARDOISE_CLAIRE. DÉCORATIF seulement :
   * 1,97:1 sur blanc, jamais un texte, jamais une bordure de composant. */
  --accent:         #faa820;

  /* Texte, surfaces, filet : theme.ts, LIGHT_THEME.colors — textPrimary
   * (ligne 132), textSecondary (133), bgDefault (126), border (137). */
  --texte-1:        #111827;
  --texte-2:        #5b6472;
  --fond:           #f4f6f9;
  --surface:        #ffffff;
  --filet:          #e8ecf1;
  /* Invite d'un champ : services/portal/app/design/tokens.ts:521,
   * GRIS_TERNE_CLAIR — 5,07:1 sur blanc (console.css : #9aa3b2, 2,54:1). */
  --invite:         #696f78;
  /* Bordure d'un champ : CALCULÉE, sans source au portail — 3,39:1 sur blanc,
   * 3,13:1 sur `--fond` (minimum 3:1 pour une limite de composant ; console.css :
   * #c8cfda, 1,57:1). Spécification 0037 A, § 4.14. */
  --champ-bord:     #838c9b;

  /* Échelle de texte : tokens.ts, TYPO (lignes 153 à 160) — 12 / 13 / 14 / 16 /
   * 20, avec leur hauteur de ligne ; deux graisses, 400 et 600. Le corps est 14. */
  --t-12: 12px;  --l-12: 16px;
  --t-13: 13px;  --l-13: 18px;
  --t-14: 14px;  --l-14: 20px;
  --t-16: 16px;  --l-16: 24px;
  --t-20: 20px;  --l-20: 28px;
  --g-normal: 400;
  --g-fort:   600;

  /* Rayons : theme.ts:81, RADIUS — sm 8, md 12, full 999. */
  --r-8:  8px;
  --r-12: 12px;
  --r-pilule: 999px;

  /* Espacements : theme.ts:80, SPACING (4, 8, 16, 24, 32, 48), auxquels le skill
   * maestro-ux (« Espace ») ajoute 12 et 64 : « 4, 8, 12, 16, 24, 32, 48, 64 ». */
  --e-4:  4px;
  --e-8:  8px;
  --e-12: 12px;
  --e-16: 16px;
  --e-24: 24px;
  --e-32: 32px;
  --e-48: 48px;
  --e-64: 64px;

  /* Un seul niveau d'ombre : skill maestro-ux, « Formes et profondeur ». */
  --ombre: 0 1px 3px rgba(0, 0, 0, .06), 0 4px 12px rgba(0, 0, 0, .04);

  /* Tons de pastille — paires CALCULÉES (WCAG), toutes à 7:1 ou plus, fixées par la spécification 0037, § 2
   * (« Pastilles d'état ») : neutre 9,10 · avertissement 7,98 · succès 7,79 · erreur 7,80 · en cours 12,46.
   * « En cours » est l'ardoise : une seule couleur de marque et deux tons d'alerte (ambre, rouge), pas de bleu
   * d'information (§ 3.1).
   *
   * TOUS NE SONT PAS RECOPIÉS DU PORTAIL, et chaque ligne le dit : « recopié » = la valeur du jeton du portail cité ;
   * « écart assumé » = la console garde la paire calculée de la spécification, pas l'encre du portail. Le portail ne
   * donne pas 7:1 partout (`success[800]` sur `success[100]` : 6,87:1, ce qui lui a fait poser VERT_PAYE_CLAIR ;
   * `error[800]` : 6,80:1, d'où ROUGE_REJETE_CLAIR), et ses fonds de ton (`grey[50]`, `success[50]`…) ne sont pas
   * ceux des pastilles de la console. `jetons-console-accordes.js` lit chaque annotation : le portail cité dit-il
   * toujours cette valeur ? « recopié » est-il encore égal, « écart assumé » encore différent ? Un portail qui bouge
   * fait rougir l'épreuve : la décision se reprend alors, elle ne dérive pas. */
  --ton-neutre:         #374151;  /* portail : grey[700] #374151 — recopié */
  --ton-neutre-fond:    #eef1f5;  /* portail : grey[50] #F9FAFB — écart assumé */
  --ton-avert:          #6e4205;  /* portail : warning[800] #93370D — écart assumé */
  --ton-avert-fond:     #fdf6e7;  /* portail : warning[50] #FFFAEB — écart assumé */
  --ton-succes:         #0a5a2e;  /* portail : VERT_PAYE_CLAIR #0A5231 — écart assumé */
  --ton-succes-fond:    #eefaf2;  /* portail : success[50] #ECFDF3 — écart assumé */
  --ton-erreur:         #941a1a;  /* portail : ROUGE_REJETE_CLAIR #941A1A — recopié */
  --ton-erreur-fond:    #fdf0ef;  /* portail : error[50] #FEF2F2 — écart assumé */
  --ton-cours:          #1e242a;  /* portail : ARDOISE[600] #1E242A — recopié */
  --ton-cours-fond:     #e1e6ea;  /* portail : ARDOISE[100] #E1E6EA — recopié */
  /* Le survol d'un bouton danger : l'erreur assombrie (blanc dessus : 10,8:1). */
  --ton-erreur-sombre:  #7a1515;
  /* Le texte sur ardoise, sur erreur et sur le fond sombre d'un toast : le blanc de `--surface`. */
  --texte-inverse:      #ffffff;

  /* Mesures partagées. */
  --cible: 44px;            /* cible tactile minimale */
  --duree: 150ms;           /* 150 à 200 ms, `ease-out` ; rien au-delà de 300 */
}

/* ==========================================================================
 * Outils communs
 * ======================================================================== */

/* Texte pour les lecteurs d'écran, invisible ailleurs. */
.s-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.s-icone {
  width: var(--t-16); height: var(--t-16); flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Le défilement de la page est figé derrière une modale ouverte. */
html.s-sans-defilement { overflow: hidden; }

/* --------------------------------------------------------------------------
 * Boutons. `button.s-btn` (0,1,1) ne bat pas `button:hover:not(:disabled)` de
 * console.css (0,2,1) : chaque état est donc écrit en `button.s-btn…:hover:not(:disabled)`
 * (0,3,1 et plus). Cible de 44 px, focus visible, deux graisses.
 * ------------------------------------------------------------------------ */
button.s-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-8);
  min-height: var(--cible); min-width: var(--cible); padding: 0 var(--e-16);
  border: 1px solid transparent; border-radius: var(--r-8);
  font: var(--g-fort) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background-color var(--duree) ease-out, border-color var(--duree) ease-out;
}
button.s-btn:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }
button.s-btn:disabled { opacity: .55; cursor: not-allowed; }
button.s-btn--primaire { background: var(--ardoise); border-color: var(--ardoise); color: var(--texte-inverse); }
button.s-btn--primaire:hover:not(:disabled) { background: var(--ardoise-sombre); border-color: var(--ardoise-sombre); color: var(--texte-inverse); }
button.s-btn--secondaire { background: var(--surface); border-color: var(--champ-bord); color: var(--ardoise); }
button.s-btn--secondaire:hover:not(:disabled) { background: var(--fond); border-color: var(--champ-bord); color: var(--ardoise); }
button.s-btn--danger { background: var(--ton-erreur); border-color: var(--ton-erreur); color: var(--texte-inverse); }
button.s-btn--danger:hover:not(:disabled) { background: var(--ton-erreur-sombre); border-color: var(--ton-erreur-sombre); color: var(--texte-inverse); }
/* Sur le fond sombre d'un toast. */
button.s-btn--toast { background: transparent; border-color: rgba(255, 255, 255, .7); color: var(--texte-inverse); flex: 0 0 auto; }
button.s-btn--toast:hover:not(:disabled) { background: rgba(255, 255, 255, .14); border-color: var(--texte-inverse); color: var(--texte-inverse); }
button.s-btn--toast:focus-visible { outline-color: var(--texte-inverse); }

/* ==========================================================================
 * Toast — succès seulement, 5 s, pause au survol et au focus
 * ======================================================================== */

.s-toasts {
  position: fixed; right: var(--e-16); bottom: var(--e-16); z-index: 1000;
  display: flex; flex-direction: column; gap: var(--e-8);
  width: min(420px, calc(100vw - 2 * var(--e-16)));
  pointer-events: none;
}
.s-toast {
  pointer-events: auto;
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-16);
  padding: var(--e-8) var(--e-16); min-height: var(--cible);
  background: var(--ardoise-nuit); color: var(--texte-inverse); border-radius: var(--r-8); box-shadow: var(--ombre);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.s-toast-texte { min-width: 0; overflow-wrap: anywhere; }
@media (prefers-reduced-motion: no-preference) {
  .s-toast { animation: s-toast-entree var(--duree) ease-out; }
  @keyframes s-toast-entree { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
}
/* Au-dessus de la barre d'enregistrement quand elle est posée, à TOUTE largeur : un toast posé dessus cacherait
 * « Enregistrer ». `--barre-h` est la hauteur RÉELLE de la barre, posée par `socle.js` sur cette zone (la barre colle à
 * 8 px du bas : 8 + hauteur + 8 d'écart). Sans elle, 96 px — la barre au repos. */
body.s-avec-barre .s-toasts { bottom: calc(var(--barre-h, calc(var(--e-64) + var(--e-32))) + var(--e-16)); }
@media (max-width: 767px) {
  .s-toasts { left: var(--e-16); right: var(--e-16); width: auto; }
}

/* ==========================================================================
 * Pastille d'état — un mot ET une icône ; jamais la couleur seule
 * ======================================================================== */

.s-pastille {
  display: inline-flex; align-items: center; gap: var(--e-4); max-width: 100%;
  padding: 2px var(--e-12) 2px var(--e-8); border-radius: var(--r-pilule);
  font: var(--g-fort) var(--t-12)/var(--l-12) var(--police, system-ui, sans-serif);
  white-space: nowrap;
}
.s-pastille .s-icone { width: var(--t-14); height: var(--t-14); }
.s-ton-neutre { color: var(--ton-neutre);  background: var(--ton-neutre-fond); }
.s-ton-avert  { color: var(--ton-avert);   background: var(--ton-avert-fond); }
.s-ton-succes { color: var(--ton-succes);  background: var(--ton-succes-fond); }
.s-ton-erreur { color: var(--ton-erreur);  background: var(--ton-erreur-fond); }
.s-ton-cours  { color: var(--ton-cours);   background: var(--ton-cours-fond); }

/* ==========================================================================
 * Bandeau persistant, états (chargement, vide, erreur), détail replié
 * ======================================================================== */

.s-bandeau {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--e-8) var(--e-16);
  padding: var(--e-12) var(--e-16); border-radius: var(--r-8); margin: var(--e-16) 0;
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.s-bandeau > .s-icone { width: var(--t-20); height: var(--t-20); margin-top: 0; }
.s-bandeau-corps { flex: 1 1 240px; min-width: 0; }
.s-bandeau-message { margin: 0; font-weight: var(--g-fort); overflow-wrap: anywhere; }
.s-detail { margin-top: var(--e-8); }
.s-detail > summary {
  cursor: pointer; min-height: var(--cible); min-width: var(--cible); display: flex; align-items: center;
  font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif);
}
.s-detail > summary:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }
.s-detail-texte {
  margin: 0; padding: var(--e-12); max-height: 240px; overflow: auto;
  background: var(--surface); color: var(--texte-1); border: 1px solid var(--filet); border-radius: var(--r-8);
  font: var(--g-normal) var(--t-12)/var(--l-12) ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap; overflow-wrap: anywhere;
}

.s-squelette { padding: var(--e-8) 0; }
.s-squelette--carte { padding: var(--e-24); background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12); }
.s-sq { background: var(--ton-cours-fond); border-radius: var(--r-8); }
.s-sq-ligne { height: 14px; margin: var(--e-8) 0; }
.s-sq-l { width: 100%; }
.s-sq-m { width: 66%; }
.s-sq-c { width: 36%; }
.s-sq-titre { height: 20px; width: 30%; margin: var(--e-8) 0 var(--e-16); }
.s-sq-item { padding: var(--e-12) var(--e-16); background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12); margin-bottom: var(--e-8); }
.s-sq-rangee { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e-16); padding: var(--e-8) var(--e-16); border-bottom: 1px solid var(--filet); }
.s-sq-rangee .s-sq-ligne { width: 80%; }
/* Sous 768 px, une liste est une suite de CARTES : son squelette aussi (pas de ligne d'en-tête, une carte par ligne). */
@media (max-width: 767px) {
  .s-squelette--tableau .s-sq-rangee.s-sq-entete { display: none; }
  .s-squelette--tableau .s-sq-rangee {
    display: block; margin-bottom: var(--e-8); padding: var(--e-12) var(--e-16);
    background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12);
  }
  .s-squelette--tableau .s-sq-rangee .s-sq-ligne { width: 60%; }
  .s-squelette--tableau .s-sq-rangee .s-sq-ligne:first-child { width: 40%; }
}
@media (prefers-reduced-motion: no-preference) {
  .s-sq { animation: s-pulsation 1.4s ease-in-out infinite; }
  @keyframes s-pulsation { 50% { opacity: .55; } }
}

.s-vide, .s-etat-erreur {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--e-12);
  padding: var(--e-24); background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif); color: var(--texte-1);
}
.s-vide { align-items: center; text-align: center; }
.s-vide-phrase, .s-etat-phrase { margin: 0; overflow-wrap: anywhere; }
.s-etat-phrase { font-weight: var(--g-fort); color: var(--ton-erreur); }

/* ==========================================================================
 * Champ — libellé au-dessus, erreur sous le champ, marque « Modifié »
 * ======================================================================== */

.s-champ { display: block; margin: var(--e-16) 0 0; min-width: 0; }
.s-champ:first-child { margin-top: 0; }
.s-champ-tete { display: flex; align-items: baseline; justify-content: space-between; gap: var(--e-8); margin: 0 0 var(--e-8); }
label.s-champ-etiquette {
  display: block; margin: 0; color: var(--texte-1);
  font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif);
}
.s-champ-modifie {
  padding: 0 var(--e-8); border-radius: var(--r-pilule); color: var(--ton-avert); background: var(--ton-avert-fond);
  font: var(--g-fort) var(--t-12)/var(--l-12) var(--police, system-ui, sans-serif);
}
.s-champ-modifie[hidden], .s-champ-erreur[hidden] { display: none; }
.s-champ .s-entree {
  display: block; width: 100%; min-height: var(--cible); padding: var(--e-8) var(--e-12);
  background: var(--surface); color: var(--texte-1);
  border: 1px solid var(--champ-bord); border-radius: var(--r-8);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.s-champ textarea.s-entree { min-height: 88px; resize: vertical; }
.s-champ .s-entree::placeholder { color: var(--invite); opacity: 1; }
.s-champ .s-entree:hover { border-color: var(--texte-2); }
.s-champ .s-entree:focus, .s-champ .s-entree:focus-visible {
  outline: 2px solid var(--ardoise); outline-offset: 1px; border-color: var(--ardoise); box-shadow: none;
}
.s-champ .s-entree[aria-invalid="true"] { border-color: var(--ton-erreur); }
.s-champ .s-entree:disabled { background: var(--fond); color: var(--texte-2); cursor: not-allowed; }
.s-champ-erreur { margin: var(--e-4) 0 0; color: var(--ton-erreur); font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif); overflow-wrap: anywhere; }
.s-secret { position: relative; display: block; }
.s-secret .s-entree { padding-right: calc(var(--cible) + var(--e-8)); }
button.s-oeil {
  position: absolute; top: 0; right: 0; width: var(--cible); height: var(--cible); padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: var(--r-8); color: var(--texte-2); cursor: pointer;
}
button.s-oeil:hover:not(:disabled) { background: transparent; color: var(--ardoise); }
button.s-oeil:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
button.s-oeil .s-icone { width: var(--t-20); height: var(--t-20); }

/* ==========================================================================
 * Modale de confirmation — `<dialog>` natif
 * ======================================================================== */

dialog.s-modale {
  width: min(480px, calc(100vw - 2 * var(--e-16))); max-height: calc(100vh - 2 * var(--e-16)); max-height: calc(100dvh - 2 * var(--e-16));
  padding: 0; border: 0; border-radius: var(--r-12); box-shadow: var(--ombre);
  background: var(--surface); color: var(--texte-1);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
dialog.s-modale::backdrop { background: rgba(19, 23, 27, .55); }
.s-modale-form { display: flex; flex-direction: column; max-height: inherit; margin: 0; }
h2.s-modale-titre { margin: 0; padding: var(--e-24) var(--e-24) var(--e-8); font: var(--g-fort) var(--t-16)/var(--l-16) var(--police, system-ui, sans-serif); color: var(--texte-1); }
.s-modale-corps { padding: 0 var(--e-24) var(--e-16); overflow-y: auto; min-height: 0; }
.s-touche { margin: 0 0 var(--e-8); padding: 0 0 0 var(--e-16); }
.s-touche li { margin: var(--e-4) 0; overflow-wrap: anywhere; }
.s-modale-alerte { margin: var(--e-12) 0 0; padding: var(--e-8) var(--e-12); border-radius: var(--r-8); color: var(--ton-erreur); background: var(--ton-erreur-fond); font-weight: var(--g-fort); }
.s-modale-alerte[hidden] { display: none; }
.s-modale-pied { display: flex; justify-content: flex-end; gap: var(--e-8); padding: var(--e-16) var(--e-24) var(--e-24); border-top: 1px solid var(--filet); }
@media (max-width: 479px) {
  h2.s-modale-titre { padding: var(--e-16) var(--e-16) var(--e-8); }
  .s-modale-corps { padding: 0 var(--e-16) var(--e-16); }
  .s-modale-pied { padding: var(--e-16); }
  /* Un verbe long (« Supprimer l'espace ») passe à la ligne plutôt que de toucher les bords. */
  .s-modale-pied .s-btn { flex: 1 1 0; white-space: normal; padding: var(--e-8) var(--e-12); }
}

/* ==========================================================================
 * Barre d'enregistrement (E2) — collante, visible seulement si le lot est sale
 *
 * `position: sticky` dans le flux de la zone de contenu : la marge basse est
 * réservée d'office (la barre n'occulte jamais la fin de la page). `--clavier`
 * est posée par `socle.js` (`visualViewport`) quand le clavier réduit la fenêtre
 * visuelle : la barre reste au-dessus de lui.
 * ======================================================================== */

.s-enr {
  position: sticky; bottom: calc(var(--clavier, 0px) + var(--e-8)); z-index: 40;
  margin: var(--e-24) 0 0; padding: var(--e-12) var(--e-16);
  background: var(--surface); color: var(--texte-1);
  border: 1px solid var(--filet); border-radius: var(--r-12); box-shadow: var(--ombre);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.s-enr[hidden] { display: none; }
.s-enr-rangee { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--e-8) var(--e-16); }
.s-enr-n { font-weight: var(--g-fort); }
.s-enr-actions { display: flex; gap: var(--e-8); }
.s-enr-alerte {
  margin: 0 0 var(--e-12); padding: var(--e-8) var(--e-12); border-radius: var(--r-8);
  color: var(--ton-erreur); background: var(--ton-erreur-fond); font-weight: var(--g-fort); overflow-wrap: anywhere;
}
.s-enr-alerte[hidden] { display: none; }
@media (max-width: 479px) {
  .s-enr-actions { flex: 1 1 100%; }
  .s-enr-actions .s-btn { flex: 1 1 0; }
  .s-enr-n { flex: 1 1 100%; }
}

/* ==========================================================================
 * Interrupteur et segmenté à effet immédiat (E1)
 * ======================================================================== */

.s-interrupteur { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--e-12); min-height: var(--cible); }
button.s-sw {
  flex: 0 0 auto; width: calc(var(--cible) + var(--e-12)); min-height: var(--cible); padding: 0; margin: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: var(--r-8); cursor: pointer;
}
button.s-sw:hover:not(:disabled) { background: transparent; }
button.s-sw:disabled { opacity: .55; cursor: progress; }
.s-sw-piste {
  position: relative; display: block; width: 44px; height: 26px; border-radius: var(--r-pilule);
  background: var(--champ-bord); transition: background-color var(--duree) ease-out;
}
.s-sw-pouce {
  position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: var(--r-pilule);
  background: var(--surface); box-shadow: 0 1px 2px rgba(0, 0, 0, .3); transition: transform var(--duree) ease-out;
}
button.s-sw[aria-checked="true"] .s-sw-piste { background: var(--ardoise); }
button.s-sw[aria-checked="true"] .s-sw-pouce { transform: translateX(18px); }
button.s-sw:focus-visible .s-sw-piste { outline: 2px solid var(--ardoise); outline-offset: 3px; }
label.s-sw-libelle {
  display: inline-block; margin: 0; padding: var(--e-8) 0; cursor: pointer; color: var(--texte-1);
  font: var(--g-fort) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
@media (prefers-reduced-motion: reduce) {
  .s-sw-piste, .s-sw-pouce { transition: none; }
}
/* Une phrase d'échec, en ligne, sous le réglage qui a échoué. */
.s-en-ligne {
  flex: 1 1 100%; margin: 0 0 var(--e-4); color: var(--ton-erreur);
  font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif); overflow-wrap: anywhere;
}
.s-en-ligne[hidden] { display: none; }

.s-segmente-bloc { display: block; }
.s-segmente-libelle {
  display: block; margin: 0 0 var(--e-8); color: var(--texte-1);
  font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif);
}
.s-segmente { display: inline-flex; max-width: 100%; border: 1px solid var(--champ-bord); border-radius: var(--r-8); background: var(--surface); }
button.s-seg {
  min-height: var(--cible); min-width: var(--cible); padding: 0 var(--e-16); margin: 0;
  background: transparent; color: var(--texte-1); border: 0; border-radius: 0; cursor: pointer;
  font: var(--g-fort) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
button.s-seg:first-child { border-radius: calc(var(--r-8) - 1px) 0 0 calc(var(--r-8) - 1px); }
button.s-seg:last-child { border-radius: 0 calc(var(--r-8) - 1px) calc(var(--r-8) - 1px) 0; }
button.s-seg:hover:not(:disabled) { background: var(--fond); color: var(--texte-1); }
button.s-seg[aria-checked="true"], button.s-seg[aria-checked="true"]:hover:not(:disabled) { background: var(--ardoise); color: var(--texte-inverse); }
button.s-seg:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -4px; }
button.s-seg[aria-checked="true"]:focus-visible { outline-color: var(--texte-inverse); }
button.s-seg:disabled { opacity: .55; cursor: progress; }

/* ==========================================================================
 * Onglets — le balisage de `poserOnglets` est conservé (`.onglets`, `.onglet`,
 * `data-onglet`) ; `.s-onglets` ajoute ce qu'il faut pour que la feuille du
 * socle se suffise (la fixture ne charge pas toujours console.css) et que les
 * onglets du socle prennent l'ardoise, la cible de 44 px et le compteur.
 * Spécificité (0,4,0) : elle l'emporte sur `.onglets .onglet.actif` de console.css.
 * ======================================================================== */

.onglets.s-onglets {
  display: flex; flex-wrap: nowrap; gap: var(--e-4); margin: 0 0 var(--e-24);
  border-bottom: 1px solid var(--filet);
  /* UNE seule ligne : six onglets sous 768 px défilent, ils ne passent pas sur deux lignes. */
  overflow-x: auto; scrollbar-width: none;
}
.onglets.s-onglets::-webkit-scrollbar { display: none; }
.onglets.s-onglets .onglet {
  display: inline-flex; align-items: center; gap: var(--e-4); flex: 0 0 auto; white-space: nowrap;
  min-height: var(--cible); padding: var(--e-8) var(--e-16); margin: 0 0 -1px;
  background: transparent; color: var(--texte-2);
  border: 0; border-bottom: 2px solid transparent; border-radius: 0; cursor: pointer;
  font: var(--g-fort) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.onglets.s-onglets .onglet:hover { background: var(--fond); color: var(--texte-1); }
.onglets.s-onglets .onglet.actif { color: var(--ardoise); border-bottom-color: var(--ardoise); }
.onglets.s-onglets .onglet:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
.s-onglet-n { color: var(--ton-avert); }
.s-panneau[hidden] { display: none; }
@media (max-width: 767px) {
  .onglets.s-onglets .onglet { flex: 0 0 auto; padding: var(--e-8) var(--e-12); }
}

/* ==========================================================================
 * Accordéon (`<details>`) et carte à titre
 * ======================================================================== */

details.s-accordeon {
  margin: 0 0 var(--e-8); background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif); color: var(--texte-1);
}
details.s-accordeon > summary.s-acc-tete {
  display: flex; align-items: center; gap: var(--e-8); min-height: var(--cible); padding: 0 var(--e-16);
  list-style: none; cursor: pointer; border-radius: var(--r-12);
}
details.s-accordeon > summary.s-acc-tete::-webkit-details-marker { display: none; }
details.s-accordeon > summary.s-acc-tete:hover { background: var(--fond); }
details.s-accordeon > summary.s-acc-tete:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
.s-acc-libelle { font-weight: var(--g-fort); min-width: 0; overflow-wrap: anywhere; }
/* La valeur d'en-tête (« 4 actifs ») est un STATUT : 7:1, donc l'encre du texte, pas le gris secondaire. */
.s-acc-valeur { min-width: 0; color: var(--texte-1); overflow-wrap: anywhere; }
.s-acc-valeur::before { content: "·"; margin: 0 var(--e-8) 0 0; }
.s-acc-valeur[hidden] { display: none; }
details.s-accordeon > summary .s-icone { margin-left: auto; transition: transform var(--duree) ease-out; }
details.s-accordeon[open] > summary .s-icone { transform: rotate(180deg); }
.s-acc-corps { padding: var(--e-4) var(--e-16) var(--e-16); }
@media (prefers-reduced-motion: reduce) { details.s-accordeon > summary .s-icone { transition: none; } }

section.s-carte {
  min-width: 0; margin: 0 0 var(--e-16); padding: var(--e-24);
  background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif); color: var(--texte-1);
}
.s-carte-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--e-8); margin: 0 0 var(--e-16); }
.s-carte-titre { margin: 0; color: var(--texte-1); font: var(--g-fort) var(--t-16)/var(--l-16) var(--police, system-ui, sans-serif); }
button.s-aide-bouton {
  flex: 0 0 auto; width: var(--cible); height: var(--cible); margin: calc(-1 * var(--e-8)) calc(-1 * var(--e-8)) calc(-1 * var(--e-8)) 0; padding: 0;
  background: transparent; border: 0; border-radius: var(--r-pilule); color: var(--texte-2); cursor: pointer;
  font: var(--g-fort) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
button.s-aide-bouton:hover:not(:disabled) { background: var(--fond); color: var(--ardoise); }
button.s-aide-bouton:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
.s-aide { margin: 0 0 var(--e-16); padding: var(--e-12); background: var(--fond); border-radius: var(--r-8); color: var(--texte-1); }
.s-aide[hidden] { display: none; }
@media (max-width: 767px) { section.s-carte { padding: var(--e-16); } }

/* ==========================================================================
 * Menu « … » (divulgation)
 * ======================================================================== */

.s-menu { position: relative; display: inline-block; }
button.s-menu-bouton {
  display: inline-flex; align-items: center; justify-content: center; width: var(--cible); height: var(--cible); padding: 0;
  background: transparent; border: 0; border-radius: var(--r-8); color: var(--texte-2); cursor: pointer;
}
button.s-menu-bouton:hover:not(:disabled), button.s-menu-bouton[aria-expanded="true"] { background: var(--fond); color: var(--ardoise); }
button.s-menu-bouton:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
button.s-menu-bouton .s-icone { width: var(--t-20); height: var(--t-20); fill: currentColor; stroke: none; }
.s-menu-panneau {
  position: absolute; right: 0; top: calc(100% + var(--e-4)); z-index: 60; min-width: 240px; max-width: min(360px, 80vw);
  padding: var(--e-4); background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-8); box-shadow: var(--ombre);
  text-align: left;
}
.s-menu-panneau[hidden] { display: none; }
button.s-menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-12); width: 100%; min-height: var(--cible);
  padding: var(--e-8) var(--e-12); margin: 0; background: transparent; color: var(--texte-1);
  border: 0; border-radius: var(--r-8); cursor: pointer; text-align: left;
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
button.s-menu-item:hover:not(:disabled) { background: var(--fond); color: var(--texte-1); }
button.s-menu-item:focus-visible { outline: 2px solid var(--ardoise); outline-offset: -2px; }
button.s-menu-item--danger, button.s-menu-item--danger:hover:not(:disabled) { color: var(--ton-erreur); }
button.s-menu-item[aria-pressed="true"] { font-weight: var(--g-fort); background: var(--ton-cours-fond); }

/* ==========================================================================
 * Liste d'objets — barre, tableau dense, carte sous 768 px, pied
 * ======================================================================== */

.s-liste { min-width: 0; font: var(--g-normal) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif); color: var(--texte-1); }
.s-liste-barre { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-8) var(--e-12); margin: 0 0 var(--e-12); }
.s-recherche { position: relative; flex: 1 1 240px; min-width: 0; max-width: 480px; }
.s-recherche > .s-icone { position: absolute; left: var(--e-12); top: 50%; transform: translateY(-50%); color: var(--texte-2); pointer-events: none; }
.s-liste input.s-recherche-entree {
  display: block; width: 100%; min-height: var(--cible); padding: var(--e-8) var(--e-12) var(--e-8) calc(var(--e-32) + var(--e-8));
  background: var(--surface); color: var(--texte-1); border: 1px solid var(--champ-bord); border-radius: var(--r-8);
  font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
}
.s-liste input.s-recherche-entree::placeholder { color: var(--invite); opacity: 1; }
.s-liste input.s-recherche-entree:hover { border-color: var(--texte-2); }
.s-liste input.s-recherche-entree:focus, .s-liste input.s-recherche-entree:focus-visible {
  outline: 2px solid var(--ardoise); outline-offset: 1px; border-color: var(--ardoise); box-shadow: none;
}
.s-filtres { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-8); min-width: 0; }
.s-filtres-liste { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-8); min-width: 0; }
.s-filtres .s-menu-filtre { display: inline-block; }
button.s-filtre {
  display: inline-flex; align-items: center; gap: var(--e-8); min-height: var(--cible); padding: 0 var(--e-16); margin: 0;
  background: var(--surface); color: var(--texte-1); border: 1px solid var(--champ-bord); border-radius: var(--r-pilule); cursor: pointer;
  white-space: nowrap; font: var(--g-fort) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif);
}
button.s-filtre:hover:not(:disabled) { background: var(--fond); color: var(--texte-1); border-color: var(--champ-bord); }
button.s-filtre[aria-pressed="true"], button.s-filtre[aria-pressed="true"]:hover:not(:disabled) { background: var(--ardoise); color: var(--texte-inverse); border-color: var(--ardoise); }
button.s-filtre:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }
.s-filtre-n { font-weight: var(--g-normal); font-variant-numeric: tabular-nums; }
button.s-filtre[aria-pressed="true"] .s-filtre-n { color: var(--texte-inverse); }
.s-filtres-autres .s-filtre-n { color: var(--texte-2); }
.s-liste-compteur { margin-left: auto; color: var(--texte-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.s-tri-select {
  display: none; min-height: var(--cible); padding: 0 var(--e-12); background: var(--surface); color: var(--texte-1);
  border: 1px solid var(--champ-bord); border-radius: var(--r-8); font: var(--g-normal) var(--t-14)/var(--l-14) var(--police, system-ui, sans-serif);
  width: auto; max-width: 100%;
}
.s-tri-select:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 1px; }

.s-liste-corps { min-width: 0; }
.s-liste table.s-liste-table {
  width: 100%; border-collapse: separate; border-spacing: 0; table-layout: auto;
  background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12); font-size: var(--t-13);
}
.s-liste .s-th {
  padding: 0 var(--e-16); text-align: left; text-transform: none; letter-spacing: 0; white-space: nowrap;
  background: var(--fond); color: var(--texte-2); border-bottom: 1px solid var(--filet);
  font: var(--g-fort) var(--t-12)/var(--l-12) var(--police, system-ui, sans-serif);
}
.s-liste .s-th:first-child { border-top-left-radius: var(--r-12); }
.s-liste .s-th:last-child { border-top-right-radius: var(--r-12); }
.s-liste .s-th-menu { width: calc(var(--cible) + var(--e-12)); }
button.s-tri-bouton {
  display: inline-flex; align-items: center; gap: var(--e-4); min-height: var(--cible); min-width: var(--cible); padding: 0; margin: 0;
  background: transparent; color: inherit; border: 0; border-radius: var(--r-8); cursor: pointer; font: inherit;
}
button.s-tri-bouton:hover:not(:disabled) { background: transparent; color: var(--texte-1); }
button.s-tri-bouton:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }
button.s-tri-bouton .s-icone { width: var(--t-14); height: var(--t-14); }
.s-liste th[aria-sort="ascending"], .s-liste th[aria-sort="descending"] { color: var(--texte-1); }
.s-liste td.s-c {
  padding: var(--e-12) var(--e-16); vertical-align: middle; border-bottom: 1px solid var(--filet);
  overflow-wrap: anywhere; min-width: 0; font: var(--g-normal) var(--t-13)/var(--l-13) var(--police, system-ui, sans-serif); color: var(--texte-1);
}
.s-liste tbody tr:last-child td.s-c { border-bottom: 0; }
.s-liste tr.s-ligne:hover td.s-c, .s-liste tr.s-ligne:focus-within td.s-c { background: var(--fond); }
.s-liste tr.s-ligne-lien { cursor: pointer; }
.s-liste td.s-c-menu { width: calc(var(--cible) + var(--e-12)); padding: var(--e-4) var(--e-8); text-align: right; }
/* Le lien mesure 44 px de haut sans agrandir la ligne : le rembourrage est repris par la marge. */
.s-liste a.s-lien-ligne {
  display: inline-block; padding: calc((var(--cible) - var(--l-13)) / 2) 0; margin: calc((var(--cible) - var(--l-13)) / -2) 0;
  color: var(--ardoise); font-weight: var(--g-fort); text-decoration: none; border-radius: var(--r-8);
}
.s-liste a.s-lien-ligne:hover { text-decoration: underline; }
.s-liste a.s-lien-ligne:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 2px; }
.s-liste-pied { margin: var(--e-12) 0 0; color: var(--texte-2); font-variant-numeric: tabular-nums; }
.s-liste-pied:empty { display: none; }

@media (max-width: 767px) {
  /* Les pastilles défilent dans leur liste ; « Autres » reste à droite, hors du défilement : son menu
     n'est pas rogné. */
  .s-filtres { flex-wrap: nowrap; flex: 1 1 100%; }
  .s-filtres-liste { flex: 1 1 auto; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding: 2px 2px var(--e-4); }
  .s-filtres-liste::-webkit-scrollbar { display: none; }
  .s-filtres .s-menu-filtre { flex: 0 0 auto; }
  .s-tri-select { display: block; flex: 1 1 auto; }
  .s-liste-compteur { flex: 0 0 auto; }
  .s-recherche { max-width: none; flex: 1 1 100%; }

  /* Une CARTE par ligne. L'en-tête disparaît : chaque cellule porte le sien
     (`data-entete`), sauf la première, qui est le titre. */
  .s-liste table.s-liste-table, .s-liste table.s-liste-table tbody, .s-liste table.s-liste-table tr,
  .s-liste table.s-liste-table td { display: block; }
  .s-liste table.s-liste-table { background: transparent; border: 0; border-radius: 0; }
  .s-liste table.s-liste-table thead { display: none; }
  .s-liste tr.s-ligne {
    position: relative; margin: 0 0 var(--e-8); padding: var(--e-12) var(--e-16);
    background: var(--surface); border: 1px solid var(--filet); border-radius: var(--r-12);
  }
  .s-liste table.s-liste-table tbody tr:last-child td.s-c { border-bottom: 0; }
  .s-liste table.s-liste-table td.s-c {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--e-16);
    padding: var(--e-4) 0; border: 0; text-align: right; background: transparent;
  }
  .s-liste table.s-liste-table tr.s-ligne:hover td.s-c,
  .s-liste table.s-liste-table tr.s-ligne:focus-within td.s-c { background: transparent; }
  .s-liste table.s-liste-table td.s-c::before {
    content: attr(data-entete); flex: 0 0 auto; max-width: 45%; text-align: left;
    color: var(--texte-2); font: var(--g-normal) var(--t-12)/var(--l-12) var(--police, system-ui, sans-serif);
  }
  .s-liste table.s-liste-table td.s-c-titre {
    display: block; padding: 0 var(--cible) var(--e-8) 0; margin: 0 0 var(--e-4); text-align: left;
    font: var(--g-fort) var(--t-16)/var(--l-16) var(--police, system-ui, sans-serif);
  }
  .s-liste table.s-liste-table td.s-c-titre::before { content: none; }
  .s-liste table.s-liste-table td.s-c-menu { position: absolute; top: var(--e-4); right: var(--e-4); display: block; width: auto; padding: 0; margin: 0; }
  .s-liste table.s-liste-table td.s-c-menu::before { content: none; }
  .s-liste table.s-liste-table td.s-c:empty { display: none; }
}

/* ==========================================================================
 * Champs à 16 px sous 768 px : sous 16 px, iOS zoome la page au focus d'un champ — et la fenêtre visuelle que suit la
 * barre d'enregistrement (`visualViewport`) n'est plus celle qu'on croit.
 * ======================================================================== */
@media (max-width: 767px) {
  .s-champ .s-entree, .s-liste input.s-recherche-entree, .s-tri-select {
    font-size: var(--t-16); line-height: var(--l-16);
  }
}
