/* ------------------------------------------------------------------ *
 * §25 — LA COQUILLE MOBILE (téléphone, debout ou couché).
 *
 * Chargée par `index.html` avec
 * `media="(max-width:767px), (pointer:coarse) and (max-height:500px)"` : sur un écran large
 * et haut, le navigateur ne l'applique JAMAIS. La seconde condition est le téléphone COUCHÉ
 * (un iPhone en paysage fait 844 px de large) ; `pointer:coarse` écarte la fenêtre de bureau
 * basse, qui n'est pas un téléphone. C'est pour cela qu'elle a son propre palier (30 Ko,
 * §25 §6) et qu'elle ne pèse pas sur le palier de la feuille bureau : les deux ne sont
 * jamais sur la même page. Elle est chargée APRÈS `ea-app.css` : à spécificité égale,
 * c'est elle qui gagne — inutile d'y répéter la gymnastique d'ordre du §23 volet 5.
 *
 * Le JS ne connaît aucune largeur (pas de `matchMedia` : absent de jsdom, et un test
 * l'interdit). Il pose TOUJOURS les nœuds de la coquille mobile — bouton de menu, avatar,
 * barre du bas, bouton « Appliquer » — et `ea-app.css` les cache ; cette feuille-ci les
 * rallume. Même idiome que le mode signalement (une classe sur `<body>`, la feuille
 * décide).
 *
 * Elle ne fait que DÉPLACER : mêmes routes, mêmes données, mêmes jetons (§25 §1). Aucune
 * couleur, aucune taille, aucune graisse écrite en dur — tout vient de `tokens.css`.
 *
 * Volet 1 (§§1-6) : la coquille. Volet 2 (§§7-13) : la mise en page par composant — cartes,
 * panneaux, cycles, tableaux, modales, champs, carte. Le tactile suit au volet 4, la vue BU
 * au volet 3 (après la fusion de `vue-bu` : rien n'est écrit ici pour elle).
 *
 * Les blocs mobiles d'`ea-app.css` portent la MÊME borne, mot pour mot, et le test d'hygiène
 * l'écrit une seule fois pour les trois endroits. Avant le §25 elle s'arrêtait à 599 px : entre
 * 600 et 767, aucun bloc ne s'appliquait — champs à 12,5 px (zoom iOS) et titres cassés à côté
 * de leurs contrôles.
 * ------------------------------------------------------------------ */

/* =====================================================================
   1. LA PAGE — l'écran ne défile pas, le canevas défile
   Au bureau, `.app` est une grille à deux colonnes et c'est le document qui défile. Sur un
   téléphone, la barre d'app et la barre du bas restent en place : elles bornent une zone
   centrale qui, elle, défile. `100dvh` suit la barre d'adresse mobile, qui se rétracte.
   ===================================================================== */
.app{display:block;min-height:0;height:100dvh;overflow:hidden;}
.main{height:100dvh;min-height:0;}
.canvas{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;}

/* Le bandeau de démonstration tient sur UNE ligne, tronqué (§25 §2), et passe SOUS la barre
   d'app comme dans la maquette : l'ordre visuel seulement, le DOM ne bouge pas (le bureau
   garde le sien, qui le met tout en haut). */
.demo{order:2;padding:6px 12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 0 auto;}
.topbar{order:1;}
.canvas{order:3;}
.tabbar{order:4;}

/* =====================================================================
   2. LA BARRE D'APP (haut, marine) — ☰ · réseau + rubrique · cloche · avatar
   `.topbar` porte déjà deux lignes au bureau (le titre, puis `.tr` qui prend toute la
   largeur) : la maquette mobile a la même forme. On teint la première en marine, on y
   pose le menu et l'avatar, et la seconde devient la sous-barre de réglages.
   ===================================================================== */
.topbar{position:relative;flex:0 0 auto;background:var(--marine);border-bottom:0;
  padding:calc(8px + var(--safe-t)) 10px 0;gap:8px;align-items:center;}
/* Trois boutons à droite depuis le 22/09 (commentaires, cloche, avatar) : le titre leur
   laisse la place, et se tronque plutôt que de passer dessous. */
.topbar>.tt{flex:1;min-width:0;padding-right:146px;}

.tb-burger{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:44px;height:44px;margin-left:-4px;padding:0;border:0;border-radius:8px;
  background:var(--sur-marine-12);color:var(--sur-marine);cursor:pointer;}
.tb-burger svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.9;}

/* Le fil d'Ariane devient la ligne de surtitre de la maquette (petites capitales) ; il ne
   garde que le périmètre courant, sans ses liens ni ses chevrons. */
.topbar .tt .bc{font-size:var(--fs-10);letter-spacing:.1em;text-transform:uppercase;
  color:var(--sur-marine-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.topbar .tt .bc a{color:inherit;text-decoration:none;pointer-events:none;}
.topbar .tt .bc .sep{margin:0 4px;}
.topbar .tt h1{font-size:var(--fs-16);color:var(--sur-marine);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;letter-spacing:0;}
/* Le sous-titre (« 57 Business Units · 84 agences… ») passe à la trappe : la place du
   téléphone va aux chiffres, et l'information reste dans la page. */
.topbar .tt p{display:none;}

/* Cloche et avatar sont posés dans la barre d'app, au-dessus de la sous-barre : le DOM les
   place plus bas (la cloche vit avec les contrôles), le bureau ne bouge donc pas d'une
   ligne. Position absolue, dans la hauteur connue de la première ligne. */
.topbar .cloche-alertes{position:fixed;top:calc(8px + var(--safe-t));right:56px;
  width:44px;height:44px;border-radius:8px;border:0;background:var(--sur-marine-12);color:var(--sur-marine);}
.topbar .cloche-alertes svg{stroke:currentColor;}
.topbar .cloche-badge{top:2px;right:2px;}
/* §25 amendé (22/09) — L'ICÔNE COMMENTAIRES MONTE DANS LA BARRE D'APP, à côté de la
   cloche. Elle vivait dans la sous-barre, qui n'existe plus : la ligne compacte ne porte
   qu'un résumé et un bouton. Même gabarit que la cloche, même rang — ce sont les deux
   mêmes gestes, signaler et être alerté. */
.topbar .signal-mode-btn{position:fixed;top:calc(8px + var(--safe-t));right:106px;
  width:44px;height:44px;border-radius:8px;border:0;
  background:var(--sur-marine-12);color:var(--sur-marine);}
.topbar .signal-mode-btn svg{stroke:currentColor;}
/* Lot rail Siège (22/09) — la cloche et le signalement vivent dans `.tr`, que la feuille
   fermée rend `visibility:hidden` — une valeur HÉRITÉE : sans ce rappel, les deux boutons de
   la barre d'app disparaissaient avec elle. `visible` sur eux seuls les garde à l'écran. */
.topbar .tr .cloche-alertes,.topbar .tr .signal-mode-btn{visibility:visible;}
.topbar .signal-mode-btn.hors-bureau{display:inline-flex;}
/* Actif, il s'allume en corail sur la barre marine : le marine sur marine ne se verrait pas. */
.topbar .signal-mode-btn[aria-pressed="true"]{background:var(--corail);border-color:var(--corail);
  color:var(--sur-marine);}
.tb-av{position:absolute;top:calc(8px + var(--safe-t));right:6px;display:inline-flex;
  align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;
  background:var(--corail);color:var(--sur-marine);font-size:var(--fs-12);font-weight:var(--w6);}
/* Le badge de rôle est remplacé par l'avatar : deux fois la même chose tiendrait mal. */
.topbar .rolebadge{display:none;}

/* =====================================================================
   3. LA LIGNE COMPACTE — un résumé qu'on ne touche pas, un bouton (§25 amendé le 22/09)
   La sous-barre défilante disparaît. Elle demandait un geste pour SAVOIR ce qui était
   réglé (défiler jusqu'au bout) et un second pour régler ; et ce qu'elle montrait
   dépendait de l'endroit où on l'avait laissée. La ligne dit l'état sans qu'on la
   touche, et tout le reste tient derrière un bouton.

   LA LARGEUR, ET LE DÉFAUT QUI VIENT AVEC (retour PE du 22/09 : « le fond ne couvre pas
   toute la largeur »). `.topbar` a 10 px de retrait de chaque côté ; un enfant en
   `flex-basis:100%` mesure donc la largeur du contenu, soit W − 20. Les marges négatives
   le décalent bien jusqu'au bord gauche, mais ne l'allongent pas : il s'arrêtait 20 px
   avant le bord droit, et le fond avec lui. La base compte donc les 20 px qu'elle reprend.
   ===================================================================== */
.tr-compact{display:flex;align-items:center;gap:8px;flex:0 0 calc(100% + 20px);
  margin:8px -10px 0;padding:8px 10px;background:var(--surface);border-top:1px solid var(--line);}
/* Le résumé : une ligne, tronquée, jamais deux. Rien d'interactif — pas un bouton, pas un
   lien : ce qu'il dit se règle dans la feuille, et deux chemins vers le même réglage
   feraient hésiter. */
.tr-resume{flex:1;min-width:0;font-size:var(--fs-12);color:var(--ink-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.tr-reglages{position:relative;display:inline-flex;align-items:center;justify-content:center;
  flex:0 0 auto;width:44px;height:44px;padding:0;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);color:var(--ink-2);cursor:pointer;}
.tr-reglages svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.9;}
/* Même grammaire que le badge de la cloche : un chiffre corail posé sur l'angle. */
.tr-reglages-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 3px;
  border-radius:8px;background:var(--corail);color:var(--sur-marine);
  font-size:var(--fs-10);font-weight:var(--w5);line-height:16px;text-align:center;}

/* =====================================================================
   4. LA FEUILLE DE RÉGLAGES — `.tr` descend en bas de l'écran (§25 amendé le 22/09)
   La feuille n'est pas un autre DOM : c'est le rail lui-même, mis en bas de l'écran. Rien
   ne se déplace, rien ne se duplique — et donc aucun contrôle ne perd son identité, ce qui
   vaut surtout pour les filtres de page montés dans le rail le 22/09 (point 2) : un
   sélecteur reconstruit se referme sous le doigt qui l'ouvre.
   Trois sections, titrées par les `.tr-sec` que le JS pose sur tous les écrans : Période et
   affichage, Périmètre, Liste. La dernière n'existe que sur les pages qui ont des filtres.
   ===================================================================== */
/*
 * PAS DE `transform` SUR CETTE FEUILLE, et c'est une contrainte, pas un goût. La cloche et
 * les commentaires vivent dans le DOM SOUS `.tr` (ils font partie du groupe droit du rail).
 * Un ancêtre transformé devient le bloc conteneur même d'un `position:fixed` : avec un
 * `translateY(100%)`, les deux boutons partaient sous l'écran avec la feuille fermée —
 * mesuré au navigateur, y = 789 pour une fenêtre de 780. La feuille se déplace donc par
 * `bottom`, et les deux boutons passent en `fixed` pour viser la fenêtre.
 */
.topbar .tr{position:fixed;left:0;right:0;z-index:46;
  margin:0;padding:10px 16px calc(16px + var(--safe-b));gap:8px;
  flex-direction:column;align-items:stretch;flex-wrap:nowrap;
  max-height:80dvh;overflow-y:auto;overflow-x:hidden;
  background:var(--surface);border-top:1px solid var(--line);border-radius:14px 14px 0 0;
  box-shadow:var(--ombre-modale);
  bottom:-100dvh;visibility:hidden;}
body.feuille-reglages .topbar .tr{bottom:0;visibility:visible;}
/* La poignée DIT que ça se glisse — c'est la seule des trois fermetures qui ne se devine
   pas (la croix et le voile, si). */
.topbar .tr::before{content:'';flex:0 0 auto;width:36px;height:4px;margin:0 auto 6px;
  border-radius:2px;background:var(--line);}
.tr-voile{position:fixed;inset:0;z-index:45;background:var(--voile);}
/* Les groupes redeviennent des blocs : une section par ligne, ses contrôles qui se replient
   dessous. `display:contents` du bureau ne vaut plus ici — chaque groupe est une section. */
/* `.tr-droite` reste TRANSPARENT : il ne porte, dans la feuille, que des nœuds qui n'y
   sont pas (cloche et commentaires, montés dans la barre d'app ; badge de rôle, caché).
   Lui donner une boîte ferait une section vide sur toutes les pages sauf une. */
.topbar .tr-droite{display:contents;}
.topbar .tr-gauche,.topbar .tr-perimetre,.topbar .tr-page,.topbar .tr-actions{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;}
/* L'ordre de la feuille : les réglages, la liste, puis les ACTIONS en bas, derrière un
   filet — ce ne sont pas des filtres, et elles ne doivent pas se confondre avec eux. */
.topbar .tr-gauche{order:1;}
.topbar .tr-page{order:2;}
.topbar .tr-actions{order:3;flex:0 0 100%;margin-top:10px;padding-top:12px;
  border-top:1px solid var(--line);}
.tr-sec{display:block;flex:0 0 100%;margin-top:6px;font-size:var(--fs-10);
  text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:var(--w-titre);}
.topbar .tr>*{flex:0 0 auto;}
/* Lot rail Siège (22/09) — la FEUILLE NE CHANGE PAS : les filtres montés dans le groupe de
   droite (transparent ici) gardent leur section et leur taille ; la section « Actions » de
   la pastille n'y paraît pas — la cloche et le signalement sont déjà dans la barre d'app. */
.topbar .tr-droite>.tr-page{flex:0 0 auto;}
.reglages .reg-actions{display:none;}
.reglages.avec-actions{flex-wrap:wrap;align-items:center;}
.avec-actions .reg-corps,.avec-actions .reg-fin{display:contents;}

/* La pastille ne fait plus sa propre feuille : elle EST la première section de celle-ci.
   Son voile et sa position fixe disparaissent, ses segments se posent en ligne. */
.reglages.ouverte{position:static;}
.reglages.ouverte .reg-tete{display:none;}
.reglages.ouverte .reg-segs{display:flex;flex-wrap:wrap;gap:8px;align-content:flex-start;}
.reglages.ouverte .reg-segs>*{flex:0 0 auto;}
.reglages.ouverte .seg,.reglages.ouverte .pill{height:auto;min-height:44px;}
/* Dans la feuille, les segments ont la place : leurs boutons prennent la cible entière
   (§25 §4), largeur comprise — ce que la ligne compacte, elle, ne pourrait pas leur donner. */
.reglages.ouverte .seg button{min-height:44px;min-width:44px;padding:0 12px;}
/* `button.reg-appliquer` et non `.reg-appliquer` : le nœud EST un <button>
   (pastilleAffichage.js), et le test de charte n'accepte --corail-fond qu'en fond de
   bouton. Que la feuille le dise coûte un point de spécificité et vaut la relecture. */
button.reg-appliquer{display:inline-flex;align-items:center;justify-content:center;flex:1 0 100%;
  order:2;min-height:44px;padding:0 16px;border:1px solid var(--corail-fond);border-radius:6px;
  background:var(--corail-fond);color:var(--sur-marine);font-size:var(--fs-12);font-weight:var(--w5);
  cursor:pointer;}
.reglages.ouverte .reg-x{display:none;}

/* =====================================================================
   5. LE TIROIR — la barre latérale, hors écran, ouverte par ☰
   C'est la MÊME barre latérale qu'au bureau (mêmes entrées, mêmes compteurs, même pied) :
   sous 768 px elle sort de la mise en page et se pose au-dessus, à gauche. Le bloc
   « ≤ 900 px » d'ea-app.css la couchait en bandeau : il est neutralisé ici.
   ===================================================================== */
.sidebar{position:fixed;top:0;bottom:0;left:0;z-index:46;width:var(--tiroir-w);max-width:86vw;
  height:100dvh;padding:calc(20px + var(--safe-t)) 0 calc(16px + var(--safe-b));
  transform:translateX(-100%);visibility:hidden;overflow-y:auto;
  transition:transform .18s ease,visibility .18s;}
body.tiroir-ouvert .sidebar{transform:none;visibility:visible;}
/* Le voile : il ferme au toucher par l'écouteur « clic dehors » déjà posé (shell.js). */
body.tiroir-ouvert .main::before{content:"";position:fixed;inset:0;z-index:45;background:var(--voile);}
.sidebar .nav{flex-direction:column;overflow:visible;gap:2px;}
.sidebar .nav-sous{flex-direction:column;align-items:stretch;margin:0 0 4px 16px;}
.sidebar .nav a{min-height:44px;}
.sidebar .sb-edge{display:none;}
.sidebar .sb-user{margin-top:auto;}
.sidebar .sb-quit button,.sidebar .sb-mentions{min-height:44px;}

/* =====================================================================
   6. LA BARRE DU BAS — quatre rubriques, l'active en corail
   Elle est DANS le flux (dernier enfant de `.main`), sous un canevas qui défile : pas de
   position fixe, donc rien à compenser en bas du contenu.
   ===================================================================== */
.tabbar{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;flex:0 0 auto;
  padding:4px 4px calc(4px + var(--safe-b));background:var(--surface);border-top:1px solid var(--line);}
.tabbar a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-height:44px;padding:4px 2px;border-radius:6px;text-decoration:none;
  color:var(--muted);font-size:var(--fs-10);font-weight:var(--w5);text-align:center;}
.tabbar a .lbl{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tabbar a svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.9;}
.tabbar a.active{color:var(--corail);}

/* =====================================================================
   7. LES CARTES KPI — deux colonnes, gouttière 8, une ligne par libellé
   La rangée est DÉJÀ à deux colonnes sous 1100 px (ea-app.css) : ici on resserre la
   gouttière à celle de la maquette et on interdit qu'un libellé passe sur deux lignes
   — c'est ce retour à la ligne qui faisait des cartes de 95 px au lieu de 86.
   ===================================================================== */
.kpirow{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;}
.card{padding:10px 12px;min-width:0;}
/* `overflow:clip` plutôt que `hidden`, avec une marge : l'ellipse du libellé fonctionne
   pareil, mais la boîte cesse de ROGNER ce qui dépasse d'elle — et ce qui dépasse, c'est la
   cible de 44 px de la pastille de disponibilité (§25 §4), qui tombait à 16 px de haut. */
.card .lab{white-space:nowrap;overflow:clip;overflow-clip-margin:14px;text-overflow:ellipsis;}
/* Le N-1 tient sur une ligne, tronqué : « 2025 : 5 510 · +15,7 % » perd sa fin plutôt
   que de pousser la carte d'une ligne. */
.card .delta{flex-wrap:nowrap;max-width:100%;}
.card .delta-base{overflow:hidden;text-overflow:ellipsis;min-width:0;}
/* Une carte SEULE sur sa dernière ligne prend les deux colonnes (maquette : .card.wide).
   Règle géométrique, pas éditoriale : désigner une mesure (« la projection est large »)
   laisserait une autre carte orpheline dès que leur nombre change — ici le trou ne peut
   pas exister, quel que soit le profil (5 cartes en BU, 6 au réseau, 8 en zone). */
.kpirow>.card:last-child:nth-child(odd){grid-column:1/-1;}

/* =====================================================================
   8. LES PANNEAUX — titre, sous-titre, PUIS les contrôles
   Au bureau, `.panel-tete` met le titre et les contrôles sur une ligne et le sous-titre
   dessous. Sur un téléphone la même ligne se casse et l'ordre à l'écran devient titre →
   contrôles → sous-titre, qui est l'inverse de ce que dit le §3.
   `display:contents` dissout la boîte de `.panel-tete` (elle ne porte ni fond ni bordure
   ni padding — seulement un `gap`, rendu ici par les marges) : titre, contrôles et
   sous-titre deviennent frères dans `.panel`, donc ordonnables. Aucun changement de DOM,
   donc aucun risque pour les captures de non-régression du bureau.
   ===================================================================== */
.panel{display:flex;flex-direction:column;}
.panel-tete{display:contents;}
.panel-tete>h3{order:0;}
.panel>.sub{order:1;}
.panel-tete>:not(h3){order:2;margin:2px 0 10px;min-width:0;}
.panel>*{order:3;}
/* Les contrôles ne passent plus à la ligne : ils défilent au doigt, comme la sous-barre. */
.panel-controles{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;}
.panel-controles::-webkit-scrollbar{display:none;}
.panel-controles>*{flex:0 0 auto;}
/* Le segment de filtre de Qualité de saisie se collait à droite sous son titre
   (`margin-left:auto`, pensé pour la ligne partagée avec le titre). */
.qs-filtre{margin-left:0;}

/* =====================================================================
   9. LES CYCLES — une ligne d'onglets défilante, un graphe à la fois
   Les quatre vignettes empilées font 851 px de panneau. Elles restent toutes dans le
   DOM (mêmes données, même légende, même modale) : seul l'affichage change.
   `.tabrow` est posée par `dashboard.js` et cachée au bureau par `ea-app.css`.
   ===================================================================== */
.tabrow{display:flex;gap:6px;margin:2px 0 8px;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.tabrow::-webkit-scrollbar{display:none;}
.tabrow button{flex:0 0 auto;min-height:44px;padding:0 12px;border:1px solid var(--line);
  border-radius:999px;background:var(--surface);color:var(--ink-2);
  font-size:var(--fs-11);font-weight:var(--w5);white-space:nowrap;cursor:pointer;}
/* L'onglet actif se distingue par son FOND et son filet, pas par la couleur de son texte.
   `color:var(--corail-fond)` donnait 3,66:1 sur --corail-soft — sous le seuil d'un texte — et
   sortait le jeton de son emploi de charte (fonds de bouton, §23 volet 4). C'est exactement la
   violation trouvée le 21/09 dans `bu.css` (`.bu-init.a`), au chiffre près : elle avait échappé
   au balayage tant qu'il ne lisait qu'`ea-app.css`, la fusion du 22/09 le lui amène.
   Le texte prend donc le marine, l'encre ferme des états actifs du portail : 12,88:1 en clair,
   8,86:1 en sombre. La distinction ne se perd pas, elle tenait déjà au fond et au filet. */
.tabrow button[aria-pressed="true"]{background:var(--corail-soft);border-color:var(--corail);
  color:var(--marine);}
.cycles-onglets>:not(.cycle-actif){display:none;}

/* =====================================================================
   10. LES TABLEAUX — la première colonne reste, le reste défile dans la carte
   Le défilement horizontal DANS la carte existe déjà (§23) ; ce qui manquait, c'est que
   le nom de la ligne parte avec lui : à fond de course, « Lyon » était à −390 px.
   `border-collapse:collapse` escamote la bordure d'une cellule collante : c'est une
   ombre d'un pixel qui la remplace.
   ===================================================================== */
.canvas .tablepanel{padding-left:0;}
.canvas .tablepanel th.sel,.canvas .tablepanel td.sel{position:sticky;left:0;z-index:2;
  background:var(--surface);min-width:34px;max-width:34px;}
.canvas .tablepanel th.sel+th,.canvas .tablepanel td.sel+td{position:sticky;left:34px;z-index:2;
  background:var(--surface);box-shadow:1px 0 var(--line);}
.canvas .tablepanel table:not(:has(th.sel)) thead th:first-child,
.canvas .tablepanel table:not(:has(th.sel)) tbody td:first-child,
.canvas .tablepanel table:not(:has(th.sel)) tbody th:first-child{position:sticky;left:0;z-index:2;
  background:var(--surface);box-shadow:1px 0 var(--line);}
/*
 * LE TRAIT SOUS L'EN-TÊTE NE S'INTERROMPT PAS SUR LES COLONNES FIGÉES (retour PE du 22/09,
 * vu sur Business Units — Réseau). `box-shadow` NE S'ADDITIONNE PAS : la dernière
 * déclaration qui gagne la cascade remplace l'autre. Les cellules figées se donnaient une
 * ombre VERTICALE (le séparateur de colonne), qui chassait l'ombre INTÉRIEURE dont l'en-tête
 * tient son trait — `border-collapse:collapse` ayant escamoté sa vraie bordure. Résultat :
 * un trait qui repart après la colonne des cases à cocher, et pas avant.
 * Les deux ombres sont donc écrites ENSEMBLE, sur les seules cellules d'EN-TÊTE figées : le
 * corps du tableau n'a pas de trait à tenir.
 */
.canvas .tablepanel thead th.sel+th,
.canvas .tablepanel table:not(:has(th.sel)) thead th:first-child{
  box-shadow:inset 0 -1px 0 var(--line),1px 0 var(--line);}

/* « Voir tout → » passe en pied (maquette) : les deux exemplaires sont posés par
   `dataTable.js`, chacun caché dans l'autre coquille. `position:sticky;left:0` lui vient
   déjà de la règle des enfants non-table de `.tablepanel`. */
.tphead .lnk{display:none;}
.tp-pied{display:block;padding:10px 16px 4px;}

/* CARTES:DEBUT — LA RÈGLE MOBILE DES TABLEAUX (Fred, 11/10, spec §31 « Mobile — règle des tableaux ») : sous 640 px, `tableauCartes.js` pose `.tc-actif` sur le tableau et une carte par ligne à sa suite.
   Décision de Fred (journal tour 027c666) : des règles sous 640 px UNIQUEMENT, aucune règle existante retirée, et une limite propre de 6 Ko pour ce bloc, tenue par `cartesMobileCss.test.js`. */
/* Retouches de Fred sur les captures mobiles de Ventes (11/10) : le titre d'une liste de phase reprend `--ink` — sa boîte est dissoute par `.panel-tete{display:contents}` (son fond corail n'est jamais peint), le texte navy
   de `--st-e` devenait illisible en sombre — et le filet qui sépare le pipe des cases hors flux disparaît. */
@media (max-width:639.98px){
.canvas .tc-actif{display:none;}
.tc-carte{position:relative;padding:10px 48px 10px 16px;border-bottom:1px solid var(--line);}
.tc-vedette{background:var(--surface-2);}
.tc-t{font-weight:var(--w6);}
.tc-l{margin-top:2px;font-size:var(--fs-13);}
.tc-t .tc-p,.tc-l .tc-p{display:inline-block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;}
.bu-nv-nom{direction:rtl;text-align:left;}
.tc-carte br,.tc-t .bu-baisse-suite{display:none;}
.tc-t .tc-p div,.tc-l .tc-p div{display:inline;}
.tc-t .bu-identite small{display:inline;margin:0 0 0 6px;font-size:inherit;font-weight:var(--w6);color:inherit;}.tc-vide+small{margin-left:0;}
.tc-l .chip{padding:0;font-size:inherit;}
.canvas .bu-phase-liste.stade .bu-liste-tete{color:var(--ink);}
.canvas .bu-etape-case[data-case="sortie"]{border-top:0;}
.tc-l .tc-p .bu-src{margin-left:6px;}
.tc-t small,.tc-l small{margin-left:6px;font-weight:var(--w4);}
.tc-vide{display:none;}
.tc-actions{margin-top:6px;}
.tc-sep{color:var(--muted);white-space:pre;}
.tc-pleine{margin-top:6px;}.tc-pleine>*{display:block;width:100%!important;}
.tc-d{display:none;margin-top:8px;font-size:var(--fs-13);}.tc-carte[aria-expanded="true"] .tc-d{display:block;}
.tc-lib{color:var(--muted);}
.tc-plus{position:absolute;top:0;right:0;width:44px;height:44px;border:0;background:none;color:var(--muted);font-size:var(--fs-18);}
}
/* CARTES:FIN */

/* =====================================================================
   11. LES MODALES — plein écran, tête collante ; la cloche en feuille de bas d'écran
   La grammaire `.cmp-*` est commune à toutes (agrandissement, comparateur, export,
   affinage, rapport) : une seule règle les met toutes au plein écran. La tête garde sa
   croix et son slot de contrôles — c'est ce qui fait que le graphe agrandi porte les
   contrôles de son panneau (§3) sans rien ajouter ici.
   ===================================================================== */
.cmp-fond{padding:0;align-items:stretch;justify-content:stretch;}
.cmp-modale{width:100%;max-width:none;height:100%;max-height:100%;border-radius:0;box-shadow:none;}
.cmp-tete{position:sticky;top:0;z-index:5;background:var(--surface);
  padding:calc(10px + var(--safe-t)) 14px 10px;}
.cmp-corps{padding:0 14px calc(16px + var(--safe-b));}
/* Le graphe agrandi prend la hauteur de la maquette (420 px) : c'est ce qui fait la
   différence entre un plein écran et une vignette étirée. Le plafond en `dvh` est pour le
   téléphone COUCHÉ, où l'écran n'a que 390 px de haut : la spec promet « paysage = 12 mois
   lisibles », donc sans défilement vertical dans la modale. */
.gr-corps .bars{height:min(420px,62dvh);}
.cmp-pied{position:sticky;bottom:0;background:var(--surface);
  padding-bottom:calc(12px + var(--safe-b));}
/* La cloche et « Signaler » descendent en feuille, comme la pastille : le panneau
   ancré à droite (420 px) prenait toute la hauteur de l'écran pour trois lignes. */
.cmp-fond:has(.msg-panel),.cmp-fond:has(.note-feuille){align-items:flex-end;justify-content:stretch;}
.msg-panel,.note-feuille{width:100%;max-width:none;height:auto;max-height:80dvh;border-radius:8px 8px 0 0;}

/* =====================================================================
   12. LES CHAMPS — 44 px de haut, 16 px de texte (§3)
   Le 16 px (contre le zoom iOS) vient d'`ea-app.css` ; ici la hauteur. Les cases,
   boutons radio et autres cibles carrées relèvent du volet 4.
   ===================================================================== */
input:not([type=checkbox]):not([type=radio]):not([type=range]),select,textarea,
.pill,.recherche input,.qs-form select,.qs-form textarea{min-height:44px;}
.pill select{min-height:40px;}
.msg-texte{min-height:88px;}
input[type=range]{height:44px;}

/* =====================================================================
   13. LA CARTE — en plein écran, jamais en ligne dans la page (§3)
   Une carte posée dans une page qui défile se dispute le doigt avec elle. Sous 768 px
   la page ne montre qu'un bouton ; la carte s'ouvre par-dessus tout.
   Le bouton et la croix sont TOUJOURS posés par `franceMap.js` et cachés au bureau —
   même idiome que la coquille (le JS ne connaît aucune largeur).
   ===================================================================== */
.francemap-ouvrir{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  min-height:44px;padding:0 16px;border:1px solid var(--line);border-radius:6px;
  background:var(--bg);color:var(--ink);font-size:var(--fs-13);font-weight:var(--w5);cursor:pointer;}
.francemap-ouvrir svg{width:18px;height:18px;stroke:var(--corail);fill:none;stroke-width:1.8;}
.francemap-wrap>.leaflet-conteneur{display:none;}
.francemap-wrap[data-plein-ecran]>.leaflet-conteneur{display:block;position:fixed;inset:0;z-index:60;
  width:100vw;height:100dvh;border-radius:0;}
.francemap-wrap[data-plein-ecran]>.francemap-fermer{display:flex;align-items:center;justify-content:center;
  position:fixed;top:calc(8px + var(--safe-t));right:10px;z-index:61;width:44px;height:44px;
  border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink);
  font-size:var(--fs-24);line-height:1;cursor:pointer;}

/* =====================================================================
   14. LE TACTILE — 44 px sous le doigt (§25 §4)
   Deux moyens, et le choix entre eux n'est pas cosmétique :
     · quand l'encre PEUT grandir (une pastille, un bouton de la sous-barre, une ligne de
       tableau), elle grandit — `min-height`, `padding`. C'est plus simple et ça laisse
       respirer la page.
     · quand l'encre NE DOIT PAS bouger (segments jointifs, ⤢ posée sur un graphe, croix
       d'une modale), seule la CIBLE s'étend, par un `::after` centré qui ne se voit pas et
       ne pousse rien. Piège vérifié au navigateur : sans `position:relative` sur l'élément,
       le `::after` se cale sur le bloc conteneur initial et n'étend rien du tout.
   Sur les segments, l'extension est VERTICALE seulement : ils sont jointifs (`.seg{padding:2px}`
   sans `gap`), deux cibles élargies se recouvriraient et le doigt toucherait le voisin.
   ===================================================================== */
.seg button,.tabs button{position:relative;}
.seg button::after,.tabs button::after{content:"";position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%);width:100%;height:max(100%,44px);}
.gr-loupe,.cmp-fermer,.repbtn,.scen-x,.note-btn{position:relative;}
.gr-loupe::after,.cmp-fermer::after,.repbtn::after,.scen-x::after,.note-btn::after{content:"";position:absolute;
  top:50%;left:50%;transform:translate(-50%,-50%);width:max(100%,44px);height:max(100%,44px);}

/* L'encre qui peut grandir. */
.pill{min-height:46px;}
.pill select{min-height:44px;}
.topbtn,.pillbar button,.reg-tete,.colonnes-bu-menu label,.qs-orphelins summary,
.coef-actions button,.exp-item,.msg-checkbox label,.signal-mode-btn{min-height:44px;}
.signal-mode-btn,.pagination button,.seg.icons button{min-width:44px;min-height:44px;}
/*
 * LES SEGMENTS DE LA SOUS-BARRE (22/09). Le point 2 y a monté les filtres des pages — dont
 * le pas-à-pas d'année de la vue BU, trois boutons de deux caractères. Ils n'avaient aucune
 * cible : seuls `.seg.icons` et les segments de la FEUILLE dépliée en recevaient une.
 *
 * La HAUTEUR leur est donnée ici — c'est l'axe dont la sous-barre dispose. La LARGEUR reste
 * hors de portée, comme dit plus haut : la forcer à 44 px sur chaque bouton ferait d'un pas
 * d'année un ruban de 132 px dans une barre qui en porte déjà quatre. C'est une cible de
 * 44 px de haut sur sa largeur propre, et non 44 × 44 : l'écart au §25 §4 est ASSUMÉ, et il
 * appartient à la passe sur téléphone réel de dire s'il se touche.
 */
.topbar .tr .seg button{min-height:44px;}
.lnk{display:inline-flex;align-items:center;min-height:44px;}
/* `.dleg .row.navigable{padding:1px 4px}` (ea-app.css) est d'un cran plus précis : il faut
   le même poids pour l'emporter, sinon la ligne reste à 20 px (mesuré). */
.dleg .row,.dleg .row.navigable{padding-top:12px;padding-bottom:12px;}
/* Les lignes de tableau : 35,8 px mesurés, filet d'un pixel pour seul séparateur. */
.canvas .tablepanel tbody td,.canvas .tablepanel tbody th{padding-top:13px;padding-bottom:13px;}
/* La case de comparaison : la colonne passe de 34 à 44 px, et la cellule entière la coche
   (`dataTable.js`) — une case de 15 px ne s'atteint pas au doigt. La cellule voisine se cale
   sur la nouvelle largeur (cf. §10). */
/* 12 px de chaque côté d'une case de 20 : la case est CENTRÉE dans ses 44 px, donc la cible
   l'est aussi — décentrée, elle mordrait sur la colonne voisine d'un côté et sur le vide de
   l'autre. */
.canvas .tablepanel th.sel,.canvas .tablepanel td.sel{min-width:44px;max-width:44px;
  padding-left:12px;padding-right:12px;}
.canvas .tablepanel th.sel+th,.canvas .tablepanel td.sel+td{left:44px;}
.canvas .tablepanel td.sel input[type=checkbox]{width:20px;height:20px;}
/* Le graphe : le doigt y pose le réticule, mais la PAGE doit pouvoir défiler quand on part
   vers le haut (`barChart.js` arbitre le geste). `pan-y` dit au navigateur ce qu'il a le droit
   de faire de lui-même, et lui interdit le panoramique horizontal, qui est au réticule. */
.bars{touch-action:pan-y;}
/* Leaflet : ses deux boutons de zoom sont jointifs et font 30 px. Sa feuille est INJECTÉE
   dans le `<head>` au montage, donc APRÈS celle-ci : à spécificité égale c'est elle qui
   gagnerait — d'où un sélecteur d'un cran plus précis que son `.leaflet-touch .leaflet-bar a`. */
.leaflet-touch .leaflet-control-zoom.leaflet-bar a{width:44px;height:44px;line-height:44px;}
.francemap-reset{width:44px;height:44px;}

/* =====================================================================
   15. LE SURVOL N'EXISTE PAS AU DOIGT (§25 §4)
   Sur un écran tactile, `:hover` se pose au toucher et RESTE jusqu'au toucher suivant : un
   fond de survol devient un faux « sélectionné ». Aucune commande n'est cachée derrière un
   survol dans ce portail (vérifié règle par règle) — c'est donc seulement le fond qu'on
   éteint, en gardant `:active` et `:focus-visible`, qui eux disent vrai.
   ===================================================================== */
@media (hover:none){
.canvas .tablepanel tbody tr[data-lien]:hover,.tablepanel th.triable:hover,.qs-ligne:hover,
.dleg .row.navigable:hover,.exp-item:hover,.alertes-ligne:hover,.msg-ligne:hover,
.tabs button:hover:not([aria-selected="true"]),.colonnes-bu-menu label:hover,
.scen:hover,.aff-annuel:hover{background:none;}
.pagination button:not([disabled]):hover,.francemap-reset:hover,.cmp-fermer:hover,
.reglages:not(.ouverte):hover{background:var(--surface);border-color:var(--line);}
.topbtn:hover,.cloche-alertes:hover,.signal-mode-btn:hover,.nav a:hover,.sb-quit button:hover,
.sb-mentions:hover{background:none;color:inherit;}
.lnk:hover,.bc a:hover{text-decoration:none;}
}

/* =====================================================================
   16. LE DÉFILEMENT HORIZONTAL SE VOIT (§25 §4)
   Les barres de défilement sont masquées (maquette) et un doigt ne les fait pas apparaître :
   rien ne disait qu'un tableau de 8 colonnes continue à droite.
   Quatre calques de fond : deux CACHES couleur surface en `background-attachment:local` (ils
   suivent le contenu et quittent le bord dès qu'on défile) et deux OMBRES en `scroll`
   (collées au bord, révélées quand le cache s'en va). Aucun nœud ajouté.
   À écrire en propriétés LONGUES, jamais avec le raccourci `background:` : `.tablepanel`
   déclare `background:var(--surface)` plus bas à spécificité égale et effacerait les calques
   (mesuré : 1 calque au lieu de 4).
   ===================================================================== */
/*
 * FUSION DU 22/09 — LES CALQUES SUIVENT CE QUI DÉFILE, et depuis le point 9 ce n'est plus
 * toujours la carte. `background-attachment:local` ne veut rien dire sur un élément qui ne
 * défile pas : les deux caches resteraient collés aux bords et les ombres ne se révéleraient
 * jamais. Sur une carte MIGRÉE, c'est le cadre `.tp-defile` qui défile ; sur une carte qui
 * n'en a pas (dashboard, projectionCa, qualiteSaisie, rapprochement, simulateur, et les
 * grilles de saisie de la Grille BU), c'est la carte. Les deux portent donc la règle, et
 * chacune ne l'anime que là où elle a une course — on n'ajoute AUCUN défilement de carte à
 * une page migrée, on déplace l'indice vers le conteneur qui l'a déjà.
 */
.canvas .tablepanel,.canvas .tp-defile{
  background-image:
    linear-gradient(to right,var(--surface) 30%,transparent),
    linear-gradient(to left,var(--surface) 30%,transparent),
    linear-gradient(to right,var(--ombre-bord),transparent),
    linear-gradient(to left,var(--ombre-bord),transparent);
  background-position:left center,right center,left center,right center;
  background-repeat:no-repeat;
  background-size:30px 100%,30px 100%,14px 100%,14px 100%;
  background-attachment:local,local,scroll,scroll;
}

/* =====================================================================
   17. MOUVEMENT — le tiroir glisse, sauf si l'on n'en veut pas (§25 §4)
   La forme universelle plutôt que douze règles à rattraper une par une : elle couvre aussi
   les transitions de Leaflet (250 ms au zoom), qui vivent dans un fichier qu'on ne touche pas.
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
.sidebar{transition:none;}
*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
  transition-duration:.01ms!important;scroll-behavior:auto!important;}
}
/* Refonte du TdB BU (24/09, spec §2 et §4) : essentiel 2×2, « À valider » compacte (point et nombre
   par famille, chevron seul ; dépliée, texte et montant puis actions), pipe vertical, duos empilés. */
/* Sous `.canvas` : bu.css est chargée APRÈS cette feuille (chargerFeuilleBu) et gagnerait à spécificité égale. */
.canvas .bu-essentiel{grid-template-columns:1fr 1fr}
.canvas .bu-essentiel>div{padding:13px 14px}
.canvas .bu-essentiel>div:nth-child(3){border-left:0}
.canvas .bu-essentiel>div:nth-child(n+3){border-top:1px solid var(--sur-marine-12)}
.canvas .bu-ess-val{font-size:var(--fs-24)}
.canvas .bu-av-tete{gap:10px;padding:8px 12px 8px 14px}
.canvas .bu-av-etiq,.canvas .bu-av-ouvrir>span{display:none}
.canvas .bu-av-familles{gap:4px 10px}
.canvas .bu-av-dedans{margin:0 12px 0 14px}
.canvas .bu-av-quoi{white-space:normal}
.canvas .bu-av-ligne{grid-template-columns:10px minmax(0,1fr) auto}
.canvas .bu-av-ligne .bu-av-act{grid-column:2/4}
.canvas .bu-av-ib{min-width:44px;height:44px}
.canvas .bu-pipe-flux{flex-direction:column}
.canvas .bu-pipe-etape{flex:none!important;min-height:60px}
.canvas .bu-lien{width:auto;flex-direction:row;gap:8px;padding:6px 0}
.canvas .bu-lien svg{transform:rotate(90deg);margin:0}
.canvas .bu-tdb .panel{padding:18px 16px}
.canvas .bu-duo{grid-template-columns:minmax(0,1fr)}
.canvas .bu-prix-l{grid-template-columns:90px 1fr auto}
.canvas .bu-taux{flex-wrap:wrap;gap:12px 28px}
.canvas .bu-col-barre{display:none}
.canvas .bu-duo+.bu-duo{margin-top:24px}
/* 24/09 (retouche de PE) : l'origine des ventes, anneau au-dessus, légende dessous en pleine largeur. */
.canvas .bu-origine{flex-direction:column;align-items:stretch;gap:18px}
.canvas .bu-origine-anneau{margin:0 auto}
.canvas .bu-origine-leg{flex:none;max-width:none}
