/* ============================================================
   MAPi Expert · fondations partagées de la refonte
   Charte MAPi : bleu #006DEC, orange #FF934F, vert #2DAE54
   (variables dans tokens.css, à charger AVANT ce fichier).
   Deux coques d'application :
   - html[data-v="a"] : version héritée améliorée (sidebar bleue)
   - html[data-v="b"] : refonte (rail compact + barre de commande)
   Échelle z-index : contenu 1 < sticky 20 < dropdowns 60 <
   bascule A/B 80 < drawer/modale 95 < paiement 300.
   ============================================================ */

/* ============================================================
   Navigation entre pages 100 % fluide, en trois couches :
   1. Le canvas imite le chrome dès la première peinture (rail bleu
      72px + bandeau 54px + panneau gris) : même une frame sans la
      coque JS ressemble à l'app, jamais de blanc.
   2. View transitions inter-documents : le rail, la barre de
      commande et le panneau portent leur propre nom, donc le chrome
      est épinglé (il ne fond jamais, il reste affiché en continu) ;
      seul le panneau de contenu glisse.
   3. Le contenu apparaît en cascade légère (voir main.page > *).
   Dégrade proprement partout : sans view transitions, les couches
   1 et 3 suffisent ; reduced-motion neutralise tout.
   ============================================================ */
html {
    scroll-behavior: smooth;
    /* La COULEUR de base (dernier composant) sert aussi de couleur de frame
       de bascule du navigateur : teinte du panneau, jamais le bleu de marque
       (le chrome est porté par un calque dégradé). Copie inline dans chaque
       <head> : garder les deux synchronisés.

       LE CALQUE DE CHROME NE SE RÉPÈTE PAS (2026-08-19). Le fond de <html>
       est propagé au CANVAS, c'est-à-dire à toute la surface peinte, alors
       que sa zone de POSITIONNEMENT s'arrête à la boîte de <html>. Avec le
       `repeat` par défaut, le calque bleu se répétait donc à l'infini sous
       cette boîte, quand le panneau clair, lui, portait `no-repeat` : dès
       qu'un écran faisait défiler le DOCUMENT au-delà de la fenêtre (le
       repli sous 960 px, une fenêtre courte), on lisait une grande zone
       bleue de marque sous la page, signalée comme telle par le
       commanditaire sur l'écran des contrats. `no-repeat` sur le calque de
       base rend ce dessous à la COULEUR de fond, celle du panneau : le
       défilement ne découvre plus qu'une continuation du contenu. */
    background:
        linear-gradient(#F7F9FC, #F7F9FC) 72px 54px / calc(100% - 72px) calc(100% - 54px) no-repeat,
        linear-gradient(var(--blue), var(--blue)) 0 0 / 100% 100% no-repeat #F7F9FC;
}
html[data-chrome="c"] {
    background:
        linear-gradient(#F7F9FC, #F7F9FC) 72px 54px / calc(100% - 72px) calc(100% - 54px) no-repeat,
        linear-gradient(165deg, var(--blue-muted) 0%, var(--blue-pale) 55%, #fff 100%) 0 0 / 100% 100% no-repeat #F7F9FC;
}
html[data-chrome="d"] {
    background:
        linear-gradient(#131A26, #131A26) 72px 54px / calc(100% - 72px) calc(100% - 54px) no-repeat,
        linear-gradient(#0B1220, #0B1220) 0 0 / 100% 100% no-repeat #131A26;
}

/* ============================================================
   Espace PARTENAIRE : pas de rail latéral. Le squelette de
   pré-peinture perd donc sa colonne de 72 px à gauche. Le mode est
   posé sur <html> par la pré-peinture du <head>, avant cette CSS.
   ============================================================ */
html[data-app="partenaire"] {
    background:
        linear-gradient(#F7F9FC, #F7F9FC) 0 54px / 100% calc(100% - 54px) no-repeat,
        linear-gradient(var(--blue), var(--blue)) 0 0 / 100% 100% no-repeat #F7F9FC;
}
html[data-app="partenaire"][data-chrome="c"] {
    background:
        linear-gradient(#F7F9FC, #F7F9FC) 0 54px / 100% calc(100% - 54px) no-repeat,
        linear-gradient(165deg, var(--blue-muted) 0%, var(--blue-pale) 55%, #fff 100%) 0 0 / 100% 100% no-repeat #F7F9FC;
}
html[data-app="partenaire"][data-chrome="d"] {
    background:
        linear-gradient(#131A26, #131A26) 0 54px / 100% calc(100% - 54px) no-repeat,
        linear-gradient(#0B1220, #0B1220) 0 0 / 100% 100% no-repeat #131A26;
}
/* PAS de view transitions inter-documents (retirées le 2026-07-18 apres
   analyse video image par image) : leur commutation de surface produisait une
   frame BLANCHE de compositeur sur certaines machines, impossible a peindre
   en CSS. Le sans-flash repose desormais sur le trio eprouve : maintien de
   l'ancienne page par le navigateur (paint holding) + rel=expect (la premiere
   peinture de la nouvelle page est COMPLETE) + squelette de chrome inline
   dans chaque head. Le changement de menu est un echange net, sans fondu. */
/* .cmd etablit un contexte d'empilement (flex item + z-index) au-dessus de
   .frame : sans cela, les menus du header (compte, plus d'actions,
   autocomplete, z-index 60) passeraient sous les elements sticky (z 20) du
   panneau. Les voiles et modales vivent hors de .app : toujours dessus. */
.cmd { z-index: 1; }
.frame { z-index: 0; }
@media (prefers-reduced-motion: no-preference) {
    /* Apparition en cascade du contenu, UNIQUEMENT aux chargements directs :
       en navigation interne (classe is-nav posee par le script inline du head
       selon document.referrer), le contenu arrive entier, d'un bloc */
    main.page > * { animation: page-item-in .3s cubic-bezier(.22, 1, .36, 1) backwards; }
    html.is-nav main.page > * { animation: none; }
    main.page > :nth-child(2) { animation-delay: .04s; }
    main.page > :nth-child(3) { animation-delay: .08s; }
    main.page > :nth-child(4) { animation-delay: .12s; }
    main.page > :nth-child(n+5) { animation-delay: .2s; }
    @keyframes page-item-in { from { opacity: 0; transform: translateY(7px); } }
    /* Page pré-rendue (Speculation Rules) : la cascade attend l'activation
       réelle, sinon elle serait déjà finie à l'affichage (voir shell.js) */
    html.is-prerender main.page > * { animation-play-state: paused; }
}
body { min-height: 100dvh; }
img { max-width: 100%; }
button { font: inherit; }

/* .sr-only vit dans css/components.css (utilitaire partagé) */

/* ---------- Ossature : le chrome enrobe le contenu ----------
   Deux chromes au choix (icône sous le logo, persisté) :
   A · Azur (défaut) : rail ET header bleu de marque PLAT
   C · Horizon : dégradé ciel très clair, textes bleu foncé */
.app {
    display: flex; align-items: stretch; height: 100dvh;
    background: var(--blue);
}
.maincol { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Le panneau de contenu, arrondi côté chrome, qui scrolle en interne.
   L'ombre interne sépare nettement le chrome du contenu focus. */
.frame {
    flex: 1; min-height: 0; overflow: auto; background: var(--gray-100);
    border-radius: 18px 0 0 0;
    box-shadow: inset 0 12px 20px -16px rgba(9, 30, 66, .45), inset 12px 0 20px -16px rgba(9, 30, 66, .3);
}
html[data-chrome="c"] .app { background: linear-gradient(165deg, var(--blue-muted) 0%, var(--blue-pale) 55%, #fff 100%); }
html[data-chrome="c"] .frame { box-shadow: inset 0 12px 20px -16px rgba(0, 109, 236, .28), inset 12px 0 20px -16px rgba(0, 109, 236, .18); }
html[data-chrome="d"] .app { background: #0B1220; }
html[data-chrome="d"] .frame { box-shadow: inset 0 12px 20px -16px rgba(0, 0, 0, .6), inset 12px 0 20px -16px rgba(0, 0, 0, .45); }
main.page { width: 100%; max-width: 1260px; margin: 0 auto; padding: 26px 30px 90px; }
/* Pleine largeur (js/large.js) : sur un kanban à sept colonnes ou une liste
   à huit colonnes, la gouttière de 1 260 px fait défiler à côté de 600 px
   de gris. Le bouton à deux flèches libère la largeur, le choix est retenu. */
main.page.is-large { max-width: none; }

/* Ancrage d'une carte déposée (js/ui.js, window.__pose). Le liseré est
   porté par `outline` et non par un pseudo-élément : les cartes des trois
   kanbans en ont déjà, et l'outline ne dépend d'aucun positionnement. */
@media (prefers-reduced-motion: no-preference) {
    .is-pose { animation: pose .44s cubic-bezier(.34, 1.56, .64, 1) both; }
    @keyframes pose {
        0% { transform: scale(1.05); outline: 2px solid var(--blue); outline-offset: 3px; }
        55% { transform: scale(.992); outline: 2px solid var(--blue); outline-offset: 2px; }
        100% { transform: none; outline: 2px solid transparent; outline-offset: 2px; }
    }
}
/* L'entrée « Pleine largeur » du menu « … » : une bascule de menu porte
   un libellé stable et une coche, pas un verbe qui s'inverse. */
/* La coche d'une entrée à bascule. Elle était accrochée à la seule
   classe `.dd-large` : toute nouvelle bascule du menu héritait d'une
   coche allumée en permanence, qui affirmait le contraire de l'état.
   Le sélecteur suit maintenant CE QUI PORTE L'ÉTAT, `aria-pressed`, et
   non le nom d'une entrée. */
.dd-item[aria-pressed] .dd-ck { margin-left: auto; opacity: 0; transform: scale(.7); transition: opacity .15s, transform .15s; }
.dd-large[aria-pressed="true"] { color: var(--blue-dark); }
.dd-item[aria-pressed="true"] .dd-ck { opacity: 1; transform: none; }
/* L'ENTRÉE NE DISPARAÎT PLUS, ET LA PRÉFÉRENCE NON PLUS (2026-08-11).
   Elle s'effaçait sous 1 400 px, au motif qu'il n'y avait pas de largeur
   à gagner, et la même règle annulait au passage le réglage déjà pris.
   Deux ennuis en un : la commande s'évanouissait sous la main au moindre
   redimensionnement, et le choix retenu se défaisait tout seul dès qu'on
   rétrécissait la fenêtre, sans revenir quand on l'élargissait.

   « Pleine largeur » n'est pas un geste, c'est une PRÉFÉRENCE : elle se
   règle quand on y pense et s'applique dès que la fenêtre a de quoi la
   servir. Elle reste donc offerte à toutes les tailles, sans effet
   visible tant que la gouttière est nulle, ce qui ne trompe personne :
   la coche dit l'état retenu, pas le résultat du moment. Elle gagne au
   passage la bande des 1 320 à 1 400 px, où il y avait bel et bien
   quelques dizaines de pixels à prendre. */
/* Jeton fonctionnel local (déconnexion) : rouge d'alerte, jamais décoratif */
:root { --danger-ink: #C13515; --danger-soft: #FCEAE5; }
html[data-chrome="d"] { --danger-ink: #FF9078; --danger-soft: #3A201A; }

/* Bascule de version : les blocs marqués ne s'affichent que dans leur version */
html[data-v="a"] [data-v-block="b"] { display: none !important; }
html[data-v="b"] [data-v-block="a"] { display: none !important; }

/* ============================================================
   La navbar unique : rail compact refondu, sur le bleu de marque
   ============================================================ */
.sb {
    flex-shrink: 0; width: 72px; height: 100%; overflow-y: auto;
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    color: #fff; padding: 12px 8px 10px;
}
.rail-logo { display: block; padding: 3px 0 8px; border-radius: 10px; }
.rail-logo img { height: 18px; width: auto; max-width: 56px; object-fit: contain; display: block; }
.rail-item {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    width: 58px; min-height: 46px; border: none; background: none; border-radius: 12px;
    color: rgba(255, 255, 255, .88); font-size: 9.5px; font-weight: 700; cursor: pointer;
    text-decoration: none; transition: background .15s, color .15s; padding: 5px 2px;
    text-align: center; line-height: 1.2;
}
.rail-item svg { width: 19px; height: 19px; }
.rail-item:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.rail-item[aria-current="page"] { background: var(--surface); color: var(--blue-dark); font-weight: 800; }
.rail-item.is-off { opacity: .5; cursor: default; }
.rail-item.is-off:hover { background: none; }
/* ============================================================
   LE TRAIT ENTRE DEUX FAMILLES DU RAIL
   ------------------------------------------------------------
   Il vit DANS le flux, pas en ::before d'une entrée : une famille
   masquée par la portée laisserait sinon un trait collé au logo, et
   deux dessins pour une même idée finissent toujours par diverger
   (c'était le cas, 44 px en pied contre 34 dans la colonne, sur un
   rail où tout est centré sur le même axe).

   Il FOND À SES DEUX BOUTS. Un filet net de 44 px entre des entrées
   de 58 laisse voir ses arrêts, et un rail n'est pas un tableau : ce
   qu'on veut dire ici, c'est « la suite parle d'autre chose », pas
   « nouvelle ligne ». Le dégradé le dit sans trancher, et il tient
   sur les trois chromes puisqu'il est fait de currentColor, le blanc
   du rail, jamais d'une couleur posée en dur.
   ============================================================ */
/* MESURÉ : sans cette ligne, les traits de la colonne se centraient sur
   x = 29 et celui du pied sur x = 36, l'axe du rail. Sept pixels de
   décalage sur trois filets censés se répondre. En cause, la .sb-nav
   qui porte son display en style inline sans alignement : ses enfants
   plus étroits que la colonne se rangeaient au bord gauche. */
.sb-nav { align-items: center; }
.rail-sep {
    display: block; width: 44px; height: 1px; flex-shrink: 0; margin: 5px 0;
    background: linear-gradient(90deg,
        transparent 0%, currentColor 26%, currentColor 74%, transparent 100%);
    opacity: .34;
}
/* Le pied a son propre écart (gap: 8px) : le trait n'y ajoute pas le
   sien, sinon la coupure du siège serait deux fois plus large que
   celles de la colonne, pour la même idée. */
.rail-foot > .rail-sep { margin: 1px 0; }
.sb.is-mini .rail-sep { width: 32px; }
.rail-foot { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; }
/* Interne et Notion font famille : rien ne les sépare, et elles se
   serrent un peu plus que le gap du pied, qui est réglé pour des
   objets de natures différentes (le sélecteur de plateforme, le
   bouton de repli). */
.rail-foot .rail-item--it + .rail-item--it { margin-top: -4px; }
/* Les entrées du siège, en pied de rail. Le trait qui les annonce est
   un .rail-sep posé par railHtml, comme dans la colonne : ce ::before
   dessinait la même idée une seconde fois, et à une autre largeur. */
.rail-item--it { position: relative; }
/* Mode réduit du rail : icônes seules */
.rail-min {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, .45);
    background: rgba(255, 255, 255, .1); color: #fff; cursor: pointer; position: relative;
    transition: background .15s, border-color .15s;
}
.rail-min:hover { background: rgba(255, 255, 255, .22); border-color: #fff; }
.rail-min::after { content: ''; position: absolute; inset: -8px; }
.sb.is-mini { width: 54px; padding-left: 6px; padding-right: 6px; }
.sb.is-mini .rail-item { width: 42px; min-height: 42px; }
.sb.is-mini .rail-item > span:not(.sb-dot) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sb.is-mini .rail-item .sb-dot { top: 4px; right: 6px; }
.sb.is-mini .rail-logo img { max-width: 40px; }
.sb .avatar--ml { background: var(--surface); color: var(--blue-dark); }
.sb :focus-visible { outline-color: #fff; }

/* ---------- Sélecteur d'apparence : icône sous le logo ---------- */
/* Déclencheur : icône nue sous le logo, discrète (plus de pastille),
   la zone de clic reste >= 44px grâce au ::after */
.rail-chrome {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 28px; height: 28px; margin-bottom: 3px; border: none; border-radius: 9px;
    background: none; color: rgba(255, 255, 255, .72); cursor: pointer; position: relative;
    transition: color .15s, background .15s;
}
.rail-chrome:hover,
.rail-chrome[aria-expanded="true"] { color: #fff; background: rgba(255, 255, 255, .16); }
.rail-chrome::after { content: ''; position: absolute; inset: -8px; }
html[data-chrome="c"] .rail-chrome { color: rgba(0, 85, 187, .58); }
html[data-chrome="c"] .rail-chrome:hover,
html[data-chrome="c"] .rail-chrome[aria-expanded="true"] { color: var(--blue-dark); background: rgba(255, 255, 255, .8); }

/* ---------- Panneau d'apparence : Mode et Ambiance ---------- */
/* Deux axes séparés et nommés plutôt qu'un cycle aveugle : le mode (Clair,
   Sombre, Système) et, tant que le rendu est clair, la couleur du chrome.
   Panneau en position fixe : il est posé dans <body> pour échapper au
   défilement du rail, ses coordonnées sont calculées par shell.js. */
.ap-panel {
    position: fixed; z-index: 60; width: 252px; padding: 12px;
    border: 1px solid var(--gray-200); border-radius: 14px;
    background: var(--surface); box-shadow: var(--shadow-lg); color: var(--text-primary);
}
.ap-grp + .ap-grp { margin-top: 12px; }
.ap-lbl {
    display: block; margin-bottom: 7px; font-size: 10.5px; font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.ap-seg { display: flex; gap: 4px; padding: 3px; border-radius: 12px; background: var(--gray-100); }
.ap-opt { position: relative; flex: 1; min-width: 0; cursor: pointer; }
/* Le bouton radio reste focusable au clavier, le libellé porte le rendu */
.ap-in { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.ap-body {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px; min-height: 44px; padding: 5px 2px; border-radius: 9px;
    font-size: 10.5px; font-weight: 700; color: var(--text-secondary);
    transition: background .15s, color .15s;
}
.ap-ic { display: inline-flex; }
.ap-tx { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ap-opt:hover .ap-body { background: var(--gray-200); color: var(--text-primary); }
.ap-opt.is-on .ap-body { background: var(--surface); color: var(--blue-dark); box-shadow: var(--shadow-sm); }
.ap-in:focus-visible ~ .ap-body { outline: 2px solid var(--blue); outline-offset: 2px; }
.ap-chip { width: 20px; height: 20px; border-radius: 50%; border: 1px solid rgba(9, 30, 66, .18); }
.ap-chip--a { background: var(--blue); }
/* Hex figés (valeurs claires de --blue-muted / --blue-pale) : la pastille doit
   montrer l'ambiance telle qu'elle s'affiche en clair, y compris quand le
   panneau est ouvert en sombre */
.ap-chip--c { background: linear-gradient(165deg, #d4eaff 0%, #ebf6ff 55%, #fff 100%); }
html[data-chrome="d"] .ap-in:focus-visible ~ .ap-body { outline-color: var(--blue-dark); }
html[data-chrome="d"] .ap-chip { border-color: rgba(255, 255, 255, .22); }

/* ---------- Rail décliné pour le chrome Horizon ---------- */
html[data-chrome="c"] .sb { color: var(--blue-dark); }
html[data-chrome="c"] .rail-item { color: var(--blue-dark); }
html[data-chrome="c"] .rail-item:hover { background: rgba(255, 255, 255, .75); color: var(--blue-dark); }
html[data-chrome="c"] .rail-item[aria-current="page"] { background: var(--surface); color: var(--blue-dark); box-shadow: var(--shadow-sm); }
html[data-chrome="c"] .rail-min { border-color: rgba(0, 109, 236, .3); background: var(--surface); color: var(--blue-dark); }
html[data-chrome="c"] .rail-min:hover { border-color: var(--blue); background: var(--blue-pale); }
html[data-chrome="c"] .sb :focus-visible { outline-color: var(--blue); }
/* Pastille non-lus (Messages) */
.sb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--orange); flex-shrink: 0; }
/* Variante chiffrée : une pastille ne porte un nombre que lorsqu'elle
   dit « quelqu'un attend une réponse de vous ». Le reste est un point. */
/* ELLE PORTAIT DU BLANC SUR L'ORANGE DE MARQUE, soit 2,20:1 : le pire
   contraste de toute l'application, et le plus répété (cinquante-deux
   occurrences au relevé mobile, parce qu'elle est dans le rail, dans la
   barre du bas et dans les onglets de chaque écran). Le jeton qui
   convient existait déjà et le disait : `--orange-ink`, « encre orange
   assombrie, >= 4,5:1 », posé le jour où l'on a constaté que l'orange
   vif ne peut pas porter du blanc. Il rend ici 5,64:1.
   LE POINT SANS CHIFFRE GARDE L'ORANGE VIF : il ne porte pas de texte,
   il n'a donc rien à contraster, et c'est lui qui fait la couleur de
   l'alerte dans l'interface. Le nombre, lui, doit se lire.
   NEUF VIRGULE CINQ PIXELS EST UNE TAILLE DE NOTE DE BAS DE PAGE, pas
   de compteur qu'on lit d'un coup d'oeil : douze, le plancher qu'on se
   donne partout ailleurs, et la pastille grandit de quatre pixels pour
   l'accueillir. */
.sb-dot.is-n {
    width: auto; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--orange-ink);
    font-size: 12px; font-weight: 800; color: #fff; font-variant-numeric: tabular-nums;
}
.rail-item .sb-dot { position: absolute; top: 7px; right: 13px; }

/* Barre de commande : posée sur le chrome (bleu en Azur, ciel en Horizon),
   compacte : les experts y vivent toute la journée. */
.cmd { display: flex; align-items: center; gap: 9px; padding: 7px 16px 7px 12px; }
.cmd :focus-visible { outline-color: #fff; }
html[data-chrome="c"] .cmd :focus-visible { outline-color: var(--blue); }

/* ---------- Bascule de portée (plateforme Admin) ----------
   Segmenté collé à la recherche : « Omniscient » (tout le parc, fonctions
   CRM internes) contre « Cabinet » (ce que voit le cabinet sélectionné).
   Piste SOMBRE et non blanche : un voile blanc sur le bleu de marque fait
   tomber le libellé sous 4.5:1 ; ici le texte blanc garde 6:1 et plus. */
.cmd-scope {
    display: inline-flex; gap: 2px; flex-shrink: 0; padding: 3px;
    background: rgba(0, 0, 0, .16); border-radius: var(--radius-pill);
}
.cmd-scope-b {
    display: inline-flex; align-items: center; gap: 6px; position: relative;
    min-height: 30px; padding: 0 12px; border: none; border-radius: var(--radius-pill);
    background: none; font: inherit; font-size: 12.5px; font-weight: 800;
    color: #fff; cursor: pointer; white-space: nowrap;
    transition: background .15s, color .15s;
}
/* 30 px visuels + 7 px de débord = 44 px de cible tactile */
.cmd-scope-b::after { content: ''; position: absolute; inset: -7px -2px; }
.cmd-scope-b svg { flex-shrink: 0; }
.cmd-scope-b:hover { background: rgba(0, 0, 0, .18); }
.cmd-scope-b[aria-pressed="true"] { background: var(--surface); color: var(--blue-dark); box-shadow: 0 1px 3px rgba(9, 30, 66, .22); }
.cmd-scope-b[aria-pressed="true"]:hover { background: var(--surface); }
html[data-chrome="c"] .cmd-scope { background: rgba(0, 109, 236, .12); }
html[data-chrome="c"] .cmd-scope-b { color: var(--blue-dark); }
html[data-chrome="c"] .cmd-scope-b:hover { background: rgba(0, 109, 236, .1); }
html[data-chrome="c"] .cmd-scope-b[aria-pressed="true"]:hover { background: var(--surface); }
@media (max-width: 1180px) { .cmd-scope-b span { display: none; } .cmd-scope-b { padding: 0 10px; } }

/* Bascule de cabinet : elle ne vaut que dans la portée « cabinet ».
   En omniscient on est au-dessus du parc, il n'y a pas de cabinet actif. */
.cmd-cab-dd { display: none; position: relative; }
body.is-cabscope .cmd-cab-dd { display: block; }
.cmd-cab { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 12px; max-width: 230px; border: none; border-radius: var(--radius-pill); background: rgba(255, 255, 255, .16); color: #fff; font: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer; transition: background .15s; }
.cmd-cab:hover { background: rgba(255, 255, 255, .28); }
.cmd-cab svg { flex-shrink: 0; }
.cmd-cab-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Sous 720 px la bascule et la recherche se partagent une ligne, et seule
   la recherche est en flex: 1 : c'est elle qui encaissait tout le
   rétrécissement. La bascule cède d'abord son libellé. */
@media (max-width: 720px) { .cmd-cab-n { display: none; } .cmd-cab { padding: 0 9px; } }

/* ---------- Modale « Basculer de cabinet » (vue admin) ---------- */
.cabm { position: fixed; inset: 0; z-index: 95; background: rgba(10, 30, 60, .45); display: flex; align-items: flex-start; justify-content: center; padding: 9dvh 20px 20px; }
.cabm[hidden] { display: none; }
.cabm-panel { width: min(480px, 100%); max-height: 78dvh; display: flex; flex-direction: column; background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-lg); padding: 18px 18px 10px; }
@media (prefers-reduced-motion: no-preference) { .cabm:not([hidden]) .cabm-panel { animation: cabm-in .26s cubic-bezier(.22, 1, .36, 1) both; } @keyframes cabm-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } } }
.cabm-h { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 13px; }
.cabm-h h2 { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 800; font-size: 17px; color: var(--text-primary); }
.cabm-h p { margin-top: 2px; font-size: 12px; color: var(--text-secondary); line-height: 1.45; }
.cabm-x { margin-left: auto; flex-shrink: 0; width: 34px; height: 34px; border: none; border-radius: 10px; background: none; color: var(--text-muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background .15s, color .15s; }
.cabm-x:hover { background: var(--gray-100); color: var(--text-primary); }
.cabm-x:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.cabm-q { width: 100%; box-sizing: border-box; min-height: 44px; padding: 10px 15px; border: 1.5px solid var(--gray-300); border-radius: 12px; font: inherit; font-size: 14px; color: var(--text-primary); background: var(--surface); }
.cabm-q:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
.cabm-count { padding: 8px 4px 6px; font-size: 11px; font-weight: 700; color: var(--text-muted); }
.cabm-list { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin; display: flex; flex-direction: column; gap: 2px; padding-bottom: 8px; }
.cabm-it { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 11px; border: none; background: none; border-radius: 10px; cursor: pointer; text-align: left; font: inherit; transition: background .13s; }
.cabm-it:hover { background: var(--gray-100); }
.cabm-it:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.cabm-it[aria-selected="true"] { background: var(--blue-pale); color: var(--blue-dark); }
.cabm-it-tx { flex: 1; min-width: 0; }
.cabm-it-tx b { display: block; font-size: 13px; font-weight: 800; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cabm-it[aria-selected="true"] .cabm-it-tx b { color: var(--blue-dark); }
.cabm-it-tx span { display: block; font-size: 11px; color: var(--text-secondary); }
.cabm-it svg { flex-shrink: 0; color: var(--blue); }
.cabm-empty { padding: 22px 10px; text-align: center; font-size: 12.5px; color: var(--text-muted); }
html[data-chrome="c"] .cmd-cab { background: var(--surface); color: var(--blue-dark); border: 1.5px solid rgba(0, 109, 236, .3); }
html[data-chrome="c"] .cmd-cab:hover { border-color: var(--blue); background: var(--blue-pale); }
.cmd-cab-panel { min-width: 270px; }
.cmd-cab-h { padding: 6px 10px 8px; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.cmd-cab-it { min-width: 0; flex: 1; }
.cmd-cab-it b { display: block; font-size: 13px; font-weight: 800; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-cab-it span { display: block; font-size: 11px; color: var(--text-muted); }
.cmd-cab-panel .dd-item[aria-checked="true"] { background: var(--blue-pale); }

/* Raccourci « menu » dans l'autocomplete : même calibre que l'avatar
   des lignes clients (32px), icône ramenée à 17px pour respirer */
.cmd-ac-mi { width: 32px; height: 32px; flex-shrink: 0; border-radius: 10px; background: var(--blue-pale); color: var(--blue-dark); display: inline-flex; align-items: center; justify-content: center; }
.cmd-ac-mi svg { width: 17px; height: 17px; }
/* Ajouter un client : bouton « + » accolé à la recherche */
.cmd-plus {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 38px; height: 38px; border: none; border-radius: 50%; background: var(--surface);
    color: var(--blue-dark); cursor: pointer; box-shadow: var(--shadow-sm);
    transition: background .15s, transform .16s cubic-bezier(.22, 1, .36, 1);
}
.cmd-plus:hover { background: var(--blue-pale); }
.cmd-plus:active { transform: scale(.94); }
html[data-chrome="c"] .cmd-plus { background: var(--blue); color: #fff; }
html[data-chrome="c"] .cmd-plus:hover { background: var(--blue-dark); }
/* Recherche globale + autocomplete clients */
.cmd-box { position: relative; flex: 1; max-width: 430px; }
.cmd-search {
    width: 100%; height: 38px; padding: 0 16px 0 40px;
    border: none; border-radius: var(--radius-pill);
    font: inherit; font-size: 13px; color: var(--text-primary); background: var(--surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%236E7A8E' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath stroke-linecap='round' d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: 14px center;
}
.cmd-search:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
html[data-chrome="c"] .cmd-search { box-shadow: var(--shadow-sm); }
html[data-chrome="c"] .cmd-search:focus-visible { outline-color: var(--blue); outline-offset: 1px; }
.cmd-ac {
    position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 60;
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: 14px;
    box-shadow: var(--shadow-lg); overflow: hidden; display: none; padding: 6px;
}
.cmd-ac.is-open { display: block; }
.cmd-ac-h {
    padding: 8px 12px 4px; font-size: 10px; font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-muted);
}
.cmd-ac-b {
    display: flex; align-items: center; gap: 10px; width: 100%; min-height: 46px; padding: 5px 10px;
    border: none; background: none; border-radius: 10px; cursor: pointer; text-align: left; font: inherit;
}
.cmd-ac-b:hover, .cmd-ac-b.is-act { background: var(--blue-pale); }
/* La ligne de description est scopée au bloc texte : un `span` nu ici
   écraserait l'avatar et la pastille de menu (fuite de sélecteur) */
.cmd-ac-b .avatar { width: 32px; height: 32px; font-size: 11px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.cmd-ac-b b { display: block; font-size: 13px; color: var(--text-primary); line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-ac-b > div > span { display: block; font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-ac-empty { padding: 12px; font-size: 12.5px; color: var(--text-secondary); }
/* CTA d'en-tête : pilule blanche nue, l'élégance par la retenue. Plus aucun contour :
   l'orange est un micro-accent (flèche, fin soulignement qui se trace au survol). */
/* LA PILULE D'ACTION DE L'EN-TÊTE (2026-08-20 : mise au gabarit).
   Elle faisait 40 px de haut et 20 px de gouttière là où la bascule
   Production / Commercial voisine en fait 36 : une pilule plus grosse
   que ses voisines au même rang lisait comme un accident, pas comme
   une hiérarchie. Elle prend donc la même hauteur, et garde sa
   surface pleine, qui suffit à dire qu'elle est le geste principal. */
.cmd-cta {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 36px; padding: 0 15px; border: none; border-radius: var(--radius-pill);
    background: var(--surface); color: var(--text-primary); font: inherit; font-size: 12.5px; font-weight: 800;
    cursor: pointer; flex-shrink: 0; box-shadow: 0 1px 2px rgba(9, 30, 66, .22);
    transition: box-shadow .2s, transform .16s cubic-bezier(.22, 1, .36, 1);
}
.cmd-cta:hover { box-shadow: 0 3px 10px rgba(9, 30, 66, .26); }
.cmd-cta:active { transform: scale(.97); }
.cmd-cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
html[data-chrome="c"] .cmd-cta { border: 1px solid var(--gray-200); box-shadow: var(--shadow-sm); }
html[data-chrome="c"] .cmd-cta:focus-visible { outline-color: var(--blue); }
/* PAS DE SOULIGNEMENT (2026-08-20). Un trait orange glissait sous le
   libellé au survol : il n'appartenait à aucune grammaire du produit
   (rien d'autre ne se souligne), il imitait un lien là où c'est un
   bouton, et il déplaçait l'oeil vers le bas alors que le geste est
   dans le bouton. Le survol se dit par l'ombre, comme partout. */
.cmd-cta .cmd-cta-arr { color: var(--orange); transition: transform .28s cubic-bezier(.22, 1, .36, 1); }
.cmd-cta:hover .cmd-cta-arr { transform: translateX(3px); }
.cmd-cta .cmd-cta-ico { display: none; }
/* ============================================================
   « ANNONCER UN DEAL » PORTE SON COTILLON (2026-08-19)
   ------------------------------------------------------------
   Les deux autres pilules du header cachent leur icône au-dessus de
   980 px : leur libellé suffit, et la ligne est encombrée. Celle-ci la
   GARDE, parce qu'elle est le seul geste festif d'une barre d'outils,
   et qu'un bouton qui déclenche une fête doit se reconnaître avant
   d'être lu. L'orange est déjà l'accent de ces pilules (le filet sous
   le libellé, la flèche) : le cotillon le reprend, il n'invente aucune
   couleur.
   ============================================================ */
/* Les deux pilules de victoire (vente et aide obtenue) portent leur
   dessin plutôt qu'une flèche : ce n'est pas une navigation. */
.cmd-cta.cmd-deal .cmd-cta-ico { display: block; color: var(--orange); }
.cmd-cta.cmd-deal .cmd-cta-arr { display: none; }
/* Le cotillon part en biais au survol, comme s'il venait d'éclater.
   Deux degrés et deux pixels : l'intention se lit, le bouton ne saute
   pas sous le curseur. */
@media (prefers-reduced-motion: no-preference) {
    .cmd-deal-ico { transition: transform .28s cubic-bezier(.34, 1.56, .64, 1); transform-origin: 20% 80%; }
    .cmd-cta.cmd-deal:hover .cmd-deal-ico { transform: rotate(-12deg) translate(-1px, -2px); }
    /* La bouteille de la production tangue au survol, comme elle
       tanguera sur l'eau de la carte. */
    .cmd-aide-ico { transition: transform .3s cubic-bezier(.34, 1.56, .64, 1); transform-origin: 50% 90%; }
    .cmd-cta.cmd-deal:hover .cmd-aide-ico { transform: rotate(9deg) translateY(-2px); }
}
.cmd-right { margin-left: auto; display: flex; align-items: center; gap: 9px; }
/* Menu « plus d'actions » : équipe MAPi, landing page, bande passante */
.cmd-more {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 38px; height: 38px; border: 1.5px solid rgba(255, 255, 255, .45); border-radius: 50%;
    background: rgba(255, 255, 255, .1); color: #fff; cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
.cmd-more:hover { border-color: #fff; background: rgba(255, 255, 255, .2); }
html[data-chrome="c"] .cmd-more { border-color: var(--gray-300); background: var(--surface); color: var(--text-secondary); }
html[data-chrome="c"] .cmd-more:hover { border-color: var(--blue); background: var(--blue-pale); color: var(--blue-dark); }
.cmd-more-panel { min-width: 264px; }

/* Compte : avatar unique + sous-menu cabinet/utilisateur */
.cmd-usr { border: none; background: none; padding: 0; cursor: pointer; border-radius: 50%; display: inline-flex; }
.cmd-usr .avatar--ml { width: 36px; height: 36px; font-size: 12px; background: var(--surface); color: var(--blue-dark); transition: background .15s; }
.cmd-usr:hover .avatar--ml { background: var(--blue-pale); }
@media (max-width: 980px) {
    .cmd-cta span, .cmd-cta .cmd-cta-arr { display: none; }
    .cmd-cta .cmd-cta-ico { display: block; color: var(--orange); }
    .cmd-cta { width: 40px; padding: 0; }
    /* Réduite à son icône, la pilule d'annonce garde son nom pour qui
       ne voit pas le dessin : le titre et l'aria-label sont posés dans
       js/shell.js, il n'y a rien à ajouter ici. */
}
.usr-panel { min-width: 268px; max-height: min(78dvh, 580px); overflow: auto; padding: 10px 8px; }
.usr-h { display: flex; align-items: center; gap: 11px; padding: 8px 10px 7px; }
.usr-h b { display: block; font-size: 14px; font-weight: 800; color: var(--text-primary); line-height: 1.25; }
/* Le sous-titre est scopé au bloc texte : un `span` nu écraserait
   l'avatar et le logo (même fuite que l'autocomplete du header) */
.usr-h > div > span { display: block; font-size: 11.5px; color: var(--text-secondary); }
.usr-h .avatar { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.usr-logo {
    width: 36px; height: 36px; border-radius: 50%; background: var(--blue-pale); flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
}
.usr-logo img { width: 22px; height: 22px; object-fit: contain; }
.usr-sep { height: 1px; background: var(--gray-200); margin: 7px 6px; }
.usr-panel .dd-item svg { color: var(--text-secondary); }
.usr-panel .usr-out, .usr-panel .usr-out svg { color: var(--danger-ink); }
.usr-panel .usr-out:hover { background: var(--orange-soft); }

/* ---------- En-tête de page ---------- */
/* En-tête de page compact : titre 22px, actions ferrées à droite sur la même ligne */
.pgh { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
.pgh-obj { width: 44px; height: 44px; object-fit: contain; filter: drop-shadow(0 6px 10px rgba(0, 60, 130, .18)); }
.pgh h1 {
    font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900;
    font-size: 22px; letter-spacing: -.02em; color: var(--text-primary);
    line-height: 1.1; text-wrap: balance;
}
.pgh-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ---------- Boutons ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 44px; padding: 0 20px; border-radius: var(--radius-pill); border: none;
    font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; text-decoration: none;
    transition: transform .16s cubic-bezier(.22, 1, .36, 1), box-shadow .16s, background .16s, border-color .16s;
}
.btn:active { transform: scale(.97); }
.btn--primary { background: var(--blue); color: #fff; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--blue-dark); box-shadow: var(--shadow-md); }
.btn--ghost { background: var(--surface); color: var(--blue-dark); border: 1.5px solid var(--gray-300); }
.btn--ghost:hover { border-color: var(--blue); background: var(--blue-pale); }
.btn--soft { background: var(--blue-pale); color: var(--blue-dark); }
.btn--soft:hover { background: var(--blue-muted); }
.btn--orange { background: var(--orange); color: #4A2408; }
.btn--orange:hover { background: #FF8438; }
.btn--sm { min-height: 36px; padding: 0 14px; font-size: 12.5px; }
.btn[disabled] { opacity: .5; cursor: default; pointer-events: none; }

/* ---------- Badges & chips ---------- */
.badge {
    display: inline-flex; align-items: center; gap: 5px; min-height: 22px; padding: 1px 10px;
    border-radius: var(--radius-pill); font-size: 11px; font-weight: 800; white-space: nowrap;
}
.badge--green { background: var(--green-soft); color: var(--green-ink); }
.badge--orange { background: var(--orange-soft); color: var(--orange-ink); }
.badge--blue { background: var(--blue-pale); color: var(--blue-dark); }
.badge--gray { background: var(--gray-200); color: var(--text-secondary); }
.chip {
    display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 13px;
    border-radius: var(--radius-pill); border: 1.5px solid var(--gray-300); background: var(--surface);
    font-size: 12.5px; font-weight: 700; color: var(--text-secondary); cursor: pointer;
    transition: border-color .15s, background .15s, color .15s;
}
.chip:hover { border-color: var(--blue); color: var(--blue-dark); }
.chip[aria-pressed="true"] { border-color: var(--blue); background: var(--blue-pale); color: var(--blue-dark); }

/* ---------- Cartes & KPI ---------- */
.card {
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); padding: 20px;
}
.card-t {
    font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 800; font-size: 16.5px;
    color: var(--text-primary); display: flex; align-items: center; gap: 9px; margin-bottom: 12px;
}
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.kpi { position: relative; overflow: hidden; }
.kpi .kpi-l { font-size: 12.5px; font-weight: 800; color: var(--text-secondary); display: flex; align-items: center; gap: 7px; }
.kpi .kpi-n {
    font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 34px;
    letter-spacing: -.02em; line-height: 1.15; color: var(--text-primary);
}
.kpi .kpi-s { font-size: 12px; color: var(--text-secondary); }
.kpi--blue { background: linear-gradient(135deg, #0053BE, #2E8AF0); border: none; }
.kpi--blue .kpi-l, .kpi--blue .kpi-n { color: #fff; }
.kpi--blue .kpi-s { color: #D4EAFF; }

/* ---------- Tableau ---------- */
.tbl { width: 100%; border-collapse: collapse; background: var(--surface); }
.tbl th {
    text-align: left; font-size: 11px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-secondary); padding: 12px 14px; border-bottom: 1.5px solid var(--gray-200);
    white-space: nowrap; background: var(--surface);
}
.tbl td { padding: 13px 14px; border-bottom: 1px solid var(--gray-200); font-size: 13.5px; vertical-align: middle; }
.tbl tbody tr { transition: background .12s; }
.tbl tbody tr:hover { background: var(--blue-pale); }
.tbl-wrap { border: 1px solid var(--gray-200); border-radius: var(--radius); overflow: auto; background: var(--surface); box-shadow: var(--shadow-sm); }
.tbl-wrap .tbl th { position: sticky; top: 0; z-index: 2; }
/* SUR TÉLÉPHONE, LA TABLE NE S'ÉCRASE PLUS : ELLE DÉFILE (2026-08-14).
   Forcée dans 358 px, elle broyait ses colonnes et cassait les titres
   en plein mot, un mot par ligne. `min-width: max-content` rend à
   chaque colonne sa largeur de contenu et c'est le CADRE qui défile
   latéralement ; `max-width` borne les cellules bavardes (un objet de
   mail, une description) à l'écran moins les gouttières, avec des
   points de suspension au-delà. Vaut d'un coup pour TOUTES les tables
   de l'app : CRM, Tâches, les deux pipes, partout où .tbl passe. */
@media (max-width: 720px) {
    .tbl { min-width: max-content; }
    .tbl th, .tbl td { white-space: nowrap; }
    .tbl td { max-width: 68vw; overflow: hidden; text-overflow: ellipsis; }
    .tbl th, .tbl td { padding: 11px 12px; }
}

/* ---------- Onglets ---------- */
/* PAS D'ASCENSEUR DANS UNE RANGÉE D'ONGLETS (2026-08-05).
   `overflow-x: auto` entraîne `overflow-y: auto` : l'onglet actif déborde
   de 1,5 px vers le bas (son `margin-bottom: -1.5px`, qui fait mordre son
   liseré sur le filet), et le navigateur ajoutait une barre de défilement
   VERTICALE dans la rangée. Une rangée d'onglets ne défile pas en hauteur ;
   et en largeur, c'est l'onglet coupé qui dit qu'il y a une suite, pas une
   barre grise sous des titres. */
.tabs {
    display: flex; gap: 4px; overflow-x: auto; overflow-y: hidden;
    border-bottom: 1.5px solid var(--gray-200); scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
    flex-shrink: 0; display: inline-flex; align-items: center; gap: 8px; min-height: 46px;
    border: none; background: none; cursor: pointer; padding: 0 16px;
    font-size: 14px; font-weight: 700; color: var(--text-secondary);
    border-bottom: 2.5px solid transparent; margin-bottom: -1.5px; transition: color .15s;
}
.tab:hover { color: var(--text-primary); }
.tab[aria-selected="true"] { color: var(--blue); border-bottom-color: var(--blue); }

/* ---------- Interrupteur (switch) ---------- */
.sw { position: relative; display: inline-flex; align-items: center; flex-shrink: 0; cursor: pointer; }
.sw input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.sw .sw-track {
    width: 44px; height: 24px; border-radius: var(--radius-pill); background: var(--gray-300);
    transition: background .18s; position: relative; pointer-events: none;
}
.sw .sw-track::after {
    content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
    border-radius: 50%; background: var(--surface); box-shadow: 0 1px 3px rgba(9, 30, 66, .3);
    transition: transform .18s cubic-bezier(.22, 1, .36, 1);
}
.sw input:checked + .sw-track { background: var(--blue); }
.sw input:checked + .sw-track::after { transform: translateX(20px); }
.sw input:focus-visible + .sw-track { outline: 2px solid var(--blue); outline-offset: 2px; }
.sw::after { content: ''; position: absolute; inset: -10px; }

/* ---------- Avatars ---------- */
.avatar {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 36px; height: 36px; border-radius: 50%; background: var(--blue-pale);
    color: var(--blue-dark); font-size: 12.5px; font-weight: 800;
}
.avatar--sm { width: 28px; height: 28px; font-size: 10.5px; }
.avatar--orange { background: var(--orange-soft); color: var(--orange-ink); }
.avatar--green { background: var(--green-soft); color: var(--green-ink); }
.avatar--ml { background: linear-gradient(135deg, #0053BE, #2E8AF0); color: #fff; }

/* ---------- Score officiel : 5 étoiles (copie produit) ---------- */
@media (prefers-reduced-motion: no-preference) {
}
 100% { transform: scale(1); opacity: 1; } }
.stars-inline .pearl-rating { flex-direction: row; gap: 8px; }
.stars-inline .pr-star { width: 19px; height: 19px; }
.stars-inline .pr-stars { gap: 3px; padding: 0; }
.stars-inline .pr-num b { font-size: 16px; }
.stars-inline .pr-num .sep { font-size: 12px; }
.stars-inline .pr-num i { font-size: 12px; }

/* ---------- États vides ---------- */
.empty { text-align: center; padding: 44px 20px; }
.empty img { width: 110px; height: auto; margin-bottom: 12px; filter: drop-shadow(0 10px 16px rgba(0, 60, 130, .16)); }
.empty h3 { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 800; font-size: 17px; color: var(--text-primary); margin-bottom: 5px; }
.empty p { font-size: 13.5px; color: var(--text-secondary); max-width: 46ch; margin: 0 auto 16px; }

/* ---------- Dropdown générique ---------- */
.dd { position: relative; }
.dd-panel {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; min-width: 220px;
    background: var(--surface); border: 1px solid var(--gray-200); border-radius: 14px;
    box-shadow: var(--shadow-lg); padding: 8px; display: none;
}
.dd.is-open .dd-panel { display: block; }
.dd-item {
    display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 0 12px;
    border: none; background: none; border-radius: 10px; cursor: pointer; text-align: left;
    font-size: 13.5px; font-weight: 600; color: var(--text-primary); text-decoration: none;
}
.dd-item:hover { background: var(--gray-100); }

/* ---------- Modale / drawer génériques ---------- */
.ovl {
    position: fixed; inset: 0; z-index: 95; display: none;
    background: rgba(9, 30, 66, .42); backdrop-filter: blur(3px);
}
.ovl.is-open { display: flex; align-items: center; justify-content: center; padding: 20px; }
.ovl-panel {
    background: var(--surface); border-radius: 20px; box-shadow: var(--shadow-lg);
    width: min(560px, 100%); max-height: min(82dvh, 720px); overflow: auto; padding: 26px;
}
/* Charpente d'une modale : en-tête, corps qui défile, pied d'actions
   toujours visible. Les pages historiques ont chacune leur copie préfixée
   (cmp-ovl-*, cl-ovl-x) ; tout nouvel écran utilise celle-ci. */
.ovl-panel:has(.ovl-body) { display: flex; flex-direction: column; padding: 0; }
/* flex-wrap : le sous-titre porte flex-basis: 100 %, sans retour à la ligne
   il se glissait entre le titre et la croix au lieu de passer dessous */
.ovl-h { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; padding: 24px 26px 14px; }
.ovl-h h2 { flex: 1; min-width: 0; font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 20px; color: var(--text-primary); }
.ovl-h p { flex-basis: 100%; font-size: 13px; color: var(--text-secondary); }
.ovl-x {
    width: 36px; height: 36px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
    border: 1.5px solid var(--gray-300); border-radius: 50%; background: var(--surface);
    color: var(--text-secondary); cursor: pointer;
}
.ovl-x:hover { border-color: var(--blue); background: var(--blue-pale); color: var(--blue-dark); }
.ovl-body { flex: 1; min-height: 0; overflow: auto; padding: 0 26px 4px; }
.ovl-foot { display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; padding: 16px 26px 22px; }
@media (prefers-reduced-motion: no-preference) {
    .ovl.is-open .ovl-panel { animation: ovl-in .34s cubic-bezier(.22, 1, .36, 1) both; }
    @keyframes ovl-in { from { opacity: 0; transform: translateY(14px) scale(.98); } to { opacity: 1; transform: none; } }
}

/* ---------- Bascule de version A/B ---------- */
.vswitch {
    /* En bas à GAUCHE (dégagé du rail) : le coin bas-droit appartient au dock messagerie */
    position: fixed; left: 90px; bottom: 14px; z-index: 80;
    display: flex; gap: 3px; padding: 4px; border-radius: var(--radius-pill);
    background: var(--surface); border: 1px solid var(--gray-200); box-shadow: var(--shadow-lg);
}
.vsw-b {
    border: none; background: none; cursor: pointer; min-height: 38px; padding: 0 16px;
    border-radius: var(--radius-pill); font: inherit; font-size: 12.5px; font-weight: 800;
    color: var(--text-secondary); transition: background .15s, color .15s;
}
.vsw-b[aria-pressed="true"] { background: var(--blue); color: #fff; }
.vsw-b:not([aria-pressed="true"]):hover { background: var(--gray-100); color: var(--text-primary); }

/* ---------- Focus & accessibilité ---------- */
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.sb :focus-visible, .kpi--blue :focus-visible { outline-color: #fff; }

/* ============================================================
   Chrome D · Sombre : les jetons vivent dans tokens.css
   (html[data-chrome="d"]) ; ici, uniquement ce que les jetons ne
   couvrent pas : le rail et la barre de commande posés sur un bleu
   nuit plus profond que le fond de page, et les couleurs figées en
   dur qui doivent s'adapter.
   ============================================================ */
/* Rail : l'onglet actif devient une pastille bleu nuit à l'encre claire
   (une pastille blanche pleine serait éblouissante sur le fond nuit) */
html[data-chrome="d"] .rail-item[aria-current="page"] { background: var(--blue-muted); color: #CBE2FF; }
html[data-chrome="d"] .rail-min { border-color: rgba(255, 255, 255, .32); }
/* Barre de commande : les pilules blanches sont devenues des surfaces
   sombres (jeton --surface) ; un liseré les détache du chrome nuit */
html[data-chrome="d"] .cmd-search { border: 1px solid var(--gray-200); }
html[data-chrome="d"] .cmd-search::placeholder { color: var(--text-muted); }
html[data-chrome="d"] .cmd-cta { border: 1px solid var(--gray-200); box-shadow: none; }
html[data-chrome="d"] .cmd-plus { border: 1px solid var(--gray-200); box-shadow: none; }
html[data-chrome="d"] .cmd-plus:hover { background: var(--blue-pale); }
/* En sombre, --blue-dark est une encre claire : les fonds « bleu foncé »
   au survol reprennent l'hex d'origine du bleu profond de marque */
html[data-chrome="d"] .btn--primary:hover { background: #0055BB; }
/* Onglets et kickers : l'encre bleue claire remplace le bleu de marque,
   trop sombre pour rester lisible sur les fonds nuit */
html[data-chrome="d"] .tab[aria-selected="true"] { color: var(--blue-dark); border-bottom-color: var(--blue-dark); }
html[data-chrome="d"] .jdw-kicker { color: var(--blue-dark); }
html[data-chrome="d"] :focus-visible { outline-color: var(--blue-dark); }
/* Étoiles éteintes, voiles, tags aux hex figés */
html[data-chrome="d"] .pr-star.off svg, html[data-chrome="d"] .pr-star.half svg:not(.pr-half) { fill: #35435C; }
html[data-chrome="d"] .ovl { background: rgba(2, 8, 18, .62); }
html[data-chrome="d"] .cabm { background: rgba(2, 8, 18, .62); }
html[data-chrome="d"] .jdw-backdrop { background: rgba(2, 8, 18, .55); }
html[data-chrome="d"] .jdw { box-shadow: -12px 0 40px rgba(0, 0, 0, .5); }
html[data-chrome="d"] .tl-tag--phase.tl-tag--production { background: var(--blue-muted); color: var(--blue-dark); }
html[data-chrome="d"] .tl-node--production { border-color: #2F4A70; }

/* ---------- Responsive ---------- */
/* Navbar mobile : fixée en bas, 5 entrées essentielles (rendue par shell.js) */
.mnav { display: none; }
@media (max-width: 960px) {
    /* LA COQUE GRANDIT AVEC SON CONTENU (2026-08-19). Couchée en colonne,
       elle gardait `height: 100dvh` : .maincol, qui n'a pas de
       `min-height: 0`, ne pouvait pas descendre sous son contenu et
       débordait donc de la coque au lieu de l'étirer. La boîte de <html>
       restait haute d'une fenêtre pendant que la page en faisait trois, ce
       qui est exactement la condition qui découvrait le fond du canvas
       (voir le calque `no-repeat` en tête de fichier). La hauteur devient
       un MINIMUM : la coque fait au moins la fenêtre, et autant que sa
       page quand celle-ci est plus longue. */
    .app { flex-direction: column; height: auto; min-height: 100dvh; }
    /* Le rail du haut se réduit au logo, au thème et au sélecteur de
       plateforme : la navigation vit dans la navbar du bas, adaptée au pouce */
    .sb { width: 100%; height: auto; flex-direction: row; padding: 8px 10px; overflow-x: auto; overflow-y: hidden; }
    .sb .sb-nav { display: none !important; }
    /* Le pied de rail se couche dans la barre du haut : le sélecteur de
       plateforme reste atteignable, la bascule de largeur n'a plus de sens */
    .sb .rail-foot { flex-direction: row; margin-top: 0; width: auto; }
    .sb .rail-foot .rail-min { display: none; }
    .rail-item { min-height: 48px; }
    /* ============================================================
       LE HEADER TIENT SUR UNE LIGNE (2026-08-03)
       Il en prenait TROIS : le rail couché (logo, thème, plateforme,
       Interne), la barre de commandes (portée, cabinet, vue, rôle, plus,
       compte) et la recherche renvoyée à la ligne. Cent quatre-vingts
       pixels de chrome avant le premier mot de contenu, sur les six cents
       que compte un écran de téléphone.

       Il n'en garde que trois choses, celles qui n'ont pas de substitut
       ailleurs : le LOGO (identité et retour à l'accueil), la RECHERCHE
       (qui est aussi la palette de commandes, donc la porte de secours
       quand la navbar du bas n'a plus de place) et le BURGER. Tout le
       reste descend dans le menu, groupé par ce qu'on vient y faire.

       Le rail couché disparaît entièrement : ses quatre commandes vivent
       désormais dans le menu, et sa navigation était déjà dans la navbar
       du bas. */
    .sb { display: none; }
    .cmd { padding: 8px 10px; flex-wrap: nowrap; gap: 8px; }
    .cmd-logo img { max-width: 62px; }
    .cmd-box { flex: 1 1 auto; min-width: 0; max-width: none; order: 0; }
    /* Ce qui descend dans le menu est masqué à la toute fin du fichier :
       plusieurs de ces classes ont une règle de base DÉCLARÉE PLUS BAS
       (.cmd-plt par exemple), qui gagnerait ici à spécificité égale. */
    .cmd-right { gap: 6px; }
    .cmd-add span { display: none; }
    .cmd-add { min-width: 42px; justify-content: center; padding: 0; }
    .frame { border-radius: 16px 16px 0 0; }
    /* `--una-cale` vaut zéro tant qu'aucun rappel de réunion n'est
       affiché ; la cloche la renseigne quand elle paraît (voir
       components.css), et la page descend d'autant au lieu de se
       laisser recouvrir. */
    /* LA RÉSERVE VAUT L'EMPREINTE DE LA BARRE, PLUS UN PEU D'AIR.
       Elle valait 132 px pour une barre de 59 : soixante-treize pixels
       de vide au bout de chaque page, sur les treize écrans. Le compte
       se lit maintenant : la hauteur de la barre, le retrait qui la
       décolle du bas, et seize pixels pour que la dernière rangée ne
       soit pas collée dessous. Le contenu, lui, passe SOUS le verre
       pendant tout le défilement : c'est ce que le flou est là pour
       montrer. */
    :root { --mnav-h: 60px; --mnav-bas: max(10px, env(safe-area-inset-bottom)); }
    main.page { padding: calc(18px + var(--una-cale, 0px)) 16px calc(var(--mnav-h) + var(--mnav-bas) + 16px); }
    /* Sans rail ni navbar mobile, le Partenaire ne réserve rien */
    html[data-app="partenaire"] main.page { padding-bottom: 40px; }
    /* ============================================================
       LA BARRE FLOTTE (2026-08-13)
       ------------------------------------------------------------
       Elle touchait les trois bords, opaque, avec un liseré en tête :
       une plinthe. Le contenu s'arrêtait dessus et les 132 px de
       réserve ouvraient un vide au bout de chaque page.

       Elle se détache maintenant des bords et devient une pilule de
       verre : le contenu la traverse en défilant, on voit passer
       dessous ce qu'on vient de lire, et l'on sait qu'il en reste. Un
       fond translucide ne suffit pas à cela, il faut le FLOU : sans
       lui, du texte gris sous du blanc à 72 % reste lisible et vient
       se mêler aux libellés. Le repli est donc franc, jamais dégradé :
       là où le flou n'existe pas, le fond redevient opaque.

       LES ÉCRANS À CARTE MESURÉE NE PASSENT PAS DESSOUS, et c'est
       délibéré : leur champ de saisie et leur bouton « Envoyer » sont
       au bas de la carte ; sous une barre, même translucide, ils
       seraient inatteignables. Ils se calent sur le BORD HAUT de la
       barre, que `window.__mnavHaut()` (js/shell.js) donne aux quatre
       écrans qui en ont besoin.
       ============================================================ */
    /* LE VERRE LIQUIDE (2026-08-14). Quatre couches, et chacune a un
       rôle : une translucidité plus franche (58 % de surface au lieu
       de 72, c'est le fond qui fait le verre), une SATURATION poussée
       du décor traversé (200 %, la signature du matériau : les
       couleurs de la page brillent à travers), un GLACIS qui descend
       du bord haut (le reflet de la lumière sur le bombé), et deux
       liserés spéculaires en ombre interne : le fil blanc du bord
       éclairé en haut, le demi-pixel d'épaisseur tout autour. PAS de
       réfraction par filtre SVG (backdrop-filter: url()) : Chrome seul
       la rend, et sur le Safari du téléphone la déclaration risquait
       d'emporter le flou avec elle, c'est-à-dire la lisibilité. */
    .mnav {
        position: fixed; z-index: 70;
        left: max(12px, calc(env(safe-area-inset-left) + 10px));
        right: max(12px, calc(env(safe-area-inset-right) + 10px));
        bottom: var(--mnav-bas);
        display: flex; gap: 2px; padding: 4px 6px;
        border: 1px solid color-mix(in srgb, var(--text-primary) 10%, transparent);
        border-radius: var(--radius-pill);
        background:
            linear-gradient(to bottom, color-mix(in srgb, #fff 36%, transparent), color-mix(in srgb, #fff 3%, transparent) 58%),
            color-mix(in srgb, var(--surface) 58%, transparent);
        backdrop-filter: blur(28px) saturate(200%);
        -webkit-backdrop-filter: blur(28px) saturate(200%);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, .65),
            inset 0 0 0 .5px rgba(255, 255, 255, .28),
            inset 0 -1px 0 rgba(9, 30, 66, .05),
            0 10px 30px rgba(9, 30, 66, .18), 0 2px 8px rgba(9, 30, 66, .08);
    }
    @supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
        .mnav, .mnav-bulle { background: var(--surface); }
    }
    /* LE LIBELLÉ PASSE DE 10 À 12 px, et c'est la correction la plus
       rentable de toute la passe mobile : cette barre est la SEULE
       navigation sous 960 px, elle est sur les treize écrans, et ses
       six mots étaient écrits plus petit que n'importe quelle mention
       légale du produit. Douze pixels est le plancher qu'on se donne
       partout ailleurs ; il n'y avait pas de raison que la chose qu'on
       touche le plus soit la seule à y échapper.
       La rangée ne grandit pas d'un pixel : elle est tenue par ses
       50 px de hauteur minimale, et l'icône de 20 px plus deux lignes
       de texte de 12 y tiennent. */
    .mnav-i {
        position: relative; flex: 1; min-width: 0; min-height: 50px;
        display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
        /* Le rayon de l'entrée suit celui de la pilule : un coin de 10
           dans un contenant tout rond se voit, surtout aux extrémités. */
        border-radius: 18px; font-size: 12px; font-weight: 700; line-height: 1.15;
        color: var(--text-secondary); text-decoration: none;
    }
    .mnav-i svg { width: 20px; height: 20px; }
    .mnav-i span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    /* L'entrée courante est une pastille de verre teinté, pas un aplat :
       un caisson opaque au milieu d'une pilule translucide cassait la
       matière. Le bleu pâle garde 76 % de sa densité, la lecture ne
       perd rien. */
    .mnav-i[aria-current="page"] {
        color: var(--blue-dark); font-weight: 800;
        background: color-mix(in srgb, var(--blue-pale) 76%, transparent);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 0 0 .5px rgba(255, 255, 255, .22);
    }
    .mnav-i:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
    .mnav-i .sb-dot { position: absolute; top: 6px; right: calc(50% - 16px); }
    /* Les docks flottants remontent au-dessus de la navbar, qui ne
       touche plus le bas : leur pied suit l'empreinte complète. */
    body .dk-root { bottom: calc(var(--mnav-h) + var(--mnav-bas) + 10px); }

    /* ============================================================
       LES DEUX BULLES DE « MESSAGES » (préfixe mnav-pop / mnav-bulle)
       ------------------------------------------------------------
       Le choix entre les deux boîtes se prenait dans le coin haut-droit
       de l'écran, le plus éloigné du pouce. C'est de la NAVIGATION : il
       redescend là où se prennent tous les choix du même rang.

       Deux bulles, et non un menu de deux lignes : elles disent chacune
       ce qu'elles contiennent et ce qui y attend, pour le même
       encombrement. Elles s'ouvrent au-dessus de l'entrée, centrées sur
       elle tant que l'écran le permet, et se rabattent au bord plutôt
       que de déborder.
       ============================================================ */
    .mnav-pop {
        position: fixed; z-index: 71; width: min(320px, calc(100vw - 24px));
        display: flex; flex-direction: column; gap: 8px;
    }
    /* Les bulles sont taillées dans le même verre que la barre qui les
       ouvre : même glacis, même liseré, à peine plus denses parce
       qu'elles portent deux lignes de texte. */
    .mnav-bulle {
        display: flex; align-items: center; gap: 12px; padding: 11px 14px;
        border: 1px solid color-mix(in srgb, var(--text-primary) 10%, transparent);
        border-radius: 16px; color: var(--text-primary);
        background:
            linear-gradient(to bottom, color-mix(in srgb, #fff 30%, transparent), color-mix(in srgb, #fff 3%, transparent) 58%),
            color-mix(in srgb, var(--surface) 64%, transparent);
        backdrop-filter: blur(24px) saturate(190%);
        -webkit-backdrop-filter: blur(24px) saturate(190%);
        text-decoration: none;
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, .6),
            inset 0 0 0 .5px rgba(255, 255, 255, .25),
            0 10px 30px rgba(9, 30, 66, .2);
    }
    .mnav-bulle-ic {
        flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
        width: 40px; height: 40px; border-radius: 13px;
        background: var(--gray-100); color: var(--text-secondary);
    }
    .mnav-bulle.is-on { border-color: var(--blue); }
    .mnav-bulle.is-on .mnav-bulle-ic { background: var(--blue); color: #fff; }
    .mnav-bulle-tx { flex: 1; min-width: 0; }
    .mnav-bulle-tx b { display: block; font-size: 14.5px; font-weight: 800; }
    .mnav-bulle-tx small {
        display: block; font-size: 12px; color: var(--text-secondary);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .mnav-bulle-n {
        flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
        min-width: 22px; height: 22px; padding: 0 7px; border-radius: var(--radius-pill);
        background: var(--blue); color: #fff; font-size: 12px; font-weight: 800;
        font-variant-numeric: tabular-nums;
    }
    .mnav-bulle:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
    .mnav-bulle:active { transform: scale(.98); }
    /* Elles montent l'une après l'autre, du bas vers le haut : la plus
       proche de la barre d'abord, comme si le doigt les soulevait. */
    @media (prefers-reduced-motion: no-preference) {
        .mnav-pop .mnav-bulle {
            animation: mnavBulle .24s cubic-bezier(.22, 1, .36, 1) both;
            animation-delay: calc((1 - var(--i)) * .05s);
        }
        @keyframes mnavBulle { from { opacity: 0; transform: translateY(10px) scale(.96); } to { opacity: 1; transform: none; } }
    }
}
html[data-chrome="d"] .mnav-bulle {
    border-color: color-mix(in srgb, #fff 14%, transparent);
    background:
        linear-gradient(to bottom, rgba(255, 255, 255, .09), rgba(255, 255, 255, .02) 58%),
        color-mix(in srgb, var(--surface) 60%, transparent);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .14),
        inset 0 0 0 .5px rgba(255, 255, 255, .06),
        0 10px 30px rgba(0, 0, 0, .55);
}
/* Sur fond sombre, l'ombre portée disparaît et c'est le liseré clair
   qui détache la pilule : le verre a besoin d'un bord pour exister, et
   le glacis blanc descend à un dixième de sa force du thème clair,
   un reflet de nuit. */
html[data-chrome="d"] .mnav {
    border-color: color-mix(in srgb, #fff 16%, transparent);
    background:
        linear-gradient(to bottom, rgba(255, 255, 255, .10), rgba(255, 255, 255, .02) 58%),
        color-mix(in srgb, var(--surface) 58%, transparent);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .15),
        inset 0 0 0 .5px rgba(255, 255, 255, .07),
        0 10px 30px rgba(0, 0, 0, .5);
}
html[data-chrome="d"] .mnav-i[aria-current="page"] {
    background: color-mix(in srgb, var(--blue-pale) 70%, transparent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
}

/* ============================================================
   LE BANDEAU DE NOTIFICATION (préfixe sh-, js/shell.js)
   ------------------------------------------------------------
   IL ÉTAIT ILLISIBLE EN THÈME SOMBRE. Son habillage vivait en style
   en ligne et prenait `var(--text-primary)` comme FOND, avec du blanc
   dessus : une encre en guise de fond, ce qui suppose qu'elle est
   sombre. Elle l'est en clair (#28323E, 12,9:1) ; en sombre elle
   devient #EAF0F8 et l'on obtenait du blanc sur du blanc, à 1,09:1.

   D'où une PAIRE DE JETONS, et non une couleur empruntée à un autre
   usage : le fond et l'encre du bandeau changent ensemble, et le
   rapport reste au-dessus de 8:1 dans les deux thèmes. En sombre on
   ne bascule pas sur une barre claire (elle éblouirait la nuit) mais
   sur l'ardoise haute du thème, la même matière que le verre de la
   barre de navigation.

   IL PREND TOUTE LA LARGEUR SUR TÉLÉPHONE, et se recentre en pilule
   de 560 px au-delà : une seule règle, deux comportements, `left` et
   `right` posés et `margin-inline: auto` qui centre quand le plafond
   est atteint. Et il se pose AU-DESSUS de la barre flottante, dont il
   lit l'empreinte : il se posait dessus.
   ============================================================ */
:root { --sh-toast-fond: #28323E; --sh-toast-encre: #fff; }
html[data-chrome="d"] { --sh-toast-fond: var(--gray-300); --sh-toast-encre: #fff; }
/* LE VERT DE CONFIRMATION NE SUIT PAS LE THÈME. `--green` (#2DAE54)
   ne porte pas de blanc lisible (2,6:1) ; `--green-ink` le porte
   (5,4:1) mais s'inverse en mode sombre, où il devient une encre
   claire. Ce bandeau est un aplat, pas une surface de l'application :
   il garde son vert profond dans les deux thèmes, comme la carte de
   fête garde ses encres. */
:root { --sh-toast-ok: #1B7A3D; }
.sh-toast {
    position: fixed; z-index: 300;
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    bottom: calc(var(--mnav-h, 0px) + var(--mnav-bas, 0px) + 14px);
    max-width: 560px; margin-inline: auto;
    padding: 13px 18px; border-radius: 14px;
    background: var(--sh-toast-fond); color: var(--sh-toast-encre);
    font-size: 14px; font-weight: 700; line-height: 1.45;
    box-shadow: var(--shadow-lg);
    opacity: 0; transform: translateY(12px); pointer-events: none;
}
.sh-toast.is-on { opacity: 1; transform: none; }
/* ============================================================
   LA CONFIRMATION D'UN GESTE QUI PART AU LOIN
   ------------------------------------------------------------
   Annoncer un contrat à toute la maison n'est pas une opération
   qu'on accompagne d'un murmure en bas d'écran : c'est un geste
   volontaire, irréversible, dont l'effet est ailleurs. Le bandeau
   remonte donc EN HAUT, là où l'oeil revient après avoir validé,
   et prend le vert de ce qui a abouti. Le bas reste au bandeau
   ambiant et aux docks.
   ============================================================ */
.sh-toast.is-ok {
    /* `--cmd-h` est le nom que le reste du produit donne à la hauteur
       de l'en-tête (voir css/aid-recherche.css) ; 54 px est la valeur
       mesurée quand personne ne la pose. */
    top: calc(var(--cmd-h, 54px) + 12px);
    bottom: auto;
    display: flex; align-items: center; gap: 10px;
    max-width: 520px;
    background: var(--sh-toast-ok); color: #fff;
    box-shadow: 0 14px 34px -12px rgba(11, 74, 36, .55);
    transform: translateY(-12px);
}
.sh-toast.is-ok.is-on { transform: none; }
.sh-toast-ic {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: rgba(255, 255, 255, .2);
}
@media (prefers-reduced-motion: no-preference) {
    .sh-toast { transition: transform .3s cubic-bezier(.22, 1, .36, 1), opacity .3s; }
}

/* ============================================================
   Journal de bord · timeline verticale de la relation client
   (.tl-*), partagée par activite-client.html (pleine page) et le
   drawer d'aperçu (.jdw-*) de la Prospection. Un rail continu relie
   des nœuds ; les événements sont groupés par phase (prospection →
   engagement → production → obtention).
   ============================================================ */
.tl { position: relative; }
.tl::before {
    content: ''; position: absolute; left: 22px; top: 26px; bottom: 26px; width: 2px;
    background: var(--gray-200); border-radius: 2px;
}
.tl-list { position: relative; }

/* En-tête de phase */
.tl-phase { display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 0 14px; margin: 26px 0 12px; }
.tl-phase:first-child { margin-top: 2px; }
.tl-phase-badge {
    grid-column: 1; justify-self: center; position: relative; z-index: 1;
    width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
    color: #fff; box-shadow: 0 3px 8px rgba(9, 30, 66, .16);
}
.tl-phase-badge svg { width: 18px; height: 18px; }
.tl-phase--prospection .tl-phase-badge { background: linear-gradient(135deg, #0053BE, #2E8AF0); }
.tl-phase--signature .tl-phase-badge { background: linear-gradient(135deg, #E67A34, var(--orange)); color: #4A2408; }
.tl-phase--production .tl-phase-badge { background: linear-gradient(135deg, #0A2E5C, #1E5FA8); }
.tl-phase--obtention .tl-phase-badge { background: linear-gradient(135deg, #1E7C3C, #2DAE54); }
.tl-phase-tx b { display: block; font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 15px; color: var(--text-primary); letter-spacing: -.01em; line-height: 1.2; }
.tl-phase-tx span { display: block; font-size: 12px; color: var(--text-secondary); }
.tl-phase-count {
    min-width: 24px; height: 24px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--gray-200);
    color: var(--text-secondary); font-size: 12px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}

/* Un événement */
.tl-item { display: grid; grid-template-columns: 46px 1fr; gap: 0 14px; padding-bottom: 18px; }
.tl-node {
    grid-column: 1; justify-self: center; position: relative; z-index: 1; margin-top: 1px;
    width: 34px; height: 34px; border-radius: 50%; background: var(--surface); flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 2px solid var(--gray-300); color: var(--text-secondary); box-shadow: var(--shadow-sm);
}
.tl-node svg { width: 16px; height: 16px; }
.tl-node--prospection { border-color: var(--blue-muted); color: var(--blue); }
.tl-node--production { border-color: #B9D3F2; color: var(--blue-dark); }
.tl-node--signature { border-color: var(--orange); color: var(--orange-ink); }
.tl-node--obtention { border-color: var(--green); color: var(--green-ink); }
.tl-node--step { border-color: var(--blue-muted); color: var(--blue-dark); }
.tl-node--fill { border: none; }
.tl-node--signature.tl-node--fill { background: var(--orange); color: #4A2408; }
.tl-node--obtention.tl-node--fill { background: var(--green); color: #fff; }

/* Corps de l'événement */
.tl-body { grid-column: 2; min-width: 0; }
.tl-head { display: flex; align-items: baseline; gap: 6px 14px; flex-wrap: wrap; }
.tl-title { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 800; font-size: 15px; color: var(--text-primary); line-height: 1.3; }
.tl-time { margin-left: auto; flex-shrink: 0; font-size: 12px; font-weight: 700; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tl-sub { display: flex; align-items: center; gap: 5px 9px; flex-wrap: wrap; margin-top: 3px; }
.tl-kind { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.tl-who { font-size: 12px; font-weight: 700; color: var(--text-secondary); }
.tl-meta { font-size: 12px; color: var(--text-muted); }
.tl-tag { font-size: 10.5px; font-weight: 800; padding: 1px 8px; border-radius: var(--radius-pill); }
.tl-tag--in { background: var(--gray-200); color: var(--text-secondary); }
.tl-tag--out { background: var(--blue-pale); color: var(--blue-dark); }
.tl-tag--issue { background: var(--green-soft); color: var(--green-ink); }
.tl-tag--phase.tl-tag--prospection { background: var(--blue-pale); color: var(--blue-dark); }
.tl-tag--phase.tl-tag--signature { background: var(--orange-soft); color: var(--orange-ink); }
.tl-tag--phase.tl-tag--production { background: #E7EFF9; color: var(--blue-dark); }
.tl-tag--phase.tl-tag--obtention { background: var(--green-soft); color: var(--green-ink); }

.tl-text { margin-top: 8px; font-size: 13.5px; color: var(--text-secondary); line-height: 1.5; max-width: 68ch; }
.tl-quote { margin-top: 8px; padding: 10px 14px; border-radius: 12px; font-size: 13.5px; line-height: 1.5; color: var(--text-primary); max-width: 68ch; }
.tl-quote--out { background: var(--blue-pale); }
.tl-quote--in { background: var(--gray-100); border: 1px solid var(--gray-200); }
.tl-pj { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 5px 11px; background: var(--surface); border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill); font-size: 12px; font-weight: 700; color: var(--blue-dark); }
.tl-pj svg { color: var(--text-muted); flex-shrink: 0; }

/* Jalons : signature, obtention */
.tl-mile { margin-top: 9px; display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-radius: 14px; max-width: 68ch; }
.tl-mile--sign { background: var(--orange-soft); }
.tl-mile--sign svg { flex-shrink: 0; color: var(--orange-ink); }
.tl-mile--sign span { font-size: 13.5px; font-weight: 700; color: var(--orange-ink); line-height: 1.45; }
.tl-mile--win { background: var(--green-soft); align-items: baseline; gap: 14px; flex-wrap: wrap; }
.tl-win-amt { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 26px; letter-spacing: -.02em; color: var(--green-ink); line-height: 1; font-variant-numeric: tabular-nums; }
.tl-win-tx { flex: 1; min-width: 150px; font-size: 13px; color: var(--green-ink); line-height: 1.45; }

/* Transcription de réunion (repliable) */
.tl-meet { margin-top: 9px; }
.tl-meet-sum { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; list-style: none; padding: 7px 13px; border-radius: var(--radius-pill); border: 1.5px solid var(--gray-300); background: var(--surface); font-size: 12.5px; font-weight: 800; color: var(--blue-dark); transition: border-color .15s, background .15s; }
.tl-meet-sum::-webkit-details-marker { display: none; }
.tl-meet-sum:hover { border-color: var(--blue); background: var(--blue-pale); }
.tl-meet-sum:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.tl-meet[open] .tl-meet-sum { margin-bottom: 10px; }
.tl-meet-body { display: flex; flex-direction: column; gap: 12px; padding: 14px; border-radius: 14px; background: var(--gray-100); border: 1px solid var(--gray-200); max-width: 68ch; }
.tl-turn { display: flex; gap: 10px; }
.tl-turn .avatar { margin-top: 2px; }
.tl-turn-b b { display: block; font-size: 12px; font-weight: 800; color: var(--text-primary); }
.tl-turn-b p { font-size: 13px; color: var(--text-secondary); line-height: 1.5; }

.tl-empty { padding: 30px 16px; text-align: center; font-size: 13.5px; color: var(--text-secondary); }

/* Version compacte (drawer d'aperçu) */
.tl--compact::before { left: 20px; top: 20px; bottom: 20px; }
.tl--compact .tl-item { grid-template-columns: 42px 1fr; gap: 0 12px; padding-bottom: 15px; }
.tl--compact .tl-node { width: 30px; height: 30px; }
.tl--compact .tl-node svg { width: 14px; height: 14px; }
.tl--compact .tl-title { font-size: 13.5px; }
.tl--compact .tl-quote, .tl--compact .tl-text { font-size: 12.5px; }
.tl--compact .tl-win-amt { font-size: 20px; }

@media (prefers-reduced-motion: no-preference) {
    .tl-item, .tl-phase { animation: tl-in .5s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--i, 0) * 35ms); }
    @keyframes tl-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
}

/* ============================================================
   Drawer d'aperçu du journal (.jdw-*) : bandeau vertical à droite,
   ouvert depuis la Prospection. z-index drawer = 95.
   ============================================================ */
.jdw-backdrop { position: fixed; inset: 0; z-index: 95; background: rgba(9, 30, 66, .32); opacity: 0; pointer-events: none; transition: opacity .28s; }
.jdw-backdrop.is-open { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: no-preference) { .jdw-backdrop { backdrop-filter: blur(2px); } }
.jdw {
    position: fixed; top: 0; right: 0; z-index: 95; height: 100dvh; width: min(430px, 94vw);
    background: var(--surface); box-shadow: -12px 0 40px rgba(9, 30, 66, .18);
    display: flex; flex-direction: column; transform: translateX(100%);
    transition: transform .34s cubic-bezier(.22, 1, .36, 1); will-change: transform;
}
.jdw.is-open { transform: none; }
.jdw-h { flex-shrink: 0; display: flex; align-items: center; gap: 12px; padding: 15px 18px; border-bottom: 1px solid var(--gray-200); }
.jdw-h .avatar { width: 42px; height: 42px; font-size: 14px; }
.jdw-h-id { flex: 1; min-width: 0; }
.jdw-kicker { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--blue); }
.jdw-h-id b { display: block; font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 17px; color: var(--text-primary); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jdw-x { flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid var(--gray-300); background: var(--surface); color: var(--text-secondary); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: border-color .15s, background .15s, color .15s; }
.jdw-x:hover { border-color: var(--blue); background: var(--blue-pale); color: var(--blue-dark); }
.jdw-note { flex-shrink: 0; padding: 11px 18px; font-size: 12px; color: var(--text-secondary); background: var(--gray-100); border-bottom: 1px solid var(--gray-200); line-height: 1.45; }
.jdw-body { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 18px; }
.jdw-foot { flex-shrink: 0; padding: 14px 18px; border-top: 1px solid var(--gray-200); }
.jdw-foot .btn { width: 100%; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important; animation-iteration-count: 1 !important;
        transition-duration: .01ms !important; scroll-behavior: auto !important;
    }
}

/* ============================================================
   App PARTENAIRE : pas de rail latéral, le header porte seul le
   chrome. Le panneau de contenu s'arrondit alors des deux coins
   hauts et son ombre interne vient uniquement du haut.
   ============================================================ */
.app.is-norail .frame {
    border-radius: 18px 18px 0 0;
    box-shadow: inset 0 12px 20px -16px rgba(9, 30, 66, .45);
}
html[data-chrome="c"] .app.is-norail .frame { box-shadow: inset 0 12px 20px -16px rgba(0, 109, 236, .28); }
html[data-chrome="d"] .app.is-norail .frame { box-shadow: inset 0 12px 20px -16px rgba(0, 0, 0, .6); }
/* Logo du header (remplace le logo du rail supprimé) */
.cmd-logo { display: inline-flex; align-items: center; flex-shrink: 0; padding: 4px 8px 4px 4px; border-radius: 10px; }
.cmd-logo img { height: 20px; width: auto; max-width: 84px; object-fit: contain; display: block; }
.cmd-logo:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
html[data-chrome="c"] .cmd-logo:focus-visible { outline-color: var(--blue); }

/* ============================================================
   LE VERROU DE MARQUE · MAPi & le partenaire (2026-08-20)
   ------------------------------------------------------------
   L'app Partenaire est celle d'un tiers qui distribue MAPi : son
   en-tête dit les DEUX noms, dans cet ordre. Le « & » n'est pas un
   ornement, c'est la nature de la relation : ni marque blanche (le
   partenaire n'efface pas MAPi), ni logo client (MAPi ne s'efface
   pas non plus).

   LES LOGOS PARTENAIRES SONT DES IMAGES EN COULEUR, posées sur le
   bleu du header : la plupart portent du bleu foncé ou du noir. Ils
   vivent donc sur une pastille blanche, qui leur rend leur contraste
   et les distingue du logo MAPi, lui monochrome et posé à même le
   fond. Sans elle, MEDEF (bleu nuit) disparaissait dans le header.
   ============================================================ */
.cmd-marque { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
.cmd-esper {
    font-family: 'Museo Sans', 'Mukta Mahee', sans-serif;
    font-size: 15px; font-weight: 700; color: rgba(255, 255, 255, .58);
    line-height: 1; user-select: none;
}
html[data-chrome="c"] .cmd-esper { color: var(--text-muted); }
.cmd-marque-b {
    display: inline-flex; align-items: center; justify-content: center;
    height: 32px; padding: 0 10px; border: 0; border-radius: 9px; cursor: pointer;
    background: #fff; box-shadow: 0 1px 2px rgba(9, 30, 66, .18);
}
.cmd-marque-b img { width: auto; max-width: 96px; object-fit: contain; display: block; }
.cmd-marque-b:hover { box-shadow: 0 3px 10px rgba(9, 30, 66, .26); }
.cmd-marque-b:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
html[data-chrome="c"] .cmd-marque-b:focus-visible { outline-color: var(--blue); }
html[data-chrome="c"] .cmd-marque-b { border: 1px solid var(--gray-200); }
/* Le chevron du sélecteur de partenaire (le logo, lui, ramène à l'accueil).
   Voile SOMBRE au survol, comme le sélecteur de plateforme : un voile blanc
   ferait tomber le glyphe sous 4.5:1 sur le bleu de marque. */
.cmd-marque-ch {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 32px; margin-left: -3px; padding: 0; border: 0;
    border-radius: 8px; background: none; color: rgba(255, 255, 255, .82); cursor: pointer;
    transition: background .15s, color .15s;
}
.cmd-marque-ch:hover { background: rgba(9, 30, 66, .28); color: #fff; }
.cmd-marque-ch:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
html[data-chrome="c"] .cmd-marque-ch { color: var(--text-muted); }
html[data-chrome="c"] .cmd-marque-ch:hover { background: var(--blue-pale); color: var(--blue-dark); }
html[data-chrome="c"] .cmd-marque-ch:focus-visible { outline-color: var(--blue); }
.cmd-marque-pop {
    position: fixed; z-index: 80; min-width: 232px; padding: 8px;
    display: flex; flex-direction: column; gap: 2px;
    background: var(--surface); border: 1px solid var(--gray-200);
    border-radius: 14px; box-shadow: var(--shadow-lg);
}
.cmd-marque-t {
    padding: 4px 8px 6px; font-size: 10.5px; font-weight: 800;
    letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted);
}
.cmd-marque-pop button {
    display: flex; align-items: center; gap: 11px; width: 100%; min-height: 40px;
    padding: 6px 9px; border: 0; border-radius: 10px; background: none; cursor: pointer;
    font: inherit; font-size: 13.5px; color: var(--text-primary); text-align: left;
}
.cmd-marque-pop button img { flex: none; width: auto; max-width: 62px; object-fit: contain; }
.cmd-marque-pop button:hover { background: var(--blue-pale); }
.cmd-marque-pop button:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.cmd-marque-pop button[aria-selected="true"] { background: var(--blue-pale); font-weight: 800; color: var(--blue-dark); }
/* Sous 720 px l'en-tête n'a plus la place de deux marques : MAPi reste,
   le partenaire se lit dans le menu. Un logo rogné ne dit rien. */
@media (max-width: 720px) { .cmd-marque { display: none; } }
/* Reprise dans la feuille mobile : le logo, puis le nom en toutes
   lettres, parce qu'une image seule dans une liste de commandes ne dit
   pas ce qu'elle commande. */
.sh-marque img { flex: none; }
@media (prefers-reduced-motion: no-preference) {
    .cmd-marque-b { transition: box-shadow .2s; }
    .cmd-marque-pop button { transition: background .15s; }
}
/* Sélecteur de plateforme : faute de rail, il se pose près du logo */
.cmd-plt { display: inline-flex; flex-shrink: 0; }
@media (max-width: 720px) { .cmd-plt .plt-lbl { display: none; } .cmd-plt .plt-btn--bar { padding: 0 9px; } }
/* Bascule de thème dans le header (reprise du bouton du rail) */
.cmd-chrome {
    display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px;
    border: none; border-radius: 50%; background: rgba(255, 255, 255, .16); color: #fff; cursor: pointer;
    transition: background .15s, transform .1s;
}
.cmd-chrome:hover,
.cmd-chrome[aria-expanded="true"] { background: rgba(255, 255, 255, .28); }
.cmd-chrome:active { transform: scale(.94); }
html[data-chrome="c"] .cmd-chrome { background: var(--blue-pale); color: var(--blue-dark); }
html[data-chrome="c"] .cmd-chrome:hover,
html[data-chrome="c"] .cmd-chrome[aria-expanded="true"] { background: var(--blue-muted); }
/* L'app Partenaire n'a pas de navigation mobile en bas d'écran */
html[data-app="partenaire"] .mnav { display: none !important; }


/* ============================================================
   LA PASTILLE DE RÔLE (cmd-role)
   Accolée à la vue Production / Commercial : deux réglages de même
   nature, « ce que je regarde » et « qui je suis ». Le rôle commande
   ce qui est visible (l'éditeur du plateau, les outils internes),
   donc il se lit en permanence, pas dans un écran de réglages.
   ============================================================ */
.cmd-role {
    display: inline-flex; align-items: center; gap: 7px; min-height: 36px; padding: 0 12px;
    border: 1.5px solid var(--gray-300); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--text-primary);
    font: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer; white-space: nowrap;
    transition: border-color .15s, background .15s;
}
.cmd-role:hover { border-color: var(--blue-muted); }
.cmd-role:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.cmd-role-panel { min-width: 268px; }
.cmd-role-t {
    padding: 4px 12px 6px; font-size: 10.5px; font-weight: 800; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-secondary);
}
.cmd-role-i { flex-direction: column; align-items: flex-start; gap: 1px; min-height: 46px; padding: 7px 12px; }
.cmd-role-i b { font-size: 13px; font-weight: 800; }
.cmd-role-i small { font-size: 11px; color: var(--text-secondary); line-height: 1.35; }
.cmd-role-i.is-on { background: var(--blue-pale); color: var(--blue-dark); }
.cmd-role-i.is-on small { color: var(--blue-dark); opacity: .8; }
@media (max-width: 1200px) { .cmd-role span { display: none; } .cmd-role { padding: 0 9px; } }

/* LE TAG D'OFFRE DU PARTENAIRE (cmd-offre)
   Même objet que le tag de rôle : une identité qu'on lit en haut à
   droite et qu'on change d'un clic. Deux différences assumées.
   1. Il GARDE SON LIBELLÉ plus longtemps : « Option pro » et
      « Apporteur d'affaires » ne se devinent pas à l'icône, et le
      header du Partenaire, sans portée ni cabinet, a la place.
   2. Son icône porte le bleu de marque : sans elle, la pastille se
      lisait comme un bouton d'action de plus. */
.cmd-offre svg:first-child { color: var(--blue); }
@media (min-width: 861px) { .cmd-offre span { display: inline; } }
@media (max-width: 860px) { .cmd-offre { padding: 0 9px; } }


/* ============================================================
   LES WIDGETS FLOTTANTS, ALLUMÉS OU ÉTEINTS (2026-08-02)
   Ils suivent d'un écran à l'autre, ce qui est leur intérêt et parfois
   leur défaut : sur un plateau de jeu, une maquette qu'on montre ou un
   écran qu'on partage, on veut le coin de l'écran pour soi. Le réglage
   vit dans le menu « … » du header, avec « Pleine largeur », et pose
   ces deux classes sur le corps.

   Les feuilles des widgets sont injectées par leurs propres modules :
   une règle posée là ne s'appliquerait qu'aux pages qui les chargent.
   Ici, elle vaut partout, et masquer les deux fait disparaître le dock
   entier plutôt que de laisser un cadre vide dans le coin.
   ============================================================ */
body.no-wdg-msg .dk-card:not(.tdk-card) { display: none; }
body.no-wdg-task .tdk-card { display: none; }
body.no-wdg-msg.no-wdg-task .dk-root { display: none; }

/* ============================================================
   LE MENU DU TÉLÉPHONE (préfixe sh-)
   Le header mobile ne garde que le logo, la recherche et ce burger ;
   tout le reste vit ici. C'est une FEUILLE PLEINE HAUTEUR et non un
   menu déroulant : sur un écran de 375 px, un panneau ancré sous le
   burger déborde par le bas et se ferme au premier défilement.
   ============================================================ */
.cmd-logo--mob { display: none; }
.cmd-burger {
    display: none; width: 40px; height: 40px; flex-shrink: 0;
    align-items: center; justify-content: center;
    border: 1.5px solid rgba(255, 255, 255, .45); border-radius: 12px;
    background: rgba(255, 255, 255, .1); color: #fff; cursor: pointer;
    transition: background .15s, border-color .15s;
}
.cmd-burger:hover, .cmd-burger[aria-expanded="true"] { background: rgba(255, 255, 255, .24); border-color: #fff; }
/* La cible tactile fait 44 px même si le bouton en montre 40 */
.cmd-burger::after { content: ''; position: absolute; inset: -2px; }
/* `relative` reste : le débord de cible tactile (::after) s'y ancre. La
   pastille de non-lus, elle, a été retirée du burger le 2026-08-10 : la
   barre du bas la porte déjà, sur l'onglet qui mène quelque part. */
.cmd-burger { position: relative; }

.cmd-sheet { position: fixed; inset: 0; z-index: 90; }
.cmd-sheet[hidden] { display: none; }
.sh-fond { position: absolute; inset: 0; border: none; padding: 0; background: rgba(9, 18, 34, .5); cursor: pointer; }
.sh {
    position: absolute; top: 0; right: 0; bottom: 0;
    width: min(400px, 92vw); display: flex; flex-direction: column;
    background: var(--surface); box-shadow: var(--shadow-lg);
}
@media (prefers-reduced-motion: no-preference) {
    .sh { animation: sh-in .24s cubic-bezier(.22, 1, .36, 1); }
    .sh-fond { animation: sh-fond-in .24s; }
    @keyframes sh-in { from { transform: translateX(100%); } }
    @keyframes sh-fond-in { from { opacity: 0; } }
}
/* L'identité d'abord : sur un menu de téléphone, la première question
   est « qui suis-je et pour quel cabinet ». */
.sh-h {
    display: flex; align-items: center; gap: 11px; flex-shrink: 0;
    padding: 14px 14px 12px calc(14px + env(safe-area-inset-left));
    border-bottom: 1px solid var(--gray-200);
}
.sh-h .avatar { width: 38px; height: 38px; font-size: 12.5px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.sh-h-tx { min-width: 0; flex: 1; }
.sh-h-tx b { display: block; font-size: 14.5px; font-weight: 800; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-h-tx span { display: block; font-size: 12px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-x {
    width: 44px; height: 44px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
    border: none; border-radius: 50%; background: none; color: var(--text-secondary); cursor: pointer;
}
.sh-x:hover { background: var(--gray-100); color: var(--text-primary); }
.sh-x:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

.sh-body {
    flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 6px 8px calc(18px + env(safe-area-inset-bottom));
}
.sh-t {
    padding: 14px 10px 6px; font-size: 10.5px; font-weight: 800;
    letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted);
}
/* Une ligne du menu : 48 px de haut, la cible tactile confortable. */
.sh-i, .sh-compte .dd-item {
    display: flex; align-items: center; gap: 11px; width: 100%; min-height: 48px;
    padding: 0 10px; border: none; border-radius: 11px; background: none;
    font: inherit; font-size: 14px; font-weight: 600; color: var(--text-primary);
    text-align: left; text-decoration: none; cursor: pointer;
}
.sh-i:hover, .sh-compte .dd-item:hover { background: var(--gray-100); }
.sh-i:focus-visible, .sh-compte .dd-item:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.sh-i svg { flex-shrink: 0; color: var(--text-secondary); }
.sh-i-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: 12px; color: var(--text-secondary); font-weight: 700; }
.sh-i-tx b { font-size: 14px; font-weight: 700; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-i-arr { margin-left: auto; color: var(--text-muted); }
/* L'action principale de la plateforme garde son rang : c'est la seule
   ligne pleine du menu. */
.sh-i--cta { background: var(--blue); color: #fff; font-weight: 800; margin: 2px 0; }
.sh-i--cta svg { color: var(--orange); }
.sh-i--cta:hover { background: var(--blue-dark); }
.sh-i .sb-dot { margin-left: auto; position: static; }
.sh-i[aria-pressed="true"] .dd-ck { opacity: 1; }
.sh-i .dd-ck { margin-left: auto; opacity: 0; color: var(--blue); }

/* Un réglage à deux ou trois positions : libellé à gauche, segmenté à
   droite. Le segmenté dit l'état ET permet d'en changer, là où deux
   lignes cochables auraient demandé deux gestes. */
.sh-seg-l { display: flex; align-items: center; gap: 10px; padding: 5px 10px; }
.sh-seg-l > span { flex: 0 0 62px; font-size: 12.5px; font-weight: 700; color: var(--text-secondary); }
.sh-seg { flex: 1; min-width: 0; display: flex; gap: 2px; padding: 3px; background: var(--gray-100); border-radius: var(--radius-pill); }
.sh-seg button {
    flex: 1; min-width: 0; min-height: 36px; padding: 0 8px;
    border: none; border-radius: var(--radius-pill); background: none;
    font: inherit; font-size: 12.5px; font-weight: 700; color: var(--text-secondary);
    cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    transition: background .15s, color .15s;
}
.sh-seg button[aria-pressed="true"] { background: var(--surface); color: var(--blue-dark); box-shadow: var(--shadow-sm); }
.sh-seg button:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

/* Le sélecteur de plateforme et le bouton d'apparence reprennent la
   forme d'une ligne : dans un menu, un bouton rond ou une barre orange
   pleine au milieu de lignes de texte se lit comme un corps étranger.
   La couleur de la plateforme reste, mais sur la seule icône : elle
   identifie sans dominer. Et l'icône garde le gabarit des autres
   lignes — une pastille de 30 px décalait le seul libellé du menu qui
   ne commençait pas sur la même verticale que ses voisins. */
.sh-plt { display: block; padding: 0; }
.sh-plt .plt-btn {
    width: 100%; min-height: 48px; justify-content: flex-start; gap: 11px;
    padding: 0 10px; border: none !important; border-radius: 11px;
    background: none !important; color: var(--text-primary) !important;
    font-size: 14px; font-weight: 600; box-shadow: none;
}
.sh-plt .plt-btn:hover { background: var(--gray-100) !important; }
.sh-plt .plt-ico {
    width: 17px; height: 17px; flex-shrink: 0; border-radius: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: none; color: var(--blue);
}
.sh-plt .plt-ico svg { width: 17px; height: 17px; }
.sh-plt .plt-btn.is-admin .plt-ico { background: none; color: var(--orange-ink); }
.sh-plt .plt-lbl { display: inline-flex; align-items: center; gap: 6px; }

/* Un titre de sous-groupe, sous un titre de section : « Rôle » a besoin
   d'un intitulé et ses quatre lignes n'entrent pas dans un segmenté. */
.sh-t2 { padding: 12px 10px 4px; font-size: 12.5px; font-weight: 700; color: var(--text-secondary); }
.sh-i--r { align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }
.sh-i--r .sh-i-tx { font-size: 11.5px; line-height: 1.35; font-weight: 500; }
.sh-i--r .sh-ck { flex-shrink: 0; margin-left: auto; color: var(--blue); opacity: 0; }
.sh-i--r.is-on { background: var(--blue-pale); }
.sh-i--r.is-on .sh-ck { opacity: 1; }
.sh-i--r.is-on .sh-i-tx b { color: var(--blue-dark); }
.sh-i--chrome { justify-content: flex-start; }
.sh-compte { border-top: 1px solid var(--gray-200); margin-top: 10px; padding-top: 4px; }
.sh-compte .usr-h { padding: 12px 10px 6px; }
.sh-compte .usr-sep { margin: 6px 10px; }
.sh-compte .usr-out, .sh-compte .usr-out svg { color: var(--danger-ink); }
/* La page ne défile plus derrière la feuille : sur iOS, le fond qui
   glisse sous une modale est le défaut qu'on remarque en premier. */
body.sh-on { overflow: hidden; }

/* Les deux bascules d'affichage vivent ICI, après les règles de base :
   à specificité égale, c'est la dernière déclarée qui gagne, et les
   poser dans le bloc mobile plus haut dans le fichier les faisait
   écraser par le `display: none` de cette section. */
@media (max-width: 960px) {
    .cmd-logo--mob { display: inline-flex; }
    .cmd-burger { display: inline-flex; }
    /* Tout ce qui descend dans le menu. On le masque plutôt que de ne pas
       l'émettre : le header se re-rendrait à chaque rotation. */
    .cmd-scope, .cmd-mode, .cmd-cab-dd, .cmd-plus, .cmd-cta,
    .cmd-role-dd, .cmd-more-dd, .cmd-usr-dd, .cmd-chrome, .cmd-plt { display: none; }
}


/* ---------- Le compte du Partenaire : les deux modales (préfixe cpt-) ---------- */
.cpt-panel { width: min(440px, 100%); }
.cpt-panel h2 { font-family: 'Museo Sans', 'Mukta Mahee', sans-serif; font-weight: 900; font-size: 20px; color: var(--text-primary); margin-bottom: 16px; }
.cpt-f { display: block; margin-bottom: 13px; }
.cpt-f > span { display: block; font-size: 12px; font-weight: 700; color: var(--text-secondary); margin-bottom: 5px; }
.cpt-f input { width: 100%; min-height: 40px; padding: 0 12px; border: 1.5px solid var(--gray-300); border-radius: 10px; font: inherit; font-size: 14px; color: var(--text-primary); background: var(--surface); }
.cpt-f input:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
.cpt-f small { display: block; font-size: 11.5px; color: var(--text-muted); margin-top: 4px; }
.cpt-sw { display: flex; gap: 11px; align-items: flex-start; padding: 12px 13px; border: 1.5px solid var(--gray-200); border-radius: 12px; margin: 4px 0 12px; cursor: pointer; }
.cpt-sw input { width: 17px; height: 17px; margin-top: 2px; accent-color: var(--blue); flex-shrink: 0; }
.cpt-sw b { display: block; font-size: 13.5px; color: var(--text-primary); }
.cpt-sw small { display: block; font-size: 12px; color: var(--text-secondary); margin-top: 2px; line-height: 1.45; }
.cpt-err { font-size: 12.5px; color: var(--danger-ink); margin: 2px 0 10px; }
.cpt-acts { display: flex; justify-content: flex-end; gap: 10px; margin-top: 6px; }
