/* ══════════════════════════════════════════════════════════════════════════
   UI2 — COQUILLE DE LA REFONTE D'INTERFACE (chantier R1, prompt 959)
   ══════════════════════════════════════════════════════════════════════════
   CE FICHIER NE S'APPLIQUE QUE SI LA COQUILLE EST ALLUMÉE.
   Toutes les règles sont préfixées `.ui2-` ou portées par `body.ui2-on` : sans
   la classe sur <body> (interrupteur éteint), AUCUNE règle d'ici ne peut
   toucher l'écran d'aujourd'hui.

   ⛔ CE FICHIER NE REDÉFINIT PAS le `max-width` de `.main-content` (1300px /
   1600px au-delà de 1400px) ni le `padding-right:148px` du widget
   d'authentification. Ces deux règles restent verrouillées (piège 1 de
   STRATEGIE_REFONTE_2026-08-11.md §3) : la coquille décale le BODY, elle
   ne retouche pas le plafond ni le padding-right.

   ⚖ LEVÉE 1071 (David 26/08) — UN seul point désormais permis : sous
   `body.ui2-on`, `.main-content` peut recevoir `width: 100%` pour occuper
   le gabarit jusqu'au plafond, au lieu de se rétracter sur son contenu
   (flex colonne + `margin: 0 auto`). Interdit : changer le plafond, le
   padding-right, ou le centrage.

   Référence visuelle : site/_design_app_dashboard/mockups/
   maquette_coquille_autonome_V3.5.html (rail 76px, panneau 250px, topbar).
   Palette : tokens L0/L1 de design_tokens.css UNIQUEMENT, aucun hex en dur.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Maquette V3.5 : rail 76px. Élargi à 84px ici parce que les libellés imposés
     par le cadrage (« Documentation », « Connecteurs ») débordaient de 76px aux
     tailles de police disponibles en tokens (le plus petit vaut 10px, la
     maquette dessinait à 8,5px — valeur sans token, donc écartée). */
  --ui2-rail-w: 92px;
  --ui2-ctx-w: var(--width-ui2-context-default);
  --ui2-topbar-h: 56px;
  /* Place réservée au widget d'authentification (`js/auth_widget.js` :
     position fixed, top 8px, right 10px, z-index 99999) : la barre du haut ne
     doit pas passer dessous. La règle `.main-content{padding-right:148px}` du
     widget n'est PAS touchée (verrou `tests/test_220_widget_auth.py`). */
  --ui2-auth-reserve: 160px;
}

/* ── Décalage du contenu existant : sur le BODY, jamais sur .main-content ── */
body.ui2-on {
  padding-left: calc(var(--ui2-rail-w) + var(--ui2-ctx-w));
  padding-top: var(--ui2-topbar-h);
  /* 1070 — colonne flex pour coller le bandeau bas (`.app-toolbar`) en bas
     de fenêtre quand le contenu est court. 1071 — `.main-content` reçoit
     `width: 100%` (ci-dessous) : le plafond et le padding-right restent
     verrouillés, tête de fichier. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
/* 1071 — largeur de page unique. Enfant flex + `margin: 0 auto` (index.html)
   = shrink-to-fit : la page prenait la largeur de la vue. `width: 100%`
   occupe l'espace jusqu'au plafond 1300/1600 ; le centrage reste. */
body.ui2-on > .main-content {
  width: 100%;
}
body.ui2-on.ui2-ctx-collapsed {
  padding-left: var(--ui2-rail-w);
}
/* 1111 (lot G) — LA RÈGLE QUI MASQUAIT L'EN-TÊTE HISTORIQUE EST RETIRÉE.
   `body.ui2-on > .app-header { display: none }` n'a plus rien à masquer :
   l'en-tête est parti d'`index.html`, et le seul `.app-header` qui subsiste
   (volet, `#rechercheHote999`) n'est PAS enfant direct de <body> — le
   combinateur `>` ne pouvait donc pas l'atteindre. Compté à 0 nœud le 31/08.
   La barre du haut de la coquille (`.ui2-topbar`) est désormais la seule. */

/* ── Rail d'icônes (7 menus) ─────────────────────────────────────────────── */
.ui2-rail {
  position: fixed; left: 0; top: 0; bottom: 0; width: var(--ui2-rail-w);
  background: var(--noir); border-top: 3px solid var(--gold-app);
  display: flex; flex-direction: column; align-items: center;
  padding: var(--space-3) 0; gap: 2px; z-index: 1200;
  /* Recette David 12/08 (R1) : une barre de defilement HORIZONTALE apparaissait
     en bas du rail. `overflow-y: auto` autorise le debordement sur l'autre axe
     des que le contenu depasse d'un pixel. On borne les deux axes. */
  overflow-y: auto; overflow-x: hidden;
}
.ui2-rail__logo {
  width: 48px; height: 48px; margin-bottom: var(--space-2);
  display: flex; align-items: center;
  justify-content: center;
}
.ui2-rail__btn {
  position: relative; width: 84px; margin-right: 0; padding: var(--space-2) 2px;
  border: none; background: transparent; color: var(--sage-light);
  border-radius: var(--radius-md); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  transition: background .15s, color .15s;
}
.ui2-rail__btn:hover { background: var(--noir-mid); color: var(--surface); }
.ui2-rail__btn.is-active { background: var(--noir-mid); color: var(--surface); }
.ui2-rail__btn:focus-visible { outline: 2px solid var(--gold-app); outline-offset: 2px; }
.ui2-rail__lbl {
  font-size: var(--font-size-xs); font-weight: var(--font-weight-semi);
  letter-spacing: .2px; text-align: center; line-height: var(--line-height-tight);
  overflow-wrap: break-word; hyphens: none; max-width: 100%;
}
.ui2-rail__spacer { flex: 1 1 auto; min-height: var(--space-3); }
.ui2-ico { flex: 0 0 auto; width: 20px; height: 20px; stroke: currentColor; stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.ui2-ico--sm { width: 15px; height: 15px; }

/* ═══════════════════════════════════════════════════════════════════════
   ICÔNES DU RAIL — COULEURS PILOTABLES
   Repris de site/_design_app_dashboard/icones/prepares/icones-rail.css.
   Les SVG sont injectés inline par ui2_shell.js : <img> empêcherait les
   variables de traverser jusqu'au dessin. La variante B est conservée,
   sans être appliquée, car David a retenu la variante A « cartouche ».
   ═══════════════════════════════════════════════════════════════════════ */
.ico {
  --ico-accent: #b99230;
  --ico-second: #5c8fa8;
  --ico-trait: #1d1d1b;
  --ico-trait-doux: #4b4a4b;
  --ico-clair: #d4d7d9;
  --ico-fond: #eceeef;
  --ico-blanc: #ffffff;
  width: 48px; height: 48px; display: block;
}
.ui2-rail--cartouche .ico {
  --ico-accent:#9ba1a4; --ico-second:#f2f4f4; --ico-trait:#45484a;
  --ico-trait-doux:#5a5d5f; --ico-clair:#cdd0d2; --ico-fond:#e6e8e9; --ico-blanc:#f4f6f6;
}
.ui2-rail--cartouche .ui2-rail__logo .ico {
  --ico-accent:#b99230; --ico-second:#5c8fa8;
}
.ui2-rail--cartouche .ui2-rail__btn.is-active .ico,
.ui2-rail--cartouche .ui2-rail__btn:hover .ico {
  --ico-accent:#b99230; --ico-second:#5c8fa8; --ico-trait:#1d1d1b;
  --ico-trait-doux:#4b4a4b; --ico-clair:#d4d7d9; --ico-fond:#eceeef; --ico-blanc:#ffffff;
}
/* Variante B — « nu » : conservée, non appliquée. */
.ui2-rail--nu .ico {
  --ico-accent:#6E8C88; --ico-second:#DCEAE8; --ico-trait:#8FB0AC;
  --ico-trait-doux:#8FB0AC; --ico-clair:none; --ico-fond:none; --ico-blanc:none;
}
.ui2-rail--nu .ui2-rail__btn.is-active .ico,
.ui2-rail--nu .ui2-rail__btn:hover .ico {
  --ico-accent:#b99230; --ico-second:#DCEAE8; --ico-trait:#FFFFFF;
  --ico-trait-doux:#FFFFFF; --ico-clair:none; --ico-fond:none; --ico-blanc:none;
}
.ico--logo { width: 48px; height: 48px; }

/* ── Panneau contextuel (coquille visuelle ; l'arborescence vivante est R3) ─ */
.ui2-ctx {
  position: fixed; left: var(--ui2-rail-w); top: 0; bottom: 0;
  width: var(--ui2-ctx-w); background: var(--noir-soft);
  display: flex; flex-direction: column; overflow: hidden; z-index: 1190;
}
.ui2-ctx__resize {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: var(--width-ui2-resize-handle); border: none; padding: 0;
  background: transparent; cursor: ew-resize; touch-action: none; z-index: 1;
}
.ui2-ctx__resize::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: var(--space-hair) solid var(--noir-mid);
}
.ui2-ctx__resize:hover::after,
.ui2-ctx__resize:focus-visible::after { border-left-color: var(--sage); }
.ui2-ctx__resize:focus-visible { outline: none; }
body.ui2-resizing { cursor: ew-resize; user-select: none; }
body.ui2-ctx-collapsed .ui2-ctx { display: none; }
.ui2-ctx__head {
  padding: var(--space-3) var(--space-4) var(--space-1);
  font-size: var(--font-size-xs); font-weight: var(--font-weight-bold);
  text-transform: uppercase; letter-spacing: .8px; color: var(--text-light);
}
.ui2-ctx__body {
  flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
  padding: var(--space-1) var(--space-3) var(--space-4);
}
.ui2-ctx__empty {
  padding: var(--space-4); font-size: var(--font-size-sm);
  color: var(--text-light); line-height: 1.5;
}
.ui2-ctx__foot {
  padding: var(--space-3) var(--space-4); border-top: 1px solid var(--noir-mid);
  font-size: var(--font-size-xs); color: var(--text-light);
}
/* `.ui2-badge-dev` retirée au 1015c avec la pastille « Nouvelle présentation —
   essai » qu'elle habillait : plus aucun nœud ne porte cette classe. */

/* ── Barre du haut ───────────────────────────────────────────────────────── */
.ui2-topbar {
  position: fixed; top: 0; right: 0;
  left: calc(var(--ui2-rail-w) + var(--ui2-ctx-w));
  height: var(--ui2-topbar-h);
  display: flex; align-items: center; gap: var(--space-4);
  padding: 0 var(--ui2-auth-reserve) 0 var(--space-6); background: var(--surface);
  border-bottom: 1px solid var(--color-border-default); z-index: 1180;
}
body.ui2-ctx-collapsed .ui2-topbar { left: var(--ui2-rail-w); }
.ui2-topbar__collapse {
  flex: 0 0 auto; width: 32px; height: 32px;
  border: 1px solid var(--color-border-default); background: var(--surface);
  border-radius: var(--radius-md); color: var(--text-mid); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ui2-topbar__collapse:hover { background: var(--gray-50); }
.ui2-topbar__collapse svg, .ui2-btn-off svg { display: block; }
.ui2-topbar__crumb { flex: 1 1 auto; min-width: 0; }
.ui2-topbar__crumb .ui2-path { font-size: var(--font-size-sm); color: var(--color-text-muted); }
.ui2-topbar__crumb h2 {
  font-family: var(--font-family-title); font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold); text-transform: uppercase;
  letter-spacing: .4px; line-height: var(--line-height-tight); margin: 1px 0 0;
}
.ui2-topbar__actions { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: var(--space-2); }
.ui2-topbar__save { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.ui2-topbar__save .dirty-marker { white-space: nowrap; }
.ui2-btn-off {
  border: 1px solid var(--color-border-default); background: var(--surface);
  color: var(--color-text-secondary); border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3); cursor: pointer;
  font-family: var(--font-family-base); font-size: var(--font-size-base);
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.ui2-btn-off:hover { background: var(--gray-50); }

/* ── Mention honnête : ce que ce chantier ne fait pas encore ─────────────── */
.ui2-note {
  margin: var(--space-2) var(--space-2) 0; padding: var(--space-3);
  border: 1px dashed var(--color-border-light); border-radius: var(--radius-md);
  font-size: var(--font-size-sm); color: var(--text-light); line-height: 1.45;
}

/* ══ R3 — ARBORESCENCE DU PANNEAU ═══════════════════════════════════════════
   La pastille reprend le composant canonique `.badge-status` (DESIGN §7.3) et
   ses tokens `--color-badge-{ok|warn|err}-{bg|text}` — AUCUNE couleur ad hoc.
   « en attente » n'a pas de ton de statut : gris neutre, jamais un vert. */
.ui2-ctx__search {
  display: flex; align-items: center; gap: var(--space-2);
  margin: var(--space-3) var(--space-4) var(--space-2);
  padding: 0 var(--space-2); background: var(--noir-mid);
  border: 1px solid var(--noir-mid); border-radius: var(--radius-md);
  color: var(--sage-light);
}
.ui2-ctx__search input {
  flex: 1 1 auto; min-width: 0; background: transparent; border: none; outline: none;
  color: var(--surface); font-family: var(--font-family-base);
  font-size: var(--font-size-base); padding: var(--space-2) 0;
}
.ui2-ctx__search input::placeholder { color: var(--text-light); }

.ui2-tree__affaire { padding: var(--space-2) var(--space-3) var(--space-3); }
.ui2-tree__k {
  font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-light);
}
.ui2-tree__v {
  font-size: var(--font-size-base); font-weight: var(--font-weight-semi);
  color: var(--surface); margin-bottom: var(--space-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ui2-tree__groupe { margin-bottom: var(--space-4); }
.ui2-tree__file-head {
  display: flex; align-items: flex-start; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-1);
  border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer;
}
.ui2-tree__file-head:hover { background: var(--noir-mid); border-radius: var(--radius-md); }
.ui2-tree__file-head:focus-visible { outline: 2px solid var(--gold-app); outline-offset: -2px; }
.ui2-tree__file-chevron { flex: 0 0 auto; color: var(--text-light); margin-top: var(--space-1); transition: transform .15s ease; }
.ui2-tree__groupe.is-collapsed .ui2-tree__file-chevron { transform: rotate(-90deg); }
.ui2-tree__file-name {
  flex: 1 1 auto; min-width: 0; color: var(--surface);
  font-size: var(--font-size-base); font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}
.ui2-tree__source-badge {
  flex: 0 0 auto; padding: 0 var(--space-2);
  border: var(--space-hair) solid var(--gold); border-radius: var(--radius-pill);
  color: var(--gold-bright); font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold); line-height: var(--line-height-badge);
}
.ui2-tree__node {
  display: flex; align-items: flex-start; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-1); border: none; border-radius: var(--radius-md);
  background: transparent; color: var(--sage-light); font: inherit;
  font-size: var(--font-size-base); text-align: left; cursor: pointer;
}
.ui2-tree__node:hover { background: var(--noir-mid); color: var(--surface); }
.ui2-tree__node:focus-visible { outline: 2px solid var(--gold-app); outline-offset: -2px; }
.ui2-tree__rep {
  flex: 0 0 auto; min-width: var(--size-ui2-repere); min-height: var(--size-ui2-repere);
  display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--space-1);
  font-family: var(--font-family-mono); font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold); background: var(--noir-mid);
  color: var(--surface); border-radius: var(--radius-md);
}
.ui2-tree__details { flex: 1 1 auto; min-width: 0; display: grid; gap: var(--space-1); }
.ui2-tree__type {
  color: var(--sage-light); font-size: var(--font-size-base); line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.ui2-tree__meta {
  color: var(--text-light); font-size: var(--font-size-xs); line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}
.ui2-status-dot {
  flex: 0 0 auto; width: var(--size-ui2-status-dot); height: var(--size-ui2-status-dot);
  margin-top: var(--space-2); border-radius: var(--radius-pill);
}
.ui2-status-dot--ok { background: var(--color-badge-ok-text); }
.ui2-status-dot--warn { background: var(--color-badge-warn-text); }
.ui2-status-dot--err { background: var(--color-badge-err-text); }
.ui2-status-dot--neutre { background: var(--text-light); }

/* Surlignage de la ligne sélectionnée — par ATTRIBUT, jamais par une classe :
   aucune classe des blocs métier n'est modifiée (interdit du prompt 961). */
   Aucun `!important` (DESIGN §10.1) : le fond est peint par une ombre INTERNE
   étalée, qui recouvre le fond existant sans le redéfinir — le texte de la
   cellule reste au-dessus. */
body.ui2-on tr[data-ui2-selected="1"] > td {
  box-shadow: inset 0 0 0 999px var(--gold-pale), inset 0 0 0 1px var(--gold-soft-border);
}
body.ui2-on .appui-card[data-ui2-selected="1"] {
  box-shadow: 0 0 0 2px var(--gold-soft-border), 0 0 0 6px var(--gold-pale);
}

/* ── R2 — Les vues : une par menu, à l'intérieur de `.main-content` ──────────
   La navigation décide de LA VUE ; l'état de l'import décide du CONTENU à
   l'intérieur de la vue (piège 3). Aucune règle de `.main-content` n'est
   redéfinie ici : les vues sont des enfants, elles n'altèrent pas leur parent. */
.ui2-view { display: none; }
.ui2-view.is-active { display: block; }
.ui2-view__empty {
  margin: var(--space-6) 0; padding: var(--space-6);
  border: 1px dashed var(--color-border-light); border-radius: var(--radius-lg);
  background: var(--gray-50); color: var(--color-text-muted);
  font-size: var(--font-size-lg); line-height: 1.5; text-align: center;
}

/* ══ R4 — ACCUEIL À DEUX ÉTATS ════════════════════════════════════════════ */
.ui2-accueil { display: grid; gap: var(--space-4); width: 100%; }
.ui2-home-card {
  padding: var(--space-5); background: var(--surface);
  border: 1px solid var(--color-border-default); border-radius: var(--radius-lg);
}
.ui2-home-card h3 {
  margin: 0 0 var(--space-3); font-family: var(--font-family-title);
  font-size: var(--font-card-header-size); font-weight: var(--font-card-header-weight);
  line-height: var(--font-card-header-line-height); color: var(--color-text-default);
}
/* 1070 — plus de liseré or en tête de carte (David 26/08 : décoratif).
   Le filet 1 px de `.ui2-home-card` suffit. */
.ui2-home-card--head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
}
.ui2-home-card--head h3 { margin: 0; }
.ui2-home-k {
  font-size: var(--font-size-xs); font-weight: var(--font-weight-bold);
  text-transform: uppercase; letter-spacing: .6px; color: var(--color-text-muted);
}
.ui2-home-lead, .ui2-home-note {
  margin: 0 0 var(--space-4); color: var(--color-text-secondary); line-height: 1.5;
}
.ui2-home-note { margin: var(--space-3) 0 0; font-size: var(--font-size-sm); }
.ui2-home-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* 979 — l'unique carte voyageuse reste entière : UI2 ne montre que son
   import source et son Word de synthèse. Le verrou de source, lui, reste dans
   index.html, là où le contenu est déjà décidé. */
body.ui2-on #affairesImportCard > .card-header {
  display: block;
}
body.ui2-on #affairesImportCard .bandeau-meta,
body.ui2-on #affairesImportCard [data-group="projet"],
body.ui2-on #affairesImportCard [data-group="import"] .import-sub + .import-sub {
  display: none;
}
body.ui2-on #affairesImportCard button[hidden] {
  display: none !important;
}
body.ui2-on #affairesImportCard .card-header-content {
  margin-bottom: var(--space-4);
}
body.ui2-on #affairesImportCard .bandeau-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
body.ui2-on #affairesImportCard .bandeau-group {
  gap: var(--space-2);
}
body.ui2-on #affairesImportCard .bandeau-group + .bandeau-group {
  padding-left: 0;
  border-left: 0;
}
body.ui2-on #affairesImportCard .import-grid {
  grid-template-columns: minmax(0, 1fr);
}
body.ui2-on #affairesImportCard .import-sub__label {
  display: none;
}
body.ui2-on #affairesImportCard .import-sub__btns {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
body.ui2-on #affairesImportCard .import-sub__btns #btnImportProject,
body.ui2-on #affairesImportCard .import-sub__btns #btnImportAcord,
body.ui2-on #affairesImportCard .import-sub__btns #generateBtn {
  width: var(--width-encart-import-btn);
}
/* 981e — UN SEUL BOUTON D'IMPORT PAR MENU (David, recette du 981d :
   « ça fonctionne mais c'est perturbant d'avoir deux boutons »).
   ⛔ Ce n'est PAS le verrou de mai : le bouton de l'autre source reste ACTIF et
   sans marqueur de refus, il est seulement RANGÉ dans son menu — un clic sur le
   menu voisin et il est là. La règle ne connaît que `data-ui2-import-menu`,
   posé par `majImportParMenu981e()` d'après le seul `_menuActif` : aucune
   donnée chargée n'entre dans cette décision. Chaque bouton emmène son nom de
   fichier (981d) avec lui. */
body.ui2-on #affairesImportCard[data-ui2-import-menu="mdbat"] #btnImportAcord,
body.ui2-on #affairesImportCard[data-ui2-import-menu="mdbat"] #ui2ImportFilenameAcord,
body.ui2-on #affairesImportCard[data-ui2-import-menu="acord"] #btnImportProject,
body.ui2-on #affairesImportCard[data-ui2-import-menu="acord"] #ui2ImportFilenameMdBat {
  display: none;
}
.ui2-import-filename {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}
.ui2-recents { display: grid; gap: var(--space-2); }
.ui2-recent {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; width: 100%;
  padding: var(--space-3); border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md); background: var(--gray-50); color: var(--color-text-default);
  text-align: left; cursor: pointer; font: inherit;
}
.ui2-recent:hover { border-color: var(--sage); background: var(--sage-pale); }
.ui2-recent span { color: var(--color-text-secondary); }
.ui2-recent small { color: var(--color-text-muted); font-family: var(--font-family-mono); }
.ui2-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); }
.ui2-stat {
  padding: var(--space-3); border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md); background: var(--gray-50);
}
.ui2-stat__k { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
.ui2-stat__v {
  margin: var(--space-1) 0; font-family: var(--font-family-mono);
  font-size: var(--font-card-header-size); font-weight: var(--font-weight-bold);
}
.ui2-stat__s { font-size: var(--font-size-xs); color: var(--color-text-muted); line-height: 1.35; }
.ui2-stat--ok .ui2-stat__v { color: var(--color-badge-ok-text); }
.ui2-stat--attente .ui2-stat__v,
.ui2-stat--reserve .ui2-stat__v,
.ui2-stat--nv .ui2-stat__v { color: var(--color-badge-warn-text); }
.ui2-stat--depasse .ui2-stat__v { color: var(--color-badge-err-text); }
.ui2-home-warning {
  margin: var(--space-4) 0 0; padding: var(--space-3);
  border-left: 3px solid var(--warning); background: var(--warning-pale);
  color: var(--color-text-secondary); line-height: 1.45;
}
.ui2-alert {
  display: grid; gap: var(--space-1); width: 100%; padding: var(--space-3) 0;
  border: none; border-bottom: 1px solid var(--color-border-light);
  background: transparent; color: var(--color-text-default); text-align: left;
  cursor: pointer; font: inherit;
}
.ui2-alert:last-child { border-bottom: none; }
.ui2-alert:hover strong { color: var(--sage-dark); }
.ui2-alert span { font-size: var(--font-size-sm); color: var(--color-text-secondary); }

/* ══ R4 — SOUS-ONGLETS PAR ÉTAPE ══════════════════════════════════════════ */
.ui2-etapes { display: grid; gap: var(--space-4); }
.ui2-tabs {
  display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2);
  border: 1px solid var(--color-border-default); border-radius: var(--radius-lg);
  background: var(--gray-50);
}
.ui2-tabs__btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3); border: 1px solid transparent;
  border-radius: var(--radius-md); background: transparent; color: var(--color-text-secondary);
  cursor: pointer; font-family: var(--font-family-base); font-size: var(--font-size-base);
}
.ui2-tabs__btn:hover { background: var(--sage-pale); color: var(--sage-dark); }
.ui2-tabs__btn.is-active {
  background: var(--surface); border-color: var(--sage); color: var(--sage-dark);
  font-weight: var(--font-weight-bold);
}
.ui2-tabs__n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--radius-pill);
  background: var(--noir-mid); color: var(--surface); font-size: var(--font-size-xs);
}
.ui2-tabs__btn.is-active .ui2-tabs__n { background: var(--gold-app); color: var(--noir); }
.ui2-etape { display: none; }
.ui2-etape.is-active { display: block; }

/* ══ R5 — LISTE DES CONFIGURATIONS DE L'AFFAIRE ══════════════════════════ */
.ui2-configurations {
  margin-bottom: var(--space-5); background: var(--surface);
  border: 1px solid var(--color-border-default); border-radius: var(--radius-lg);
  overflow: hidden;
}
.ui2-configurations__head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5); border-bottom: 1px solid var(--color-border-light);
}
.ui2-configurations__head h3 {
  margin: 0 0 var(--space-1); font-family: var(--font-family-title);
  font-size: var(--font-card-header-size); font-weight: var(--font-card-header-weight);
  line-height: var(--font-card-header-line-height); color: var(--color-text-default);
}
.ui2-configurations__head p {
  margin: 0; color: var(--color-text-secondary); font-size: var(--font-size-sm);
  line-height: 1.45;
}
.ui2-configurations__count {
  flex: 0 0 auto; padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill); background: var(--sage-pale);
  color: var(--sage-dark); font-size: var(--font-size-sm); font-weight: var(--font-weight-bold);
}
.ui2-configurations__table-wrap { overflow-x: auto; }
.ui2-configurations__table {
  width: 100%; min-width: var(--min-width-ui2-configurations-table); border-collapse: collapse;
  font-family: var(--font-family-base); font-size: var(--font-size-base);
}
.ui2-configurations__table .ui2-pastille { font-size: var(--font-size-xs); }
.ui2-pastille--ok { background: var(--color-badge-ok-bg); color: var(--color-badge-ok-text); }
.ui2-pastille--warn { background: var(--color-badge-warn-bg); color: var(--color-badge-warn-text); }
.ui2-pastille--err { background: var(--color-badge-err-bg); color: var(--color-badge-err-text); }
.ui2-pastille--neutre { background: var(--color-badge-neutral-bg); color: var(--color-badge-neutral-text); }
.ui2-configurations__table th,
.ui2-configurations__table td {
  padding: var(--space-3); border-bottom: 1px solid var(--color-border-light);
  text-align: left; vertical-align: middle;
}
.ui2-configurations__table th {
  background: var(--gray-50); color: var(--color-text-secondary);
  font-size: var(--font-size-xs); font-weight: var(--font-weight-bold);
  text-transform: uppercase; letter-spacing: .45px;
}
.ui2-configurations__row { cursor: pointer; }
.ui2-configurations__row:hover td { background: var(--sage-pale); }
.ui2-configurations__row.is-active td { background: var(--sage-pale); }
.ui2-configurations__row.is-active td:first-child {
  box-shadow: inset 3px 0 0 0 var(--sage-dark);
}
.ui2-configurations__row:focus-visible { outline: 2px solid var(--gold-app); outline-offset: -2px; }
.ui2-configurations__repere,
.ui2-configurations__taux { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* 1101 — la colonne de coches est passée EN TÊTE : le taux est la 8ᵉ colonne,
   plus la 7ᵉ. Sans ce décalage, l'en-tête aligné à droite serait « Statut ». */
.ui2-configurations__table .ui2-configurations__taux,
.ui2-configurations__table th:nth-child(8) { text-align: right; }
/* ── 1101 — LA COLONNE « NOTE » (cases à cocher) ─────────────────────────────
   Même geste que la fenêtre de recopie du 970 (`.ui2-duplication__cible input`) :
   une case simple, l'accent sauge de l'application, et l'état grisé qui porte
   son motif au survol. Aucune couleur en dur : tokens seulement. */
.ui2-configurations__coche { width: 1%; white-space: nowrap; text-align: center; }
.ui2-configurations__coche-input {
  width: 16px; height: 16px; margin: 0;
  accent-color: var(--sage-dark); cursor: pointer; vertical-align: middle;
}
.ui2-configurations__coche.is-disabled { cursor: not-allowed; }
.ui2-configurations__coche-input[disabled] { opacity: .4; cursor: not-allowed; }
.ui2-configurations__head-actions {
  display: flex; flex: 0 0 auto; align-items: center; gap: var(--space-3);
}
.ui2-configurations__repere { font-family: var(--font-family-mono); font-weight: var(--font-weight-bold); }
.ui2-configurations__reverifier {
  display: block; margin-top: var(--space-1); color: var(--color-badge-warn-text);
  font-size: var(--font-size-xs); font-weight: var(--font-weight-bold);
}
.ui2-configurations__action {
  display: flex; align-items: center; gap: var(--space-2); white-space: nowrap;
}
.ui2-configurations__action .btn-row-action,
.ui2-configurations__action .btn-row-action:hover { box-shadow: none; transform: none; }
.ui2-configurations__empty {
  margin: 0; padding: var(--space-6); color: var(--color-text-muted); text-align: center;
}
body.ui2-on [data-ui2-view="connecteurs"] #catSummaryStrip {
  margin: 0; padding: var(--space-4); border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg); background: var(--gray-50);
}
body.ui2-on [data-ui2-view="connecteurs"] .cat-main-dropdown { z-index: 20; }

/* Prompt 970 — sélection explicite d'une ou plusieurs cibles. Les cibles hors
   périmètre restent visibles : l'état disabled et son motif portent la limite. */
.ui2-duplication__content { width: min(560px, calc(100vw - 2 * var(--space-5))); }
.ui2-duplication__cibles {
  display: grid; gap: var(--space-2); max-height: min(52vh, 460px);
  margin: var(--space-4) 0; overflow-y: auto;
}
.ui2-duplication__cible {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-2) var(--space-3);
  align-items: start; padding: var(--space-3); border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md); background: var(--surface); cursor: pointer;
}
.ui2-duplication__cible.is-disabled {
  background: var(--gray-50); color: var(--color-text-muted); cursor: not-allowed;
}
.ui2-duplication__cible input { margin-top: 2px; }
.ui2-duplication__cible input[disabled] { opacity: .4; cursor: not-allowed; }
.ui2-duplication__identite { display: grid; gap: 2px; min-width: 0; }
.ui2-duplication__identite span,
.ui2-duplication__identite small { color: var(--color-text-secondary); }
.ui2-duplication__motif {
  grid-column: 2; color: var(--color-text-muted); font-size: var(--font-size-xs);
  line-height: 1.4;
}
.ui2-duplication__retour {
  min-height: 1.4em; margin: 0; color: var(--color-badge-err-text);
  font-size: var(--font-size-sm);
}

/* ── Fenêtre étroite : le panneau se replie, le rail reste ───────────────── */
@media (max-width: 1100px) {
  body.ui2-on { padding-left: var(--ui2-rail-w); }
  .ui2-ctx { display: none; }
  .ui2-topbar { left: var(--ui2-rail-w); }
  .ui2-ctx__resize { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   R7-1 (prompt 998) — HÔTE DU PANNEAU DE CONFIGURATION DU CONNECTEUR
   ══════════════════════════════════════════════════════════════════════════
   LA COQUE SEULE. Aucun contenu : il arrive au lot R7-2. Pas de fil d'étapes
   ni de pied « Précédent / Suivant » — organes du lot R7-5, dont la maquette
   doit être validée par David AVANT le code.

   Cible visuelle, suivie sans improvisation : site/_design_app_dashboard/
   mockups/maquette_coquille_autonome_V3.5.html — `.side-panel` (L491-499 du
   markup, L346-351 du CSS). Un seul écart, dit franchement : la maquette
   utilise `--shadow-panel`, qui N'EXISTE PAS dans design_tokens.css ; le token
   d'ombre réellement disponible pour un organe qui surplombe est
   `--shadow-modal`. Aucun hex en dur, comme partout dans ce fichier.

   ⛔ LE MARKUP EST CRÉÉ PAR LE PROGRAMME (ui2_shell.js), jamais écrit dans
   index.html : interrupteur éteint, l'hôte n'existe pas du tout, et il ne peut
    donc pas toucher l'empreinte `.main-content` (aded83e3387fedc7, verrous 964
    et 970, ré-ancrée au 1070). Il vit en enfant direct de <body>, hors de `.main-content`.

   LES DEUX RÉGIMES DE PLACE (décision David + mesure 994 volet A) :
     · ≥ 2192px (452 de coquille + 780 de plancher du tableau,
       `--min-width-table`, + 960 de panneau) : CÔTE À CÔTE. Le corps est décalé par un
       padding-right SUR LE BODY — jamais sur `.main-content` (même règle que
       le rail, en-tête de ce fichier). Le tableau reste utilisable.
     · en dessous : RECOUVREMENT. Le panneau passe par-dessus, un voile
       assombrit le fond, et sa fermeture rend le tableau intact.
   Aucun réglage utilisateur : le comportement suit la place, tout seul.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* min(960px, 85vw) : cible David. 85vw garde une marge visible sur petit
     écran, où le régime est de toute façon le recouvrement. */
  --ui2-cx-w: min(960px, 85vw);
  /* Seuil de bascule — CORRIGÉ AU 999 (geste 0), sur la mesure du 998.
     Le 998 avait livré 1740px (= 960 de panneau + 780 de `--min-width-table`),
     valeur du prompt, en signalant que la formule oublie la coquille elle-même :
     rail (92) + arborescence (~360) = **452 px** pris à gauche AVANT que le
     contenu commence. Largeur réellement visible du tableau des configurations,
     panneau ouvert (998, `place_reelle.py`) :
         viewport 1740 -> 286 px (coupé de 613)   viewport 1920 -> 466 (coupé de 433)
         viewport 2190 -> 736 px (coupé de 163)   viewport 2560 -> 1106 (coupé de 0)
     Seuil juste = 452 + 780 + 960 = **2192px**. En dessous, le côte à côte
     mentirait : il laisserait le tableau à l'écran en le tronquant. La règle de
     David — « côte à côte tant que les deux tiennent » — n'est vraie qu'ici.
     ⚠ Une variable CSS ne peut pas servir de condition à une `@media` : cette
     déclaration DOCUMENTE le seuil, la valeur qui gouverne est celle écrite en
     dur dans le `@media` plus bas. Les deux se changent ensemble. */
  --ui2-cx-cote-a-cote: 2192px;
}

/* Le voile : recouvrement seulement (neutralisé côte à côte, plus bas). */
.ui2-cx-overlay {
  position: fixed; inset: 0; background: var(--color-overlay);
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s;
  z-index: 1999;
}
.ui2-cx-overlay.is-open { opacity: 1; visibility: visible; }

.ui2-cx-panel {
  position: fixed; top: 0; right: 0; height: 100vh; width: var(--ui2-cx-w);
  background: var(--surface);
  /* 1070 — le liseré sage 3 px du flanc était décoratif. La poignée
     `.ui2-cx-panel__resize` porte déjà le filet de séparation. */
  box-shadow: var(--shadow-modal);
  transform: translateX(100%); transition: transform .25s ease;
  z-index: 2000; display: flex; flex-direction: column;
}
.ui2-cx-panel.is-open { transform: translateX(0); }

/* Bandeau titre sombre, liseré doré : même famille que le rail et la topbar. */
.ui2-cx-panel__head {
  flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-3);
  /* Recette 998 à 1280 px : la croix se retrouvait SOUS le widget
     d'authentification (`js/auth_widget.js` : fixed, top 8px, right 10px,
     z-index 99999). Le panneau est collé à droite, donc son bandeau passe
     dessous — exactement le conflit que la topbar règle depuis R1 avec la même
     réserve. Vu sur capture, pas déduit. */
  padding: var(--space-4) var(--ui2-auth-reserve) var(--space-4) var(--space-5);
  background: var(--noir); border-top: 3px solid var(--gold-app);
  /* Sans cette ligne, l'icône du bandeau hérite de la couleur de texte par
     défaut — sombre sur fond noir, donc invisible. Vu sur la capture 1280. */
  color: var(--sage-light);
}
.ui2-cx-panel__head h3 {
  flex: 1 1 auto; margin: 0;
  font-family: var(--font-family-title); font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold); text-transform: uppercase;
  letter-spacing: .5px; color: var(--surface);
}
.ui2-cx-panel__close {
  flex: 0 0 auto; width: 30px; height: 30px;
  border: 1px solid var(--sage-dark); background: transparent;
  color: var(--sage-light); border-radius: var(--radius-md);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.ui2-cx-panel__close:hover { background: var(--noir-mid); color: var(--surface); }
.ui2-cx-panel__close:focus-visible {
  outline: 2px solid var(--gold-app); outline-offset: 2px;
}

/* Le corps — R7-5 (1003) : UNE COLONNE, UNE SEULE BANDE QUI DÉFILE.
   Rappel de la pièce, fil des étapes et résumé en haut ; pied en bas ; le
   contenu de l'étape au milieu, et lui seul défile (contrat §1, §2, §3).
   `min-height: 0` est indispensable : sans lui, une bande flex refuse de
   rétrécir sous la taille de son contenu et c'est le PIED qui sort de l'écran. */
.ui2-cx-panel__body {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  overflow: hidden;
}
.ui2-cx-panel__scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: var(--space-4) var(--space-5) var(--space-6);
}
.ui2-cx-panel__vide {
  margin: 0; color: var(--color-text-muted); font-size: var(--font-size-md);
  font-style: italic;
}

/* ══ R7-5 (prompt 1003) — LES ORGANES DES QUATRE ÉTAPES ═══════════════════
   Contrat : `site/_design_app_dashboard/mockups/CIBLE_R7-5_comportements.md`,
   maquette `CIBLE_R7-5_volet_etapes.html`, arbitrée par David le 16/08.
   TRAITEMENT A (arbitrage 1 : « je choisi A ») : aucun cadre, aucune ombre,
   aucun liseré d'accent en tête de bloc — la hiérarchie vient de la taille, de
   la graisse et du blanc ; un filet fin sépare chaque bande.
   ⛔ Le liseré or du BANDEAU SOMBRE du volet et du rail RESTE (arbitrage 2 :
   « Il peut rester ») : il est plus haut dans ce fichier, on n'y touche pas.
   ══════════════════════════════════════════════════════════════════════════ */

/* Le rappel de la pièce analysée : bandeau du contenu, DÉPLACÉ ici pour qu'il
   ne défile pas et reste au-dessus du fil (ordre vertical du contrat §7). */
.ui2-cx-rappel {
  flex: 0 0 auto; padding: var(--space-3) var(--space-5) 0;
}
.ui2-cx-rappel:empty { display: none; }

/* ── Le fil des quatre étapes (contrat §1) ─────────────────────────────── */
.ui2-cx-steps {
  flex: 0 0 auto; display: flex; align-items: flex-end; gap: var(--space-6);
  padding: var(--space-3) var(--space-5) 0;
  border-bottom: 1px solid var(--border);
}
#ui2CxPanel .ui2-cx-steps__i {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  padding: 0 2px var(--space-2); margin: 0;
  background: none; border: none; border-bottom: 2px solid transparent;
  font: inherit; font-size: var(--font-size-lg); color: var(--text-light);
  cursor: default;
}
.ui2-cx-steps__n {
  font-family: var(--font-family-mono); font-size: var(--font-size-md);
  color: var(--text-light);
}
/* Faite : numéro vert + libellé gris — lisible sans la couleur seule, le
   numéro passant aussi en gras (contrat §1, « rendu des 3 états »). */
#ui2CxPanel .ui2-cx-steps__i.is-done { color: var(--color-text-secondary); cursor: pointer; }
#ui2CxPanel .ui2-cx-steps__i.is-done .ui2-cx-steps__n {
  color: var(--vert); font-weight: var(--font-weight-bold);
}
#ui2CxPanel .ui2-cx-steps__i.is-done:hover {
  color: var(--color-text-default); border-bottom-color: var(--sage-light);
}
#ui2CxPanel .ui2-cx-steps__i.is-done:focus-visible {
  outline: 2px solid var(--gold-app); outline-offset: 2px;
}
/* Active : libellé noir gras, sans filet sous l'étape (1012, amendement 2). */
#ui2CxPanel .ui2-cx-steps__i.is-on {
  color: var(--color-text-default); font-weight: var(--font-weight-bold);
  cursor: default;
}
#ui2CxPanel .ui2-cx-steps__i.is-on .ui2-cx-steps__n {
  color: var(--gold-app); font-weight: var(--font-weight-bold);
}
/* À venir : gris clair, aucun survol, aucun curseur main — `disabled` la sort
   déjà de la tabulation. On ne saute jamais en avant. */
#ui2CxPanel .ui2-cx-steps__i.is-todo { cursor: not-allowed; }
/* ⚠ `opacity: 1` explicite : `#rechercheHote999 button:disabled` impose 0.4,
   ce qui rendrait une étape à venir presque invisible. */
#ui2CxPanel .ui2-cx-steps__i:disabled { pointer-events: none; opacity: 1; }

/* ── Le résumé des choix (contrat §2) ──────────────────────────────────── */
.ui2-cx-summary {
  flex: 0 0 auto; display: flex; flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--color-border-light);
}
.ui2-cx-summary[hidden] { display: none; }
#ui2CxPanel .ui2-cx-summary__i {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  background: none; border: none; padding: 0; margin: 0;
  font: inherit; text-align: left; cursor: pointer;
}
#ui2CxPanel .ui2-cx-summary__i--lecture { cursor: default; }
.ui2-cx-summary__k {
  font-size: var(--font-size-xs); text-transform: uppercase;
  letter-spacing: .6px; color: var(--text-light);
  font-weight: var(--font-weight-semi);
}
.ui2-cx-summary__v {
  font-family: var(--font-family-mono); font-size: var(--font-size-base);
  color: var(--color-text-default); border-bottom: 1px dotted var(--border);
}
#ui2CxPanel .ui2-cx-summary__i--lecture .ui2-cx-summary__v { border-bottom-color: transparent; }
#ui2CxPanel .ui2-cx-summary__i:not(.ui2-cx-summary__i--lecture):hover .ui2-cx-summary__v {
  border-bottom-color: var(--sage-dark); color: var(--sage-dark);
}
#ui2CxPanel .ui2-cx-summary__i:focus-visible {
  outline: 2px solid var(--gold-app); outline-offset: 2px;
}

/* ── Les deux emplacements de message (contrat §5) ─────────────────────────
   Ils N'EXISTENT PAS tant qu'il n'y a rien à dire : `hidden` est natif, donc
   pas de bandeau vide ni de place creuse réservée. */
.ui2-cx-msg {
  flex: 0 0 auto; display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3) var(--space-5);
  font-size: var(--font-size-md); line-height: var(--line-height-base);
}
.ui2-cx-msg[hidden] { display: none; }
.ui2-cx-msg--warn {
  background: var(--color-banner-warn-bg);
  border-bottom: none;
  color: var(--color-banner-warn-text);
}
.ui2-cx-msg--refus {
  background: var(--danger-pale); border-top: 1px solid var(--danger);
  color: var(--danger-dark);
}
.ui2-cx-msg__k {
  font-family: var(--font-family-mono); font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold); text-transform: uppercase;
  letter-spacing: .5px; white-space: nowrap;
}
.ui2-cx-msg__t { color: inherit; }

/* ── Le pied (contrat §3) ─────────────────────────────────────────────────
   Il ne défile pas et NE SE DÉROBE JAMAIS : le bloc de refus qui s'insère
   au-dessus rétrécit la bande qui défile, il ne pousse pas le pied. */
.ui2-cx-foot {
  flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--border); background: var(--surface);
}
.ui2-cx-foot__n {
  flex: 1 1 auto; text-align: center;
  font-family: var(--font-family-mono); font-size: var(--font-size-md);
  color: var(--text-light);
}
#ui2CxPanel .ui2-cx-foot__btn {
  font: inherit; font-size: var(--font-size-base);
  font-weight: var(--font-weight-semi); border-radius: var(--radius-md);
  padding: 7px var(--space-4); cursor: pointer;
  border: 1px solid transparent; white-space: nowrap;
}
#ui2CxPanel .ui2-cx-foot__btn--ghost {
  background: transparent; border-color: var(--border);
  color: var(--color-text-secondary);
}
#ui2CxPanel .ui2-cx-foot__btn--ghost:hover:not(:disabled) {
  border-color: var(--sage-dark); color: var(--color-text-default);
}
#ui2CxPanel .ui2-cx-foot__btn--primary { background: var(--noir); color: var(--surface); }
#ui2CxPanel .ui2-cx-foot__btn--primary:hover:not(:disabled) { background: var(--noir-mid); }
#ui2CxPanel .ui2-cx-foot__btn--retenir { background: var(--vert); color: var(--surface); }
#ui2CxPanel .ui2-cx-foot__btn--retenir:hover:not(:disabled) { background: var(--vert-light); }
#ui2CxPanel .ui2-cx-foot__btn:disabled {
  background: var(--gray-100); border-color: var(--border);
  color: var(--text-light); cursor: not-allowed; opacity: 1;
}
#ui2CxPanel .ui2-cx-foot__btn:focus-visible {
  outline: 2px solid var(--gold-app); outline-offset: 2px;
}
/* 1004 (contrat §0-bis) — « Suivant » n'apparaît qu'à partir de l'étape 3 :
   aux étapes 1-2 c'est la SÉLECTION qui fait avancer. ⚠ La règle est écrite
   explicitement : `[hidden]` de la feuille du navigateur ne pèse que (0,1,0) et
   tomberait devant n'importe quelle règle d'auteur posant `display` sur ces
   boutons — c'est le même piège de spécificité que `#rechercheHote999 button`
   (défaut du 976, retrouvé au 1003). Il ne laisse AUCUNE place creuse : le
   compteur et « Précédent » se répartissent la largeur du pied. */
#ui2CxPanel .ui2-cx-foot__btn[hidden] { display: none; }

/* ── La poignée d'étirement (contrat §4) ──────────────────────────────────
   Reprise VERBATIM du langage de la poignée du panneau d'arborescence
   (`.ui2-ctx__resize`, 971-979) : 12 px de zone sensible, un filet d'un pixel
   au milieu, `ew-resize`. Seul le côté change — elle est à GAUCHE. */
.ui2-cx-panel__resize {
  position: absolute; top: 0; left: 0; bottom: 0;
  width: var(--width-ui2-resize-handle); border: none; padding: 0;
  background: transparent; cursor: ew-resize; touch-action: none; z-index: 5;
}
.ui2-cx-panel__resize::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
  border-left: var(--space-hair) solid var(--border);
}
.ui2-cx-panel__resize:hover::after,
.ui2-cx-panel__resize:focus-visible::after { border-left-color: var(--sage); }
.ui2-cx-panel__resize:focus-visible { outline: none; }
body.ui2-resizing .ui2-cx-panel__resize::after { border-left-color: var(--sage-dark); }

/* ── Ce que la coquille marque DANS le contenu servi tel quel ──────────────
   Deux marques, et deux seulement : le fournisseur choisi (le contenu ne le
   marquait pas, parce qu'en fenêtre le clic changeait aussitôt de niveau) et
   la ligne de résultat choisie (le contrat §3 rend « Retenir » dépendant
   d'elle). Portée `#rechercheHote999` : rien de ceci n'atteint la fenêtre
   classique, qui n'a pas cet hôte. */
#rechercheHote999 .fournisseur-icon.is-cx-choisi {
  border-color: var(--noir); box-shadow: inset 0 2px 0 0 var(--noir);
}
#rechercheHote999 tr.conn-l1-row.is-cx-choisie > td {
  background: var(--sage-pale) !important;
}
#rechercheHote999 tr.conn-l1-row.is-cx-choisie > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--sage-dark);
}

/* ══ 1011 (D2) — LES VIGNETTES DE LA CARTE NE SONT PAS DES BOUTONS D'ACTION ══
   Recette David 17/08 : « les vignettes de pose et de fixation sont rendues sur
   FOND NOIR ; la cible d'origine les montre blanches/claires ».

   LA CAUSE, MESURÉE — c'est un piège de SPÉCIFICITÉ, pas une couleur choisie.
   `recherche_panneau.css` (feuille GÉNÉRÉE au 999) porte la règle générique du
   bouton sous la racine de l'hôte : `#rechercheHote999 button { background:
   var(--noir-mid); color: var(--sage-light) }` — spécificité (1,0,1). Les règles
   de la carte, elles, sont des CLASSES : `.equerre-choice-tile` (0,1,0),
   `.equerre-pose-select` (0,1,0). L'identifiant l'emporte, donc la carte est
   repeinte. Dans la FENÊTRE `/recherche` la même déclaration s'écrit `button`
   (0,0,1) et PERD contre ces mêmes classes : d'où une carte claire là-bas et
   sombre ici. Relevé sur la vraie application
   (`backend/tests/tmp_diag/p1011/etape_a4.json`) : 18 boutons sur 26 à
   `rgb(30, 30, 30)`, dont les 7 vignettes de pose et les 6 tuiles de choix.

   POURQUOI ICI ET SOUS CETTE FORME. C'est exactement le geste que la coquille
   fait déjà pour ses propres organes (`#ui2CxPanel .ui2-cx-steps__i`,
   `.ui2-cx-foot__btn`, plus haut dans ce fichier) et que la carte fait déjà pour
   le SURVOL (`components.css`, prompt 846, qui nomme la même liste de cinq
   classes pour la même raison). On ne redessine rien : on rend à ces cinq
   boutons l'habillage que la charte leur donne, avec SES tokens.
   ⛔ Portée `#rechercheHote999` : la fenêtre `/recherche` et le reste de
   l'application ne sont pas touchés d'un pixel. */
#rechercheHote999 .equerre-pose-zoom,
#rechercheHote999 .equerre-pose-select,
#rechercheHote999 .equerre-aide-zoom,
#rechercheHote999 .equerre-panel-collapse-btn {
  background: transparent;
  color: inherit;
  border: none;
}
#rechercheHote999 .equerre-choice-tile {
  background: var(--color-surface-card);
  color: var(--color-text-default);
  border: var(--space-hair) solid var(--color-border-default);
}
#rechercheHote999 .equerre-choice-tile.is-active {
  background: var(--sage-pale);
  border-color: var(--sage-dark);
}
#rechercheHote999 .equerre-choice-tile.is-disabled {
  background: var(--color-surface-readonly);
  color: var(--color-text-muted);
  border-style: dashed;
}
/* Le survol : même intention qu'au 846, avec la spécificité qu'il faut ici.
   Sans lui, survoler une vignette la repeint en vert et l'agrandit de 2 %. */
#rechercheHote999 .equerre-pose-zoom:hover:not(:disabled),
#rechercheHote999 .equerre-pose-select:hover:not(:disabled),
#rechercheHote999 .equerre-aide-zoom:hover:not(:disabled),
#rechercheHote999 .equerre-panel-collapse-btn:hover:not(:disabled) {
  background: transparent;
  color: inherit;
  transform: none;
}
#rechercheHote999 .equerre-choice-tile:hover:not(:disabled) {
  background: var(--color-surface-card);
  color: var(--color-text-default);
  border-color: var(--sage-dark);
  transform: none;
}
#rechercheHote999 .equerre-choice-tile.is-active:hover:not(:disabled) {
  background: var(--sage-pale);
}

/* ══ 1011 (D4) — ZÉRO LISERÉ SUR LES ENCARTS DE LA CONFIGURATION ════════════
   Décision David 17/08, verbatim : « je ne voulais plus aucun liseré sur les
   encarts et cela dans toute la configuration connecteur. »
   C'est le TRAITEMENT A, qu'il avait déjà choisi le 16/08 pour le volet
   (« 1 je choisi A » — contrat R7-5 §8 : « aucun cadre, aucune ombre, aucun
   liseré d'accent ; la hiérarchie vient de la taille, de la graisse et du
   blanc »), étendu à toute la configuration connecteur.

   LES SEPT ENCARTS, RELEVÉS UN PAR UN sur la vraie application
   (`backend/tests/tmp_diag/p1011/etape_a4.json`, section `encarts`) — aucun
   n'est deviné, aucun autre n'est touché.

   ⛔ CE QUI RESTE, ET POURQUOI — le retrait ne déborde pas :
     · le liseré or du BANDEAU SOMBRE du volet et du rail : arbitrage 2 de
       David, verbatim « Il peut rester » (contrat §0, ligne 2) ;
     · le filet or de 2 px de l'ÉTAPE ACTIVE : contrat §1, « rendu des 3 états » ;
     · les filets fins de séparation des blocs (`.equerre-zone`, 1 px sous le
       titre) : le traitement A les CONSERVE explicitement ;
     · les CONTRÔLES — tuiles, boutons, champs — qui ne sont pas des encarts et
       dont le bord porte l'état (choisi, incompatible, focus) ;
     · le reste de l'application, qui attend sa propre décision (BACKLOG P3).
   La portée `#ui2CxPanel #rechercheHote999` tient cette frontière par
   construction (`#rechercheHote999` EST le corps du volet, cf `ui2_shell.js` :
   « il englobe maintenant tout le corps »).
   ⚠ LES DEUX IDENTIFIANTS SONT NÉCESSAIRES, et c'est mesuré : trois de ces
   encarts (`.charges-bar`, `.filters-wrap`, `.modal-fam-bar`) sont déclarés
   dans la feuille GÉNÉRÉE, déjà sous `#rechercheHote999` — donc à égalité de
   spécificité (1,1,0), et cette feuille est chargée APRÈS celle-ci
   (`index.html` L76 puis L82) : à égalité, c'est elle qui gagnait. Premier
   essai avec un seul identifiant : quatre encarts nettoyés sur sept, les trois
   autres intacts — vu au verrou, pas déduit. */
#ui2CxPanel #rechercheHote999 .charges-bar,
#ui2CxPanel #rechercheHote999 .filters-wrap,
#ui2CxPanel #rechercheHote999 .modal-fam-bar,
#ui2CxPanel #rechercheHote999 .equerre-e9-panel,
#ui2CxPanel #rechercheHote999 .equerre-doctrine,
#ui2CxPanel #rechercheHote999 .equerre-efforts,
#ui2CxPanel #rechercheHote999 .equerre-aide,
/* ⚠ `.results-wrap` a été AJOUTÉ APRÈS COUP, et il faut dire pourquoi : le
   premier relevé A4 a été pris à l'ÉTAPE 3, où le bloc de résultats n'existe
   pas encore. Il est apparu sur la capture de l'étape 4 — un liseré or de 3 px
   en tête, exactement le même motif que `.filters-wrap`. Un inventaire fait à
   une seule étape ne couvre pas un volet qui en a quatre. */
#ui2CxPanel #rechercheHote999 .results-wrap {
  border: none;
}

/* Les éléments masqués du contenu rapatrié ne doivent pas reprendre le
   `display:flex` de la feuille source. */
#ui2CxPanel .charges-bar[hidden],
#ui2CxPanel .charge-item[hidden] { display: none; }

/* ⛔ R7-6 (1015c) — LE MASQUE DE `.btn-reset` EST LEVÉ, PAS DÉPLACÉ.
   Le 1013b masquait deux organes du contenu rapatrié. Les deux boutons
   « Réinitialiser » n'existent PLUS : ils sont retirés de la source
   (`frontend/recherche.html`), donc de la copie régénérée — un masque sur un
   nœud absent est un masque qui ment sur ce qu'il garde.
   ⚠ `#familyCounters` RESTE masqué, et ce n'est pas un oubli : la chaîne des
   compteurs de famille est encore la voie de navigation de 19 fichiers e2e
   (`_selectFamilyFromCounter`, mesuré le 18/08), dont **15** que rien ne remplace
   aujourd'hui — les quatre autres sont 156, 265 et 683, qui ont ou avaient un
   équivalent nommé, et le verrou volet du 265 qui ne fait que le citer. Le chiffre
   16 écrit ici au 1015c était faux d'une unité (relévé du contrôle SOL de clôture,
   vérifié : le corps du rapport 1015c disait bien 15). Tant qu'ils n'ont pas migré,
   la chaîne vit — et elle doit rester invisible dans le volet, où le parcours en
   quatre étapes fait ce travail. */
#ui2CxPanel #rechercheHote999 #familyCounters { display: none !important; }

/* 1012 (D4) : le plafond de la fenêtre historique est desserré UNIQUEMENT
   dans le volet UI2. La fenêtre autonome /recherche conserve sa grille. */
#ui2CxPanel #rechercheHote999 #connectorGrid {
  max-height: none;
  overflow-y: visible;
}

/* Le pied de version (`#app-footer`, index.html : `position: fixed`, coin bas
   droit, `z-index: 9999`) passait PAR-DESSUS le volet — vu sur la capture 2560
   du 999, pas déduit. Invisible tant que le corps du volet était vide (998),
   il se superpose dès qu'il porte du contenu jusqu'en bas. On le range sous le
   panneau pendant qu'il est ouvert, et lui seul : le pied retrouve sa place
   dès la fermeture. C'est un réglage d'empilement, pas une retouche du
   contenu — la règle de tête du fichier reste tenue. */
/* ⚠ `!important` obligatoire, et pour une raison vérifiée : le `z-index: 9999`
   du pied est écrit en style INLINE (`index.html`, `<footer id="app-footer"
   style="…">`). Un style inline bat toute feuille externe ; premier essai sans
   `!important` : aucun effet, revu sur capture. */
body.ui2-on.ui2-cx-open #app-footer { z-index: 1 !important; }

/* 1070 — LE BANDEAU « Signaler un bug · Conditions d'utilisation ».
   Constaté AVANT correctif : ce n'est PAS `#app-footer` (version, `position:
   fixed`, coin bas droit, déjà collé). C'est le wrapper `.app-toolbar` en
   flux, juste après `.main-content` : sur une page courte il s'arrête sous
   le contenu, au milieu de la fenêtre. `margin-top: auto` dans la colonne
   flex du body absorbe le vide. Quand le contenu dépasse, l'auto-marge
   vaut 0 et le bandeau reste sous le contenu — jamais par-dessus.
   ⚠ Le régime 1066 (volet côte à côte / recouvrement) ne porte que sur
   `padding-right` et le repli d'arbre : inchangé. */
body.ui2-on > .app-toolbar {
  margin-top: auto;
  flex: 0 0 auto;
  width: 100%;
}
body.ui2-on > .app-footer { flex: 0 0 auto; }

/* ── Régime CÔTE À CÔTE : le corps se décale, le voile disparaît ─────────── */
@media (min-width: 2192px) {
  body.ui2-on.ui2-cx-open { padding-right: var(--ui2-cx-w); }
  .ui2-cx-overlay.is-open { opacity: 0; visibility: hidden; }
}

/* ══════════════════════════════════════════════════════════════════════════
   1066 — LE CÔTE À CÔTE SERRÉ : LA PLACE VIENT DE L'ARBORESCENCE
   ══════════════════════════════════════════════════════════════════════════
   MOTIF MESURÉ (David 25/08, « c'est une app publique ») : sur un écran
   courant de 1920 px, le volet ouvert rendait la carte INTOUCHABLE. Pas parce
   qu'il la recouvre — le champ « G surfacique » est à x 596-692 et le volet
   commence à 960 — mais parce que le voile prend `inset: 0` et avale le clic
   (mesuré : `elementFromPoint` rend `.ui2-cx-overlay`).
   LE SEUIL, RECALCULÉ AVEC LA MÊME FORMULE QU'AU 999 : 92 (rail) + 360
   (arborescence) + 780 (`--min-width-table`) + 960 (volet) = 2192. Repliée,
   l'arborescence rend ses 360 px et le seuil tombe à 92 + 780 + 960 = **1832**.
   ⚠ La condition `.ui2-ctx-collapsed` n'est pas décorative : c'est elle qui
   rend la formule VRAIE. Sans le pli, 1832 px laisserait le contenu à 420 px et
   le côte à côte mentirait — la faute que le 999 a corrigée en montant de 1740
   à 2192. Le pli est posé par `ui2_shell.js` à l'ouverture du volet, et défait
   à sa fermeture ; David qui replie lui-même obtient le même régime.
   ⚠ Mêmes deux valeurs en dur qu'au-dessus, et même règle : une variable CSS
   ne peut pas servir de condition à une `@media`. Elles se changent ensemble.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1832px) {
  body.ui2-on.ui2-cx-open.ui2-ctx-collapsed { padding-right: var(--ui2-cx-w); }
  body.ui2-on.ui2-cx-open.ui2-ctx-collapsed .ui2-cx-overlay.is-open {
    opacity: 0; visibility: hidden;
  }
}

/* Confort de lecture : pas d'animation si l'utilisateur n'en veut pas. */
@media (prefers-reduced-motion: reduce) {
  .ui2-cx-panel, .ui2-cx-overlay { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   1068 — LA VUE « APPUIS LIBRES » NAVIGUE PAR L'ARBORESCENCE
   ══════════════════════════════════════════════════════════════════════════
   Maquette VALIDÉE par David le 25/08 (`site/_design_appuis_libres_
   arborescence_2026-08-25/`, option A) : les 3 TYPES deviennent les entrées de
   menu de l'arborescence, la fenêtre principale montre UNE pièce.
   ⛔ AUCUN TOKEN NOUVEAU : tout est repris du composant d'arbre livré au 977
   (`.ui2-tree__*` ci-dessus). Le trait or de la ligne sélectionnée reste le
   geste §7.1 des tableaux ; aucun liseré décoratif n'est ajouté.
   ⚠ PORTÉE : `body.ui2-on` uniquement. Sans la coquille il n'y a pas
   d'arborescence — donc pas d'autre accès aux pièces : la vue historique garde
   ses onglets et sa pile, intactes.
   ══════════════════════════════════════════════════════════════════════════ */

/* Les onglets de type quittent la carte : c'est l'arborescence qui les porte.
   Ils RESTENT dans le DOM — `libelleModule()` y lit le nom des types, et
   l'arbre actionne leur handler d'origine pour changer de type (§961 : on
   actionne l'organe existant, on ne réécrit pas l'état du module). */
body.ui2-on #alModeTabs { display: none; }

/* Une pièce à la fois. Les autres cartes restent dans le DOM : le panneau y
   lit l'état réellement rendu pour leur pastille (`collecterPanneau977`). */
body.ui2-on .appui-card[data-al-hors-vue-1068="1"] { display: none; }

/* ⛔ LE HALO OR DE LA CARTE SÉLECTIONNÉE DISPARAÎT — et ce n'est pas le geste
   §7.1 qu'on retire. Depuis le 1068, la carte affichée EST toujours la
   sélectionnée : un cadre permanent n'informe plus de rien, il ne fait que
   remettre un bord décoratif autour de la carte (vu à l'écran, capture
   `tmp_diag/1068/captures/reel_poteau_2560.png`). L'ATTRIBUT `data-ui2-selected`
   reste posé — c'est lui que la recette lit (tests 963 et 964) — et le trait or
   de la LIGNE d'arbre, lui, ne bouge pas. */
body.ui2-on .appui-card[data-ui2-selected="1"] { box-shadow: none; }

/* ⛔ PLUS DE LISERÉ DÉCORATIF DE BORD — règle générale de David, 25/08,
   ÉTENDUE AU RESTE DE L'APP au 1070 (26/08) : Accueil, MD BAT, ACORD,
   Appuis libres. Le liseré or des bandeaux SOMBRES (rail, tête du volet)
   RESTE (arbitrage David 17/08). Les liserés PORTEURS DE SENS (sélection
   §7.1, bandeaux warning/danger, pastilles de conformité) RESTENT. */
body.ui2-on .appui-card { border-left: 1px solid var(--color-border-default); }
body.ui2-on #alEncartControle { border-left: 1px solid var(--border); }
body.ui2-on .appui-schema { border-top: 1px solid var(--color-border-default); }
body.ui2-on #chargesNonPondCard,
body.ui2-on #acordFdElucard,
body.ui2-on #acordREcard,
body.ui2-on #chargesPondereesCard,
body.ui2-on #affairesImportCard {
  border-left: 1px solid var(--color-border-default);
}
/* `.card` pose un accent HAUT sage 3 px (index.html). Sous la coquille,
   le filet 1 px du bord suffit — même geste que les encarts d'import au 373. */
body.ui2-on .card {
  border-top-width: 1px;
  border-top-color: var(--border);
}
/* `th:first-child` pose un accent 3 px `--mode-color` sur TOUTE table.
   Décoratif sur MD BAT / ACORD (la couleur ne dit pas un état). */
body.ui2-on th:first-child {
  border-left-width: 1px;
  border-left-color: #333;
}

/* Le titre de la carte enveloppe DISPARAÎT sous la coquille : le fil d'Ariane et
   le titre de la barre disent déjà l'affaire, le type et la pièce, et « Appuis
   libres : N » est devenu le compteur de chaque type dans l'arbre. Un même
   renseignement affiché deux fois est un écran qui se répète.
   ⚠ Le bloc reste dans le DOM : `contexte()` y lit `#alActiveProject` et
   `#alActiveElement` pour le fil, et le repli de la carte s'y branche. */
body.ui2-on #alEncartControle > .card-header--collapsible { display: none; }

/* Les deux rangées d'actions du bas quittent la fenêtre : « + Ajouter un appui »
   est désormais dans l'arbre, sous CHAQUE type (option A, David 25/08), et les
   deux actions d'affaire sont montées dans la barre de titre. Les organes restent
   dans le DOM — l'arbre et la barre les ACTIONNENT, ils ne les recréent pas. */
body.ui2-on #btnAddAppuiLibre { display: none; }
/* 1107 — « + Ajouter une pièce bois » rejoint l'arbre, comme le jumeau
   ci-dessus. L'organe reste dans le DOM : `boutonAjout1068` l'ACTIONNE,
   il ne le recrée pas. */
body.ui2-on [data-action="add-piece"] { display: none; }
/* La rangée qui a rendu ses boutons à la barre ne laisse pas un vide. */
body.ui2-on .al-actions-row[data-ui2-al-actions-vide-1068="1"] { display: none; }

/* ── Le TYPE : niveau 2 de l'arborescence ─────────────────────────────────
   Même geste que l'en-tête de fichier (`.ui2-tree__file-head`) : chevron,
   nom, repli mémorisé. Il s'en distingue par la couleur d'accent, qui dit
   « entrée de menu » et non « note importée ». */
.ui2-tree__type-groupe { margin: var(--space-1) 0 var(--space-2); }
.ui2-tree__type-head {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-1);
  border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer;
}
.ui2-tree__type-head:hover { background: var(--noir-mid); border-radius: var(--radius-md); }
.ui2-tree__type-head:focus-visible { outline: 2px solid var(--gold-app); outline-offset: -2px; }
.ui2-tree__type-groupe.is-collapsed .ui2-tree__file-chevron { transform: rotate(-90deg); }
.ui2-tree__type-name {
  flex: 1 1 auto; min-width: 0; color: var(--gold-bright);
  font-size: var(--font-size-xs); font-weight: var(--font-weight-bold);
  text-transform: uppercase; letter-spacing: .6px; overflow-wrap: anywhere;
}
.ui2-tree__count {
  flex: 0 0 auto; min-width: var(--size-ui2-status-dot); padding: 0 var(--space-2);
  background: var(--noir-mid); color: var(--sage-light); border-radius: var(--radius-pill);
  font-family: var(--font-family-mono); font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold); line-height: var(--line-height-badge);
  text-align: center;
}
.ui2-tree__type-empty {
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-6);
  color: var(--text-light); font-size: var(--font-size-xs); font-style: italic;
}
/* Les pièces d'un type sont décalées d'un cran : la hiérarchie se lit sans
   trait ni puce ajoutés. */
.ui2-tree__type-groupe > .ui2-tree__node { padding-left: var(--space-5); }

/* Le bouton « + Ajouter » — OPTION A (David, 25/08) : dernier enfant du type.
   Bordure en tirets pour dire « ce n'est pas une pièce, c'est un geste ». */
.ui2-tree__add {
  display: flex; align-items: center; gap: var(--space-2);
  width: calc(100% - var(--space-5)); margin: var(--space-1) 0 0 var(--space-5);
  padding: var(--space-2);
  border: 1px dashed var(--sage-dark); border-radius: var(--radius-md);
  background: transparent; color: var(--sage-light); font: inherit;
  font-size: var(--font-size-xs); text-align: left; cursor: pointer;
}
.ui2-tree__add:hover { background: var(--noir-mid); color: var(--surface); border-color: var(--sage); }
.ui2-tree__add:focus-visible { outline: 2px solid var(--gold-app); outline-offset: -2px; }
.ui2-tree__add svg { flex: 0 0 auto; }

/* ── Les actions d'AFFAIRE dans la barre de titre de la vue ───────────────
   Elles portent toutes les pièces, pas celle affichée : leur place est ici,
   visible quelle que soit la pièce sélectionnée. Grisage inchangé — il reste
   décidé par `index.html`. */
.ui2-topbar__al { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
/* Une action d'affaire ne se casse jamais en plusieurs lignes dans la barre, et
   aucune action ne se laisse écraser par ses voisines : à 1280 les libellés se
   chevauchaient (« conEnregistrer »), vu sur capture au premier rendu. */
.ui2-topbar__al > button { white-space: nowrap; }
body.ui2-on .ui2-topbar__actions > * { flex: 0 0 auto; }
/* Le fil et le titre cèdent la place en premier : un titre tronqué reste lisible,
   deux boutons superposés ne le sont pas. */
body.ui2-on .ui2-topbar__crumb .ui2-path,
body.ui2-on .ui2-topbar__crumb h2 {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ui2-topbar__al[hidden] { display: none; }

/* L'état vide de la fenêtre (M3) : le bloc du module s'efface tant qu'aucune
   pièce n'existe, et les 3 tuiles de démarrage prennent sa place. Par ATTRIBUT,
   posé par la coquille — aucune classe des blocs métier n'est modifiée (961). */
body.ui2-on #alEncartControle[data-ui2-libres-vide-1068="1"] { display: none; }
/* Les 3 tuiles côte à côte, comme M3 — empilées elles s'étalaient sur toute la
   largeur à 1920 (vu à l'écran). Elles repassent en colonne sous 900 px. */
body.ui2-on [data-ui2-libres-vide] .ui2-recents {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3);
}
body.ui2-on [data-ui2-libres-vide] .ui2-recent { align-items: flex-start; }
/* ⛔ Le liseré or du haut part aussi : « plus aucun liseré décoratif de bord de
   carte ou tuile » (David, 25/08). M3 ne le montre pas. */
body.ui2-on [data-ui2-libres-vide] .ui2-home-card--start {
  border-top: 1px solid var(--color-border-default);
}

.ui2-tree__node.is-sel { background: var(--noir-mid); color: var(--surface); }
.ui2-tree__node.is-sel .ui2-tree__type {
  color: var(--surface); font-weight: var(--font-weight-bold);
}
body.ui2-menu-compte .ui2-ctx__search { display: none; }
.compte-somm__sep {
  margin: var(--space-4) var(--space-1) var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--noir-mid);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--text-light);
}
[data-ui2-compte] { display: flex; flex-direction: column; gap: var(--space-5); }
[data-ui2-compte] .card {
  background: var(--color-surface-card);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-xl);
  padding: var(--space-7);
}
[data-ui2-compte] .card h2,
[data-ui2-compte] .card .card__head h2 {
  font-family: var(--font-family-title);
  font-size: var(--font-card-header-size);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-title);
  color: var(--noir);
}
[data-ui2-compte] .card__lead {
  margin: var(--space-2) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  line-height: var(--line-height-base);
  max-width: 900px;
}
[data-ui2-compte] .card__note {
  margin: var(--space-4) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-lg);
  line-height: var(--line-height-base);
  max-width: 900px;
}
[data-ui2-compte] .card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
}
[data-ui2-compte] .card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-5);
}
[data-ui2-compte] .meta-chip {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  background: var(--color-meta-chip-bg);
  border: 1px solid var(--color-meta-chip-border);
  border-radius: var(--radius-pill);
  font-size: var(--font-size-base);
}
[data-ui2-compte] .meta-chip__label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semi);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-label);
  color: var(--color-meta-chip-label);
  white-space: nowrap;
}
[data-ui2-compte] .meta-chip__value {
  color: var(--color-meta-chip-value);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
}
[data-ui2-compte] .t-sub {
  display: block;
  margin-top: 2px;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
}
[data-ui2-compte] .t-strong { font-weight: var(--font-weight-semi); }
[data-ui2-compte] .t-mono {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}
.compte-demande {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  background: var(--gray-50);
}
.compte-demande__txt {
  font-size: var(--font-size-lg);
  color: var(--color-text-secondary);
  max-width: 1000px;
}
.compte-demande__txt b { color: var(--text); }
.compte-groupe { margin-top: var(--space-6); }
.compte-groupe:first-of-type { margin-top: var(--space-4); }
.compte-groupe__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border-light);
  white-space: nowrap;
}
.compte-groupe__k {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--color-text-muted);
}
.compte-groupe__n {
  font-family: var(--font-family-title);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--noir);
}
.compte-groupe__note {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}
.compte-groupe .data-table { margin-top: var(--space-3); }
.compte-motif { color: var(--color-text-muted); font-size: var(--font-size-sm); }
.compte-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  margin-top: var(--space-5);
}
.compte-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 320px;
}
.compte-field label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semi);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-label);
  color: var(--color-text-accent);
}
.compte-field input {
  width: 100%;
  padding: 9px var(--space-3);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-lg);
  background: var(--surface);
  font-family: var(--font-family-base);
  font-size: var(--font-size-xl);
  color: var(--text);
}
.compte-field small { color: var(--color-text-muted); font-size: var(--font-size-sm); }
[data-ui2-compte] .compte-msg {
  display: none;
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  font-size: var(--font-size-lg);
}
[data-ui2-compte] .compte-msg.is-ok {
  display: block;
  background: var(--vert-pale);
  color: var(--vert);
}
[data-ui2-compte] .compte-msg.is-err {
  display: block;
  background: var(--danger-pale);
  color: var(--danger);
}
[data-ui2-compte] .compte-licence-err {
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  background: var(--danger-pale);
  border-left: 4px solid var(--danger);
  color: var(--text);
  font-size: var(--font-size-lg);
}
