/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE REGISTRE - LA charte mobile 91STUDIO (28/07/2026)
   Sources : recherche état de l'art fintech 2025-26 (iOS HIG / Material 3 /
   Linear mobile / Revolut / N26 / Mercury) - specs chiffrées, pas des goûts :
   · rangée transaction = 2 lignes, 64px confortable / 52px compacte, jamais <44px
   · ligne 1 : libellé 15px/500 + montant tabular 600 à droite
   · ligne 2 : métas 13px à 60 % d'opacité
   · header ~52px · filtres = chips scrollables · cibles 44px · zéro scroll horizontal
   Chargée APRÈS les CSS modules : elle impose la doctrine ≤639px.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 639px) {
  :root {
    --mreg-row: 64px;
    --mreg-row-compact: 52px;
    --mreg-pad-x: 16px;
    --mreg-primary: 15px;
    --mreg-secondary: 13px;
    --mreg-meta: 11.5px;
  }

  /* ── Rangées de registre (toutes les tables Trésorerie passées en grille) ──
     :not(.tv5-trexp) 30/07 : cette règle visait les rangées de DONNÉES ; elle
     imposait aussi 64px au tiroir de détail fermé de Transactions (rangée
     technique, toujours dans le DOM) - même bug que sur desktop (Henri :
     « Transactions et Collecteurs n'ont pas le même aspect »), version mobile. */
  #page-content .treso-table tbody tr:not(.tv5-trexp) {
    min-height: var(--mreg-row);
    padding: 8px var(--mreg-pad-x);
    row-gap: 2px;
  }
  #page-content .treso-table tbody td { font-size: var(--mreg-secondary); }
  #page-content .treso-table tbody .treso-cell-name,
  #page-content .treso-table tbody td:first-child {
    font-size: var(--mreg-primary);
    font-weight: 500;
  }
  #page-content .treso-table tbody .treso-cell-secondary,
  #page-content .treso-table tbody .treso-cell-muted {
    font-size: var(--mreg-secondary);
    opacity: 0.62;
  }
  #page-content .treso-table tbody .treso-cell-amount {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: var(--mreg-primary);
  }

  /* Registre v5 (vue d'ensemble) : mêmes proportions */
  #page-content .tv5-row { min-height: var(--mreg-row-compact); }
  #page-content .tv5-lib .nm { font-size: var(--mreg-primary); font-weight: 500; }
  #page-content .tv5-lib .ref { font-size: var(--mreg-meta); opacity: 0.62; }
  #page-content .tv5-amt { font-weight: 600; }

  /* ── Zones de filtres : UNE bande de chips scrollable, plus d'empilement ── */
  #page-content .iden-bar,
  #page-content .treso-toolbar,
  #page-content .treso-filters {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 8px;
    padding: 8px var(--mreg-pad-x);
    align-items: center;
  }
  #page-content .iden-bar::-webkit-scrollbar,
  #page-content .treso-filters::-webkit-scrollbar { display: none; }
  #page-content .iden-bar > *,
  #page-content .treso-filters > * { flex: 0 0 auto; }
  #page-content .iden-bar input[type="text"],
  #page-content .treso-filters input[type="text"] { flex: 0 0 190px; min-width: 0; }
  #page-content .iden-bar .iden-in,
  #page-content .treso-filters select,
  #page-content .treso-filters input {
    height: 36px;
    min-height: 36px;
    font-size: var(--mreg-secondary);
  }

  /* ── Cibles tactiles : le minimum absolu partout ──
     09/08/2026, grille mobile mesure 7 (scripts/grille-mobile.cjs) : les 36 px des
     boutons compacts laissaient 4 à 8 cibles non tapables par écran. Apple HIG dit
     44 ; on l'applique aux BOUTONS. Les chips de filtre restent à 36 (elles sont
     larges : la surface tapable est suffisante et 44 casserait le rythme des barres). */
  #page-content .studio-btn,
  #page-content .studio-chip,
  .stsh .studio-btn { min-height: 44px; }
  #page-content .studio-btn-sm { min-height: 44px; }
  #page-content .studio-chip { min-height: 36px; }
  #page-content .studio-iconbtn { width: 44px; height: 44px; }
  /* 🪤 MESURÉ le 10/08 : dans un INTITULÉ DE SECTION, ce carré de 44 px impose sa
     hauteur à tout le bloc - l'en-tête « Plans d'exécution » faisait 68 px pour un
     texte de 15. Le bouton y garde sa zone tapable de 44 px, mais par un ::after
     fantôme : ce qu'on VOIT fait 28 px et ne commande plus la hauteur.
     Même motif que .studio-state ci-dessous : agrandir la cible, pas l'icône. */
  #page-content .chp-card-h .studio-iconbtn,
  #page-content .chp-socle-outils .studio-iconbtn { width: 28px; height: 28px; position: relative; }
  /* La pilule d'actions de l'en-tête chantier : ses boutons à 44 px imposaient la
     hauteur de la ligne du code (mesuré 92 px pour l'en-tête). Même motif : ce qu'on
     VOIT descend, la zone tapable reste à 44 par le ::after fantôme. */
  #ch-content .ch-header-actions .studio-btn,
  #ch-content .ch-header-actions .ch-search { min-height: 32px; height: 32px; position: relative; }
  #ch-content .ch-header-actions .studio-btn::after { content: ""; position: absolute; inset: -6px; }
  #page-content .chp-card-h .studio-iconbtn::after,
  #page-content .chp-socle-outils .studio-iconbtn::after { content: ""; position: absolute; inset: -8px; }
  /* Même raison pour la barre de filtres : le bouton « Filtres » à 44 px imposait sa
     hauteur à toute la bande. Zone tapable conservée par le ::after fantôme. */
  #page-content .chp-filters .studio-btn { min-height: 34px; height: 34px; position: relative; }
  #page-content .chp-filters .studio-btn::after { content: ""; position: absolute; inset: -5px 0; }
  /* Le point d'état (.studio-state, canonique 24 px validé) : sa ZONE TAPABLE passe
     à 44 px sans rien changer à ce qu'on VOIT - le bouton est fantôme, seul le point
     de 8 px est visible. Motif iOS : agrandir la cible, pas l'icône. */
  #page-content .studio-state { min-width: 44px; min-height: 44px; }

  /* ── Notifications : au-dessus des commandes du bas ──
     🪤 MESURÉ le 10/08 : le toast s'affichait à 807-847 px sur un écran de 852, donc
     DANS la zone du dock et du repère de page. Il passait bien au-dessus en z-index,
     mais tombait sur les commandes et se lisait mal (« les pop up ne sont pas
     visibles », Henri). Sa place est ici, dans la charte mobile, pas dans critical. */
  /* 🪤 `body` n'est pas décoratif : critical.css est chargée LIGNE 308 d'index.html,
     donc APRÈS cette feuille (ligne 96). À spécificité égale elle gagnerait. Cette
     charte ne l'emporte que par la spécificité de `#page-content` - une règle qui n'en
     a pas, comme celle-ci, doit en gagner autrement. Mesuré : sans `body`, le toast
     restait à 832 px, sur les commandes du bas. */
  body .toast-container {
    left: 12px; right: 12px;
    bottom: calc(124px + env(safe-area-inset-bottom, 0px));  /* mesuré : le repère de page commence à 739 sur 852 */
    align-items: stretch;
  }
  body .toast-container .toast { max-width: none; }

  /* ── Anti-patterns bannis ── */
  #page-content { overflow-x: clip; }
  #page-content table { min-width: 0 !important; }
}

/* Feuille de changement d'onglet (remplace le select natif au tap) */
.mnd-sheet-item {
  display: flex; align-items: center; width: 100%;
  min-height: 44px; padding: 0 4px;
  background: none; border: none; border-bottom: 0.5px solid var(--border-light);
  font: inherit; font-size: 15px; color: var(--text-primary);
  text-align: left; cursor: pointer;
}
.mnd-sheet-item:last-child { border-bottom: none; }
.mnd-sheet-item.on { font-weight: 600; background: var(--bg-active); border-radius: 8px; }

/* ── PURIFICATION (Henri 29/07) : le header module ne porte plus qu'un titre en
   DOUBLON du sélecteur d'écran → masqué ≤1024 (le tiroir + la barre du bas
   donnent le contexte, comme Linear). 48px rendus au contenu. */
@media (max-width: 1024px) {
  #layout-team > main > header { display: none; }
}

/* ── ZÉRO CARTE SUR MOBILE - listes pures pleine largeur (Henri 29/07).
   Les conteneurs de données perdent arrondis/ombres/bords latéraux : il ne
   reste que les hairlines horizontales et l'espacement. */
@media (max-width: 639px) {
  #page-content .tvd-b,
  #page-content .tvd-b > div,
  #page-content .tv5-panel,
  #page-content .tv5-card,
  #page-content .treso-card,
  #page-content .studio-card {
    border-radius: 0 !important;
    box-shadow: none !important;
    border-left: none !important;
    border-right: none !important;
    background-image: none !important;
  }
  #page-content .tvd-grid { gap: 0; }
  #page-content .tvd-b { border-bottom: 0.5px solid var(--border-light); padding: 4px 0 12px; }
  #page-content .tvd-b:last-child { border-bottom: none; }
}

/* Bouton Scanner fixe de la barre du bas : action centrale, toujours là */
.shell-bottom-nav-item.is-scan { background: none; border: none; font: inherit; color: inherit; cursor: pointer; }

/* Pass 2 purification (vérifié live 29/07) */
@media (max-width: 1024px) {
  /* le sélecteur précédent ratait sa cible : la classe, pas le chemin */
  #layout-team .main-header { display: none !important; }
}
@media (max-width: 639px) {
  /* signaux « À décider » : plus de sous-cartes arrondies */
  #page-content .oip-group,
  #page-content #tresoDecisionZone {
    border-radius: 0 !important;
    box-shadow: none !important;
    border-left: none !important;
    border-right: none !important;
  }
}

/* P1 v2 - LE VERRE, recomposé (29/07) après MESURE de Linear desktop (session
   Henri) : Linear n'a AUCUN backdrop-filter sur ordinateur - l'en-tête opaque vit
   HORS de la boîte de défilement. Le verre dépoli est le langage iOS (réf Qonto)
   et n'a de sens qu'en UNE SEULE SURFACE CONTINUE : barre d'état + titre + outils,
   bord à bord, pilules posées dessus. Jamais des pilules givrées séparées avec des
   jours de contenu brut autour - c'était le bug des captures d'Henri. */
@media (max-width: 1024px) {
  /* ── AU REPOS : AUCUN VERRE. La barre se fond dans la page (même fond, zéro
     filet) - c'est la règle iOS : le matériau signale du contenu caché dessous,
     il n'est pas une décoration permanente. ── */
  #page-content .studio-screenbar {
    background: var(--bg-primary) !important;
    border-bottom-color: transparent !important;
    border-radius: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    box-shadow: none !important;
    transition: background 0.18s ease, backdrop-filter 0.18s ease,
                -webkit-backdrop-filter 0.18s ease, border-bottom-color 0.18s ease;
  }
  /* ── DÈS QUE ÇA DÉFILE : le verre et le filet apparaissent, d'un seul tenant. ── */
  body.mob-scrolled #page-content .studio-screenbar {
    background: color-mix(in srgb, var(--bg-primary) 78%, transparent) !important;
    -webkit-backdrop-filter: blur(22px) saturate(1.8);
    backdrop-filter: blur(22px) saturate(1.8);
    border-bottom-color: var(--border-subtle, rgba(0, 0, 0, 0.06)) !important;
  }
  /* La barre d'état iPhone appartient à la MÊME surface : opaque au repos,
     verre au défilement - jamais un liseré différent du bandeau. */
  body::after {
    content: '';
    position: fixed;
    top: 0; left: 0; right: 0;
    height: env(safe-area-inset-top, 0px);
    background: var(--bg-primary);
    z-index: 90;
    pointer-events: none;
    transition: background 0.18s ease, backdrop-filter 0.18s ease, -webkit-backdrop-filter 0.18s ease;
  }
  body.mob-scrolled::after {
    background: color-mix(in srgb, var(--bg-primary) 78%, transparent);
    -webkit-backdrop-filter: blur(22px) saturate(1.8);
    backdrop-filter: blur(22px) saturate(1.8);
  }
  /* Les barres collent SOUS la barre d'état - jamais un jour entre les deux. */
  #page-content .studio-screenbar--1 { top: env(safe-area-inset-top, 0px); }
  #page-content .studio-screenbar--2 { top: calc(env(safe-area-inset-top, 0px) + 44px); }
}
@media (max-width: 639px) {
  /* LE TROU DES CAPTURES (29/07) : la coquille masque la barre-titre (--1) mais
     la barre d'outils (--2) gardait son top desktop de 44px → fenêtre de 44px de
     contenu BRUT au-dessus d'elle. Quand --1 est masquée, --2 colle au sommet. */
  /* Seule la Trésorerie masque sa barre-titre à ce jour ; si un autre module
     adopte la coquille, ajouter SA barre 2 ici. */
  #page-content .treso-bar2 {
    top: env(safe-area-inset-top, 0px) !important;
  }

  /* ── PLEIN CADRE (29/07) - MESURÉ au banc : le panneau Linear gardait sa
     gouttière de 8 px et son arrondi de 12 px sur téléphone, donc le bandeau
     s'arrêtait à 8 px des bords : une carte flottante, jamais une barre de
     navigation iOS. Sur un écran de 390 px, le panneau EST l'écran.
     🪤 cette feuille est chargée AVANT les autres → à spécificité égale elle
     PERD : tout est en !important et préfixé `body`. ── */
  body { --mob-gutter: 16px; }
  body .main-content {
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-top: 0 !important;
  }
  body #page-content {
    border-radius: 0 !important;
    border-left: 0 !important;
    border-right: 0 !important;
    border-top: 0 !important;
    padding-left: var(--mob-gutter) !important;
    padding-right: var(--mob-gutter) !important;
  }
  /* Les barres SORTENT de la gouttière du panneau : bord à bord, texte aligné
     sur le contenu (marge négative + padding égal = colonne conservée).
     🪤 MESURÉ 29/07 : `width:auto` ne suffit PAS - les barres sont des éléments
     flex dans le conteneur du module (#tresoContent), elles restaient à la largeur
     du conteneur (343 px sur 375) et laissaient une bande de contenu nu à droite.
     La largeur doit être calculée explicitement. */
  body #page-content .studio-screenbar {
    width: calc(100% + 2 * var(--mob-gutter)) !important;
    max-width: none !important;
    margin-left: calc(-1 * var(--mob-gutter)) !important;
    margin-right: calc(-1 * var(--mob-gutter)) !important;
    padding-left: var(--mob-gutter) !important;
    padding-right: var(--mob-gutter) !important;
  }

  /* ── Barre de navigation à la HIG : le TITRE prend la largeur, les actions
     deviennent des icônes. Avant : « Vue d'ensemble » en 27 px tronqué à
     « Vue d'... » parce que le bouton « + Importer » mangeait 175 px. ── */
  body #page-content .treso-bar2 .mobile-tab-dropdown {
    font-size: 24px !important;
    padding-right: 22px !important;
  }
  body #page-content .treso-toolbar-right .studio-btn-primary {
    font-size: 0 !important;
    width: 38px;
    padding: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  body #page-content .treso-toolbar-right .studio-btn-primary::before {
    content: '+';
    font-size: 21px;
    font-weight: 500;
    line-height: 1;
  }
}

/* P5 - narration de trésorerie : 2 lignes maximum, hauteur STABLE, le détail au tap */
#tresoCashNarration {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 41px;
  cursor: pointer;
}

/* ══════════ REGISTRE DES TRANSACTIONS - recomposition mobile (29/07)
   Constat Henri, capture à l'appui : « sur téléphone la qualité est médiocre ».
   Mesuré : à ≤639 la rangée masquait catégorie, banque ET statut → il ne restait
   qu'un libellé tronqué et un montant, sur des rangées hautes et vides. C'est le
   contraire de la charte (rangée 2 lignes, information hiérarchisée).
   Recomposition : ligne 1 = libellé + montant, ligne 2 = catégorie · banque en
   second plan. Casse de phrase partout (les capitales sont bannies). ══════════ */
@media (max-width: 639px) {
  body #page-content .tv5-row {
    grid-template-columns: auto 1fr auto !important;
    grid-template-areas: "lib lib amt" "cat bank amt" !important;
    align-items: center !important;
    height: auto !important;
    min-height: 62px !important;
    padding: 8px 16px !important;
    row-gap: 2px !important;
    column-gap: 8px !important;
  }
  body #page-content .tv5-row > .tv5-lib { grid-area: lib; min-width: 0; }
  body #page-content .tv5-row > .tv5-lib .nm {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: -0.01em;
  }
  body #page-content .tv5-row > .tv5-catcell {
    grid-area: cat;
    display: flex !important;
    align-items: center;
    font-size: 13px;
    opacity: 0.62;
    min-width: 0;
  }
  body #page-content .tv5-row > .tv5-c-bank {
    grid-area: bank;
    display: block !important;
    font-size: 13px;
    opacity: 0.62;
  }
  /* la banque redevient un mot, pas une pastille bordée */
  body #page-content .tv5-row > .tv5-c-bank .tv5-bank {
    background: none !important;
    border: 0 !important;
    padding: 0 !important;
    font-size: 13px !important;
    letter-spacing: 0 !important;
  }
  body #page-content .tv5-row > .tv5-amt {
    grid-area: amt;
    align-self: center;
    font-size: 15px;
    font-weight: 600;
  }
  body #page-content .tv5-row > .tv5-c-st { display: none !important; }

  /* En-tête de jour : casse normale, respiration, aucun aplat */
  body #page-content .tv5-day {
    background: transparent !important;
    padding: 14px 16px 6px !important;
    border-bottom: 0 !important;
  }
  body #page-content .tv5-day .dt {
    text-transform: none !important;
    letter-spacing: 0 !important;
    font-size: 13px !important;
    font-weight: 600 !important;
  }

  /* En-tête du bloc : titre à gauche, liens à droite, sur UNE ligne */
  body #page-content .tv5-card-h {
    flex-wrap: nowrap !important;
    gap: 8px !important;
    align-items: baseline !important;
  }
  body #page-content .tv5-card-h .t { font-size: 15px; white-space: nowrap; }
  body #page-content .tv5-card-h .tv5-link { font-size: 13px; white-space: nowrap; }
  /* Une seule action par en-tête de section (HIG) : « Factures récentes » vit
     déjà dans l'onglet Factures - sur 390 px les deux liens se chevauchaient. */
  body #page-content .tv5-card-h span > .tv5-link:first-child { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA CADENCE - une seule respiration pour tout le mobile (09/08/2026)

   Auto-évaluation du soir : « espacement 3/10 ». Mesuré : neuf valeurs de padding
   différentes dans le seul portail (4, 6, 8, 9, 10, 12, 14, 16, 18). Le « trop de
   vide partout » d'Henri ne vient pas de valeurs trop GRANDES, il vient de
   l'ABSENCE DE CADENCE - l'œil ne trouve aucun rythme. Référence : Things 3, où
   l'on ne peut désigner aucun espace en disant « pourquoi si grand ici ».

   Deux règles, pas plus :
     · RAIL LATÉRAL UNIQUE à 16 px - titre, onglets, filtres et rangées partent
       tous de la MÊME verticale (c'était 10 pour la page, 12/14/18 dans les cartes).
     · RYTHME VERTICAL sur 8 : 8 dans un bloc, 16 entre deux blocs, 24 avant une
       nouvelle section. Aucune valeur intermédiaire.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  :root { --mreg-rail: 16px; --mreg-v1: 8px; --mreg-v2: 16px; --mreg-v3: 24px; }

  /* Le rail : une seule verticale de départ pour TOUT le contenu. */
  #page-content { padding-left: var(--mreg-rail); padding-right: var(--mreg-rail); }
  #page-content .chp-card,
  #page-content .chp-card-h,
  #page-content .chp-filters,
  #page-content .chp-subnav,
  #page-content .chp-grp td,
  #page-content .chp-table tr.chp-row-plan,
  #page-content .chp-table tr.chp-row-visa,
  #page-content .chp-table thead tr,
  #page-content .chp-ev,
  #page-content .chp-table tbody td { padding-left: 0; padding-right: 0; }
  #page-content .chp-scroll { margin-left: 0; margin-right: 0; }

  /* Le rythme vertical : 8 / 16 / 24, rien entre. */
  #page-content .chp-card { margin-bottom: var(--mreg-v2); }
  /* 🪤 MESURÉ le 10/08 : ce rythme avait été réglé quand l'intitulé de section était
     un TITRE de 15 px. Depuis la cible validée, c'est une ÉTIQUETTE en petites
     capitales de 10 px - 16 px au-dessus et 8 en dessous la font flotter, et le bloc
     pesait 52 px pour un texte de 15. Une étiquette annonce ce qui suit : elle se
     colle à sa liste. v1 en haut, la moitié en bas. */
  #page-content .chp-card-h { padding-top: var(--mreg-v1); padding-bottom: 4px; }
  #page-content .chp-subnav { margin: var(--mreg-v1) 0 var(--mreg-v2); }
  #page-content .chp-filters { padding-top: 0; padding-bottom: var(--mreg-v1); }
  /* 🪤 Même mesure : l'intertitre de lot pesait 75 px - 24 px de padding haut sur le
     td, PLUS 12 px en haut et en bas hérités de `.chp-table tr` (l'ancien mode
     « une ligne = une carte »). Le tr ne porte plus de padding, le td descend à v2. */
  #page-content .chp-grp { padding-top: 0; padding-bottom: 0; }
  #page-content .chp-grp td { padding-top: var(--mreg-v2); padding-bottom: 4px; }
  #page-content .chp-table tr.chp-row-plan { padding-top: var(--mreg-v1); padding-bottom: var(--mreg-v1); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   91S-106 - HOMOGENEISER LES DECISIONS SUR TOUTES LES VUES (11/08/2026)

   MESURÉ AVANT D'ÉCRIRE, en 393 x 852 sur la production, par
   `scripts/mesure-registre-mobile.cjs` et une sonde de détail :

     écran      | rangée | filets | débordements | LA cause
     Projets    |  99 px | 14/19  |      26      | .studio-screenbar--2 : 698 px dans 361
     Chantiers  |  99 px |  3/5   |       2      | .ch-toolbar.studio-screenbar : 527 dans 369
     Portail ✅ |  46 px |  0/97  |       0      | (la cible validée)

   Les 26 et les 2 ne sont pas 28 défauts : c'est UN SEUL, la barre d'écran
   canonique qui ne sait pas rétrécir. Tout ce qu'elle contient (chips, boutons
   ronds, cta) déborde parce qu'ELLE déborde. On corrige donc le canonique, pas
   chaque module - c'est précisément ce que « homogénéiser » veut dire, et la
   recette existe déjà trois blocs plus haut pour .iden-bar / .treso-filters.

   🪤 CE QUI N'EST PAS TRAITÉ ICI, ET POURQUOI. Les 99 px ne viennent PAS du
   padding : ils viennent de QUATRE lignes de texte empilées dans une rangée en
   grille (mesuré : `display: grid`, padding 8/8, 4 lignes). Passer à 46 px
   demande de décider quelles deux lignes survivent - et les cellules de Projets
   sont des `td` SANS CLASSE. Les cibler reviendrait à viser par RANG, le piège
   qui fait mentir un intitulé dès qu'une colonne bouge (payé le 10/08 sur
   Situations). La composition demande donc d'abord de NOMMER ces cellules dans
   js/projets.js : c'est une passe à part, pas un oubli.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  /* ── 1. La barre d'écran canonique devient une bande qui défile ──────────
     Même recette que .iden-bar / .treso-toolbar / .treso-filters : rien de
     nouveau n'est inventé, le motif est étendu à la barre que TOUS les écrans
     au gabarit utilisent (Consultations, Projets, Chantiers, et tout écran neuf
     - `.studio-screenbar` est canonique depuis le 19/07, PR n°587).
     🪤 Le numéro de PR s'écrit « n°587 » et JAMAIS avec un croisillon devant :
     le ratchet de style compte les hex dans les commentaires, et un croisillon
     suivi de trois chiffres en est un. Piège cité une heure plus tôt dans un
     message de commit, repayé ici, puis repayé une SECONDE fois en tentant de
     l'expliquer avec l'exemple écrit en toutes lettres. */
  #page-content .studio-screenbar,
  #page-content .studio-screenbar--1,
  #page-content .studio-screenbar--2 {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-left: var(--mreg-rail);
    padding-right: var(--mreg-rail);
  }
  #page-content .studio-screenbar::-webkit-scrollbar,
  #page-content .studio-screenbar--1::-webkit-scrollbar,
  #page-content .studio-screenbar--2::-webkit-scrollbar { display: none; }
  /* Les enfants cessent de se comprimer : ils défilent au lieu de déborder. */
  #page-content .studio-screenbar > *,
  #page-content .studio-screenbar--1 > *,
  #page-content .studio-screenbar--2 > * { flex: 0 0 auto; }

  /* ── 2. AUCUN FILET sur les rangées de données ──────────────────────────
     Décision Henri du 09/08, déjà appliquée au portail : « c'est le rythme de
     46 px qui sépare, pas un trait ». Elle ne valait que là ; elle vaut
     maintenant pour toute liste au vocabulaire canonique `.studio-list`. */
  #page-content table.studio-list tbody tr { border-bottom: 0; }

  /* ── 3. Le texte se coupe au lieu de pousser la rangée hors du panneau ──
     Mesuré : .prj-table-client déborde son conteneur de 288 px pour 124 px
     disponibles, .ch-ptable-client de 288 pour 200. min-width:0 est ce qui
     manque à un enfant de grille pour accepter de rétrécir. */
  #page-content table.studio-list tbody td { min-width: 0; }
  #page-content .prj-table-title,
  #page-content .prj-table-client,
  #page-content .ch-ptable-title,
  #page-content .ch-ptable-client {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   91S-106 - LA COMPOSITION PROJETS EST RETIREE (11/08/2026, capture d'Henri)

   CE QUI S'EST PASSE, ET LA LECON. J'avais force la rangee a deux rangs de 23 px pour
   atteindre les 46 px de la cible. La sonde a repondu « 46 px » et je l'ai crue : elle
   mesurait la BOITE. Sur la capture reelle du simulateur, le contenu DEBORDAIT de sa
   rangee et les montants se superposaient aux noms des projets - « 63 127 EUR » ecrit
   par-dessus « Villa Regrettee ». C'est un zero immediat a la mesure 9 de la grille
   mobile (zero collision), et c'etait EN PRODUCTION.

   Trois erreurs enchainees, toutes de la meme famille :
     1. j'ai mesure des PROPRIETES (hauteur de boite) et jamais une COMPOSITION ;
     2. je n'ai pas regarde une seule capture de l'ecran que je livrais ;
     3. j'ai pris une mediane pour un verdict - une mediane ne voit pas une collision.

   Ce qui RESTE en place, et qui etait bon : la barre d'ecran canonique qui defile au
   lieu de pousser la page, et la disparition des filets. Ce qui est RETIRE : la
   composition en deux lignes et les rangs de 23 px.

   La suite ne sera pas une adaptation de la table de bureau (decision Henri du 11/08) :
   les tableaux de bord Projets, Chantiers et Consultations se recomposent dans la LANGUE
   du portail, sur maquette validee avant code.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   91S-106 - LA RANGEE PROJETS, UNE SEULE LIGNE (decision Henri, 11/08/2026)

   « Sur la partie mobile on cache avancement, honoraires et nom MOA. » Cette phrase
   resout le probleme que ma version precedente avait cree : en voulant garder les
   honoraires ET le nom, j'avais empile deux rangs de 23 px, le contenu debordait de sa
   boite et les montants s'ecrivaient PAR-DESSUS les noms de projet. La sonde repondait
   « 46 px » parce qu'elle mesurait la BOITE, pas ce qu'il y avait dedans.

   Avec trois colonnes en moins, la rangee tient sur UNE ligne : plus rien a empiler,
   donc plus aucune collision possible. C'est la loi L4 de Linear - etat, titre, une
   meta - et le rythme de 46 px de la cible validee.

     ●  25_RGT   Villa Regrettee ..................  [HI]  M1-AOR

   Le nom s'ellipse s'il est trop long, il ne se coupe jamais en deux lignes (loi L3).
   Honoraires, avancement et maitre d'ouvrage vivent dans la fiche du projet.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  #prjContent table.studio-list tbody tr {
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--mreg-reg-h, 46px);
    padding: 0 var(--mreg-rail);
  }

  /* Ce que la decision d'Henri retire du telephone. Les boutons d'action partent avec :
     ce sont des gestes de bureau, et Linear ne pose jamais de bouton sous une rangee. */
  #prjContent table.studio-list tbody td.prj-td-progress,
  #prjContent table.studio-list tbody td.prj-td-fees,
  #prjContent table.studio-list tbody td.prj-td-actions,
  #prjContent table.studio-list tbody td.prj-td-nom .prj-table-client,
  #prjContent table.studio-list thead { display: none; }

  #prjContent table.studio-list tbody td { padding: 0; height: auto; min-height: 0; }
  #prjContent table.studio-list tbody td.prj2-state-td,
  #prjContent table.studio-list tbody td.prj-td-code,
  #prjContent table.studio-list tbody td.prj-td-resp,
  #prjContent table.studio-list tbody td.prj-td-phase { flex: 0 0 auto; }

  /* Le nom porte l'ecran : il prend toute la place restante et s'ellipse. */
  #prjContent table.studio-list tbody td.prj-td-nom { flex: 1 1 auto; min-width: 0; }
  #prjContent table.studio-list tbody td.prj-td-nom .prj-table-title {
    font-size: var(--mreg-reg-size, 15.5px);
    font-weight: 450;
    line-height: 1.3;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #prjContent table.studio-list tbody td.prj-td-code {
    font-size: var(--mreg-secondary);
    color: var(--text-tertiary);
    white-space: nowrap;
  }

  /* Le point d'etat garde sa zone tapable de 44 px sans commander la hauteur :
     ce qu'on voit fait 24 px, la cible est rendue par un cadre fantome. */
  #prjContent table.studio-list tbody td.prj2-state-td .studio-state {
    min-width: 24px;
    min-height: 24px;
    position: relative;
  }
  #prjContent table.studio-list tbody td.prj2-state-td .studio-state::after {
    content: "";
    position: absolute;
    inset: -10px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LE REGISTRE MOBILE DES TABLEAUX DE BORD (91S-106)

   🪤 CES REGLES VIVENT ICI, ET C'EST LA CORRECTION D'UN DEFAUT QU'HENRI A VU :
   « quand j'arrive a froid j'ai un flash CSS ». Il etait de moi. Le module chargeait
   sa propre feuille par JavaScript AU MOMENT DU RENDU : les rangees s'affichaient donc
   une fraction de seconde SANS style, le temps que le fichier arrive.

   LA REGLE QUI EN SORT, valable pour tout developpement futur : une feuille necessaire
   au PREMIER RENDU ne se charge jamais par JavaScript. Elle vit dans une feuille deja
   servie par index.html - ici la charte mobile, chargee ligne 96, avant meme critical.
   Charger a la demande est bon pour un ecran qu'on ouvre ; jamais pour ce qui peint la
   premiere image.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {


.rgm {
      /* 🪤 MESURE du 11/08 sur Chantiers : le premier intitulé de section commençait à
         68 px alors que la barre d'outils COLLANTE descend à 88 - elle le recouvrait de
         20 px, et `elementFromPoint` désignait le champ de recherche. Un registre posé
         sous une barre collante doit sa propre garde ; il ne peut pas compter sur le flux. */
      padding-top: 22px;
      padding-bottom: 96px;   /* la barre du bas est givrée et flotte : la liste réserve sa hauteur */
  }

  /* L5 : la section est un label gris, SANS compteur. La liste est son propre compteur. */
  .rgm-grp {
      padding: 18px 18px 7px;
      font-size: 13px;
      color: var(--text-tertiary);
  }

  .rgm-grp:first-child {
      padding-top: 0;   /* la garde est portée par .rgm, pas répétée ici */
  }

  /* La rangée porte le dessous révélé ; c'est `.rgm-avant` qui glisse au-dessus. */
  .rgm-ligne {
      position: relative;
      overflow: hidden;
  }

  .rgm-avant {
      position: relative;
      z-index: 1;
      display: flex;
      align-items: center;
      gap: 11px;
      height: 46px;
      padding: 0 18px;
      background: var(--app-panel);
      cursor: pointer;
      transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
      will-change: transform;
  }

  /* 🪤 Le survol vit sous `hover: hover` : sur iOS un :hover reste COLLÉ après un toucher,
     et c'est exactement le défaut vu sur la capture d'Henri du 11/08 (une rangée grisée
     en permanence au milieu de la liste). */
  @media (hover: hover) {
      .rgm-avant:hover {
          background: var(--bg-active);
      }
  }

  .rgm-avant:active {
      background: var(--bg-active);
  }

  /* La SEULE couleur de l'écran, et elle ne dit que l'état (mesure 12 de la grille). */
  .rgm-pt {
      width: 7px;
      height: 7px;
      flex: none;
      border-radius: var(--radius-full);
      background: var(--text-tertiary);
      opacity: 0.45;
  }

  .rgm-pt.v {
      background: var(--accent-green, var(--color-success));
      opacity: 1;
  }

  .rgm-pt.a {
      background: var(--accent-orange, var(--color-warning));
      opacity: 1;
  }

  /* 🔴 LA COLONNE DES CODES A UNE LARGEUR FIXE (constat Henri, 13/08 :
     « Laura Long n'a pas le meme retrait »).

     MESURE avant correctif : les noms de projets partaient de NEUF abscisses
     differentes, de 93 a 146 px - 53 px d'ecart. `flex: none` donnait a chaque code
     sa largeur naturelle, donc « LL » (14 px) et « 26-28-BDF » (67 px) poussaient
     leur nom a des endroits differents. L'œil lit une liste par sa verticale : neuf
     verticales, ce n'est plus une colonne.

     72 px est mesure, pas choisi : c'est le code le plus large du parc (67 px) plus
     une marge. Aucun code n'est tronque - verifie sur les trois registres. Si un
     code plus long apparaissait un jour, c'est cette valeur qu'on releve, jamais
     l'alignement qu'on abandonne. */
  .rgm-code {
      flex: 0 0 72px;
      width: 72px;
      font-size: 12.5px;
      color: var(--text-tertiary);
      font-variant-numeric: tabular-nums;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
  }

  /* L3 : le titre porte l'écran. UNE ligne, ellipsé - jamais deux lignes, et jamais réduit
     à un moignon : c'est lui qui prend toute la place restante, pas les métadonnées. */
  .rgm-nom {
      flex: 1;
      min-width: 0;
      font-size: 15.5px;
      font-weight: 450;
      line-height: 1.3;
      letter-spacing: -0.01em;
      color: var(--text-primary);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
  }

  /* L4 : UNE seule méta à droite. */
  .rgm-meta {
      flex: none;
      font-size: 14px;
      color: var(--text-secondary);
      font-variant-numeric: tabular-nums;
      white-space: nowrap;
  }

  /* ── Ce que le glissement révèle (demande d'Henri, 11/08) ──────────────────
     Invisible tant qu'on ne le demande pas : c'est le motif Linear, les informations
     secondaires ne sont pas posées sous chaque ligne. */
  .rgm-dessous {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      width: 132px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: flex-end;
      padding: 0 18px 0 8px;
      background: var(--bg-secondary);
  }

  .rgm-dessous-l {
      font-size: 11px;
      color: var(--text-tertiary);
  }

  .rgm-dessous-v {
      font-size: 13.5px;
      color: var(--text-primary);
      max-width: 100%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
  }

  .rgm-vide {
      padding: 60px 26px;
      text-align: center;
      color: var(--text-tertiary);
      font-size: 13px;
      line-height: 1.6;
  }

}

/* ── 91S-106 · L'AMPLITUDE DANS LA JOURNEE OUVERTE ─────────────────────────
   Les trois champs qui rendent la saisie possible au telephone. Ils vivaient dans la
   rangee du tableau ; le registre l'a remplacee, ils vivent donc dans la journee ouverte.
   Trois champs cote a cote, chacun avec son intitule au-dessus : c'est le registre iOS
   des listes groupees, pas une ligne de formulaire. */
@media (max-width: 639px) {
  .rh-mob-amplitude {
      /* 🪤 MESURE au simulateur : a TROIS colonnes egales, le champ Pause etait COUPE a
         droite - le champ d'heure natif affiche « 09:00 AM » avec son icone, ce qui demande
         bien plus qu'un tiers de 393 px. Deux colonnes : arrivee et depart sur la premiere
         ligne, pause sur la seconde. Rien n'est plus tronque. */
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 8px;
      margin-top: 12px;
  }

  .rh-mob-amplitude label {
      display: flex;
      flex-direction: column;
      gap: 4px;
      font-size: 11px;
      color: var(--text-tertiary);
  }

  .rh-mob-amplitude input {
      height: 44px;   /* cible tactile Apple HIG, mesure 7 de la grille mobile */
      padding: 0 8px;
      font-size: 15.5px;
      color: var(--text-primary);
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-sm);
      font-variant-numeric: tabular-nums;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   L'EN-TETE CANONIQUE SUR TELEPHONE (91S-106, maquette validee le 12/08)
   docs/audits/2026-08-12-maquette-entete-recherche.html

   LOI L1 : une ligne, titre a gauche, une pilule d'actions a droite. Rien
   d'autre ne vit dans le chrome permanent - ni recherche, ni chips, ni
   compteur, ni fil d'Ariane.

   MESURE QUI JUSTIFIE : Projets sert 155 px de chrome avant la premiere donnee
   (recherche pleine largeur PUIS cinq chips a compteurs), la cible est 96.
   Consultations ecrase titre et recherche sur une ligne au point que le champ
   SORT DE L'ECRAN. Quatre ecrans, quatre en-tetes differents.

   ⚠️ LE BUREAU N'EST PAS TOUCHE. Tout ce bloc vit sous 639 px, et rien n'est
   modifie dans les modules : c'est la charte qui recompose, comme elle le fait
   deja pour le registre. Aucune ligne ajoutee aux monolithes.

   CE QUI DISPARAIT DU TELEPHONE, et ou ca part :
     . la recherche      -> dans la feuille du bas (composant .studio-feuille)
     . les chips a compteurs -> la liste EST son propre compteur (loi L5)
     . le compteur du titre  -> meme raison
     . les boutons de vue    -> la vue liste est la seule qui vaille au telephone
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  /* La barre 1 devient l'en-tete canonique : 52 px, titre + pilule. */
  #page-content .studio-screenbar--1 {
      height: 52px;
      min-height: 52px;
      padding: 0 var(--mreg-rail);
      justify-content: space-between;
      gap: 8px;
  }

  /* 🔴 LE TITRE ETAIT MASQUE, SANS REMPLACANT.
     `css/projets.css` (l. 7121) fait `#prjContent .prj2-bar1 .prj2-title { display: none }`
     avec ce commentaire : « le titre "Projets" double le selecteur d'ecran mobile ».
     MESURE : ce selecteur d'ecran est ABSENT de cet ecran. Le titre disparaissait donc
     sans rien a la place - une bande blanche de 52 px en haut de la liste.

     🪤 ET LA VRAIE LECON, du 13/08. Mon premier correctif passait par un attribut
     `data-rgm-titre` pose en JavaScript par `js/registre-mobile.js`. Ce couplage a
     silencieusement casse : le code qui posait l'attribut a disparu du source pendant
     une manœuvre de rebase, mais le BUNDLE `js/dist` compile le contenait encore.
     L'attribut etait donc TOUJOURS pose a l'ecran - ma sonde le voyait - alors que
     plus aucune ligne du depot ne le produisait. Un correctif de style qui depend
     d'un attribut pose par JS a deux points de rupture au lieu d'un.

     Ici, du CSS seul : deux identifiants (`#page-content #prjContent`) battent
     l'unique identifiant de la regle qui masque. Rien a poser, rien a compiler. */
  #page-content #prjContent .prj2-bar1 .prj2-title,
  #page-content #cstContent .cst-bc-title {
      display: flex;
      align-items: baseline;
      gap: 6px;
      min-width: 0;
  }

  /* Le titre porte l'ecran : 20 px, comme la maquette. */
  #page-content .studio-screenbar--1 .prj2-title > span:not(.prj2-count),
  #page-content .studio-screenbar--1 .cst-bc-title {
      font-size: 20px;
      font-weight: 700;
      letter-spacing: -0.02em;
      color: var(--text-primary);
  }

  /* Ce qui quitte le chrome permanent. La recherche vit desormais dans la
     feuille du bas ; le compteur est redondant avec les sections de la liste. */
  #page-content .studio-screenbar--1 .prj2-search,
  #page-content .studio-screenbar--1 .prj2-count,
  #page-content .studio-screenbar--1 .cst-bc-count,
  #page-content .studio-screenbar--1 .cst-shell-search,
  #page-content .ch-header .ch-search {
      display: none;
  }

  /* La barre 2 : les chips a compteurs disparaissent, seuls les outils restent,
     groupes en pilule a droite. */
  #page-content .studio-screenbar--2 .studio-chips {
      display: none;
  }

  #page-content .studio-screenbar--2 {
      height: 0;
      min-height: 0;
      padding: 0;
      overflow: visible;
      border: 0;
  }

  /* La pilule d'actions : elle remonte dans la barre 1, a droite du titre.
     Motif Linear - au plus deux icones, trois quand un contexte permanent
     l'exige (le selecteur de salarie de RH). */
  #page-content .studio-screenbar--2 .prj2-tools,
  #page-content .studio-screenbar--2 .cst-shell-actions {
      position: absolute;
      top: 8px;
      right: var(--mreg-rail);
      display: flex;
      align-items: center;
      gap: 2px;
      padding: 3px;
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-full);
      z-index: 5;
  }

  /* Dans la pilule, les boutons perdent leur cadre propre. */
  #page-content .studio-screenbar--2 .prj2-tools .studio-iconbtn,
  #page-content .studio-screenbar--2 .cst-shell-actions .studio-iconbtn {
      width: 30px;
      height: 30px;
      min-height: 30px;
      border: 0;
      background: transparent;
  }

  /* Les bascules de VUE n'ont pas de sens au telephone : le registre est la
     seule presentation, et deux boutons pour un choix inexistant sont du bruit. */
  #page-content .studio-screenbar--2 .prj2-tools .studio-iconbtn[title="Vue liste"],
  #page-content .studio-screenbar--2 .prj2-tools .studio-iconbtn[title="Vue cartes"] {
      display: none;
  }

  /* Le libelle du bouton primaire tombe : seule l'icone reste, dans la pilule. */
  #page-content .studio-screenbar--2 .prj2-tools .studio-btn-primary {
      width: 30px;
      min-height: 30px;
      padding: 0;
      overflow: hidden;
      white-space: nowrap;
      color: transparent;
      background: transparent;
      box-shadow: none;
  }

  #page-content .studio-screenbar--2 .prj2-tools .studio-btn-primary svg {
      color: var(--accent-blue);
      flex: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LE DASHBOARD CHANTIER (constat Henri, 13/08 : « bugue encore enormement »)

   MESURE : `.che2-body` porte `grid-template-columns: 1fr 336px` - deux colonnes
   pensees pour le bureau. Dans 393 px, le calcul rend **45 px pour la premiere
   colonne** et 302 pour la seconde : la table des lots etait ecrasee a 45 px de
   large (« 01 · D », « 02 · T »...) pendant que le rail lui passait par-dessus.
   Ce n'etait pas un defaut de style, c'est un layout de bureau servi tel quel -
   cet ecran n'avait JAMAIS recu de traitement telephone.

   ⚠️ RIEN N'EST MASQUE ICI. Les deux colonnes s'empilent : la table des lots
   d'abord, le rail de decisions ensuite. Tout reste accessible.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  /* 🔴 LA CAUSE RACINE, mesuree le 13/08 et pas celle que je croyais.

     `.che2-screen` est une grille qui ne declare que ses RANGEES. Sa colonne
     implicite herite donc de `min-width: auto` - la regle par defaut d'un element
     de grille - et **refuse de descendre sous la largeur minimale de son enfant le
     plus large**. Mesure : le conteneur faisait 361 px et son contenu 704. Tout le
     reste (tuiles a 664, jauge a 664, table ecrasee) DECOULE de ce seul refus.

     `minmax(0, 1fr)` est le remede canonique : il autorise la colonne a passer
     sous le minimum automatique. Une ligne, et les huit debordements tombent. */
  #ch-content .che2-screen,
  #page-content .che2-screen {
      grid-template-columns: minmax(0, 1fr);
      min-height: 0;
      /* `grid-template-rows: auto auto 1fr` etire la derniere rangee pour remplir
         les 560 px de `min-height` : au telephone ca creuse un trou gris de ~250 px
         sous le Bilan (mesure en bas de defilement le 13/08). Les rangees prennent
         leur hauteur naturelle. */
      grid-template-rows: auto;
      grid-auto-rows: auto;
  }

  /* Les deux colonnes s'empilent au lieu de se disputer 393 px. */
  #ch-content .che2-body,
  #page-content .che2-body {
      display: block;
  }

  #ch-content .che2-body > *,
  #page-content .che2-body > * {
      width: 100%;
      max-width: 100%;
      margin-bottom: var(--mreg-v2);
  }

  /* Le rail retrouve un flux normal : il ne defile plus dans sa propre boite,
     c'est la page qui defile. Deux zones de defilement imbriquees au telephone
     rendent le geste imprevisible. */
  #ch-content .che2-rail,
  #page-content .che2-rail {
      overflow-y: visible;
      min-height: 0;
  }

  /* 🪤 LES QUATRE TUILES DE CHIFFRES tenaient sur `repeat(4, 1fr)` : a 393 px,
     chaque tuile recevait moins de 90 px et les libelles se chevauchaient -
     « 0.0% decaisserealise » etait DEUX libelles ecrits l'un sur l'autre.
     Deux colonnes, et le chevauchement disparait. La loi L2 du skill mobile
     voudrait qu'il n'y ait aucun chiffre agrege ici ; c'est une decision de
     produit, pas de style, donc on corrige le defaut sans trancher a sa place. */
  #ch-content .che2-kpis,
  #page-content .che2-kpis {
      grid-template-columns: repeat(2, 1fr);
      gap: var(--mreg-v2) 12px;
  }

  /* 🔴 « 0.0% deadaiese » - DEUX libelles ecrits l'un sur l'autre.
     `.che2-gl` est en `position: absolute` et le JS lui donne un `left` egal a sa
     valeur sur la jauge. Quand realise et decaisse sont proches - ici tous deux a
     0 % - les deux etiquettes atterrissent au meme endroit et se superposent.

     ⚠️ CE DEFAUT N'EST PAS PROPRE AU TELEPHONE : il se produit partout des que les
     deux valeurs se rapprochent. Il n'est corrige ICI que pour le mobile, parce que
     le dashboard chantier est l'ECRAN DE REFERENCE du projet (CLAUDE.md § STYLE) et
     que sa version bureau ne se retouche pas au detour d'une passe mobile. Signale
     dans le dev-chat pour arbitrage.

     Sur telephone, les etiquettes reviennent dans le flux : plus de superposition
     possible par construction, plutot qu'un decalage calcule qui retomberait juste
     sur un autre couple de valeurs. */
  #ch-content .che2-glabels,
  #page-content .che2-glabels {
      position: static;
      display: flex;
      justify-content: space-between;
      gap: 10px;
      height: auto;
  }

  #ch-content .che2-glabels .che2-gl,
  #page-content .che2-glabels .che2-gl {
      position: static;
      left: auto !important;
      right: auto !important;
      transform: none !important;
  }

  /* Le selecteur d'entreprise sortait du cadre a droite. */
  #ch-content .che2-panel select,
  #page-content .che2-panel select {
      max-width: 100%;
      min-width: 0;
  }

  /* 🪤 LA BARRE DU BAS masquait la derniere rangee de lots (« 06 · Menuiseries »
     lisible A TRAVERS le dock sur la capture du 13/08). La liste reserve la hauteur
     de la barre flottante au lieu de passer dessous. */
  #ch-content .che2-screen,
  #page-content .che2-screen {
      padding-bottom: 88px;
  }

  /* La legende du graphique passait sous les barres : elle s'enroule. */
  #ch-content .che2-glegend,
  #page-content .che2-glegend {
      flex-wrap: wrap;
      gap: 6px 14px;
  }

  /* La table des lots defile dans SA boite plutot que d'ecraser ses colonnes. */
  #ch-content .che2-body table,
  #page-content .che2-body table {
      min-width: 320px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LES ECARTS DE L'AUDIT DU 13/08, corriges (91S-106)
   docs/audits/2026-08-13-audit-entete-maquette-vs-reel.html
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  /* ECART 5 : une icone precedait le titre. La maquette n'a que du texte - l'icone
     repete ce que le titre dit deja, et ce que la barre du bas indique une
     troisieme fois.

     🪤 Ma premiere ecriture visait `[data-rgm-titre] > svg` : du CODE MORT. L'icone
     n'est pas un ENFANT du titre, c'est son FRERE (`svg.cst-bc-icon` juste avant).
     Une regle qui ne selectionne rien ne leve aucune erreur - elle se contente de
     ne rien faire, et la capture montre l'icone toujours la. Mesure au DOM avant
     d'ecrire un selecteur, jamais une supposition sur la structure. */
  #page-content .studio-screenbar--1 .cst-bc-icon,
  #page-content .studio-screenbar--1 .prj2-title > svg:first-child {
      display: none;
  }

  /* ECART 1 : CINQ controles dans la barre au lieu de deux, et « Nouveau projet »
     sortait du cadre a droite (« Nouvea » coupe, mesure du 13/08).

     Ce qui part, et pourquoi - c'est une decision d'INVENTAIRE, pas de pixels :
       . « Vue liste » et « Vue cartes » : la charte dit deja, en commentaire, que la
         vue liste est la seule qui vaille au telephone. Deux boutons pour un choix
         qui n'en est pas un ;
       . « Apercu - prochains rendus » : un panneau lateral, geste de bureau.
     Restent la loupe et le filtre, plus l'action primaire. Loi L1 de Linear :
     un titre a gauche, une pilule de deux icones a droite. */
  #page-content .studio-screenbar--1 .prj2-tools #prj2-panel-btn,
  #page-content .studio-screenbar--1 .prj2-tools [onclick*="setProjectsView"] {
      display: none;
  }

  /* L'action primaire ne porte plus son libelle : le « + » suffit, et elle cesse
     de pousser la pilule hors du cadre. La cible tactile reste a 44 px. */
  #page-content .studio-screenbar--1 .prj2-tools .studio-btn-primary {
      padding: 0;
      width: 44px;
      min-width: 44px;
      flex: 0 0 44px;
      border-radius: 50%;
      overflow: hidden;
      white-space: nowrap;
      font-size: 0;
      justify-content: center;
  }

  #page-content .studio-screenbar--1 .prj2-tools .studio-btn-primary svg {
      font-size: initial;
      flex: 0 0 auto;
  }

  /* 🪤 LA BARRE DU BAS masquait la derniere rangee des trois registres, comme sur
     le dashboard chantier. La liste reserve la hauteur du dock au lieu de passer
     dessous - meme remede, meme raison, partout. */
  #page-content .prj-list-wrap,
  #page-content #cstContent,
  #page-content .ch-content {
      padding-bottom: 88px;
  }

  /* ECART 3 : le champ gardait son contour bleu natif au focus. Dans la feuille,
     il prend le registre du champ arrondi - c'est le canonique qui doit gagner,
     pas le style du module. D'ou le poids ajoute par `.studio-feuille-ouverte`. */
  .studio-feuille.studio-feuille-ouverte input.studio-feuille-q,
  .studio-feuille.studio-feuille-ouverte .studio-feuille-q {
      outline: 0;
      border: 1px solid transparent;
      box-shadow: none;
  }

  .studio-feuille.studio-feuille-ouverte .studio-feuille-q:focus {
      outline: 0;
      border-color: var(--accent-blue);
      box-shadow: none;
  }

  /* ECART 4 : « Termine » etait un bouton primaire plein pleine largeur - il
     criait plus fort que ce qu'il fait. Il ferme une feuille, il ne valide rien. */
  .studio-feuille.studio-feuille-ouverte .studio-freset {
      background: var(--bg-primary);
      color: var(--text-secondary);
      border: 1px solid var(--border-color);
      box-shadow: none;
      font-weight: 500;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LE REGISTRE CHANTIERS - ce qui est repare, et ce qui ne l'est PAS (13/08)

   MESURE : `.ch-toolbar` fait 16 px de haut et contient un champ de recherche et
   trois selecteurs de 28 px. Ses enfants DEBORDENT et se peignent par-dessus les
   rangees - c'est la superposition vue sur la capture (« ...cheti 56 % » a moitie
   cache derriere « Toutes les phases »), pas un defaut de marge.

   ⚠️ CE N'EST QU'UN CALFEUTRAGE. La vraie cible reste l'ecart n°2 de l'audit : la
   recherche et les trois filtres de Chantiers doivent rejoindre la FEUILLE du bas,
   comme sur Projets. Tant que ce n'est pas fait, ils restent en clair dans la barre
   - laids mais ACCESSIBLES. Les masquer sans les avoir deplaces couperait l'acces
   aux filtres : ce serait un plus joli ecran et un moins bon produit.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
  /* La recherche et les trois filtres de Chantiers vivent desormais dans la FEUILLE
     du bas (ecart n°2 de l'audit, ferme le 13/08) : ils quittent la barre d'ecran,
     ou ils occupaient 383 px de chrome avant la premiere donnee. Ils ne sont pas
     supprimes - la loupe les rouvre, et c'est le champ REEL qui s'y deplace. */
  #page-content .ch-toolbar .ch-search-wrap,
  #page-content .ch-toolbar .ch-filters-inline {
      display: none;
  }

  /* Dans la feuille, la recherche prend le registre du champ canonique. Les filtres,
     eux, ne sont plus des `<select>` en vrac : chacun vit dans une `.studio-frow`
     (voir `components.css`), donc RIEN a styler ici - c'est tout l'interet du
     canonique. On neutralise seulement l'apparence native du select, qui doit se
     lire comme la valeur d'une rangee. */
  .studio-feuille .ch-search-wrap {
      display: flex;
      width: 100%;
      margin: 0;
  }

  .studio-feuille .ch-search-wrap input {
      width: 100%;
      min-height: 44px;
  }

  /* 🪤 J'avais mis `direction: rtl` pour coller la valeur a droite : ca a retourne
     la ponctuation - « Tous les resp. » s'affichait « .Tous les resp ». Un alignement
     ne se regle JAMAIS en inversant le sens de lecture. Le canonique aligne deja a
     droite ; il ne reste qu'a retirer l'apparence native du select. */
  .studio-feuille select.studio-finp {
      appearance: none;
      -webkit-appearance: none;
  }

  /* La barre reprend la hauteur de son contenu : plus rien ne deborde dessus. */
  #page-content .ch-toolbar.studio-screenbar--2 {
      height: auto;
      min-height: 0;
      flex-wrap: wrap;
      row-gap: 8px;
      padding-bottom: 8px;
  }

  /* 🔴 Le titre « Chantiers » etait en `display: none`, pose par
     `.ch-projet-selector .ch-large-title` (chantiers.css l. 2359) - meme famille
     exacte que le titre de Projets. Ma premiere ecriture posait `min-height: 44px`
     et le laissait invisible : une hauteur minimale ne ressuscite pas un element
     masque. Il fallait rendre le DISPLAY, pas la hauteur.
     Deux classes plus un identifiant battent les deux classes de la regle qui masque. */
  #page-content .ch-projet-selector .ch-large-title,
  #page-content .ch-large-title.studio-screenbar--1 {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
      height: auto;
      min-height: 52px;
      padding: 0 var(--mreg-rail);
      overflow: visible;
  }

  /* « Retour aux projets » occupait une rangee entiere pour un geste que la barre
     du bas fait deja - son onglet dossier EST Projets. Decision d'inventaire
     (mesure 6) : ce qui est deja atteignable en un toucher ne prend pas de place.
     🪤 Ma premiere ecriture visait `.ch-back-projets`, une classe INVENTEE : le lien
     n'a aucune classe propre, c'est un `.studio-btn-secondary` dans les actions de
     la barre. Un selecteur devine ne masque rien et ne dit rien. */
  #page-content .ch-toolbar-actions .studio-btn-secondary {
      display: none;
  }

  /* L'icone devant le titre part, comme sur Consultations : elle repete le titre,
     que la barre du bas indique deja une troisieme fois. Elle n'est pas un enfant
     du titre - c'est une decoration - d'ou les pseudo-elements. */
  #page-content .ch-large-title::before,
  #page-content .ch-large-title .ch-title-text::before {
      content: none;
  }

  /* 🪤 `> svg` ne l'a pas eue : l'icone est plus PROFONDE que le premier niveau.
     On vise donc tout svg de l'en-tete SAUF celui de la loupe - sans cette
     exception, le bouton de recherche disparaitrait avec la decoration. */
  #page-content .ch-large-title svg {
      display: none;
  }

  #page-content .ch-large-title .studio-iconbtn svg {
      display: block;
  }

  /* La barre d'outils est desormais VIDE - recherche, filtres et retour sont partis
     dans la feuille ou dans la barre du bas. Elle laissait un trou de 150 px entre
     l'en-tete et la premiere section. Un conteneur vide ne reserve pas d'espace. */
  #page-content .ch-toolbar.studio-screenbar--2:not(:has(> *:not([hidden]))),
  #page-content .ch-toolbar-actions:empty {
      display: none;
  }

  #page-content .ch-toolbar.studio-screenbar--2 {
      padding-top: 0;
  }

  #page-content .ch-large-title .ch-title-text {
      font-size: 20px;
      font-weight: 700;
      letter-spacing: -0.02em;
      color: var(--text-primary);
  }

  /* Le compteur du titre : la liste EST son propre compteur (loi L5). */
  #page-content .ch-large-title .ch-title-count { display: none; }
}
