/* ============================================================
   Refonte v2 — la coque et le rail latéral
   Lot 1, points 2 et 3.

   Mesures relevées dans design/Dashboard CRM.dc.html, pas
   approximées : rail 64 px, boutons 40×40 en rayon 12, icônes 19 px
   trait 1.6, repère actif 3×20 à −6 px, panneau volant 232 px à
   70 px du bord.

   Portée : le rail et la couche de lueurs portent `data-v2`, donc
   les jetons de tokens-v2.css n'y résolvent que pour eux. Les écrans
   encore à l'ancienne, dans #kanban-container, gardent les leurs.
   ============================================================ */

/* ── Les lueurs ──────────────────────────────────────────────
   Deux dégradés radiaux fixes, sous tout le reste, sans capture
   de souris. Ambre en haut à gauche, bleu acier en haut à droite. */
.v2-lueurs {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* EXTINCTION PROGRESSIVE, PAS LINÉAIRE.
     Un dégradé « couleur → transparent » s'éteint en ligne droite : l'œil
     voit le bord au point d'arrivée — c'est le « jaune qui ne fond pas »
     relevé par Joris le 11/08/2026. Les paliers intermédiaires imitent
     une courbe d'atténuation : dense au centre, puis une traîne de plus
     en plus légère, morte bien avant le bord du dégradé. */
  background:
    radial-gradient(1000px 640px at 10% -10%,
      var(--glow-a) 0%,
      color-mix(in srgb, var(--glow-a) 55%, transparent) 34%,
      color-mix(in srgb, var(--glow-a) 22%, transparent) 56%,
      transparent 78%),
    radial-gradient(800px 540px at 92% 2%,
      var(--glow-b) 0%,
      color-mix(in srgb, var(--glow-b) 50%, transparent) 40%,
      transparent 76%);
}

/* UNE SEULE SOURCE DE LUEUR SOUS LA COQUE.
   styles.css pose ses propres halos sur le CORPS de page — ils défilent
   avec le contenu, pendant que la nappe ci-dessus est fixe. Deux ambres
   de centres et d'extinctions différents se chevauchaient : raccord
   visible, et qui glissait au défilement. Sous la coque v2, le corps ne
   porte que sa couleur de base ; la nappe est la seule à peindre. */
body.v2-coque { background-image: none; background-color: #eeedea; }

/* ── L'EN-TÊTE EN VERRE DÉPOLI (Joris, 11/08/2026) ─────────────
   Pour qu'un flou ait quelque chose à flouter, le contenu doit passer
   SOUS l'en-tête : le défilement vertical remonte donc du conteneur
   vers <main>, et l'en-tête devient collant. Le défilement HORIZONTAL
   du kanban descend sur le plateau .kanban (voir le bloc kanban plus
   bas) — app-kanban.js lit et restaure le scrollLeft du plateau avec
   repli conteneur. Un conteneur sans contrainte de hauteur
   (flex: 0 0 auto) ne produit plus jamais d'ascenseur vertical. */
body.v2-coque main.main { overflow-y: auto; overflow-x: hidden; }
body.v2-coque #kanban-container,
body.v2-coque #simulateur-container { flex: 0 0 auto; min-height: 0; }

body.v2-coque main .header {
  position: sticky;
  top: 0;
  z-index: 30;

  backdrop-filter: blur(10px) saturate(1.1);
  -webkit-backdrop-filter: blur(10px) saturate(1.1);
  border-bottom: 1px solid rgba(20, 20, 25, .06);
}
[data-app-theme="dark"] body.v2-coque main .header,
[data-theme="dark"] body.v2-coque main .header {
  background: rgba(12, 13, 15, .68);
  border-bottom-color: rgba(255, 255, 255, .06);
}

/* Les en-têtes de tableaux collants doivent s'arrêter SOUS le verre,
   pas derrière. 96px = un peu moins que l'en-tête le plus bas mesuré
   (97-99px selon l'écran) : le pixel ou deux excédentaires glissent
   sous le fond translucide — aucune couture visible. */
body.v2-coque .list-view .list-table thead th,
body.v2-coque .sim-mt th { top: 96px; }
/* PAS .sr-table ici : ce tableau vit dans la modale « Saisie rapide »
   des techniciens, dont l'ascenseur est .sr-wrap — décalé de 96 px,
   son en-tête flotterait au milieu du cadre (contre-expertise 11/08). */
/* styles.css:2684 pose `overflow: hidden` sur .list-table pour rogner
   ses coins — mais un tableau en overflow non-visible CAPTURE le
   sticky de ses th. Même piège sur .sim-missions-table-wrap
   (overflow-x: auto), l'emballage des tableaux du simulateur.
   L'arrondi est repris par les cellules d'angle, les tableaux
   peuvent rester ouverts. */
body.v2-coque .list-view .list-table,
body.v2-coque .sim-missions-table-wrap,
body.v2-coque .sim-mt { overflow: visible; }
body.v2-coque .sim-missions-table-wrap th:first-child { border-top-left-radius: 12px; }
body.v2-coque .sim-missions-table-wrap th:last-child { border-top-right-radius: 12px; }
/* Leur fond d'origine est translucide — posé sur un tableau opaque ça
   passait, mais des lignes défilent dessous désormais : même verre que
   l'en-tête, sinon les lignes fantômes se lisent à travers. */
body.v2-coque .list-view .list-table thead th,
body.v2-coque .sim-mt th {
  background: rgba(238, 237, 234, .88);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
[data-app-theme="dark"] body.v2-coque .list-view .list-table thead th,
[data-app-theme="dark"] body.v2-coque .sim-mt th,
[data-theme="dark"] body.v2-coque .list-view .list-table thead th,
[data-theme="dark"] body.v2-coque .sim-mt th { background: rgba(18, 19, 22, .88); }

/* Les sauts internes (puces data-jump du tableau de bord) doivent
   s'arrêter SOUS l'en-tête en verre, pas derrière lui. */
body.v2-coque main [id^="section-"] { scroll-margin-top: 110px; }

/* Un seul ascenseur : <main>. La vue liste et le simulateur avaient leur
   propre défilement interne (height: 100% + overflow: auto) — sous la
   coque on les libère, sinon la page glisse de 150px puis un panneau à
   moitié caché sous le verre prend le relais. Le kanban, lui, garde ses
   colonnes à défilement interne : c'est son motif propre. */
body.v2-coque .list-view { height: auto; overflow: visible; }
body.v2-coque .simulateur-container,
body.v2-coque #simulateur-container {
  overflow: visible;
  /* L'ancien `--bg` du simulateur est le crème #FAF7F0 d'avant la
     neutralisation — posé sur le #eeedea de la coque, il se lit JAUNE
     (« pourquoi y a toujours du jaune en fond du simulateur », Joris,
     11/08/2026). Transparent : le fond de page est le seul à peindre. */
  background: transparent;
}
body.v2-coque .sim-view { height: auto; overflow: visible; }
body.v2-coque .sim-content { overflow-y: visible; }

/* FENÊTRE ÉTROITE : sous ~1200 px les tableaux dépassent l'écran et
   <main> rogne (overflow-x: hidden sans ascenseur de remplacement.
   On rend leur défilement horizontal aux emballages ; ce scroller
   local recapture le sticky des th, qui se recollent à son bord
   (top: 0) — préférable à des colonnes inaccessibles. La coque ne se
   monte pas sous 768 px au chargement, mais survit à un rétrécissement
   de fenêtre ou à une rotation : ce filet couvre ces états-là. */
@media (max-width: 1200px) {
  body.v2-coque .list-view { overflow-x: auto; }
  body.v2-coque .sim-missions-table-wrap { overflow-x: auto; }
  body.v2-coque .list-view .list-table thead th,
  body.v2-coque .sim-mt th { top: 0; }
}

[data-app-theme="dark"] body.v2-coque,
[data-theme="dark"] body.v2-coque { background-color: #0c0d0f; }

/* ══════════════════════════════════════════════════════════════════
   L'ANCIEN SYSTÈME PASSE AU NEUTRE SOUS LA COQUE (11/08/2026 —
   « enlève tous les collages, je veux que tout soit intégré »).
   Les écrans refaits portent leurs jetons [data-v2] ; tout le reste
   (volet de fiche, modales, champs, pastilles héritées) lit encore la
   palette d'origine, restée CHAUDE : ivoire #FAF7F0, crème #F4F0E6,
   bordures beiges, encres taupe. C'est elle qui faisait « collage ».
   On re-mappe ces jetons vers les neutres de la maquette — les
   éléments ne bougent pas, ils changent de peau. Les LUMINANCES sont
   conservées à l'identique : seule la teinte se neutralise, aucun
   contraste ne bouge. */
body.v2-coque {
  --bg: #eeedea;
  --bg-3: #f0efec;
  --bg-4: #e6e5e1;
  --border: #dedddb;
  --border-2: #c9c8c4;
  --text: #16171a;
  --text-2: #55595f;
  --text-3: #6b6f76;
  --k: 20, 20, 25;
}
[data-app-theme="dark"] body.v2-coque,
[data-theme="dark"] body.v2-coque {
  --bg: #141518;
  --bg-2: #1d1f23;
  --bg-3: #26282d;
  --bg-4: #2f3238;
  --border: #3a3d44;
  --border-2: #4a4e56;
  --text: #f0f1f3;
  --text-2: #c2c6cc;
  --text-3: #9aa0a8;
  --k: 240, 242, 245;
}
/* Le résumé de fiche portait un dégradé ambre → ROSE codé en dur,
   vestige d'avant le système : il redevient un bloc neutre. */
body.v2-coque .summary-box {
  background: var(--panel-2, rgba(255,255,255,.42));
  border-color: var(--stroke, rgba(20,20,25,.075));
}

/* La Carte : le fond de carte s'encadre comme les autres contenus au
   lieu de coller bord à bord sous l'en-tête. */
body.v2-coque .map-view { padding: 20px 30px 30px; gap: 12px; display: flex; flex-direction: column; }
body.v2-coque .map-stats {
  border-radius: var(--r-sm, 12px);
  background: var(--panel, rgba(255,255,255,.66));
  border: 1px solid var(--stroke, rgba(20,20,25,.075));
  padding: 10px 14px;
}
body.v2-coque #map-canvas, body.v2-coque .map-canvas {
  border-radius: var(--r-sm, 12px);
  overflow: hidden;
  border: 1px solid var(--stroke, rgba(20,20,25,.075));
}

/* LA NAPPE EST ÉTEINTE PARTOUT (décision Joris, 11/08/2026 — « j'en peux
   plus de l'ambré »). L'élément et ses dégradés restent définis
   au-dessus : les rallumer, c'est retirer cette seule ligne. La base de
   page passe du crème #FAF7F0 hérité au gris-beige #eeedea de la
   maquette — neutre, sans chaleur, et les cartes blanches y ressortent. */
.v2-lueurs { display: none; }

/* ── Le rail ─────────────────────────────────────────────────
   Sombre dans les deux thèmes : c'est la signature du produit
   (piège n° 1 du handoff). */
.v2-rail {
  position: sticky;
  top: 0;
  z-index: 6;
  width: 64px;
  min-width: 64px;
  height: 100vh;
  overflow-y: auto;
  overflow-x: visible;
  padding: 12px 0;
  background: var(--rail-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}
.v2-rail::-webkit-scrollbar { width: 0; }

.v2-mark { width: 28px; height: 35.1px; object-fit: contain; flex-shrink: 0; }

.v2-groupe {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.v2-filet {
  width: 26px;
  height: 1px;
  background: var(--rail-line);
  flex-shrink: 0;
}

/* ── Les boutons du rail ─────────────────────────────────── */
.v2-btn {
  all: unset;
  cursor: pointer;
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  display: grid;
  place-items: center;
  color: var(--rail-fg);
  background: transparent;
  transition: background .14s ease, color .14s ease;
}
.v2-btn:hover { background: rgba(255,255,255,.09); color: #fff; }
.v2-btn:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: 2px; }
/* `actif` = on est sur cet écran. Seul état qui porte le repère ambre. */
.v2-btn.actif { background: rgba(255,255,255,.2); color: #fff; }
/* `ouvert` = le sous-menu est déplié. Même éclaircissement que le survol,
   volontairement : déplier un menu n'est pas y être. */
.v2-btn.ouvert { background: rgba(255,255,255,.09); color: #fff; }
.v2-btn > svg { width: 19px; height: 19px; }
.v2-chevron svg { width: 9px; height: 9px; }

/* Repère actif : pilule de 3×20 à gauche du bouton. */
.v2-marque {
  position: absolute;
  left: -6px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  border-radius: 99px;
  background: transparent;
  transition: background .14s ease;
}
.v2-btn.actif .v2-marque { background: var(--accent-bright); }

/* Chevron des groupes dépliants : dans le coin bas-droit de la case de
   40 px, à 3-4 px des bords, comme la maquette. Je l'avais sorti à -1 px
   en croyant le dégager de l'icône ; il débordait alors du rail. */
.v2-chevron {
  position: absolute;
  right: 3px;
  bottom: 4px;
  display: grid;
  place-items: center;
  color: var(--rail-fg);
}
.v2-btn:hover .v2-chevron,
.v2-btn.actif .v2-chevron { color: #fff; }

/* Compteur : ambre plein, encre sombre — jamais #fff en dur
   (piège n° 3). Le chiffre vient de la liste comptée, jamais
   d'un littéral (piège n° 7). */
.v2-pastille {
  position: absolute;
  top: 1px;
  right: 1px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 99px;
  background: var(--accent-bright);
  color: var(--sur-accent, #1b1a12);
  font-size: 10px;
  font-weight: 680;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ── L'avatar, en pied de rail ───────────────────────────── */
.v2-pied { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.v2-avatar {
  all: unset;
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: 99px;
  display: grid;
  place-items: center;
  background: var(--accent-bright);
  color: var(--sur-accent, #1b1a12);
  font-size: 12px;
  font-weight: 680;
  letter-spacing: -.01em;
}
.v2-avatar:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: 2px; }

/* ── Le panneau volant ───────────────────────────────────────
   `position: fixed` et non `absolute` : le rail a
   `overflow-y: auto`, un panneau posé dedans serait rogné et
   invisible (piège n° 6). Le `top` est mesuré sur l'icône à
   l'ouverture, jamais codé en dur. */
.v2-volant {
  position: fixed;
  left: 70px;
  z-index: 40;
  width: 232px;
  /* `body` est un conteneur flex dans ce projet : sans ces quatre
     lignes, le panneau est étiré sur toute la hauteur de la fenêtre
     (901 px mesurés) et son `top` calculé part au plafond. */
  bottom: auto;
  height: fit-content;
  max-height: calc(100vh - 16px);
  flex: 0 0 auto;
  padding: 8px;
  border-radius: var(--r-md);
  background: var(--rail-bg);
  border: 1px solid var(--rail-line);
  box-shadow: 0 18px 46px -12px rgba(0,0,0,.6);
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}
.v2-volant[hidden] { display: none; }

.v2-volant-titre {
  font-size: 11px;
  font-weight: 620;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(255,255,255,.34);
  padding: 5px 10px 7px;
}
/* Panneau du compte (avatar du pied de rail) : le nom garde la casse
   réelle — c'est une identité, pas un intitulé de section. */
.v2-volant-compte .v2-volant-titre { text-transform: none; letter-spacing: 0; font-size: 12.5px; color: rgba(255,255,255,.8); }
.v2-compte-role { display: block; margin-top: 2px; font-size: 11px; font-weight: 550; color: rgba(255,255,255,.4); }
.v2-lien-depart:hover { background: rgba(240,119,106,.14); color: #f0776a; }

.v2-lien {
  all: unset;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  color: var(--rail-fg);
  background: transparent;
  transition: background .14s ease, color .14s ease;
}
.v2-lien:hover { background: rgba(255,255,255,.09); color: #fff; }
.v2-lien:focus-visible { outline: 2px solid var(--v2-accent); outline-offset: -2px; }
.v2-lien.actif { background: rgba(255,255,255,.2); color: #fff; }
/* Taille explicite obligatoire : les icônes sont reprises des entrées
   d'origine, où leur dimension venait d'une règle liée à leur ancienne
   classe. Un SVG avec viewBox et sans taille s'étire pour remplir son
   conteneur — chaque ligne faisait 236 px de haut. */
.v2-lien svg { width: 17px; height: 17px; flex: 0 0 17px; }
.v2-lien-txt { flex: 1; font-size: 13.5px; font-weight: 550; white-space: nowrap; }
.v2-lien-meta {
  font-size: 11px;
  color: rgba(255,255,255,.4);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .v2-btn, .v2-lien, .v2-marque { transition: none; }
}

/* ── Cohabitation avec la coque existante ────────────────────
   L'ancienne barre latérale et l'ancienne barre du haut sont
   masquées ; leurs entrées restent dans le document, c'est le
   rail qui déclenche leur clic. Rien de la navigation existante
   n'est réécrit. */
/* LE RAIL DOIT TOUCHER LES TROIS BORDS.
   Il flottait à 8 px du haut et de la gauche : `body` garde la marge par
   défaut du navigateur, que personne n'avait remise à zéro — invisible tant
   que le fond de page et celui du contenu se ressemblent, criant dès qu'un
   rail sombre longe le bord. */
body.v2-coque { margin: 0; }

body.v2-coque .sidebar,
body.v2-coque .topbar { display: none; }

/* LA BANDE MORTE SOUS L'EN-TÊTE.
   `.filters` est la barre de filtres du kanban. Sur les écrans qui n'en ont
   pas — tableau de bord, tâches, simulateur — elle est vide, mais garde son
   `padding: 10px 24px` et sa bordure basse : 21 px de vide pleine largeur qui
   séparaient l'en-tête du contenu et donnaient l'impression que rien n'était
   aligné. Vide, elle ne prend plus de place. */
body.v2-coque main .filters:empty { display: none; }
body.v2-coque .app {
  display: grid;
  grid-template-columns: 64px 1fr;
  align-items: stretch;
  gap: 0;
  padding: 0;
  margin: 0;
  max-width: none;
  height: 100vh;
}
body.v2-coque #kanban-container {
  position: relative;
  z-index: 1;
  /* Le conteneur portait `height: 100vh; overflow-y: auto` : c'était LUI
     l'ascenseur. Depuis l'en-tête en verre dépoli (11/08/2026), c'est
     <main> qui défile — le conteneur grandit avec son contenu, sinon le
     contenu ne passe jamais sous le verre. Exceptions bornées : le bloc
     « écrans-application » ci-dessous. */
  height: auto;
  overflow: visible;
  padding: 20px 30px;
}

/* ÉCRANS-APPLICATION : kanban, carte, calendrier et caisses gardent
   leur motif propre — cadre borné à l'écran, défilement(s) interne(s).
   Leur chaîne height:100% (map-canvas, cal-week-body, caisses-page)
   repose sur un parent à hauteur contrainte : flex: 1 1 auto la leur
   rend, <main> étant une colonne flex de 100vh. Sans cette exception,
   la carte Leaflet tombait à 0 px, l'auto-défilement 08:00 de la vue
   semaine mourait, et les sous-onglets Caisses partaient au défilement
   (contre-expertise du 11/08/2026). Les autres écrans grandissent et
   défilent dans <main>, sous le verre.
   Pour le kanban s'ajoute le défilement horizontal, descendu du
   conteneur vers le plateau : un ancêtre en overflow-x:auto CAPTURE le
   position:sticky de tout ce qu'il contient, même s'il ne défile
   jamais — c'est lui qui cassait l'en-tête de liste collant. */
body.v2-coque #kanban-container:has(> .kanban),
body.v2-coque #kanban-container:has(> .map-view),
body.v2-coque #kanban-container:has(> .cal-page),
body.v2-coque #kanban-container:has(> .caisses-page-wrap) { flex: 1 1 auto; min-height: 0; }
body.v2-coque #kanban-container > .kanban { overflow-x: auto; min-width: 0; }

/* ══════════════════════════════════════════════════════════════════
   L'EN-TÊTE DE PAGE (lot 1, point 4)

   L'en-tête n'est pas reconstruit : celui du CRM porte déjà le titre
   (#page-title), le sur-titre (#page-subtitle) et l'action principale
   (#add-btn), tous tenus à jour par l'application. On le restyle et on
   remet le sur-titre au-dessus du titre par l'ordre flex — le DOM
   n'est pas touché, donc rien de ce qui l'écrit ne casse.

   Le champ de recherche avait été écarté le 07/08/2026 — « un champ qui ne
   cherche rien apprend à ne pas s'en servir ». L'objection portait sur un
   champ décoratif, pas sur la recherche. Celui du tableau de bord (.d3-cmds,
   v3-tableau.css) OUVRE la palette ⌘K, qui cherche réellement dans les fiches
   et dans les actions : la raison du refus ne s'y applique pas.
   ══════════════════════════════════════════════════════════════════ */
body.v2-coque main .header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  padding: 20px 30px 16px;
  margin: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  font-family: var(--font);
}

/* Sur-titre : capitales, 11 px, au-dessus du titre. `order: -1` et
   une largeur pleine le font passer sur sa propre ligne. */
body.v2-coque main .header #page-subtitle {
  order: -1;
  flex: 1 0 100%;
  margin: 0;
  font-size: 11px;
  font-weight: 640;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--v2-text-3);
}
body.v2-coque main .header #page-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 680;
  letter-spacing: -.035em;
  color: var(--v2-text);
}

/* Tout ce qui suit le titre part à droite. */
body.v2-coque main .header > *:not(#page-title):not(#page-subtitle) { margin-left: 0; }
body.v2-coque main .header #page-title { margin-right: auto; }

/* Un seul bouton ambre plein par écran : l'action principale. */
body.v2-coque main .header .btn.primary,
body.v2-coque main .header #add-btn {
  background: var(--accent-bright);
  color: var(--sur-accent, #1b1a12);
  border: 0;
  border-radius: var(--r-sm);
  padding: 9px 15px;
  font-size: 13.5px;
  font-weight: 640;
  letter-spacing: -.01em;
  box-shadow: var(--shadow-sm);
  transition: filter .14s ease, transform .14s ease;
}
body.v2-coque main .header .btn.primary:hover { filter: brightness(1.06); }
body.v2-coque main .header .btn.primary:active { transform: scale(.98); }

/* Les autres commandes de l'en-tête — Filtres, Kanban/Liste, Gérer les
   champs, Depuis une signature — ne sont PAS restylées. Elles gardent
   leurs anciens jetons et restent pleinement fonctionnelles jusqu'à
   leur lot. Un bouton à moitié repris pendant six lots ne se distingue
   plus d'un bouton cassé.  */

/* La bascule de thème, rapatriée depuis l'ancienne barre du haut. */
body.v2-coque main .header #theme-btn {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--panel);
  border: 1px solid var(--stroke);
  color: var(--v2-text-2);
  cursor: pointer;
  backdrop-filter: blur(20px);
  transition: background .14s ease, color .14s ease;
}
body.v2-coque main .header #theme-btn:hover { background: var(--inset); color: var(--v2-text); }
body.v2-coque main .header #theme-btn svg { width: 17px; height: 17px; }

/* ══ v3 — rail par module et lanceur (NAVIGATION-MODULES.md) ═══════ */
/* Le logo, à 34 px dans une zone cliquable de 46 px, ramène au lanceur. */
.v3-maison {
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; margin: 8px auto 2px;
  border: 0; background: none; cursor: pointer; border-radius: var(--r-xs, 9px);
}
.v3-maison:hover { background: rgba(255, 255, 255, .08); }
.v3-maison .v2-mark { width: 34px; height: 34px; margin: 0; display: block; }

.v3-ecrans, .v3-pied-modules {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 0;
}
.v3-ressort { flex: 1 1 auto; }
/* Le pied liste les autres modules — encre plus discrète que les
   écrans du module ouvert, même géométrie. */
.v3-pied-modules .v2-btn { opacity: .78; }
.v3-pied-modules .v2-btn:hover { opacity: 1; }

/* ── Le lanceur : sept tuiles, rien d'autre ── */
body.v3-sur-lanceur main .header { display: none; }
.v3-lanceur {
  padding: 72px 30px 60px;
  min-width: 0;                 /* jamais le min-width des écrans-tableaux */
}
/* Les tuiles du lanceur vivent dans v3-rail.css, et NULLE PART AILLEURS.
   Elles étaient déclarées ici ET là : la cascade donnait la main à
   v3-rail (chargée après) pour la forme, mais le survol différait —
   translateY(-1px) ici, (-2px) là-bas — donc deux comportements pour la
   même tuile selon la règle qu'on lisait. Audit Claude Design du
   02/09/2026, défaut 10 bis : une déclaration, dans une feuille nommée.
   « .v3-tuiles-2 » est partie avec : sa max-width de 740 px n'a jamais
   rien fait, aucun écran ne pose cette classe. */
.v3-tuile-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--r-sm, 10px);
  background: var(--accent-soft); color: var(--v2-accent);
}
.v3-tuile-t { font-size: 17px; font-weight: 640; letter-spacing: -.02em; color: var(--v2-text, var(--v2-text, #16171a)); }
.v3-tuile-s { font-size: 12.5px; line-height: 1.5; color: var(--v2-text-3, var(--v2-text-3, #6b6f76)); }
.v3-porte { padding-top: 40px; }
/* La photo du compte, en bas du rail (23/09/2026) */
.v3-compte-av.a-photo { padding: 0; overflow: hidden; }
.v3-compte-av img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 99px; }
