/* ==========================================================================
   Kit d'en-tete standard de la plateforme gher.io
   Barre de navigation commune (marque a gauche, items a droite, hamburger
   en mobile) + bande d'identite de l'application.
   Autonome : aucune dependance, valeurs de charte en dur, classes prefixees
   .hap- pour ne jamais entrer en collision avec le CSS de l'application.
   ========================================================================== */
/* --------------------------------------------------------------------------
 * her-appbar.css — FEUILLE COMMUNE au portail ET aux 27 applications.
 *
 * Qui la charge :
 *   - le PORTAIL : templates/layout.php, après her.css et her-v2.css (donc
 *     elle l'emporte à spécificité égale), avant le <style id="herPersoCss">
 *     d'habillage de l'en-tête ;
 *   - les APPLICATIONS : injectée par /assets/her-appbar.js (constante
 *     CSS_URL), lui-même ajouté à chaque page HTML d'app par la passerelle
 *     (AppGateway) ou appelé par l'app ; her-appbar.js charge ensuite
 *     /assets/her-appbar-perso.css (PersonnalisationRepository::cssAppbar(),
 *     route publique de public/index.php), qui repeint le fond de `.hap-bar`
 *     et de `.hap-nav` selon le réglage d'entête de l'administrateur.
 *
 * Contrôlée par src/Controle/Registre.php : l'interrupteur (I01/I02) doit
 * être défini ICI et nulle part ailleurs, et toute variable `var(--her-*)`
 * doit porter un repli (les variables du portail n'existent pas dans une app).
 *
 * Balisage attendu — posé par her-appbar.js (bandeau) :
 *   header.hap-header > .hap-bar > (.hap-left > a.hap-brand [.hap-logo-pastille
 *   > img, b] + .hap-crumb [.hap-crumb-sep, a.hap-crumb-link]) + nav.hap-nav
 *   (a, a.is-active, .hap-sep, a.hap-appitem, .hap-appsep) + button.hap-burger
 *   (3 span, classe `open`) ; puis .hap-id (img, .hap-t, .hap-d) et
 *   footer.hap-footer.
 * Balisage attendu — posé par les pages (portail comme apps) :
 *   label.hap-switch > input[type=checkbox] + span.hap-switch__track
 *   (voisins IMMÉDIATS), label.hap-bascule (+ .hap-bascule__mot),
 *   .hap-setting (.hap-setting__text/__title/__help/__state),
 *   section.hap-panel > h2.hap-panel__titre (sous-sections des Paramètres) ;
 *   les classes .hap-ag-* (écran « Accès gestionnaire ») ne sont posées QUE
 *   par window.HerAccesGestionnaire (her-appbar.js), jamais par une page ; le bouton
 *   .hap-help-btn et les classes .hap-has-help / .hap-open / .is-busy /
 *   .is-error sont posés par her-appbar.js.
 *   ⚠ Les attributs data-hap-confirm, data-hap-autosubmit, data-hap-live et
 *   data-hap-export sont lus par her-appbar.js ; aucune règle ici.
 *
 * Sommaire (chaque section est repérée par un commentaire « [§N] ») :
 *   1. Barre rouge : marque, navigation, hamburger
 *   2. Bande d'identité de l'application (.hap-id)
 *   3. Téléphone (≤ 760 px) : menu déroulant sous la barre
 *   4. Pied de page normalisé (.hap-footer)
 *   5. Groupe de gauche : marque + fil d'Ariane, et son arbitrage téléphone
 *   6. Interrupteur on/off (.hap-switch) : états, contraste forcé, animation
 *   7. Interrupteur suivi d'un mot (.hap-bascule)
 *   8. Ligne de réglage (.hap-setting) et bouton d'aide ⓘ
 *   9. Page « Paramètres » d'une application : titre et sous-onglets (.hap-tabs)
 *  10. Panneau blanc (.hap-panel) et écran « Accès gestionnaire » (.hap-ag-*)
 *  11. Outils du bandeau (.hap-outils)
 *  12. Accès réservés : clé, intertitre « Gestion », mention de titre (.hap-reserve-*)
 * -------------------------------------------------------------------------- */
/* ---- 1. Barre rouge : marque à gauche, navigation à droite, hamburger ----
 * Rouge de marque écrit en dur (#E2001A) : le kit n'a aucune variable ;
 * le réglage d'entête le remplace via her-appbar-perso.css. */
.hap-bar{position:relative;display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:0 24px;height:64px;background:#E2001A;color:#fff;
  box-shadow:0 2px 14px rgba(0,0,0,.07);font-family:Arial,Helvetica,sans-serif}
.hap-brand{display:flex;align-items:center;gap:12px;color:#fff;text-decoration:none}
.hap-brand img{height:26px;width:auto;display:block}
/* ⚠ Le logo du Groupe porte du rouge et du gris foncé : sur un bandeau rouge il
   serait illisible. Pastille blanche — on ne recolore pas une marque pour
   l'accommoder, ce serait en livrer une autre. Même traitement qu'au portail. */
.hap-logo-pastille{background:#fff;padding:5px 9px;border-radius:8px;display:flex;
  align-items:center;line-height:0;flex:0 0 auto}
.hap-brand b{font-size:18px;font-weight:bold;letter-spacing:.2px;white-space:nowrap}
/* Navigation de droite : liens de l'app (ou du menu effectif servi par
   * /me/menu.json), séparateurs, lien actif souligné. */
.hap-nav{display:flex;align-items:center;gap:18px;font-size:14px}
.hap-nav a{color:#fff;font-weight:bold;text-decoration:none;white-space:nowrap}
.hap-nav a:hover{text-decoration:underline}
.hap-nav a.is-active{text-decoration:underline;text-underline-offset:4px}
.hap-nav .hap-sep{width:1px;height:20px;background:rgba(255,255,255,.4)}
/* Bouton hamburger : caché sur écran large ; ses trois traits forment une
   * croix quand her-appbar.js lui pose la classe `open`. */
.hap-burger{display:none;background:none;border:0;cursor:pointer;padding:8px;flex-direction:column;gap:5px}
.hap-burger span{display:block;width:24px;height:2px;background:#fff;border-radius:2px;
  transition:transform .2s,opacity .2s}
.hap-burger.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.hap-burger.open span:nth-child(2){opacity:0}
.hap-burger.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
/* [§2] */
/* Bande d'identite de l'application (sous la barre rouge) */
.hap-id{display:flex;align-items:center;gap:14px;padding:12px 24px;background:#fff;
  border-bottom:1px solid #E3E3E5;font-family:Arial,Helvetica,sans-serif}
.hap-id img{width:40px;height:40px;border-radius:10px;object-fit:cover;background:#fff;border:1px solid #E3E3E5}
.hap-id .hap-t{font-size:18px;font-weight:bold;color:#2B2B2B;line-height:1.2}
.hap-id .hap-d{font-size:13px;color:#6B6B6B;margin-top:2px}
/* ---- 3. Téléphone (≤ 760 px) : le menu devient un panneau déroulant ----
   * absolu sous la barre, ouvert par la classe `open` que pose le hamburger. */
@media (max-width:760px){
  .hap-burger{display:flex}
  .hap-bar{padding:0 16px}
  .hap-nav{position:absolute;top:100%;left:0;right:0;z-index:900;flex-direction:column;
    align-items:stretch;gap:0;background:#E2001A;box-shadow:0 2px 14px rgba(0,0,0,.07);
    padding:4px 0;display:none}
  .hap-nav.open{display:flex}
  .hap-nav a{padding:12px 18px;width:100%}
  .hap-nav .hap-sep{display:none}
  .hap-id{padding:10px 16px}
}

/* ---- 3 bis. Menu trop long pour la barre, sur PC (07/10/2026) ----
   her-appbar.js pose `.hap-header--replie` quand le menu de l'app ne tient
   plus à droite du nom (il le recouvrait : 10 entrées dans l'Annuaire, et la
   clé des accès réservés ajoute ~120 px). Le menu passe alors au déroulant du
   téléphone, quelle que soit la largeur ; la marque et le nom restent ceux du
   PC. Mêmes règles que le §3 et le §12 téléphone : les tenir ensemble. */
.hap-header--replie .hap-burger{display:flex}
.hap-header--replie .hap-nav{position:absolute;top:100%;left:auto;right:0;z-index:900;flex-direction:column;
  align-items:stretch;gap:0;background:#E2001A;box-shadow:0 2px 14px rgba(0,0,0,.07);
  padding:4px 0;display:none;min-width:280px;max-width:100%}
.hap-header--replie .hap-nav.open{display:flex}
.hap-header--replie .hap-nav a{padding:12px 18px}
.hap-header--replie .hap-nav .hap-sep{display:none}
.hap-header--replie .hap-nav .hap-appgroupe{display:block;margin-top:4px;padding:12px 18px 4px;
  border-top:1px solid rgba(255,255,255,.3);color:rgba(255,255,255,.8);
  font-size:11px;font-weight:bold;letter-spacing:.8px;text-transform:uppercase}
.hap-header--replie .hap-nav .hap-appgroupe:first-child{margin-top:0;border-top:0}
.hap-header--replie .hap-nav .hap-appgroupe ~ .hap-appsep{display:block;width:auto;height:1px;margin:4px 0;
  background:rgba(255,255,255,.3)}

/* ⚠ Les styles de l'item « Favoris » ont été retirés avec le composant
   (25/08/2026). Mon premier retrait, ligne à ligne, avait laissé DEUX
   SÉLECTEURS ORPHELINS suivis d'une virgule : les accolades s'équilibraient
   toujours, et le `@media` qui suivait se retrouvait avalé par la liste de
   sélecteurs — donc ignoré. Compter les accolades ne prouve pas qu'une feuille
   est valide. */

/* [§4] */
/* Footer normalisé (identique au portail), injecté par her-appbar.js */
.hap-footer{
  max-width:680px;margin:26px auto 50px;padding:0 20px;
  display:flex;flex-wrap:wrap;gap:8px 18px;justify-content:space-between;
  font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#6b7280;
}
.hap-footer a{color:#6b7280;text-decoration:none}
.hap-footer a:hover{color:#2B2B2B;text-decoration:underline}

/* [§5] */
/* ---- Groupe de gauche : marque + fil d'Ariane « › Nom de l'application » ---- */
.hap-left{display:flex;align-items:center;gap:12px;min-width:0}
.hap-crumb{display:flex;align-items:center;gap:10px;min-width:0}
.hap-crumb-sep{color:rgba(255,255,255,.7);font-size:20px;line-height:1}
.hap-crumb-link{color:#fff;text-decoration:none;font-size:18px;font-weight:bold;letter-spacing:.2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:34vw;opacity:.95}
.hap-crumb-link:hover{text-decoration:underline;opacity:1}
.hap-crumb-link:focus-visible{outline:2px solid #fff;outline-offset:2px;border-radius:4px}
/* ==========================================================================
   SUR TÉLÉPHONE : LE LOGO, PUIS LE NOM DE L'APPLICATION.
   --------------------------------------------------------------------------
   ⚠ C'EST L'INVERSE DE CE QUI SE FAISAIT (25/08/2026). Le fil d'Ariane — donc
     le nom de l'application — était masqué sur petit écran, et il ne restait
     que « Portail PoC IA HER ». Sur un écran étroit, c'est le contraire qui
     aide : on sait qu'on est sur le portail, on veut savoir DANS QUOI.

   ⚠ Le lien vers l'accueil du portail n'est pas perdu : il est porté par le
     LOGO, qui reste cliquable. Retirer un texte ne doit jamais retirer un
     chemin.
   ========================================================================== */
@media (max-width:760px){
  .hap-brand b{display:none}
  .hap-crumb{display:flex}
  .hap-crumb-sep{display:none}          /* plus rien à séparer */
  .hap-crumb-link{font-size:16px;max-width:52vw}
  .hap-left{gap:8px}
}

/* [§6] */
/* ==========================================================================
   INTERRUPTEUR on/off  (§1 du portage Portail 357)
   --------------------------------------------------------------------------
   Composant MUTUALISÉ : il vit ici, dans la feuille servie à la fois au
   portail et aux applications, et NULLE PART AILLEURS. Recopié par
   application, il divergerait à la première retouche — sur un geste que
   l'utilisateur doit justement reconnaître d'un coup d'œil.

   Tous les `var()` portent un REPLI : les variables de couleur du portail
   n'existent pas dans une application, et une variable non résolue ne lève
   rien — le filet et le contour disparaîtraient simplement.

   Balisage attendu (l'ordre des deux enfants est IMPÉRATIF) :

     <label class="hap-switch">
       <input type="checkbox" name="x" value="1"><span class="hap-switch__track"></span>
     </label>

   ⚠ C'est une CASE À COCHER HABILLÉE, jamais un bouton en JavaScript :
     elle garde la barre d'espace, l'ordre de tabulation, l'annonce par un
     lecteur d'écran et la soumission du formulaire.
   ⚠ La case et la piste sont voisines IMMÉDIATES : l'état se lit par le
     sélecteur de voisinage direct `input:checked + .hap-switch__track`.
     Glisser QUOI QUE CE SOIT entre les deux — même un commentaire HTML — et
     l'interrupteur cesse de changer d'apparence, SANS LA MOINDRE ERREUR.
   ========================================================================== */
.hap-switch{
  position:relative;display:inline-flex;align-items:center;
  flex:0 0 auto;vertical-align:middle;cursor:pointer;
}
/* La case reste dans le flux et reste focalisable : on la rend seulement
   invisible. `display:none` ou `visibility:hidden` la sortiraient de l'ordre
   de tabulation et la retireraient au lecteur d'écran. */
.hap-switch input[type="checkbox"]{
  position:absolute;top:0;left:0;width:100%;height:100%;
  margin:0;opacity:0;cursor:pointer;z-index:1;
}
/* ⚠ La piste ne doit PAS être un élément inline : un `span` ignore largeur,
   hauteur et débordement, et s'étirerait sur la hauteur de la ligne de texte. */
.hap-switch__track{
  display:inline-block;position:relative;
  width:44px;height:24px;flex:0 0 44px;border-radius:999px;
  background:#c9ccd1;
  border:1px solid var(--her-line,#E3E3E5);
  transition:background-color .16s ease-in-out;
}
.hap-switch__track::after{
  content:"";position:absolute;top:2px;left:2px;
  width:18px;height:18px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.28);
  transition:transform .16s ease-in-out;
}
/* ⚠ La couleur du « allumé » est FONCTIONNELLE (vert franc) et ne suit donc
   PAS la couleur de marque réglée par l'administrateur : une couleur de
   marque pâle rendrait les deux états indiscernables. Écrite en dur, sans
   variable, délibérément. */
.hap-switch input[type="checkbox"]:checked + .hap-switch__track{
  background:#1B8A3A;border-color:#166F2F;
}
.hap-switch input[type="checkbox"]:checked + .hap-switch__track::after{
  transform:translateX(20px);
}
.hap-switch input[type="checkbox"]:focus-visible + .hap-switch__track{
  outline:2px solid #1565C0;outline-offset:2px;
}
.hap-switch input[type="checkbox"]:disabled + .hap-switch__track{
  opacity:.45;cursor:not-allowed;
}
.hap-switch input[type="checkbox"]:disabled{cursor:not-allowed}
/* Pendant l'aller-retour serveur : la piste dit qu'elle attend. */
.hap-switch.is-busy .hap-switch__track{opacity:.6}

/* ⚠⚠ EN CONTRASTE FORCÉ, L'INTERRUPTEUR NE DIT PLUS RIEN. Le système repeint
   fonds et bordures avec SA palette : la piste allumée et la piste éteinte
   deviennent deux pastilles identiques, et l'utilisateur qui a le plus besoin
   de contraste est celui qui ne peut plus lire l'état. On rend alors la case
   à cocher NATIVE — dessinée par le système, elle, avec sa coche — et l'on
   retire la piste. La case n'a jamais quitté le document : il suffit de la
   remettre dans le flux.
   ⚠ Repris de « Envoi sécurisé », qui portait cette garde pour son propre
     interrupteur : en adoptant le composant commun, elle l'aurait perdue —
     homogénéiser ne doit rien retirer à personne. */
@media (forced-colors: active){
  .hap-switch input[type="checkbox"]{
    position:static;opacity:1;width:auto;height:auto;margin:0;
  }
  .hap-switch__track{display:none}
}
/* Qui demande moins d'animation n'en reçoit aucune : la piste change d'état
   sans glisser. L'état, lui, reste parfaitement lisible. */
@media (prefers-reduced-motion: reduce){
  .hap-switch__track,
  .hap-switch__track::after{transition:none}
}

/* [§7] */
/* ---- L'interrupteur SUIVI D'UN MOT ---------------------------------------
   Quand le libellé tient en un mot (« terminal », « proposée ») et doit rester
   cliquable avec l'interrupteur, on enveloppe le tout dans UN label.

   ⚠ Le `label` enveloppe, il ne remplace pas : la piste reste le frère
     IMMÉDIAT de la case, sans quoi l'état cesse de s'afficher (contrôle I02).
   ⚠ Écrit ICI, dans la feuille commune, et nulle part ailleurs : deux
     gabarits du portail en avaient chacun leur copie, allumée en ROUGE de
     marque — là où l'interrupteur commun s'allume en vert franc. Deux
     interrupteurs contradictoires dans le même portail, et le contrôle I01
     ne voyait ni l'un ni l'autre : il ne regardait que les feuilles .css. */
.hap-bascule{
  display:inline-flex;align-items:center;gap:8px;
  cursor:pointer;font-weight:400;margin:0;
  /* ⚠ `flex-direction` EST DÉCLARÉE, et ce n'est pas une redondance : les
     applications posent souvent cette classe sur un libellé de formulaire déjà
     en colonne (`.champ`, `.abo__field`…). Sans cette ligne, l'interrupteur
     s'empile AU-DESSUS de son mot au lieu de le précéder — et rien ne le
     signale : la page reste valide, elle est seulement fausse. */
  flex-direction:row;
}
.hap-bascule__mot{
  font-size:.9em;color:var(--her-muted,#6B6B6B);line-height:1.3;
}
@media (max-width:820px){
  /* La même cible tactile de 44 px que le reste des écrans d'administration. */
  .hap-bascule{min-height:44px}
}

/* [§8] */
/* ---- La ligne de réglage : titre, explication, interrupteur -------------- */
.hap-setting{
  display:flex;align-items:flex-start;gap:14px;
  padding:12px 0;border-top:1px solid var(--her-line,#E3E3E5);
}
.hap-setting:first-of-type{border-top:0}
.hap-setting__text{flex:1 1 auto;min-width:0}
.hap-setting__title{
  display:block;font-weight:700;color:var(--her-ink,#2B2B2B);
  font-size:15px;line-height:1.35;
}
.hap-setting__help{
  display:block;margin-top:3px;
  font-size:13px;line-height:1.45;color:var(--her-muted,#6B6B6B);
}
.hap-setting__state{
  display:block;margin-top:4px;font-size:12px;color:var(--her-muted,#6B6B6B);
}
.hap-setting__state.is-error{color:#8A0012;font-weight:700}
/* Le bouton ⓘ est posé par her-appbar.js, jamais par l'application. */
.hap-help-btn{
  display:none;margin-left:6px;padding:0;
  width:18px;height:18px;line-height:16px;text-align:center;
  border:1px solid var(--her-line,#c9ccd1);border-radius:50%;
  background:transparent;color:var(--her-muted,#6B6B6B);
  font:inherit;font-size:12px;font-weight:700;cursor:pointer;vertical-align:1px;
}
.hap-help-btn:hover{background:#f2f3f5;color:var(--her-ink,#2B2B2B)}
.hap-help-btn:focus-visible{outline:2px solid #1565C0;outline-offset:1px}

/* Sur un écran large la place existe : UN TEXTE VISIBLE VAUT TOUJOURS MIEUX
   QU'UN TEXTE CACHÉ. Le repli derrière le ⓘ ne sert qu'au téléphone.

   ⚠ Le masquage doit être ASSEZ SPÉCIFIQUE — et une media query n'ajoute
   AUCUNE spécificité. `.hap-setting__help` est stylé plus haut par un
   sélecteur à UNE classe ; on masque ici par un sélecteur à DEUX classes,
   posé plus bas dans la feuille. Les deux conditions (spécificité ET ordre)
   sont réunies volontairement : sur le portail d'origine, le ⓘ apparaissait
   et le texte restait. */
@media (max-width:760px){
  .hap-setting.hap-has-help .hap-setting__help{display:none}
  .hap-setting.hap-has-help.hap-open .hap-setting__help{display:block}
  .hap-setting .hap-help-btn{display:inline-block}
}

/* [§9] */
/* ==========================================================================
   PAGE « PARAMÈTRES » D'UNE APPLICATION : TITRE ET SOUS-ONGLETS  (01/10/2026)
   --------------------------------------------------------------------------
   Le MÊME dessin que la page Paramètres du portail (.param-tabs de her.css) :
   un administrateur passe du portail à une application sans changer de
   repères. Composant MUTUALISÉ, comme l'interrupteur : il vit ici et nulle
   part ailleurs, et chaque var() porte un repli (les variables du portail
   n'existent pas dans une application).

   Balisage attendu :

     <h1 class="hap-page-title">Paramètres</h1>
     <nav class="hap-tabs" aria-label="Sections des paramètres">
       <a class="hap-tab is-active" aria-current="page"
          data-onglet="acces-gestionnaire" href="?v=parametres&onglet=acces-gestionnaire">Accès gestionnaire</a>
       <a class="hap-tab" data-onglet="general" href="?v=parametres&onglet=general">Général</a>
     </nav>

   Un onglet tenu en JavaScript prend <button type="button" class="hap-tab">
   avec aria-selected : même dessin. Sur téléphone, la barre ne passe pas à
   la ligne : elle défile horizontalement, comme celle du portail.
   ========================================================================== */
.hap-page-title{color:var(--her-red,#E2001A);margin:0 0 10px}
.hap-tabs{
  display:flex;flex-wrap:wrap;gap:4px;margin:0 0 18px;
  border-bottom:2px solid var(--her-line,#E3E3E5);
}
.hap-tab{
  padding:9px 15px;text-decoration:none;color:var(--her-ink,#2B2B2B);font:inherit;font-weight:600;
  background:transparent;border:1px solid transparent;border-bottom:none;border-radius:8px 8px 0 0;
  white-space:nowrap;position:relative;top:2px;cursor:pointer;line-height:inherit;margin:0;
}
.hap-tab:hover{background:#f5f5f5}
.hap-tab:focus-visible{outline:2px solid #1565C0;outline-offset:1px}
.hap-tab.is-active,.hap-tab[aria-selected="true"]{
  background:#fff;border-color:var(--her-line,#E3E3E5);
  border-bottom:2px solid #fff;color:var(--her-red,#E2001A);
}
@media (max-width:760px){
  .hap-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch}
  .hap-tab{top:0;border-radius:8px;border-color:var(--her-line,#E3E3E5)}
  .hap-tab{min-height:44px;box-sizing:border-box;display:inline-flex;align-items:center}  /* cible du doigt */
  .hap-tab.is-active,.hap-tab[aria-selected="true"]{border-bottom:1px solid var(--her-line,#E3E3E5)}
}

/* [§10] */
/* ==========================================================================
   PANNEAU BLANC (.hap-panel) ET ÉCRAN « ACCÈS GESTIONNAIRE » (.hap-ag-*)
   (01/10/2026)
   --------------------------------------------------------------------------
   1. LE PANNEAU. Chaque sous-section des Paramètres d'une application est un
      panneau blanc posé sur le fond gris clair de la page (#F4F4F5, que
      l'application garde) : c'est le dessin de la carte du portail
      (.her-card de her.css), pour qu'un administrateur passe du portail à une
      application sans changer de repères. Il vit ICI et nulle part ailleurs :
      aucune règle d'application ne cible .hap-panel*. Recopié dans 17
      applications, il aurait 17 rayons et 17 ombres à la première retouche.

        <section class="hap-panel">
          <h2 class="hap-panel__titre">Titre de la sous-section</h2>
          …
        </section>

   2. L'ÉCRAN « ACCÈS GESTIONNAIRE ». Tout est dessiné par
      window.HerAccesGestionnaire (her-appbar.js) : l'application ne fournit
      qu'un conteneur et l'adresse de son API. Les classes .hap-ag-* ne sont
      donc écrites QUE par le script et stylées QUE par cette section.

   ⚠ Chaque var() porte un REPLI : les variables du portail n'existent pas
     dans une application, et une variable non résolue ne lève rien — le
     filet rouge et l'ombre disparaîtraient simplement (contrôle I01/I11).
   ⚠ Les sélecteurs de l'écran portent DEUX classes (.hap-ag .hap-ag__x) :
     les applications ont leurs propres règles `table td`, `select`,
     `button`… La double classe l'emporte sur elles sans `!important`.
   ⚠ Sur téléphone (≤ 760 px) le tableau devient des FICHES empilées, chaque
     valeur précédée de son intitulé (attribut data-label, lu par ::before) :
     un tableau à cinq colonnes ne tient pas sur 390 px, et le faire défiler
     de côté cacherait l'interrupteur — la colonne qui compte le plus.
   ========================================================================== */
.hap-panel{
  display:block;box-sizing:border-box;margin:0 0 22px;
  background:var(--her-white,#FFFFFF);
  color:var(--her-ink,#2B2B2B);
  border:1px solid var(--her-line,#E3E3E5);
  border-top:4px solid var(--her-red,#E2001A);
  border-radius:var(--her-radius,10px);
  box-shadow:var(--her-shadow,0 2px 14px rgba(0,0,0,.07));
  padding:30px 32px;
}
.hap-panel__titre{
  margin:0 0 12px;font-size:19px;line-height:1.3;font-weight:700;
  color:var(--her-ink,#2B2B2B);
}
@media (max-width:760px){
  .hap-panel{padding:22px 18px}
}

/* ---- L'écran « Accès gestionnaire » ------------------------------------- */
.hap-ag{font-family:inherit;font-size:14px;line-height:1.45}
.hap-ag .hap-ag__intro{margin:0 0 16px;color:var(--her-ink-soft,#6B6B6B);font-size:14px}
/* Texte réservé au lecteur d'écran (légende du tableau, précisions). */
.hap-ag .hap-ag__sr{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
/* Le tableau ne fait JAMAIS défiler la page de côté : s'il est plus large que
   le panneau (libellés de SAC très longs), c'est cette zone qui défile. */
.hap-ag .hap-ag__zone{width:100%;overflow-x:auto}
.hap-ag .hap-ag__table{
  width:100%;border-collapse:collapse;border-spacing:0;margin:0;
  background:transparent;font-size:14px;
}
.hap-ag .hap-ag__table th,
.hap-ag .hap-ag__table td{
  padding:8px 10px;border:0;border-bottom:1px solid var(--her-line,#E3E3E5);
  text-align:left;vertical-align:middle;background:transparent;color:inherit;
}
.hap-ag .hap-ag__table thead th{
  padding:0;border-bottom:2px solid var(--her-line,#E3E3E5);
  font-weight:700;white-space:nowrap;
}
/* L'en-tête est un BOUTON : il se trie au clavier comme à la souris. */
.hap-ag .hap-ag__tri{
  display:flex;align-items:center;gap:6px;width:100%;min-height:40px;margin:0;
  padding:8px 10px;border:0;border-radius:0;background:transparent;box-shadow:none;
  font:inherit;font-weight:700;color:var(--her-ink,#2B2B2B);text-align:left;cursor:pointer;
}
.hap-ag .hap-ag__tri:hover{background:#f5f5f5}
.hap-ag .hap-ag__tri:focus-visible{outline:2px solid #1565C0;outline-offset:-2px}
/* La flèche : discrète tant que la colonne n'est pas triée, franche sinon. */
.hap-ag .hap-ag__fleche{display:inline-block;min-width:1em;color:#9a9ca1;font-size:12px}
.hap-ag .hap-ag__tri[data-sens] .hap-ag__fleche{color:var(--her-red,#E2001A)}
.hap-ag .hap-ag__table tbody tr:hover{background:#fafafa}
.hap-ag .hap-ag__table tr.is-office{background:#f7f7f8}
.hap-ag .hap-ag__table tr.is-busy{opacity:.6}
/* Ligne ajoutée ou restaurée : un éclat bref pour la retrouver dans la liste. */
.hap-ag .hap-ag__table tr.is-nouvelle{background:#fff6d6}
.hap-ag .hap-ag__nom{font-weight:700}
/* « par le portail » : la ligne existe parce que le portail la donne. */
.hap-ag .hap-ag__badge{
  display:inline-block;margin-left:8px;padding:1px 8px;border-radius:999px;
  background:#eceef1;color:var(--her-ink-soft,#6B6B6B);
  font-size:12px;font-weight:700;white-space:nowrap;vertical-align:1px;
}
.hap-ag .hap-ag__badge--externe{background:#fff4e5;color:#8a4b00}
/* ⚠ La colonne du niveau reçoit une part FIXE de la largeur, et le
   sélecteur la remplit. En largeur naturelle, le libellé « Automatique
   (repris du portail : Sociétés de la SAC …) » élargissait le tableau
   au-delà du panneau : la zone défilait, et la colonne Société sortait de
   l'écran sans que rien ne le signale. */
.hap-ag .hap-ag__table th[data-col="niveau"]{width:40%}
.hap-ag .hap-ag__niveau{
  box-sizing:border-box;width:100%;max-width:100%;min-height:36px;margin:0;
  padding:6px 8px;font:inherit;font-size:14px;color:var(--her-ink,#2B2B2B);
  background:#fff;border:1px solid #c9ccd1;border-radius:6px;
}
.hap-ag .hap-ag__niveau:disabled{background:#f2f3f5;color:var(--her-ink-soft,#6B6B6B);cursor:not-allowed}
.hap-ag .hap-ag__niveau:focus-visible{outline:2px solid #1565C0;outline-offset:1px}
/* Le libellé global des formulaires du portail (label{display:block;margin…})
   décollerait l'interrupteur de sa cellule. */
.hap-ag label.hap-switch{margin:0;min-height:36px;min-width:44px;justify-content:center}
.hap-ag .hap-ag__date{white-space:nowrap;font-variant-numeric:tabular-nums}
.hap-ag .hap-ag__vide{margin:14px 0 0;color:var(--her-ink-soft,#6B6B6B)}

/* ---- La recherche à autocomplétion -------------------------------------- */
.hap-ag .hap-ag__recherche{position:relative;margin:22px 0 0;max-width:34em}
.hap-ag .hap-ag__etiquette{display:block;margin:0 0 6px;font-weight:700;font-size:14px}
.hap-ag .hap-ag__champ{
  box-sizing:border-box;display:block;width:100%;min-height:40px;margin:0;
  padding:8px 12px;font:inherit;font-size:15px;color:var(--her-ink,#2B2B2B);
  background:#fff;border:1px solid #c9ccd1;border-radius:6px;
}
.hap-ag .hap-ag__champ:focus{outline:2px solid #1565C0;outline-offset:1px;border-color:#1565C0}
.hap-ag .hap-ag__aide{margin:6px 0 0;font-size:13px;color:var(--her-ink-soft,#6B6B6B);min-height:1.2em}
.hap-ag .hap-ag__liste{
  position:absolute;left:0;right:0;top:100%;z-index:950;
  margin:4px 0 0;padding:4px 0;list-style:none;max-height:320px;overflow-y:auto;
  background:#fff;border:1px solid #c9ccd1;border-radius:6px;
  box-shadow:0 6px 22px rgba(0,0,0,.12);
}
.hap-ag .hap-ag__liste[hidden]{display:none}
.hap-ag .hap-ag__option{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;
  margin:0;padding:8px 12px;min-height:40px;box-sizing:border-box;cursor:pointer;
}
.hap-ag .hap-ag__option.is-actif{background:#e8f0fb;outline:2px solid #1565C0;outline-offset:-2px}
.hap-ag .hap-ag__option[aria-disabled="true"]{cursor:default;color:#8a8c91}
.hap-ag .hap-ag__option-soc{font-size:13px;color:var(--her-ink-soft,#6B6B6B)}
.hap-ag .hap-ag__option-deja{font-size:12px;font-style:italic}

/* ---- Messages : erreur et « Annuler » ----------------------------------
   Collés au bas de l'écran tant que le panneau est visible (sticky) : sur
   une longue liste, une erreur affichée en haut du tableau ne serait pas lue
   par qui vient de basculer la dernière ligne. */
.hap-ag .hap-ag__annonces{position:sticky;bottom:12px;z-index:940;margin:16px 0 0}
.hap-ag .hap-ag__erreur,
.hap-ag .hap-ag__toast{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;
  margin:8px 0 0;padding:10px 14px;border-radius:8px;font-size:14px;
}
.hap-ag .hap-ag__erreur[hidden],
.hap-ag .hap-ag__toast[hidden]{display:none}
.hap-ag .hap-ag__erreur{background:#fdecee;color:#8A0012;border:1px solid #f3b6be;font-weight:700}
.hap-ag .hap-ag__toast{background:#2B2B2B;color:#fff;box-shadow:0 4px 18px rgba(0,0,0,.2)}
.hap-ag .hap-ag__texte{flex:1 1 14em;min-width:0}
.hap-ag .hap-ag__bouton{
  min-height:36px;margin:0;padding:6px 14px;border-radius:6px;cursor:pointer;
  font:inherit;font-weight:700;border:1px solid currentColor;background:transparent;color:inherit;
}
.hap-ag .hap-ag__toast .hap-ag__bouton{color:#fff;border-color:rgba(255,255,255,.7)}
.hap-ag .hap-ag__bouton:focus-visible{outline:2px solid #1565C0;outline-offset:2px}
.hap-ag .hap-ag__toast .hap-ag__bouton:focus-visible{outline-color:#fff}

/* ---- Téléphone : des fiches empilées ------------------------------------ */
@media (max-width:760px){
  .hap-ag .hap-ag__zone{overflow-x:visible}
  .hap-ag .hap-ag__table,
  .hap-ag .hap-ag__table tbody,
  .hap-ag .hap-ag__table tr,
  .hap-ag .hap-ag__table td{display:block;width:auto}
  /* L'en-tête reste : il devient la barre de TRI, chaque intitulé un bouton. */
  .hap-ag .hap-ag__table thead{display:block}
  .hap-ag .hap-ag__table thead tr{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 12px}
  .hap-ag .hap-ag__table thead th,
  .hap-ag .hap-ag__table th[data-col="niveau"]{display:block;width:auto;border:0;padding:0}
  .hap-ag .hap-ag__tri{
    width:auto;min-height:44px;padding:6px 12px;font-size:13px;
    border:1px solid var(--her-line,#E3E3E5);border-radius:999px;background:#fff;
  }
  .hap-ag .hap-ag__table tbody tr{
    margin:0 0 12px;padding:6px 14px;border:1px solid var(--her-line,#E3E3E5);border-radius:8px;
  }
  .hap-ag .hap-ag__table tbody tr:hover{background:transparent}
  .hap-ag .hap-ag__table tbody tr.is-office{background:#f7f7f8}
  .hap-ag .hap-ag__table tbody tr.is-nouvelle{background:#fff6d6}
  .hap-ag .hap-ag__table td{
    display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:4px 12px;
    padding:8px 0;min-height:44px;box-sizing:border-box;overflow-wrap:anywhere;
  }
  .hap-ag .hap-ag__table td:last-child{border-bottom:0}
  .hap-ag .hap-ag__table td::before{
    content:attr(data-label);flex:0 0 auto;
    font-size:12px;font-weight:700;color:var(--her-ink-soft,#6B6B6B);
  }
  /* Le sélecteur prend toute la largeur, sous son intitulé. */
  .hap-ag .hap-ag__table td.hap-ag__c-niveau{flex-direction:column;align-items:stretch}
  .hap-ag .hap-ag__niveau{width:100%;min-height:44px;font-size:16px}
  .hap-ag label.hap-switch{min-height:44px;min-width:44px}
  .hap-ag .hap-ag__recherche{max-width:none}
  /* 16 px : en dessous, iOS agrandit la page au focus du champ. */
  .hap-ag .hap-ag__champ{min-height:44px;font-size:16px}
  .hap-ag .hap-ag__option{min-height:44px}
  .hap-ag .hap-ag__bouton{min-height:44px}
}

/* [§11] */
/* ---- Outils du bandeau : société · année · recherche (her-appbar.js, bloc 8) ----
   Sur ordinateur seulement (le bloc 8 ne déplace rien sous 761 px). Le design
   est celui du portail, quelle que soit l'application : les règles portent
   deux classes pour l'emporter sur la feuille de l'application (.ctx-bar,
   .gouv-select…), chargée avant celle-ci. */
.hap-outils{margin-left:auto;display:flex;align-items:center;justify-content:flex-end;gap:10px;min-width:0;flex:1 1 auto}
.hap-outils[hidden]{display:none}
.hap-outils__place{display:flex;align-items:center;position:relative;min-width:0}
.hap-outils__place:empty{display:none}
.hap-outils__place[data-place="societe"]{flex:0 1 280px}
.hap-outils__place[data-place="annee"]{flex:0 0 auto}
.hap-outils__place[data-place="recherche"]{flex:0 1 340px}
.hap-outils .hap-outil{margin:0;padding:0;border:0;box-shadow:none;background:none;
  display:flex;align-items:center;gap:0;width:100%;min-width:0;position:relative;border-radius:0}
.hap-outils .hap-outil label,.hap-outils .hap-outil svg{display:none}
.hap-outils select.hap-outil,.hap-outils .hap-outil select{
  width:100%;min-width:0;max-width:none;height:38px;padding:0 32px 0 14px;margin:0;
  font:14px/1.2 Arial,Helvetica,sans-serif;color:#2B2B2B;
  border:1px solid #E3E3E5;border-radius:999px;background-color:#F6F7F9;
  text-overflow:ellipsis;white-space:nowrap;overflow:hidden;cursor:pointer}
.hap-outils__place[data-place="societe"] select{min-width:180px}
.hap-outils__place[data-place="annee"] select{width:auto;min-width:96px}
.hap-outils .hap-outil input[type="search"]{
  width:100%;min-width:200px;height:38px;padding:0 14px 0 38px;margin:0;
  font:14px/1.2 Arial,Helvetica,sans-serif;color:#2B2B2B;
  border:1px solid #E3E3E5;border-radius:999px;background:#F6F7F9;box-shadow:none}
.hap-outils select.hap-outil:focus,.hap-outils .hap-outil select:focus,
.hap-outils .hap-outil input[type="search"]:focus{
  outline:none;border-color:#E2001A;background-color:#fff;box-shadow:0 0 0 3px rgba(226,0,26,.12)}
.hap-outil__loupe{position:absolute;left:13px;top:50%;transform:translateY(-50%);z-index:1;
  width:16px;height:16px;color:#6B6B6B;pointer-events:none;display:block}
.hap-outil__loupe svg{display:block;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
.hap-outils .hap-outil [data-hap-liste]{position:absolute;top:calc(100% + 6px);right:0;left:auto;
  width:min(520px,90vw);max-height:60vh;overflow-y:auto;z-index:950}
/* Société unique (data-hap-societe-seule) : une pastille, pas un sélecteur.
   Repère seul ; masquée hors du bandeau (téléphone). */
[data-hap-societe-seule]:not(.hap-outil){display:none}
.hap-outils__place[data-place="societe"]:has(.hap-societe){flex:0 0 auto}
.hap-outils .hap-societe{display:inline-flex;align-items:center;justify-content:center;width:auto;
  height:38px;padding:3px 14px;border:1px solid #E3E3E5;border-radius:999px;background:#fff;cursor:default}
.hap-outils .hap-societe img{display:block;max-height:30px;max-width:150px;width:auto;height:auto;object-fit:contain}
.hap-outils .hap-societe__acr{font:bold 14px/1 Arial,Helvetica,sans-serif;color:#2B2B2B;letter-spacing:.3px;
  white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis}
/* Téléphone : seule la pastille monte, en petit, à droite du nom. */
@media (max-width:760px){
  .hap-outils{gap:6px;flex:0 0 auto}
  .hap-outils .hap-societe{height:30px;padding:2px 10px}
  .hap-outils .hap-societe img{max-height:22px;max-width:96px}
  .hap-outils .hap-societe__acr{font-size:12px;max-width:110px}
}
/* Écran moyen : le descriptif cède la place aux outils, le nom reste. */
@media (max-width:1100px){
  .hap-id--outils .hap-d{display:none}
}

/* [§12] */
/* ---- Accès réservés : la clé des gestionnaires (her-appbar.js, bloc 9) ----
   Un seul repère pour tout ce que l'utilisateur standard ne voit pas : une
   petite clé devant le texte, la bulle (title) dit le rôle. Dessinée en
   currentColor : blanche dans le bandeau, couleur du texte ailleurs. Dans le
   menu, les entrées réservées viennent APRÈS un séparateur (PC) ou sous
   l'intertitre « Gestion » (menu déroulant du téléphone). Un titre de page
   réservé porte la mention écrite, en pastille discrète. */
/* Le dessin est un MASQUE : la clé d'origine ci-dessous ; un autre choix de
   l'administrateur redéfinit la variable dans her-appbar-perso.css, chargée
   après celle-ci (PersonnalisationRepository::RESERVE_PICTOS). */
:root{--hap-reserve-picto:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%222.4%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%227.5%22%20cy%3D%2215.5%22%20r%3D%224.5%22%2F%3E%3Cpath%20d%3D%22M10.7%2012.3%2020%203M16%207l3%203M14%209l2%202%22%2F%3E%3C%2Fsvg%3E")}
.hap-reserve-cle{display:inline-block;width:1.1em;height:1.1em;margin-right:.35em;vertical-align:-.18em;
  flex:0 0 auto;background-color:currentColor;
  -webkit-mask:var(--hap-reserve-picto) center/contain no-repeat;mask:var(--hap-reserve-picto) center/contain no-repeat}
.hap-reserve-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.hap-nav .hap-appgroupe{display:none}
.hap-reserve-mention{display:inline-flex;align-items:center;margin-left:12px;padding:3px 10px;
  font:600 12px/1.3 Arial,Helvetica,sans-serif;letter-spacing:.1px;color:#5A5A5A;vertical-align:middle;
  background:#F1F1F3;border:1px solid #E3E3E5;border-radius:999px;white-space:nowrap}
.hap-reserve-mention .hap-reserve-cle{margin-right:.4em}
@media (max-width:760px){
  .hap-nav .hap-appgroupe{display:block;margin-top:4px;padding:12px 18px 4px;
    border-top:1px solid rgba(255,255,255,.3);color:rgba(255,255,255,.8);
    font-size:11px;font-weight:bold;letter-spacing:.8px;text-transform:uppercase}
  .hap-nav .hap-appgroupe:first-child{margin-top:0;border-top:0}
  /* « Aide » et ce qui suit ne sont pas réservés : un trait ferme la section. */
  .hap-nav .hap-appgroupe ~ .hap-appsep{display:block;width:auto;height:1px;margin:4px 0;
    background:rgba(255,255,255,.3)}
  /* Sous un titre long, la mention passe à la ligne plutôt que de déborder. */
  .hap-reserve-mention{margin:6px 0 0;white-space:normal}
  h1 .hap-reserve-mention,h2 .hap-reserve-mention,h3 .hap-reserve-mention{display:flex;width:fit-content}
}
@media (forced-colors: active){
  .hap-reserve-mention{border-color:CanvasText}
  /* Le fond peint est retiré en contraste forcé : on force la couleur du texte. */
  .hap-reserve-cle{forced-color-adjust:none;background-color:CanvasText}
}
