/* ═══════════════════════════════════════════════════════════════════════════════
   feuille.css — Le style de l'application, en un fichier.

   ⚠️ IL VIVAIT DANS `page()`, RECOPIE DANS CHAQUE REPONSE. 314 ko de style dans une
   page de 347 : quatre-vingt-dix pour cent du poids, reparti a chaque ecran ouvert et
   jamais garde par le navigateur. Mesure du 25/08/2026, sur la remarque de Rodolphe
   « la page est peu intuitive et lente ». Le serveur repondait pourtant en cinq a
   cinquante millisecondes : le calcul n'etait pas en cause, c'est le fil qui portait
   le poids — et sur un telephone en 4G cela se paie a chaque navigation.

   ⚠️ UNE SEULE VALEUR ETAIT DYNAMIQUE dans ces 6366 lignes : la couleur d'accent du
   conseiller. Elle reste en ligne dans la page, en soixante octets ; ce fichier porte
   tout le reste, identique pour tout le monde, donc cachable.

   ⚠️ ET IL EST SERVI SOUS UNE ADRESSE QUI PORTE LA VERSION — /style.<version>.css.
   Sans elle, un navigateur qui garde le fichier un an garderait aussi les corrections
   d'un an. Avec elle, un deploiement change l'adresse, donc le fichier demande, et le
   cache d'avant devient sans objet.

   ⚠️ C'EST ICI QUE LE STYLE VIT DESORMAIS. rendu/layout.js n'en garde que le lien.
   ═══════════════════════════════════════════════════════════════════════════════ */

      /* ---------------------------------------------------------------
         Jetons de style. Les neutres sont DÉRIVÉS de la couleur d'accent :
         un gris pur jurerait avec une couleur choisie librement par l'agent.
         --------------------------------------------------------------- */
      :root {
        /* ⚠️ VALEUR DE REPLI, TOUJOURS REDEFINIE PAR LA PAGE. Ce fichier est le meme pour
           tout le monde — c'est ce qui le rend cachable — et la couleur d'accent
           appartient a chaque conseiller. La page pose un <style> de soixante octets
           APRES ce fichier, qui gagne a specificite egale parce qu'il vient apres.
           Ce repli est celui de l'espace agent : sans lui, un navigateur qui n'aurait
           que ce fichier afficherait une application sans couleur. */
        --accent: #334155;
        --accent-fonce: color-mix(in oklab, var(--accent) 82%, #000);
        --accent-pale: color-mix(in oklab, var(--accent) 10%, #fff);
        --accent-bord: color-mix(in oklab, var(--accent) 24%, #fff);

        --encre:    color-mix(in oklab, var(--accent) 12%, #10141c);
        --encre-2:  color-mix(in oklab, var(--accent) 10%, #4a5261);
        --encre-3:  color-mix(in oklab, var(--accent) 8%,  #79818f);
        /* ⚠️ CE QUATRIEME TON MANQUAIT, ET TREIZE REGLES L UTILISAIENT DEJA. Une
           declaration qui appelle une variable inexistante est INVALIDE : le navigateur
           la jette en silence, sans erreur de console. Consequence mesuree le
           24/08/2026 : les chevrons, les heures de l agenda, la pastille des envois et
           dix autres endroits heritaient de la couleur de leur parent au lieu du gris
           voulu — et une bande hachuree posee sur l agenda ne s affichait pas du tout,
           son fond ET sa bordure etant tous deux invalides.

           Le pas suit celui des trois autres : chaque ton s eclaircit et perd deux
           points d accent. */
        --encre-4:  color-mix(in oklab, var(--accent) 6%,  #a3aab6);

        /* ⚠️ LE FOND RECULE POUR QUE LES CONTENANTS AVANCENT. Il etait a trois pour
           cent d accent sur un blanc casse : les cartes blanches s y fondaient, et il
           fallait un trait gris pour les detacher. A six pour cent sur un gris plus
           franc, l ombre suffit et la bordure devient facultative. */
        --papier:   color-mix(in oklab, var(--accent) 6%, #f4f6f9);
        --surface:  #ffffff;
        --trait:    color-mix(in oklab, var(--accent) 9%, #e2e6ec);

        --succes: #0f7a3d;
        --succes-pale: #eaf6ee;
        --danger: #a4231c;
        --danger-pale: #fdeeed;
        --attention: #8a5a00;

        /* Rythme d'espacement : une seule échelle pour toute l'application. */
        --e1: .25rem; --e2: .5rem; --e3: .75rem; --e4: 1rem;
        --e5: 1.5rem; --e6: 2rem; --e7: 3rem;

        /* Des rayons plus genereux : c est ce qui separe un outil interne d un produit.
           Releve avec Rodolphe le 20/08/2026 sur la maquette du tableau de bord. */
        --r-petit: 10px; --r: 16px; --r-grand: 22px;

        /* ⚠️ CES DEUX JETONS ÉTAIENT UTILISÉS SANS AVOIR JAMAIS ÉTÉ DÉFINIS.

           Treize règles réclamaient le fond « fond-2 » et le rayon « r2 ». Une variable
           absente ne déclenche rien : le fond restait transparent et le rayon tombait à
           zéro. Les blocs de proposition, d avertissement et d écart s affichaient donc
           à plat et à coins carrés, sans que rien ne le signale. Vérifié dans le
           navigateur le 20/08/2026, getPropertyValue rendait une chaîne vide.

           « fond-2 » est le fond de second niveau, un ton sous le papier : ce qui est
           posé DANS une carte, et non la carte elle-même. « r2 » est le rayon de ces
           blocs internes, plus serré que celui d une carte.

           ⚠️ PAS D ACCENT GRAVE DANS CE BLOC : il ferme le gabarit de la page. */
        --fond-2: color-mix(in oklab, var(--accent) 5%, #f3f5f8);
        --r2: 8px;
        /* ⚠️ CHAQUE OMBRE EST TRIPLE, ET C EST LA TROISIEME PASSE QUI COMPTE.

           Un liseré de contact, une passe moyenne, une passe large et tres diffuse. Les
           deux premieres dessinent le bord ; c est la troisieme qui decolle vraiment la
           carte de la page. Sans elle, une ombre ressemble a un trait gris.

           Trois hauteurs, pas une : ce qui est pose, ce qui se saisit, ce qui flotte.
           Une ombre unique met tout au meme plan. */
        --ombre: 0 1px 1px rgba(16,20,28,.04), 0 2px 4px rgba(16,20,28,.05),
                 0 4px 10px rgba(16,20,28,.04);
        --ombre-relief: 0 1px 2px rgba(16,20,28,.05), 0 6px 12px rgba(16,20,28,.07),
                        0 16px 32px rgba(16,20,28,.07);
        --ombre-haute: 0 2px 4px rgba(16,20,28,.06), 0 12px 24px rgba(16,20,28,.09),
                       0 32px 64px rgba(16,20,28,.12);

        /* La courbe de toutes les transitions de l application : demarre vite, finit
           doucement. Une transition lineaire se remarque, celle-ci ne se remarque pas. */
        --vif: cubic-bezier(.2,.7,.3,1);
      }

      * { box-sizing: border-box; }
      /* Nos composants définissent display, ce qui l'emporte sur la règle par défaut
         du navigateur : sans ceci, un élément masqué par hidden resterait visible. */
      [hidden] { display: none !important; }
      html { -webkit-text-size-adjust: 100%; }
      body {
        margin: 0;
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
        font-size: 16px; line-height: 1.6; color: var(--encre);
        background: var(--papier);
        font-variant-numeric: tabular-nums; /* chiffres alignés : surfaces, prix, % */
      }

      /* --- Échelle typographique (rapport 1,25) --- */
      h1 { font-size: 1.85rem; line-height: 1.2; letter-spacing: -.021em;
           margin: 0 0 var(--e3); font-weight: 700; text-wrap: balance; }
      h2 { font-size: 1.2rem; line-height: 1.3; letter-spacing: -.012em;
           margin: var(--e6) 0 var(--e3); font-weight: 650; text-wrap: balance; }

      /* ⚠️ LE SERIF NE SERT PLUS QU AU LOGO. « Je ne veux plus du tout voir cette
         police d ecriture sur l application, sauf sur le logo » — Rodolphe,
         28/08/2026. Il reste donc a deux endroits, et deux seulement : la marque en
         haut du rail et celle des ecrans sans rail. Partout ailleurs, la police du
         systeme.

         LA GRAISSE PASSE DE 800 A 700 EN MEME TEMPS. Le 800 existait parce que Iowan
         Old Style ne distingue pas 600 de 700 — les deux rendaient la meme largeur,
         mesure a l appui. La police du systeme, elle, les distingue : garder 800 aurait
         donne des titres nettement plus lourds qu avant. */
      .espace-agent h1, .espace-agent h2 {
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
        font-weight: 700;
      }
      .espace-agent h1 { letter-spacing: -.03em; }
      .espace-agent h2 { letter-spacing: -.015em; font-size: 1.32rem; }
      h3 { font-size: 1rem; margin: var(--e4) 0 var(--e2); font-weight: 650; }
      p  { margin: 0 0 var(--e3); }
      .plomb { font-size: 1.08rem; color: var(--encre-2); max-width: 62ch; }
      .discret { color: var(--encre-3); font-size: .92rem; }

      /* LA PROPOSITION : ce qu'on a trouve, soumis au vendeur.
         Encadree et non fondue dans la page : elle demande une decision, et une
         decision ne se signale pas comme une note de bas de page. Mais discrete
         quand meme, car elle apparait sans qu'on l'ait demandee. */
      .proposition {
        margin: .5rem 0 0; padding: .7rem .8rem;
        border: 1px solid var(--trait); border-left: 3px solid var(--accent);
        border-radius: var(--r2); background: var(--fond-2);
      }
      .proposition-titre { margin: 0 0 .4rem; font-weight: 650; font-size: .92rem; }

      /* --- LES EMPLACEMENTS DE DEPOT D UNE PIECE ---
         Un champ de fichier brut, avec son bouton a cote et ses styles ecrits a la
         main dans le gabarit : sur une carte d identite qui en demande deux, cela
         faisait deux lignes de commandes systeme empilees, chacune d une largeur
         differente selon le navigateur. On encadre chaque emplacement, on nomme la
         face, et le champ prend toute la place qui reste.
         La variante « depot-face » est celle qui porte un nom, Recto ou Verso. Sans
         nom, un seul emplacement et pas de cadre : toutes les autres pieces.
         ⚠️ AUCUN ACCENT GRAVE DANS CE BLOC : il coupe le gabarit en deux et le serveur
         ne demarre plus. Celui-ci en portait un, pose ici meme le 2026-08-12. */
      .depot {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        margin: 0 0 .35rem;
      }
      /* LE CHAMP DE FICHIER NATIF EST CACHE, PAS SUPPRIME.
         Il rend un bouton ET un texte d etat que le CSS ne sait pas remplacer :
         « Aucun fichier choisi » restait affiche a cote du nom du fichier deja
         depose, deux affirmations contraires sur la meme ligne. On le rend invisible
         et l on redessine les deux morceaux : un label qui ouvre le selecteur, et
         notre propre etat.
         PAS de display none : un champ ainsi masque n est plus atteignable au clavier,
         et le label ne l ouvrirait plus dans certains navigateurs. */
      .depot input[type="file"] {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
        overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
      }
      .depot-choisir {
        flex: none; cursor: pointer; padding: .3rem .65rem; font-size: .82rem;
        border: 1px solid var(--trait); border-radius: var(--r2);
        background: var(--surface); color: var(--encre); white-space: nowrap;
      }
      .depot-choisir:hover { border-color: var(--accent); color: var(--accent-fonce); }
      .depot input[type="file"]:focus-visible + .depot-etat,
      .depot input[type="file"]:focus-visible ~ .depot-choisir { outline: 2px solid var(--accent); }
      /* L etat : ce qui remplace « Aucun fichier choisi ». */
      .depot-etat {
        flex: 1 1 6rem; min-width: 0; font-size: .82rem; color: var(--encre-3);
        overflow: hidden; text-overflow: ellipsis;
      }
      /* Le fichier depose, a la place de cet etat : vert, avec son lien et son retrait. */
      /* Le retour a la ligne : depuis que la marque de relecture s ajoute ici, la ligne
         compte quatre elements. Sans lui, le nom du fichier se faisait rogner jusqu a
         « Donation-… » pour leur laisser la place. */
      .depot-fichier {
        display: inline-flex; align-items: center; gap: .3rem; font-size: .82rem;
        color: var(--succes); max-width: 100%; flex-wrap: wrap;
      }
      .depot-fichier a {
        color: var(--succes); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .depots { margin-top: .5rem; }
      /* Retirer reste possible sans etre mis en avant : un lien discret, jamais un
         bouton, pour que le geste attendu reste celui de deposer. */
      .lien-retrait {
        background: none; border: 0; padding: 0 0 0 .2rem; margin: 0;
        font-size: .78rem; color: var(--encre-3); text-decoration: underline;
        cursor: pointer;
      }
      .lien-retrait:hover:not(:disabled) { background: none; color: var(--danger); }
      /* Ce que la derniere relecture d un document a donne. Sur sa propre ligne :
         accole aux liens "relire" et "retirer", on le prenait pour un troisieme. */
      .marque-relu {
        display: flex; align-items: center; gap: .25rem; width: 100%;
        margin-top: .2rem; font-size: .75rem; color: var(--encre-3);
      }
      /* L attente d une relecture. Une lecture de scan prend une dizaine de secondes,
         pendant lesquelles la page ne bougeait pas : on recliquait, et deux lectures
         partaient. La barre ne mesure rien, elle dit seulement que ca travaille. */
      .barre-lecture {
        width: 100%; height: 3px; margin-top: .3rem; border-radius: 2px;
        background: var(--trait); overflow: hidden;
      }
      .barre-lecture span {
        display: block; width: 35%; height: 100%; border-radius: 2px;
        background: var(--accent); animation: va-et-vient 1.1s ease-in-out infinite;
      }
      /* ── La barre du changement de page ───────────────────────────────────────
         Elle repond au clic pendant que la page suivante arrive. Elle ne mesure rien :
         elle dit « c est parti », qui est la seule question qu on se pose a cet
         instant. Voir public/chargement.js.
         ⚠️ ELLE PORTE SA PROPRE PISTE CLAIRE. Posee sans fond, elle se serait perdue
         sur le bandeau vert de l espace agent ou sur le blanc des autres ecrans selon
         la page : la piste lui donne son propre sol, et le repere devient le meme
         partout. ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .barre-navigation {
        position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 90;
        background: color-mix(in oklab, var(--accent) 16%, #fff);
        overflow: hidden; pointer-events: none;
      }
      .barre-navigation span {
        display: block; width: 35%; height: 100%;
        background: var(--accent);
        animation: va-et-vient 1.1s ease-in-out infinite;
      }
      @media (prefers-reduced-motion: reduce) {
        .barre-navigation span { width: 100%; animation: none; }
      }

      @keyframes va-et-vient {
        0% { transform: translateX(-100%); }
        100% { transform: translateX(340%); }
      }
      /* Le mouvement disparait pour qui demande moins d animations : la barre reste,
         immobile et pleine, et continue de dire que quelque chose est en cours. */
      @media (prefers-reduced-motion: reduce) {
        .barre-lecture span { width: 100%; animation: none; }
      }
      .depot-face {
        padding: .35rem .5rem; border: 1px dashed var(--trait); border-radius: var(--r2);
        background: var(--surface);
      }
      /* Le nom de la face, court et fixe : les deux emplacements s alignent. */
      .depot-nom {
        flex: none; min-width: 3.4rem; font-size: .72rem; font-weight: 700;
        text-transform: uppercase; letter-spacing: .04em; color: var(--encre-3);
      }
      .depot .bouton-2 { margin: 0; padding: .3rem .7rem; font-size: .82rem; }

      /* Une question posee DANS la carte d une piece : le type du document, sa date.
         Elle n a pas la place d une question de formulaire, et n en est pas une. */
      .ligne-piece {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        margin: .45rem 0 .2rem;
      }
      .etiquette-piece { font-size: .82rem; color: var(--encre-2); }
      .saisie-piece {
        font-size: .85rem; padding: .25rem .4rem; margin: 0;
        border: 1px solid var(--trait); border-radius: var(--r2); background: var(--surface);
      }
      .consigne-piece { margin: .1rem 0 0; font-size: .82rem; }

      /* CE QUE LES DOCUMENTS ONT DONNE, annonce en tete du formulaire.
         Les propositions se posent sous les questions concernees, parfois dans une
         partie qui n est pas celle affichee : sans ce compte en haut, un depot qui a
         servi passe pour un depot qui n a rien fait.
         Posee par public/propositions.js, et seulement si le compte est superieur a
         zero : une annonce a vide serait pire que le silence. */
      .recolte {
        margin: 0 0 var(--e4); padding: .8rem .9rem;
        border: 1px solid color-mix(in oklab, var(--succes) 35%, var(--trait));
        border-left: 3px solid var(--succes);
        border-radius: var(--r2); background: color-mix(in oklab, var(--succes) 6%, var(--surface));
      }
      /* Les notes datees d un dossier. Une colonne de commentaires, du plus recent au
         plus ancien, avec un filet a gauche qui les relie : on lit une suite, pas une
         pile de cartes independantes. */
      .fil-notes {
        list-style: none; margin: var(--e4) 0 0; padding: 0;
        display: flex; flex-direction: column; gap: var(--e3);
      }
      .fil-notes li {
        border-left: 2px solid var(--trait); padding: 0 0 0 var(--e3);
        position: relative;
      }
      .fil-notes li::before {
        content: ""; position: absolute; left: -5px; top: .45rem;
        width: 8px; height: 8px; border-radius: 50%;
        background: var(--trait-fort, var(--trait));
      }
      .quand-note {
        margin: 0; font-size: .78rem; color: var(--encre-3);
        font-variant-numeric: tabular-nums;
      }
      .texte-note { margin: .15rem 0 .2rem; white-space: pre-wrap; }
      .fil-notes .lien-discret { font-size: .82rem; padding: 0; }

      /* L avancement du palier 1 sur la fiche du dossier, depuis que le tableau des 29
         champs a ete retire : la fiche du bien le rend mieux, sans les cases vides. Une
         ligne qui dit ou on en est, et les deux chemins pour lire ou pour ecrire. */
      .resume-champs {
        display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap;
        margin: var(--e3) 0 0; font-size: .93rem;
      }
      .resume-champs a { font-weight: 600; }

      /* ---- La grille du tableau de bord ----

         ⚠️ UNE SEULE COLONNE PAR DEFAUT, DEUX SEULEMENT QUAND LA PLACE EXISTE. Ecrite
         dans l autre sens, la regle laisserait un telephone tenter deux colonnes de
         cent-quatre-vingts pixels avant qu une requete de media ne le rattrape.

         Le seuil est a 1100 px : en dessous, deux colonnes donneraient des lignes de
         vendeurs trop etroites pour porter un nom et deux boutons. */
      .grille-bord { display: flex; flex-direction: column; }
      /* ⚠️ LE PANNEAU S INTERCALE, DONC LA REGLE DOIT LE TRAVERSER. Les sections sont
         desormais enveloppees dans un panneau d onglet transparent : sans la seconde
         ligne, le premier titre de chaque colonne retrouvait sa marge haute et la
         colonne de droite redescendait d un centimetre. */
      .colonne-agir > *:first-child,
      .colonne-lire > *:first-child,
      .colonne-agir > .panneau-bord:first-child > *:first-child,
      .colonne-lire > .panneau-bord:first-child > *:first-child { margin-top: 0; }

      /* ---- L en-tete d un ecran, et ses onglets ----------------------------------

         Sur ordinateur : un titre, une ligne discrete, un bouton avec son mot. C est ce
         qui existait, ecrit une seule fois pour les trois ecrans au lieu de trois fois.
         Le bandeau vert n arrive que sur telephone, plus bas. */
      /* ── LE BANDEAU VERT, SUR TOUS LES ECRANS DE L AGENT ET A TOUTES LES LARGEURS ─
         Le tableau de bord en avait un, les quatre autres ecrans commencaient par un
         titre noir sur blanc : la meme application ne se presentait pas de la meme
         facon selon la page qu on ouvrait. « sur PC ca doit ressembler vraiment au
         mobile », Rodolphe, 20/08/2026.

         La geometrie suit celle du tableau de bord : le bandeau sort de la carte par
         une marge negative et se coiffe des memes rayons hauts. */
      .espace-agent .tete-ecran {
        position: relative; overflow: hidden;
        margin: calc(var(--e6) * -1) calc(var(--e6) * -1) var(--e5);
        padding: var(--e6) var(--e5) var(--e5);
        /* ⚠️ UNE HAUTEUR PLANCHER COMMUNE. Sans elle la bande suit son contenu :
           108 px sur les reglages, 183 sur les listes, et la jointure avec le blanc
           tombait a un endroit different a chaque onglet. Le plancher les aligne ; une
           page qui porte davantage — la fiche d un dossier, avec son fil, son adresse,
           son vendeur, son etiquette et sa frise — depasse, et c est normal : on ne
           coupe pas du contenu pour tenir une ligne. */
        min-height: 11.4rem;
        border-radius: var(--r-grand) var(--r-grand) 0 0;
        background: linear-gradient(150deg, #0a3d2e 0%, #0d5c46 52%, #127054 100%);
        color: #fff; box-shadow: var(--ombre-haute);
      }
      .espace-agent .tete-ecran::after {
        content: ""; position: absolute; inset: 0; pointer-events: none;
        background: radial-gradient(58% 130% at 78% 8%,
          rgba(150,235,200,.20), transparent 72%);
      }
      .espace-agent .tete-ecran h1,
      .espace-agent .tete-ecran-sous,
      .espace-agent .fil-ecran { position: relative; color: #fff; }
      .espace-agent .tete-ecran-sous { color: rgba(255,255,255,.72); }
      .espace-agent .fil-ecran { color: rgba(255,255,255,.7); }
      .espace-agent .fil-ecran a { color: rgba(255,255,255,.85); text-decoration: none; }
      .espace-agent .fil-ecran a:hover { color: #fff; }
      /* Sur le vert, le bouton d action devient blanc a l encre du produit. */
      .espace-agent .tete-ecran-action {
        background: #fff; color: var(--accent-fonce); box-shadow: var(--ombre-relief);
      }
      .espace-agent .tete-ecran-action:hover { background: var(--accent-pale); color: var(--accent-fonce); }
      /* ── LA PASTILLE DU VENDEUR DANS LE BANDEAU ───────────────────────────────────
         « Dans la bande verte je verrais plus, de maniere stylee, le nom du
         proprietaire », Rodolphe, 21/08/2026. Le bandeau d une conversation porte donc
         l identite : la pastille, le nom, le bien et l avancement.

         ⚠️ ELLE ABANDONNE SES QUATRE TEINTES ICI. Un aplat pale tire au hasard du nom
         sur un vert profond donne une tache dont on ne sait pas si elle veut dire
         quelque chose. Sur le vert, la pastille devient un rond de verre : blanc
         attenue, cercle blanc fin, initiales pleines. */
      .tete-ecran-avant { position: relative; flex: none; }
      .espace-agent .tete-ecran-avant .initiales {
        width: 52px; height: 52px; font-size: 1rem; font-weight: 700;
        background: rgba(255, 255, 255, .16); color: #fff;
        border: 1px solid rgba(255, 255, 255, .34);
        box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
        backdrop-filter: blur(2px);
      }
      /* Le titre du bandeau d une conversation est un NOM DE PERSONNE : il se lit mieux
         un peu plus serre que le titre d un ecran, et la ligne du dessous porte le bien
         plutot qu une phrase. */
      .tete-messagerie .tete-ecran-haut { align-items: center; margin-bottom: 0; }
      /* ⚠️ PLUS SERRE QUE LES AUTRES BANDEAUX, ET C EST VOULU. Celui-ci ne titre pas un
         ecran, il nomme une personne : il n a pas besoin des trente-deux pixels que
         prennent « Vendeurs » ou « Visites » au-dessus de leur titre. Cent quarante-sept
         pixels sur une fenetre de sept cent soixante, c etait un cinquieme de l ecran
         pris a la conversation. */
      .tete-messagerie .tete-ecran { padding: var(--e5) var(--e5) var(--e4); }
      .tete-messagerie .tete-ecran-sous { font-size: .86rem; letter-spacing: .01em; }
      /* La frise posee dans le bandeau : ses ronds passent en blanc. */
      .espace-agent .tete-ecran-dessous { position: relative; }
      .espace-agent .tete-ecran-dessous .etape-frise .rond-frise {
        background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.28); color: rgba(255,255,255,.8);
      }
      .espace-agent .tete-ecran-dessous .etape-frise.faite .rond-frise {
        background: rgba(255,255,255,.9); border-color: rgba(255,255,255,.9); color: var(--accent-fonce);
      }
      .espace-agent .tete-ecran-dessous .etape-frise.encours .rond-frise {
        background: #fff; border-color: #fff; color: var(--accent-fonce);
      }
      .espace-agent .tete-ecran-dessous .nom-frise { color: rgba(255,255,255,.75); }
      .espace-agent .tete-ecran-dessous .etape-frise.encours .nom-frise { color: #fff; }
      .espace-agent .tete-ecran-dessous .etape-frise:hover { background: rgba(255,255,255,.12); }

      /* ═══════════ LE BANDEAU DU DOSSIER, DESSIN « C » ═══════════
         Maquette validee par Rodolphe le 26/08/2026 : « la c est propre, la C ».

         Un seul bloc au lieu de deux. Le vert porte l identite, l action, le fil des
         etapes, puis les onglets en pastilles. La seconde barre blanche disparait.

         ⚠️ LA FRISE DEVIENT UN RAIL A TOUTES LES LARGEURS. C est le dessin que le
         telephone avait deja : onze segments, aucun nom, et le nom de l etape courante
         ecrit au-dessus en toutes lettres. Onze legendes de six pixels dans un bandeau
         ne se lisaient pas — elles ont ete mesurees a 2,23 de contraste, sous le seuil
         de 4,5 — et les allonger aurait rendu le bandeau plus haut, pas plus clair.
         CHAQUE SEGMENT RESTE UN LIEN : rien ne devient inatteignable. */
      /* ⚠️ EN COLONNE, PAS EN LIGNE. La regle generale range ce bloc en flex : la
         legende et le rail se partageaient la largeur, et le rail tombait a quatre-vingt-
         dix pixels pour onze segments. */
      .espace-agent .tete-ecran-dessous { display: block; }
      .espace-agent .tete-ecran-dessous .frise-etapes {
        padding: var(--e2) 0 0; margin-bottom: 0; overflow: visible;
      }
      .espace-agent .tete-ecran-dessous .frise-piste {
        width: 100%; gap: 3px; margin: 0; transform: none;
      }
      /* Le segment fait six pixels de haut et se touche sur trente : le trait reste
         fin, la zone sensible l entoure. */
      .espace-agent .tete-ecran-dessous .etape-frise {
        flex: 1; min-width: 0; padding: 0; gap: 0; min-height: 30px;
        justify-content: center; transform: none; opacity: 1; border-radius: 3px;
      }
      .espace-agent .tete-ecran-dessous .etape-frise .nom-frise { display: none; }
      .espace-agent .tete-ecran-dessous .etape-frise .rond-frise {
        width: 100%; height: 6px; border-radius: 3px; border: 0;
        font-size: 0; background: rgba(255,255,255,.22); color: transparent;
        box-shadow: none;
      }
      /* ⚠️ `font-size: 0` NE CACHE PAS UN DESSIN. Il efface le CHIFFRE d une etape a
         venir, pas la coche d une etape faite : une icone est un SVG, elle porte sa
         propre taille et se moque de la taille du texte. Mesure du 27/08/2026 : quinze
         pixels de coche dans un segment de six, debordant de neuf par le bas, onze fois
         de suite. C est la « frise avec des V » signalee par Rodolphe, et elle datait du
         jour ou le rail compact a ete ecrit.

         Rien n est perdu : dans un rail, « c est fait » se dit par la couleur pleine du
         segment — la coche ne repetait qu une information deja donnee. */
      .espace-agent .tete-ecran-dessous .etape-frise .rond-frise svg { display: none; }
      .espace-agent .tete-ecran-dessous .etape-frise.faite .rond-frise {
        background: rgba(255,255,255,.85);
      }
      .espace-agent .tete-ecran-dessous .etape-frise.encours .rond-frise {
        background: #fff; box-shadow: 0 0 0 3px rgba(255,255,255,.22);
      }
      .espace-agent .tete-ecran-dessous .etape-frise.regarde .rond-frise {
        background: rgba(255,255,255,.6);
      }
      .espace-agent .tete-ecran-dessous .etape-frise:hover { background: none; }
      .espace-agent .tete-ecran-dessous .etape-frise:hover .rond-frise {
        background: #fff;
      }

      /* Le nom de l etape et son rang, qui ne servaient que sur telephone : ils
         deviennent la legende du rail, a toutes les largeurs. */
      /* ⚠️ UNE SEULE PASTILLE, POUSSEE A DROITE. C etaient deux objets aux deux bouts
         d une ligne qui disaient la meme chose : ou en est le dossier. Reunis, ils se
         lisent d un coup.

         ⚠️ ET SA COULEUR EST CELLE DU TEMPS, comme sur les cartes de la fiche vendeur :
         meme information, meme teinte, d un ecran a l autre. Les tons du fond clair ne
         valent rien sur ce vert-la — un bleu pale y devient gris — donc chaque temps a
         ici sa variante claire sur fond sombre. */
      .espace-agent .tete-ecran-dessous .etape-bandeau {
        position: relative; display: flex; justify-content: flex-end;
        align-items: baseline; margin: 0;
      }
      .etape-jeton {
        display: inline-flex; align-items: baseline; gap: .4rem;
        font-size: .78rem; font-weight: 500; letter-spacing: .01em;
        border-radius: 999px; padding: .2rem .65rem;
        background: rgba(255,255,255,.16); color: rgba(255,255,255,.92);
      }
      .etape-jeton b { font-weight: 700; font-variant-numeric: tabular-nums; }
      .etape-jeton.temps-estime { background: rgba(147,190,244,.2); color: #c3dcfb; }
      .etape-jeton.temps-mandat { background: rgba(246,217,138,.2); color: #f3d99a; }
      .etape-jeton.temps-vend   { background: rgba(126,226,176,.2); color: #a7ecc8; }
      .etape-jeton.temps-perdu  { background: rgba(255,150,140,.2); color: #ffb3ab; }

      /* ── LA FICHE D UN VENDEUR, BANDEAU RANGE ──────────────────────────────────
         « Trop d ecriture n importe ou, c est brouillon » — Rodolphe, 26/08/2026.
         Vingt objets de texte dans le bandeau, huit apres. Ce qui part, ce sont les
         CADRES et les CAPITALES : le decor, pas le contenu. Une pastille dit « je suis
         un objet », une capitale dit « je suis un titre » — vingt objets qui reclament
         tous d etre un titre, c est ce qui fait le brouillon.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .etat-ligne {
        margin: .22rem 0 0; font-size: .74rem; font-weight: 400;
        color: rgba(255,255,255,.6); letter-spacing: .012em;
        display: flex; gap: .45rem; align-items: center; flex-wrap: wrap;
      }
      .etat-point {
        width: 5px; height: 5px; border-radius: 50%; background: #84dbb0;
        flex: none; margin-right: .1rem;
      }
      .etat-sep { opacity: .45; }
      /* Le vendeur, sous l adresse du bien : petit, souligne, donc reconnaissable comme
         un lien. Sur fond vert, un lien qui ne porte ni couleur distincte ni
         soulignement ne se distingue pas d un sous-titre — et personne n essaie de
         cliquer sur un sous-titre. */
      .lien-vendeur {
        display: inline-block; margin-top: .15rem;
        color: rgba(255,255,255,.92); text-decoration: underline;
        text-underline-offset: 3px; text-decoration-thickness: 1px;
        text-decoration-color: rgba(255,255,255,.45);
      }
      .lien-vendeur:hover {
        color: #fff; text-decoration-color: #fff;
      }

      .etat-large { display: inline; }
      @media (max-width: 560px) { .etat-large { display: none; } }

      /* Un seul objet plein dans tout le bandeau : c est ce qui le fait ressortir sans
         qu on ait besoin de le grossir. */
      .gestes-vendeur { display: flex; gap: .45rem; align-items: center; margin: var(--e3) 0 0; }
      .gestes-vendeur a {
        display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
        height: 36px; border-radius: 999px; text-decoration: none;
        font-size: .86rem; font-weight: 500; letter-spacing: .01em;
      }
      .gestes-vendeur a:hover { text-decoration: none; }
      .geste-plein {
        padding: 0 .95rem; background: #fff; color: #0a3d2e;
        font-variant-numeric: tabular-nums;
      }
      /* Sur ordinateur on lit le numero, sur telephone on appuie. */
      .tel-mot { display: none; }
      @media (max-width: 560px) {
        .tel-numero { display: none; }
        .tel-mot { display: inline; }
      }
      .geste-plein:hover { color: #0a3d2e; background: rgba(255,255,255,.9); }
      .geste-trait {
        width: 36px; border: 1px solid rgba(255,255,255,.22); color: rgba(255,255,255,.88);
      }
      .geste-trait:hover { color: #fff; background: rgba(255,255,255,.1); }

      /* La ligne « ce qui attend » n existe que si elle a quelque chose a dire : c est
         le rendu qui la supprime, pas une regle d affichage. */
      .attend-vendeur {
        position: relative; display: flex; gap: .45rem; align-items: center;
        flex-wrap: wrap; margin: .85rem 0 0;
      }
      .marque-vendeur {
        display: inline-flex; align-items: center; gap: .4rem;
        font-size: .78rem; font-weight: 400; letter-spacing: .01em;
        border-radius: 999px; padding: .22rem .65rem;
        border: 1px solid rgba(255,255,255,.22); color: rgba(255,255,255,.85);
      }
      /* Ce qui appelle une action, et seulement cela, prend la couleur d attention. */
      .marque-vendeur.chaud {
        border-color: rgba(246,217,138,.55); color: #f3d99a; font-weight: 500;
      }

      /* ═════ LE MEME FILTRE, SUR FOND CLAIR ═════
         Des pastilles sur une piste grise : la forme que prend un filtre partout dans
         l application — les pieces d un dossier l ont depuis hier, la liste des
         conversations la prend a son tour. Un meme objet dessine de deux facons se lit
         comme deux objets differents.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .barre-volets.barre-volets-piste {
        display: flex; gap: .2rem; margin: 0 0 var(--e3);
        padding: .2rem; border-radius: 999px; background: var(--papier);
        border-bottom: 0; position: static;
      }
      .barre-volets-piste > .volet-mot {
        flex: 1; flex-direction: row; justify-content: center; gap: .35rem;
        padding: .35rem .5rem; border-radius: 999px;
        font-size: .85rem; font-weight: 500; color: var(--encre-3);
      }
      .barre-volets-piste > .volet-mot::after { display: none; }
      .barre-volets-piste > .volet-mot:hover { color: var(--encre-2); }
      .barre-volets-piste > .volet-mot.actif {
        background: var(--surface); color: var(--encre); font-weight: 650;
        box-shadow: var(--ombre);
      }

      /* ═════ LA LISTE DES VENDEURS PORTE LE MEME BANDEAU QUE LA FICHE D UN DOSSIER ═════
         « Est-ce que tu peux t occuper du bandeau, des sous-onglets et de la barre de
         recherche pour avoir une similarite avec celle du dossier ? » — Rodolphe,
         27/08/2026.

         Cet ecran portait deja les deux memes objets — un champ et des onglets — mais
         poses sur une carte blanche flottant sous le vert. La liste et la fiche qu elle
         ouvre se ressemblent desormais : meme bande, memes pastilles, meme jonction.

         ⚠️ C EST LE BLOC PARENT QUI PORTE LE VERT, ET NON LA BARRE. Ici deux elements
         montent ensemble dans le bandeau, le champ et les onglets ; sur la fiche d un
         dossier il n y en a qu un. La bande est donc peinte une fois, sur leur
         conteneur.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ `.monte-bandeau` A DISPARU LE 28/08/2026, ET SES DEUX REGLES AVEC LUI.
         Il peignait une SECONDE bande verte sous celle du bandeau, sur la messagerie
         seule : mesure a 1440 px, le bandeau finissait a 135 px et le bloc courait de
         111 a 234. Les onglets de la messagerie prennent maintenant la meme mise en
         place que partout ailleurs, portee par `.barre-volets-vert`. */

      /* ═══════ LES ONGLETS, EN PASTILLES SUR LE VERT ═══════

         ⚠️ ILS RESTENT DANS LE DOCUMENT, ET NON DANS LE BANDEAU. Un element collant
         enferme dans un bloc a `overflow: hidden` — ce qu est le bandeau, pour que son
         degrade ne deborde pas — cesse de coller. On remonte donc la barre PAR-DESSUS le
         vert avec une marge negative : elle a l air d y etre, et elle garde sa position
         collante quand on descend dans une longue fiche.

         ⚠️ ET ELLE PORTE SON PROPRE FOND, plus sombre que le bandeau. Une bande
         volontairement distincte plutot qu un raccord de degrade impossible a ajuster —
         et le jour ou elle se colle en haut de l ecran, elle reste opaque. */
      .espace-agent .bascule-volet ~ .barre-volets.barre-volets-vert {
        /* ⚠️ UN FONDU ENTRE LES DEUX VERTS. « Un petit fondu entre les deux fonds verts
           serait pas mal » — Rodolphe, 26/08/2026. La bande partait d un aplat plus
           sombre : le raccord se lisait comme un trait. Elle commence donc a la couleur
           que le bandeau porte a cet endroit-la et descend vers la sienne. Le degrade
           reste peint quand la barre se colle en haut : elle ne devient jamais
           transparente. */
        background: linear-gradient(180deg, #0d5c46 0%, #0b4636 68%); border-bottom: 0;
        margin: calc(var(--e5) * -2) calc(var(--e6) * -1) var(--e5);
        padding: var(--e3) var(--e5) var(--e4);
        gap: .25rem;
      }
      .espace-agent .barre-volets.barre-volets-vert .volet-mot {
        flex: 1; flex-direction: row; justify-content: center; gap: .4rem;
        padding: .45rem .5rem; border-radius: 999px;
        font-size: .86rem; color: rgba(255,255,255,.78);
      }
      .espace-agent .barre-volets.barre-volets-vert .volet-dessin { margin-bottom: 0; }
      .espace-agent .barre-volets.barre-volets-vert .volet-compte {
        background: rgba(255,255,255,.18); color: #fff; border: 0;
      }
      .espace-agent .barre-volets.barre-volets-vert .volet-mot:hover {
        color: #fff; background: rgba(255,255,255,.1);
      }
      /* La pastille pleine dit ou l on est. Le trait sous le mot ne se voyait pas sur
         un fond colore ; un fond blanc, si. */
      .espace-agent .bascule-volet:nth-of-type(1):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(1),
      .espace-agent .bascule-volet:nth-of-type(2):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(2),
      .espace-agent .bascule-volet:nth-of-type(3):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(3),
      .espace-agent .bascule-volet:nth-of-type(4):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(4),
      .espace-agent .bascule-volet:nth-of-type(5):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(5),
      .espace-agent .bascule-volet:nth-of-type(6):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(6) {
        background: #fff; color: #0a3d2e; font-weight: 650;
      }
      .espace-agent .barre-volets.barre-volets-vert .volet-mot::after { display: none; }
      /* La variante « liens » n a pas de bouton radio pour dire ou l on est : c est la
         classe `actif` posee par le serveur. */
      .espace-agent .barre-volets.barre-volets-vert > .volet-mot.actif {
        background: #fff; color: #0a3d2e; font-weight: 650;
      }
      .espace-agent .barre-volets.barre-volets-vert > .volet-mot.actif .volet-compte {
        background: #0a3d2e; color: #fff;
      }
      /* ⚠️ SUR TELEPHONE, LA REPRISE DU BAS DE FEUILLE GAGNAIT. Elle repeint la barre en
         blanc et annule sa marge negative : le vert disparaissait, et le texte blanc des
         onglets se retrouvait sur du blanc — on ne lisait plus qu un « Eta... ». Toutes
         les regles ci-dessus portent donc une classe de plus, ce qui les fait gagner
         quelle que soit leur place dans le fichier.

         Sur telephone, le dessin reste celui d avant : l icone au-dessus du mot. Quatre
         pastilles de soixante-dix-neuf pixels ne tiennent pas « Le bien 28/29 » sur une
         ligne. */
      @media (max-width: 560px) {
        /* ⚠️ CINQ CLASSES EN FACE, PAS QUATRE. La reprise du telephone qui remet la
           marge du haut a zero s ecrit `.espace-agent .tete-ecran ~ .bascule-volet ~
           .barre-volets` : quatre classes, et non trois comme je les avais comptees. A
           poids egal la derniere gagne, et elle est mille lignes plus bas. On reprend
           donc le meme chemin en ajoutant la notre, ce qui fait cinq — et l ordre du
           fichier cesse d avoir son mot a dire. Mesure : marge du haut a 0 px au lieu
           de -16, soit une lisiere blanche entre le bandeau et sa bande d onglets. */
        /* ⚠️ CETTE REPRISE A ETE RETIREE LE 28/08/2026, ET SA MESURE AVEC. Elle
           calait une SECONDE bande verte sous la premiere ; il n y en a plus qu une, et
           la barre d onglets vient mordre dessus comme les cases de la liste (voir le
           bloc `max-width: 760px`). Laissee en place, sa marge de -16 px gagnait contre
           celle de la ligne glissante — quatre classes contre trois. */
        /* ⚠️ LE DESSIN RESTE SUR LA LIGNE DU MOT, MEME SUR TELEPHONE. « L epaisseur de
           la barre d onglets est trop grosse, enleve les dessins, c est peut-etre ca »
           — Rodolphe, 27/08/2026. Le dessin n est pas en cause, c est son EMPILEMENT :
           icone au-dessus du mot, la pastille fait cinquante-deux pixels et la bande
           soixante-seize. Cote a cote, la bande tombe a quarante-six.

           Cette disposition en colonne datait du jour ou les onglets portaient encore
           leurs compteurs — « Le bien 28/29 » ne tenait pas sur une ligne de soixante-
           dix-neuf pixels. Ils ont ete retires depuis, et la raison avec eux. */
        /* Le reglage des pastilles du bandeau part avec elles : sur le bandeau, un
           onglet est une case depuis le 27/08, et `.volet-mot` n y existe plus. */
      }

      .espace-agent .bascule-volet:nth-of-type(1):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(1) .volet-compte,
      .espace-agent .bascule-volet:nth-of-type(2):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(2) .volet-compte,
      .espace-agent .bascule-volet:nth-of-type(3):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(3) .volet-compte,
      .espace-agent .bascule-volet:nth-of-type(4):checked ~ .barre-volets.barre-volets-vert > .volet-mot:nth-child(4) .volet-compte {
        background: #0a3d2e; color: #fff;
      }

      .tete-ecran-haut {
        display: flex; align-items: flex-start; gap: var(--e4); flex-wrap: wrap;
        margin-bottom: var(--e4);
      }
      .tete-ecran-mots { flex: 1; min-width: 0; }
      /* D ou l on vient, et sous quel numero. Sur ordinateur c est la ligne discrete
         qui remplace le lien de retour ; dans le bandeau du telephone, elle passe en
         blanc attenue avec le reste. */
      .fil-ecran {
        margin: 0 0 var(--e2); font-size: .82rem; color: var(--encre-3);
        display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
      }
      .fil-ecran a { color: var(--encre-2); }
      .fil-ecran a:hover { color: var(--accent); }

      /* ─────────────────────────────────────────────────────────────────────────
            LE BOUTON RETOUR. Une fleche et un mot, rien de plus : il ne nomme pas sa
            destination, parce qu il revient la ou l on etait et non la ou l ecran se
            range. Voir la note de `teteEcran` et public/retour.js.
            ───────────────────────────────────────────────────────────────────────── */
      /* ⚠️ IL EST ENTOURE, ET NON SEULEMENT AU SURVOL. « Peut-etre entourer le bouton
            retour » — Rodolphe, 24/08/2026. Sans contour, il se lisait comme une ligne
            de texte au-dessus du titre : rien ne disait qu on pouvait appuyer dessus, et
            sur telephone il n y a pas de survol pour le reveler. */
      /* ⚠️ LE MEME OBJET QUE `.conv-retour` DE LA MESSAGERIE, et c est voulu : un rond
            de quarante pixels, la fleche seule, pose a gauche de ce qu on quitte. Deux
            dessins pour un meme geste, c est deux choses a apprendre. */
      .bouton-retour {
        display: grid; place-items: center; flex: none;
        width: 40px; height: 40px; margin: 0;
        border: 1px solid var(--trait); border-radius: 50%;
        background: var(--surface);
        color: var(--encre-2); text-decoration: none;
      }
      .bouton-retour:hover {
        border-color: var(--accent-bord); background: var(--papier);
        color: var(--accent); text-decoration: none;
      }
      .bouton-retour svg { flex: none; }
      /* Pose seul en tete de contenu — les ecrans sans bandeau — il garde de l air
            sous lui, sinon le titre qui suit lui colle dessus. */
      p > .bouton-retour { margin-bottom: var(--e2); }

      /* ⚠️ LA VARIANTE CLAIRE EST CELLE DU BANDEAU, PAS CELLE DE L ESPACE AGENT.
            Ecrite `.espace-agent .bouton-retour`, elle s appliquait a TOUTES les pages du
            conseiller — dont celles qui n ont pas de bandeau vert : bordure blanche sur
            fond blanc, bouton invisible. Constate sur la fiche imprimable d un bien, ou
            il ne restait qu un vide en haut de page. Le selecteur vise donc le bandeau,
            qui est le seul fond fonce. */
      .espace-agent .tete-ecran .bouton-retour {
        background: rgba(255,255,255,.08);
        border-color: rgba(255,255,255,.35);
        color: rgba(255,255,255,.92);
      }
      .espace-agent .tete-ecran .bouton-retour:hover {
        background: rgba(255,255,255,.2);
        border-color: rgba(255,255,255,.6); color: #fff;
      }
      /* ⚠️ ET LE TITRE SE DECALE, IL NE PASSE PAS DESSOUS. `.tete-ecran-haut` aligne
            ses enfants sur la ligne de base : le rond, plus haut que le mot, tirait le
            titre vers le bas. On centre. */
      .tete-ecran-haut:has(.bouton-retour) { align-items: center; }

      /* ═════════════════════════════════════════════════════════════════════════
            LA FICHE VENDEUR, REORGANISEE (maquette validee le 24/08/2026).

            Ce qu on vient y faire, dans l ordre : joindre la personne, savoir ou en
            sont ses affaires, agir sur celle qui le demande. L ecran suivait l ordre
            inverse — reglages en haut, dossiers tout en bas.
            ═════════════════════════════════════════════════════════════════════════ */

      /* Les etats sous le nom : actif, depuis quand, vu quand. Des pastilles et non
            une phrase — on les lit sans les lire. */
      .etats-vendeur { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e2); }
      .etat-vendeur {
        display: inline-flex; align-items: center; gap: .3rem;
        padding: .15rem .55rem; border-radius: 999px;
        font-size: .74rem; font-weight: 600;
        background: rgba(255,255,255,.16); color: #fff;
      }
      .etat-vendeur.vif { background: rgba(120,235,190,.24); }
      .etat-vendeur.tiede { background: rgba(255,214,140,.26); }
      .etat-vendeur.eteint { background: rgba(255,170,160,.24); }
      .etat-vendeur i {
        width: 6px; height: 6px; border-radius: 50%; background: currentColor;
      }

      /* ⚠️ TROIS CIBLES PLEINES, ET NON TROIS LIENS. C est le geste qu on vient faire
            ici neuf fois sur dix : appeler. Il etait un lien souligne au milieu d une
            phrase, a cote du numero.

            ⚠️ ET LA CLASSE S APPELLE `contacter`, PAS `joindre`. `joindre` existait
            deja, plus bas dans ce fichier : c est le bouton qui attache un fichier a un
            message. Mesure : la regle d en bas gagnait, le bloc passait en grille de
            quarante pixels de large et les trois boutons s empilaient hors du bandeau.
            Septieme collision de nom relevee dans ce fichier. */
      .contacter { display: flex; gap: var(--e2); margin-top: var(--e4); }
      .contacter a {
        flex: 1; min-height: 44px;
        display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
        border-radius: var(--r-petit); text-decoration: none;
        font-size: .88rem; font-weight: 600;
        background: rgba(255,255,255,.14); color: #fff;
        border: 1px solid rgba(255,255,255,.22);
        transition: background .15s var(--vif);
      }
      .contacter a.primaire { background: #fff; color: #0a3d2e; border-color: #fff; }
      .contacter a:hover { background: rgba(255,255,255,.26); text-decoration: none; }
      .contacter a.primaire:hover { background: #eafff5; }

      /* ⚠️ LA LIGNE DE VIE REPOND AVANT QU ON AIT CLIQUE. Prochain rendez-vous,
            avancement, relances, derniere connexion : quatre chiffres qu il fallait
            aller chercher dans quatre endroits differents de la page. */
      .ligne-vie {
        display: grid; gap: var(--e3);
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        margin: 0 0 var(--e4); padding: var(--e4);
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r); box-shadow: var(--ombre);
      }
      .vie-k {
        display: block; font-size: .68rem; font-weight: 700; letter-spacing: .07em;
        text-transform: uppercase; color: var(--encre-3);
      }
      .vie-v {
        display: block; margin-top: .1rem; line-height: 1.3;
        font-size: 1.02rem; font-weight: 650; color: var(--encre);
      }
      .vie-v.alerte { color: var(--danger); }
      .vie-v.bien { color: var(--succes); }

      /* ═════ LA CARTE D UN DOSSIER ═════
            ⚠️ L ETAT SE LIT AU BORD, PAS DANS UNE PASTILLE. Une bande de trois pixels
            se repere en balayant une liste ; une pastille demande de lire. */
      .carte-affaire {
        display: block; background: var(--surface);
        border: 1px solid var(--trait); border-left: 3px solid var(--encre-4);
        border-radius: var(--r); box-shadow: var(--ombre);
        overflow: hidden; text-decoration: none; color: inherit;
        transition: box-shadow .15s var(--vif), transform .15s var(--vif);
      }
      .carte-affaire + .carte-affaire { margin-top: var(--e3); }
      .carte-affaire:hover {
        box-shadow: var(--ombre-relief); transform: translateY(-1px);
        text-decoration: none; color: inherit;
      }
      .carte-affaire.avance { border-left-color: var(--succes); }
      .carte-affaire.attente { border-left-color: var(--attention); }
      .carte-affaire.retard { border-left-color: var(--danger); }

      /* ═════ LES QUATRE TEMPS D UNE AFFAIRE ═════
         « Mettre le nom de l etape a la place du numero, et le mettre en valeur avec des
         couleurs differentes » — Rodolphe, 26/08/2026.

         ⚠️ QUATRE COULEURS, PAS ONZE. Onze teintes font un arc-en-ciel ou plus rien ne
         ressort, et une couleur qui ne se compare a rien ne dit rien. Les quatre temps
         sont ceux du metier — on prend contact, on estime, on decroche le mandat, on
         vend — et c est ce qui les rend lisibles sans legende : on voit ou en est
         l affaire avant d avoir lu le mot. Le partage des etapes vit dans
         metier/statuts.js, `tempsDeLEtape`.

         ⚠️ ILS NE REMPLACENT PAS `avance` / `attente` / `retard`, qui disent autre chose :
         non pas ou en est l affaire, mais si elle avance ou si elle traine. Ces trois-la
         sont ecrits APRES dans cette feuille, et gagnent donc le bord gauche quand ils
         s appliquent — c est voulu : un retard prime sur un temps. */
      /* ⚠️ « PRISE DE CONTACT » ÉTAIT EN GRIS, ET LE GRIS NE DIT RIEN. C est le seul
         des cinq temps qui n avait pas de couleur : il empruntait `--encre-3`, la
         teinte du texte secondaire, ce qui le faisait lire comme une mention éteinte
         plutôt que comme un moment du parcours. Il prend l accent de l application —
         celui du menu, des liens et des cerclages — et le nuancier redevient complet.
         Rodolphe, 27/08/2026 : « ces gris sont dégueulasses, j en veux plus ». */
      .temps-contact { --temps: var(--accent); --temps-fond: var(--accent-pale); }
      .temps-estime  { --temps: #1d5fb4; --temps-fond: #e9f1fb; }
      .temps-mandat  { --temps: var(--attention); --temps-fond: #fdf3e0; }
      .temps-vend    { --temps: var(--succes); --temps-fond: var(--succes-pale); }
      .temps-perdu   { --temps: var(--danger); --temps-fond: var(--danger-pale); }
      .carte-affaire[class*="temps-"] { border-left-color: var(--temps); }

      /* L etape, a la place du numero. Elle porte la couleur de son temps. */
      .etape-pastille {
        flex: none; font-size: .76rem; font-weight: 600; letter-spacing: .01em;
        padding: .18rem .6rem; border-radius: 999px; white-space: nowrap;
        background: var(--temps-fond, var(--papier)); color: var(--temps, var(--encre-3));
      }

      .affaire-haut {
        display: flex; align-items: flex-start; gap: var(--e3);
        padding: var(--e4) var(--e4) var(--e3);
      }
      .affaire-mots { flex: 1; min-width: 0; }
      .affaire-titre { margin: 0; font-size: 1rem; font-weight: 650; line-height: 1.3; }
      .affaire-lieu {
        margin: .1rem 0 0; font-size: .84rem; color: var(--encre-3);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .affaire-numero {
        flex: none; font-size: .72rem; font-weight: 600; color: var(--encre-3);
        font-variant-numeric: tabular-nums;
        padding: .1rem .45rem; border-radius: 999px; background: var(--papier);
      }
      /* ═════ OUVRIR UN DOSSIER ═════
         Une invitation au trait, pas une carte. Elle suit la pile des dossiers et doit
         peser MOINS qu eux : posee en carte pleine, de la meme taille et du meme poids,
         elle se lisait comme un troisieme dossier. */
      .ouvrir-dossier { margin-top: var(--e3); }
      .ouvrir-dossier > summary {
        display: flex; align-items: center; gap: var(--e3);
        padding: var(--e3) var(--e4); border-radius: var(--r);
        border: 1.5px dashed var(--trait); background: none;
        color: var(--encre-2); font-size: .92rem; font-weight: 500;
        cursor: pointer; list-style: none;
      }
      .ouvrir-dossier > summary::-webkit-details-marker { display: none; }
      .ouvrir-dossier > summary::marker { content: ""; }
      .ouvrir-dossier > summary:hover { border-color: var(--accent); color: var(--encre); }
      .ouvrir-rond {
        flex: none; width: 30px; height: 30px; border-radius: 50%;
        border: 1.5px solid var(--trait); display: grid; place-items: center;
        color: var(--encre-3);
      }
      .ouvrir-dossier[open] > summary {
        border-style: solid; border-radius: var(--r) var(--r) 0 0; border-bottom: 0;
      }
      .ouvrir-dossier[open] .corps-section {
        border: 1.5px solid var(--trait); border-top: 0;
        border-radius: 0 0 var(--r) var(--r); padding: var(--e4);
      }

      /* La frise du parcours, reduite a onze traits : c est la meme information que
            la grande frise du dossier, a la taille ou l on compare plusieurs affaires. */
      .frise-mini { display: flex; gap: 3px; padding: 0 var(--e4) var(--e3); }
      .frise-mini i {
        flex: 1; height: 4px; border-radius: 999px; background: var(--trait);
      }
      .frise-mini i.faite { background: color-mix(in oklab, var(--encre-3) 55%, #fff); }
      /* Le segment allume prend la couleur du temps : la pile se trie sans lire. */
      .frise-mini i.ici { background: var(--temps, var(--accent)); }
      .affaire-etape {
        display: flex; align-items: baseline; justify-content: space-between;
        gap: var(--e3); padding: 0 var(--e4) var(--e3);
      }
      /* Le numero descend ici : c est une reference administrative, celle qu on donne au
         notaire, et non une information de travail. */
      .affaire-etape .numero {
        font-size: .78rem; color: var(--encre-3); font-variant-numeric: tabular-nums;
      }
      .affaire-etape .rang {
        flex: none; font-size: .78rem; color: var(--encre-3);
        font-variant-numeric: tabular-nums;
      }
      /* ⚠️ « CE QU IL RESTE A FAIRE » EST LA LIGNE QU ON VIENT CHERCHER. La jauge de
            pourcentage disait un chiffre, pas un geste : « 45 % complete » ne dit pas
            quoi faire, « quatre pieces manquent » si. */
      .affaire-faire {
        display: flex; align-items: center; gap: var(--e3);
        padding: var(--e3) var(--e4);
        background: var(--papier); border-top: 1px solid var(--trait);
        font-size: .86rem; color: var(--encre-2);
      }
      .affaire-faire b { color: var(--encre); font-weight: 650; }
      .affaire-faire .chevron { flex: none; color: var(--encre-4); display: flex; }

      /* ⚠️ DEUX COLONNES A PARTIR DE NEUF CENTS PIXELS, ET UNE SEULE EN DESSOUS.
            Les cartes de dossier sont ce qu on vient lire ; les rendez-vous et l acces
            sont utiles mais jamais urgents. Sur ordinateur ils tiennent a cote sans
            rien voler ; sur telephone ils descendent, parce qu une colonne de trois
            cents pixels ne montre plus une adresse. */
      /* ⚠️ `minmax(0, 1fr)` DES LA PREMIERE COLONNE, ET PAS SEULEMENT SUR ORDINATEUR.
            Sans template, la colonne implicite vaut `auto`, donc `min-width: auto` :
            l adresse d un bien, qui ne se coupe pas, poussait la carte au-dela de son
            conteneur. Mesure a 375 pixels : le volet allait de 16 a 359, la carte de 16
            a 363. Quatre pixels, mais la carte ne s alignait plus sur la ligne de vie
            juste au-dessus. */
      .fiche-deux-colonnes {
        display: grid; gap: var(--e4); align-items: start;
        grid-template-columns: minmax(0, 1fr);
      }
      /* ⚠️ SUR TELEPHONE, LES RENDEZ-VOUS PASSENT DEVANT. « Ce serait bien de pouvoir
         les avoir en haut de la page, avant les dossiers » — Rodolphe, 26/08/2026.
         Sur ordinateur ils sont dans la colonne de droite, donc a hauteur d oeil ; en
         une seule colonne ils tombaient sous la pile des dossiers, c est-a-dire hors de
         l ecran des qu il y en a deux. Or c est la premiere chose qu on regarde avant
         d appeler quelqu un : est-ce qu on le voit bientot. */
      .fiche-deux-colonnes > :nth-child(2) { order: -1; }
      @media (min-width: 900px) {
        .fiche-deux-colonnes {
          grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
        }
        .fiche-deux-colonnes > :nth-child(2) { order: 0; }
      }
      /* Le rendez-vous, dans la colonne de droite : le jour en gros, le reste a
            cote. C est la forme qu on lit d un coup d oeil dans un agenda. */
      .rdv-bref { display: flex; gap: var(--e3); align-items: flex-start; padding: var(--e2) 0; }
      .rdv-bref + .rdv-bref {
        border-top: 1px solid color-mix(in oklab, var(--trait) 60%, transparent);
      }
      .rdv-bref.passe { opacity: .55; }
      .rdv-jour {
        flex: none; width: 46px; text-align: center; line-height: 1.15; padding-top: .1rem;
      }
      .rdv-jour b { display: block; font-size: 1.05rem; font-weight: 700; }
      .rdv-jour span {
        display: block; font-size: .66rem; font-weight: 700; letter-spacing: .06em;
        text-transform: uppercase; color: var(--encre-3);
      }
      .rdv-bref-quoi { flex: 1; min-width: 0; }
      .rdv-bref-quoi b { display: block; font-size: .9rem; font-weight: 600; }
      .rdv-bref-quoi span { font-size: .8rem; color: var(--encre-3); }

      @media (max-width: 560px) {
        .contacter { flex-wrap: wrap; }
        .contacter a { flex: 1 1 30%; font-size: .82rem; }
        .ligne-vie { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: var(--e3); }
        /* ⚠️ LES ETIQUETTES RESERVENT DEUX LIGNES SUR TELEPHONE. « Prochain
              rendez-vous » se casse en deux a cette largeur, les trois autres non : les
              valeurs se retrouvaient decalees d une ligne d une colonne a l autre, et la
              ligne de vie ne se lisait plus comme une ligne. */
        .vie-k { min-height: 2.1em; }
      }

      /* Ce qui se pose sous le titre. Sur ordinateur, la frise y garde son arc de ronds
         legendes : elle a simplement quitte la carte d avancement pour remonter ici. */
      .tete-ecran-dessous { margin-top: var(--e3); }
      .tete-ecran-dessous .frise-etapes { margin-bottom: 0; }
      /* Le nom court de l etape et son rang ne servent que sur telephone, ou la frise
         perd ses legendes. Sur ordinateur chaque rond porte deja son nom. */
      .etape-bandeau { display: none; }
      .espace-agent .tete-ecran h1 { margin: 0; }
      .tete-ecran-sous { margin: .25rem 0 0; color: var(--encre-3); font-size: .92rem; }
      .tete-ecran-action {
        display: inline-flex; align-items: center; gap: var(--e2); flex: none;
        min-height: 44px; padding: .6rem 1.05rem; border-radius: var(--r-petit);
        background: var(--accent); color: #fff; font-weight: 600; text-decoration: none;
        box-shadow: var(--ombre-relief);
      }
      .tete-ecran-action:hover { background: var(--accent-fonce); color: #fff; }
      /* Le signe remplace le mot sur telephone, ou le bouton devient un rond. */
      .signe-action { display: none; }

      /* Les onglets d une page. Cachés par défaut : ils n existent que sur les écrans
         qui en déclarent, et la barre ne se voit jamais sur ordinateur. */
      /* Le bien visité, sous le nom : sur une visite d acquereur ce sera la seule chose
         qui dise de quel logement on parle.

         ⚠️ PAS « .ligne-bien » : CE NOM EST DEJA PRIS, dix-huit cents lignes plus bas,
         par la rangee cliquable des biens d un vendeur. La regle la plus tardive
         l emportait, et le bien visite s affichait dans un cadre gris avec une fleche.
         Troisieme collision de nom de classe dans ce fichier. */
      .visite-bien {
        margin: .1rem 0 0; font-size: .8rem; color: var(--encre-3);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .heure-visite { font-variant-numeric: tabular-nums; }
      /* ⚠️ LA PASTILLE PLEINE DEVIENT UN POINT SUIVI DU MOT. Sur une liste de dix
         lignes, dix pastilles vertes tiraient l oeil plus fort que les noms qu elles
         decrivaient : la couleur suffit a dire l etat, le fond le repetait en occupant
         six fois plus de place. */
      .etat-point { display: inline-flex; align-items: center; gap: .32rem; }
      .etat-point::before {
        content: ""; width: 6px; height: 6px; border-radius: 50%;
        background: var(--encre-3); flex: none;
      }
      .etat-point.etat-tard { color: var(--danger); }
      .etat-point.etat-tard::before { background: var(--danger); }
      .etat-point.etat-ok::before { background: var(--succes); }
      .etat-point.etat-attente::before { background: var(--attention); }

      /* ── L IDENTITE DE L ESPACE AGENT, A TOUTES LES LARGEURS ──────────────────
         Confrontation faite le 20/08/2026, maquette par maquette, propriete par
         propriete, puis relevee sur l ecran.

         ⚠️ CES REGLES NE SONT PLUS RESERVEES AU TELEPHONE. Elles decrivent un DESSIN —
         des graisses, des teintes, des rayons — et un dessin ne depend pas de la
         largeur de l ecran. Les avoir enfermees dans le bloc des 560 pixels donnait
         deux applications differentes selon l appareil.

         « sur PC ca doit ressembler vraiment au mobile », Rodolphe, 20/08/2026.

         ⚠️ LA PASTILLE D INITIALES PERD SON DEGRADE SATURE. Blanc sur vert fonce, six
         ronds par ecran devenaient la premiere chose qu on voyait, devant les noms
         qu ils accompagnent. Aplat pale, lettres dans l encre de la meme teinte : le
         role est le meme, reconnaitre quelqu un d un coup d oeil, sans passer devant
         lui. C est le plus gros ecart entre l ecran et la maquette. */
      .espace-agent .initiales {
        width: 36px; height: 36px; font-size: .72rem; font-weight: 600;
        box-shadow: none;
      }
      .espace-agent .initiales.teinte-1 { background: #e4efe9; color: #1d5c48; }
      .espace-agent .initiales.teinte-2 { background: #e5ebf4; color: #2f4d75; }
      .espace-agent .initiales.teinte-3 { background: #f3ece2; color: #7a5527; }
      .espace-agent .initiales.teinte-4 { background: #efe8f2; color: #5c4470; }
      .espace-agent .ligne-conv .initiales { width: 44px; height: 44px; font-size: .78rem; }

      /* Le nom d une ligne : .93rem et 500, non 650. La maquette allege partout ou le
         gras ne porte rien, et un nom se lit sans etre appuye. */
      .espace-agent .ligne-nom { font-size: .93rem; font-weight: 500; }
      /* ⚠️ LA LIGNE D INFORMATION AVAIT PERDU SA TAILLE. Elle etait fixee a .75rem par
         le bloc en double retire plus tot, et le bloc d identite ne la reprenait pas :
         elle est repassee a .84rem sans que rien ne le signale. Mesuree, pas lue. */
      .espace-agent .ligne-meta { font-size: .75rem; }
      .espace-agent .conv-nom { font-size: .93rem; font-weight: 500; }
      .espace-agent .conv-attend .conv-nom { font-weight: 600; }

      /* Rayons et rembourrages des listes : 14 et non 16, .6rem .75rem et non .8rem. */
      .espace-agent .liste-lignes, .espace-agent .liste-conv { border-radius: 14px; }
      .espace-agent .ligne-vendeur { padding: .6rem .75rem; }

      /* ⚠️ LE FILET PART APRES L AVATAR, IL NE TRAVERSE PLUS LA CARTE. Un trait qui va
         d un bord a l autre decoupe la liste en tranches ; decale sous le texte, il
         regroupe. C est le geste qui distingue une liste d un tableau, et c est ce que
         montrent les trois maquettes. La liste des messages le faisait deja ; celle des
         vendeurs et des visites gardaient une bordure pleine largeur.

         ⚠️ LE PSEUDO-ELEMENT D APRES ET NON CELUI D AVANT : celui d avant porte deja le
         filet d accent qui se deploie au survol. */
      .espace-agent .ligne-vendeur { border-bottom: 0; }
      .espace-agent .ligne-vendeur + .ligne-vendeur::after {
        content: ""; position: absolute; left: 3.4rem; right: .75rem; top: 0;
        height: 1px; background: var(--trait);
      }

      /* ⚠️ LE BOUTON D APPEL DEVIENT UN ROND GRIS, PAS UN CARRE BLANC CERCLE. Sur une
         ligne blanche, un bouton blanc a cadre se lit comme un champ de saisie ; le
         rond gris pale des maquettes se lit comme une touche. Trente-quatre pixels au
         lieu de quarante : c est la taille dessinee, et elle reste au-dessus du seuil
         ou le pouce attrape le voisin puisque deux boutons ne se touchent jamais. */
      .espace-agent .ligne-tel {
        width: 34px; height: 34px; border-radius: 50%;
        border: 0; background: var(--papier);
      }
      .espace-agent .ligne-tel:hover { background: var(--accent-pale); color: var(--accent); }

      /* Le bien, sous le nom : .75rem comme dessine. Deux noms pour la meme ligne —
         « visite-bien » sur une visite, « ligne-sujet » sur un vendeur — parce que le
         premier est ne avec l ecran des visites ; ils portent le meme style, et c est ce
         qui compte a l oeil. */
      .visite-bien, .ligne-sujet {
        margin: .1rem 0 0; font-size: .8rem; color: var(--encre-3);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .espace-agent .visite-bien, .espace-agent .ligne-sujet { font-size: .75rem; }

      /* L etat en point suivi du mot : .72rem, comme la maquette. */
      .espace-agent .etat-point { font-size: .72rem; }

      /* L apercu d une conversation, et la pastille du nombre en attente. */
      .espace-agent .conv-apercu { font-size: .79rem; }
      .espace-agent .conv-compte {
        min-width: 19px; height: 19px; font-size: .66rem; font-weight: 600;
        background: var(--succes);
      }
      .espace-agent .conv-quand { font-size: .68rem; }
      /* Meme rembourrage que les autres lignes de l application : .6rem .75rem. Il
         restait a .65rem 1rem, seul de son espece. */
      .espace-agent .ligne-conv { padding: .6rem .75rem; }
      .espace-agent .ligne-conv + .ligne-conv::before { left: 4.1rem; right: .75rem; }

      /* ⚠️ LE CHEVRON DE FIN DE LIGNE ETAIT PLUS PETIT QUE DESSINE : 16 pixels contre
         17.6. A cette taille la difference se voit, c est le seul repere qui dise que
         la ligne s ouvre. */
      .espace-agent .ligne-chevron { font-size: 1.1rem; }

      /* Le titre d un ecran : 700 et non 800. Le jour du tableau de bord suit la
         meme regle — il etait a 32 px et 800, les autres titres a 29,6 et 700 : la
         meme police ecrite deux fois differemment sur deux onglets voisins. */
      .espace-agent .tete-ecran h1,
      .espace-agent .tete-bord-jour { font-weight: 700; }


      /* ⚠️ DEUX CHASSES SERREES QUI NE L ETAIENT PAS DANS LA MAQUETTE. Le jour du
         tableau de bord etait a -.03em contre -.02, et le nombre des cartes a -.035em
         contre une chasse normale : a vingt-sept pixels, les chiffres se touchaient. */
      .espace-agent .tete-bord-jour { letter-spacing: -.02em; }
      .espace-agent .chiffres-bord .carte-chiffre .chiffre { letter-spacing: normal; }

      /* Le libelle sous un nombre : 700 et une chasse ouverte, comme dessine. La
         taille reste a .54rem, seul ecart assume : a .58 « REMPLIES SEULES » passe sur
         deux lignes et les trois cases cessent de se ressembler. */
      .espace-agent .chiffres-bord .carte-chiffre .quoi {
        font-weight: 700; letter-spacing: .05em; margin-top: .25rem;
      }

      /* ---- Une liste de conversations, a la maniere d une messagerie -------------

         Avatar, nom, apercu sur UNE ligne, l heure en haut a droite et le nombre en
         attente juste dessous. C est la disposition que tout le monde lit dix fois par
         jour sans y penser.

         ⚠️ LA COLONNE DE DROITE EST CE QUI REND LA LISTE BALAYABLE. L heure et la
         pastille alignees a droite sur deux lignes se lisent d un seul coup d oeil
         vertical : on voit ce qui attend sans lire un seul nom. */
      .liste-conv {
        background: var(--surface); border-radius: var(--r); overflow: hidden;
        box-shadow: var(--ombre);
      }
      .ligne-conv {
        display: grid; grid-template-columns: auto 1fr auto; gap: var(--e3);
        align-items: start; padding: .65rem var(--e4);
        text-decoration: none; color: inherit; position: relative;
      }
      /* ⚠️ LE SEPARATEUR PART APRES L AVATAR. Un trait qui traverse toute la carte la
         decoupe en tranches ; decale sous le texte, il regroupe. C est le geste qui
         distingue une liste d un tableau. */
      .ligne-conv + .ligne-conv::before {
        content: ""; position: absolute; left: 4.1rem; right: var(--e4); top: 0;
        height: 1px; background: var(--trait);
      }
      .ligne-conv:hover { background: var(--papier); text-decoration: none; color: inherit; }
      .ligne-conv .initiales { width: 44px; height: 44px; font-size: .78rem; }
      .conv-corps { min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
      .conv-nom {
        font-weight: 500; font-size: .95rem;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .conv-attend .conv-nom { font-weight: 650; }
      /* Le bien, quand le vendeur en confie plusieurs : il suit le nom sur la meme
         ligne, en plus petit et en gris, parce qu il precise le nom au lieu de le
         concurrencer. Le poids ne suit pas celui du nom en gras : ce qui attend une
         reponse, c est la personne, pas l appartement. */
      /* Le bien, sur sa propre ligne, et seulement quand le vendeur en confie
         plusieurs. A la suite du nom, la coupure mangeait les deux moities a la fois :
         le nom de famille ET la commune. Mesure a 375 px. */
      .conv-bien {
        font-weight: 500; font-size: .78rem; color: var(--accent-fonce);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      /* Un seul apercu, sur une seule ligne : deux lignes par conversation, c est trois
         conversations de moins par ecran. Le texte se coupe n importe ou, un message
         sans espace debordait de son bloc de vingt et un pixels. */
      .conv-apercu {
        font-size: .82rem; color: var(--encre-3); overflow-wrap: anywhere;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .conv-vous { color: var(--encre-3); opacity: .7; }
      .conv-droite {
        display: flex; flex-direction: column; align-items: flex-end; gap: .3rem;
        flex: none; padding-top: .1rem;
      }
      .conv-quand {
        font-size: .72rem; color: var(--encre-3); white-space: nowrap;
        font-variant-numeric: tabular-nums;
      }
      .conv-attend .conv-quand { color: var(--accent-fonce); }
      .conv-compte {
        min-width: 20px; height: 20px; padding: 0 .34rem; border-radius: 10px;
        background: var(--accent); color: #fff; font-size: .68rem; font-weight: 700;
        display: grid; place-items: center; font-variant-numeric: tabular-nums;
      }

      /* ── DEUX VOLETS SUR ORDINATEUR, UN SEUL SUR TELEPHONE ────────────────────────
         « Sur PC on pourrait optimiser l onglet conversation comme WhatsApp Web, avec
         toutes les conversations a gauche et la conversation selectionnee a droite »,
         Rodolphe, 21/08/2026 — et « sur PC uniquement », precise-t-il.

         ⚠️ LE TELEPHONE EST LA REGLE DE BASE, ET IL NE CHANGE PAS. Un volet par ecran,
         exactement comme avant : la liste sur son adresse, le fil sur la sienne. C est
         la largeur qui ajoute le second volet, jamais qui en retire un.

         Les deux volets sont rendus par le serveur dans les deux cas — il ne connait
         pas la largeur de l ecran, et la deviner sur l agent du navigateur serait la
         deviner faux. C est le style qui masque celui dont on n a pas besoin. */
      .messagerie[data-messagerie="liste"] .messagerie-panneau,
      .messagerie[data-messagerie="fil"] .messagerie-liste { display: none; }
      /* Le bandeau vert de la conversation : sur ordinateur seulement. Sur telephone,
         l ecran commence par le nom du vendeur, fige en haut — un bandeau au-dessus
         repousserait la premiere parole la ou la place manque le plus. */
      .tete-messagerie { display: none; }

      @media (min-width: 761px) {
        /* La colonne de gauche a une largeur fixe : une liste de conversations se lit
           en colonne etroite, l etirer n ajoute que du blanc entre le nom et l heure. */
        /* ⚠️ LA MESSAGERIE TIENT DANS LA FENETRE, ET CHAQUE VOLET DEFILE CHEZ LUI.
           C est ce que demande Rodolphe le 21/08/2026 : « figer la colonne des
           conversations a gauche tout le long sur PC et figer la barre de texte en bas
           sur PC et mobile ». Tant que la page entiere defilait, la colonne de gauche
           partait avec elle des que la conversation etait courte — une colonne collee
           ne peut pas depasser la hauteur de sa rangee.

           LES QUATRE-VINGT-HUIT PIXELS RETIRES SONT MESURES, pas devines : la marge du
           conteneur principal (e5) et ses deux rembourrages (e6 deux fois). */
        .tete-messagerie { display: block; }
        /* ⚠️ LE BANDEAU COLLE AU HAUT DE LA CARTE, SUR ORDINATEUR AUSSI. Il porte sa
           propre marge negative pour deborder du rembourrage du conteneur ; la regle
           « premier enfant, marge du haut a zero » la lui reprenait, et trente-deux
           pixels de blanc restaient au-dessus du vert sur chaque ecran de l espace
           agent. Sur telephone le bandeau touchait bien le haut — c est ce qui rendait
           l ecart invisible pendant qu on dessinait le telephone. */
        main.contenu > .tete-ecran:first-child { margin-top: calc(var(--e6) * -1); }
        /* ⚠️ C EST LE CONTENEUR QUI PORTE LA HAUTEUR, PAS LA MESSAGERIE. Elle la
           portait, calculee en retirant les marges connues ; le jour ou un bandeau vert
           s est pose au-dessus, la page s est remise a defiler de sa hauteur exacte. Le
           conteneur fait la fenetre, la messagerie prend ce qui reste — quoi qu on
           mette au-dessus d elle, et sans que personne ait a le recompter. */
        body:has(.messagerie) main.contenu {
          display: flex; flex-direction: column;
          height: calc(100vh - var(--h-entete, 0px) - var(--e5) * 2);
        }
        .messagerie {
          display: grid; grid-template-columns: 21rem minmax(0, 1fr);
          gap: var(--e5); align-items: stretch;
          flex: 1 1 auto; min-height: 0;
        }
        /* Le volet du fil s empile : l en-tete, le fil qui defile, la barre d envoi.
           Seul celui du milieu bouge, et la barre reste au bas de la fenetre sans avoir
           besoin d etre collee. */
        .messagerie-panneau {
          display: flex; flex-direction: column; min-height: 0;
        }
        /* ⚠️ UNE CONVERSATION COURTE SE POSE EN BAS, PAS EN HAUT. Deux bulles dans un
           cadre de six cents pixels se rangeaient sous les onglets, laissant un grand
           vide entre elles et la barre d envoi — alors que sur toute messagerie, les
           messages s empilent depuis le bas. « Fais bouger la conv, meme celles qui ont
           pas beaucoup de messages, tu verras », Rodolphe, 21/08/2026.

           La marge automatique ne fait rien des que le fil deborde : la meme regle sert
           les deux cas, sans compter les messages. */
        .messagerie-panneau > [data-au-dernier] {
          flex: 1 1 auto; min-height: 0; overflow-y: auto;
          overscroll-behavior: contain; margin: 0;
          display: flex; flex-direction: column;
        }
        .messagerie-panneau > [data-au-dernier] > .volets { margin-top: auto; }
        /* ⚠️ LES BULLES SE RESSERRENT, ET LE FOND RESTE BLANC. A soixante-dix-huit pour
           cent d un volet de huit cents pixels, une ligne faisait cent trente
           caracteres — on ne relit pas ces lignes-la. Un fond papier avait ete essaye
           pour separer le fil de la colonne des conversations, a la maniere de la
           capture ; Rodolphe l a refuse le 21/08/2026, et il a raison : ici le gris
           porte deja un sens, c est celui des bulles. */
        .messagerie .fil-conv .bulle-msg { max-width: 62%; }
        .messagerie-panneau .zone-reponse { position: static; }
        /* ⚠️ ET L EN-TETE DU VOLET DE DROITE DISPARAIT : le bandeau vert porte
           desormais la pastille, le nom, le bien et le lien vers la fiche. Les garder
           tous les deux, c etait le meme nom deux fois a soixante pixels d ecart. Il
           reste entier sur telephone, ou il n y a pas de bandeau. */
        .messagerie[data-messagerie="fil"] .tete-conv { display: none; }
        /* ⚠️ LES ONGLETS SE COLLENT AU HAUT DE LEUR CADRE, ET NON DE LA FENETRE. Un
           element colle dans un cadre qui defile compte son decalage depuis CE cadre :
           les soixante-trois pixels de l en-tete plus les soixante du nom, mesures
           depuis la fenetre, les enfoncaient de cent vingt-trois pixels dans le fil.
           Mesure : barre a 338 la ou le cadre commence a 179. */
        .messagerie-panneau > [data-au-dernier] .bascule-volet ~ .barre-volets { top: 0; }

        .messagerie[data-messagerie="liste"] .messagerie-panneau,
        .messagerie[data-messagerie="fil"] .messagerie-liste { display: block; }
        .messagerie-panneau { min-width: 0; }
        /* Plus de hauteur minimale : le volet fait desormais la fenetre, exactement. */
        /* ⚠️ LA LISTE DEFILE DANS SON PROPRE CADRE, ET S ARRETE AU BAS DE LA FENETRE.
           Sans hauteur maximale, une liste de quarante conversations allongeait la page
           bien au-dela du fil, et l on faisait defiler la conversation pour atteindre
           le bas d une liste. Chaque volet defile chez lui, comme sur la capture. */
        /* ⚠️ UNE HAUTEUR, PAS UNE HAUTEUR MAXIMALE. Avec un plafond, la colonne faisait
           la taille de son contenu : quatre conversations donnaient un bloc de trois
           cents pixels flottant en haut, et le trait qui la separe du fil s arretait
           avec lui. « Il faudrait figer la colonne des conversations a gauche tout le
           long sur PC », Rodolphe, 21/08/2026. Elle occupe donc toute la fenetre et
           defile chez elle, comme sur sa capture. */
        .messagerie-liste {
          min-height: 0; overflow-y: auto; overscroll-behavior: contain;
          border-right: 1px solid var(--trait); padding-right: var(--e4);
        }
        /* Le champ et les deux pastilles restent en tete de la colonne pendant qu elle
           defile : chercher ne doit pas demander de remonter d abord. */
        .messagerie-liste .barre-recherche,
        .messagerie-liste .barre-volets.barre-liens {
          position: sticky; z-index: 2; background: var(--surface);
        }
        .messagerie-liste .barre-recherche { top: 0; padding-top: .2rem; }
        /* ⚠️ SON DECALAGE SE COMPTE DEPUIS LE HAUT DE SA COLONNE, et non depuis
           l en-tete de l application : la regle generale des barres d onglets vise
           « --h-entete », ce qui l enfonce de soixante-trois pixels dans la liste.
           Mesure faite : 63 px la ou il en faut 48.

           ⚠️ ET LE SELECTEUR PORTE LES DEUX CLASSES. Ecrit « .messagerie-liste
           .barre-liens », il pesait exactement autant que la regle generale, qui vient
           apres et l emportait donc en silence. Sixieme collision de ce genre. */
        .messagerie-liste .barre-volets.barre-liens {
          top: 3rem; margin-bottom: var(--e3);
        }
        /* ⚠️ ET PAS DE FLECHE DE RETOUR QUAND LA LISTE EST A COTE. Elle ramenait a une
           page qui est deja a l ecran, a gauche : un bouton qui ne fait rien de plus
           que regarder ailleurs. Elle reste entiere sur telephone, ou elle est le seul
           chemin de retour. */
        .messagerie[data-messagerie="fil"] .conv-retour { display: none; }
        .messagerie-vide {
          display: grid; place-items: center; align-content: center; gap: var(--e3);
          min-height: 24rem; color: var(--encre-3); text-align: center;
        }
        .messagerie-vide svg { color: var(--encre-4); }
        .messagerie-vide p { margin: 0; }
      }
      /* La conversation ouverte se reconnait dans la liste : c est ce qui fait qu on
         sait ou l on est quand les deux volets sont a l ecran. */
      .ligne-conv.conv-ouverte { background: var(--accent-pale); }
      .ligne-conv.conv-ouverte:hover { background: var(--accent-pale); }

      /* Les groupes marqués « téléphone » se remettent à plat dès qu il y a de la
         place : leurs sections tiennent côte à côte sur un écran d ordinateur, et les
         ranger en onglets y cacherait ce qui était visible. */
      @media (min-width: 561px) {
        .bascule-volet ~ .barre-volets.barre-telephone { display: none; }
        .bascule-volet ~ .volets.volets-telephone > .volet { display: block; }
      }

      /* ⚠️ « .onglets-liens » ET « .onglet-lien » ONT ETE SUPPRIMES LE 22/08/2026, et
            leurs deux rangees ont rejoint le dessin des onglets. C etaient des boutons
            groupes dans une gouttiere grise, a un pouce des onglets soulignes de la
            fiche d un dossier : deux facons d habiller la meme rangee, au meme endroit
            de l ecran, pour le meme geste. « Je vais virer les especes de boutons, ca
            donnera au moins un style uniforme a l application », Rodolphe.

            La mecanique, elle, reste differente et le doit : voir `ongletsLiens` dans
            ce fichier. */

      /* Un ecran sans rien du tout. Deux phrases, pas un paragraphe. */
      .ecran-vide {
        padding: var(--e6) var(--e4); text-align: center;
        background: var(--fond-2); border-radius: var(--r); margin-bottom: var(--e4);
      }
      .ecran-vide p { margin: 0 0 var(--e2); }
      .ecran-vide p:last-child { margin-bottom: 0; }

      .bascule-volet { position: absolute; opacity: 0; width: 1px; height: 1px; }
      .barre-volets { display: none; }
      .volet { display: block; }

      /* ⚠️ LES ONGLETS VALENT A TOUTES LES LARGEURS, PAS SEULEMENT SUR TELEPHONE.
         Ecrits pour le seul telephone, les volets s affichaient TOUS sur ordinateur :
         la meme visite figurait dans « Sans suite » et dans « Toutes », l une sous
         l autre, et l ecran se lisait comme une liste qui begaye. Un onglet est une
         facon de trier, pas une contrainte de place. */
      /* ── LES ONGLETS RESTENT SOUS LA MAIN QUAND ON DEFILE ─────────────────────────
         Poses en haut de l ecran, ils disparaissaient au premier mouvement du doigt :
         sur une liste de douze vendeurs, changer d onglet demandait de remonter tout en
         haut. Colles, ils restent la, et l ecran dit en permanence dans quelle section
         on se trouve.

         ⚠️ ILS PERDENT LEUR CADRE GRIS POUR UN SOULIGNEMENT. Un selecteur pose dans une
         gouttiere grise se lit comme un reglage ; un onglet souligne se lit comme une
         section. C est la meme convention que la barre du bas, et le meme trait.

         ⚠️ ET LE FOND EST OPAQUE. Colle, la barre passe au-dessus du contenu qui defile
         dessous : sans fond plein, les noms des vendeurs se lisaient au travers. */
      /* ⚠️ SOUS L EN-TETE, ET NON DERRIERE. Colles tout en haut, les onglets venaient se
         ranger exactement la ou l en-tete de l application est deja colle : sur
         ordinateur, des le premier mouvement de la molette, la barre DossFlow et les
         onglets occupaient les memes soixante pixels, et l un des deux disparaissait.
         « il manque l en-tete au-dessus des onglets », Rodolphe, 21/08/2026.

         La variable --h-entete est publiee par public/entete.js et vaut zero la ou il est
         masque — sur telephone cote agent : la meme ligne sert donc les deux. */
      /* ⚠️ DEUX MECANIQUES, UN SEUL DESSIN. Un onglet montre ce qui est deja dans
            la page : c est un bouton radio, rien ne se recharge. Un FILTRE change la
            requete — la liste des vendeurs est plafonnee, le tri et la recherche
            doivent s appliquer au groupe choisi — donc c est un lien, avec sa propre
            adresse. Les deux se ressemblaient de loin sans jamais se ressembler
            vraiment : boutons groupes dans une gouttiere grise d un cote, onglets
            soulignes de l autre. « Ca donnera au moins un style uniforme a
            l application », Rodolphe, 22/08/2026.

            Les declarations sont donc ecrites UNE fois et atteintes de deux facons :
            par le bouton radio, ou par la classe « barre-liens » pour ce qui navigue. */
      .bascule-volet ~ .barre-volets,
      .barre-volets.barre-liens {
        display: flex; gap: 0; margin: 0 0 var(--e4); padding: 0;
        position: sticky; top: var(--h-entete, 0px); z-index: 30;
        background: var(--surface); border-bottom: 1px solid var(--trait);
      }
      .volet-mot {
        position: relative;
        flex: 1; min-width: 0; cursor: pointer; text-align: center;
        display: flex; flex-direction: column; align-items: center; gap: .05rem;
        padding: .5rem .2rem .45rem; border-radius: 0;
        font-size: .78rem; font-weight: 500; color: var(--encre-3);
        text-overflow: ellipsis; white-space: nowrap;
        transition: color .15s var(--vif);
      }
      /* ⚠️ PLUS D `overflow: hidden` ICI : la pastille du nombre se pose SUR le dessin,
         en debordant vers le haut, et l etiquette la coupait net. La coupure du texte
         reste assuree par `.volet-libelle`, qui la porte deja. */
      .volet-dessin {
        display: inline-flex; align-items: center; gap: .22rem;
        line-height: 0; margin-bottom: .1rem;
      }
      .volet-mot:hover { color: var(--encre-2); }
      /* Le meme mot, qu il soit etiquette de bouton radio ou lien. */
      a.volet-mot { text-decoration: none; }
      a.volet-mot:hover { text-decoration: none; }
      /* ⚠️ LE MOT EST DANS UNE ENVELOPPE, ET LE POINT SE COLLE A LUI. Pose dans le
            coin de l etiquette, en element absolu, il flottait a cent pixels du mot
            « Suivi » et se lisait comme une decoration de la barre — pas comme la
            marque de cet onglet-la. C est la meme regle que le point du bien : il
            qualifie un mot, il se tient donc contre lui.

            L enveloppe reprend la coupure du texte, qui ne peut plus vivre sur
            l etiquette : celle-ci est une colonne, et la coupure ne s applique qu au
            texte que l on porte soi-meme. */
      .volet-libelle {
        max-width: 100%; overflow: hidden;
        text-overflow: ellipsis; white-space: nowrap;
      }
      .volet-mot[data-point="oui"] .volet-libelle::after {
        content: ""; display: inline-block; width: 7px; height: 7px;
        margin-left: .3rem; border-radius: 999px; background: var(--danger);
        vertical-align: .1em;
      }
      /* Le compte devient une pastille : un nombre pose sous un mot se lit comme une
         seconde ligne de texte, dans une pastille il se lit comme une quantite. */
      .volet-compte {
        font-size: .6rem; font-weight: 700; color: var(--encre-3);
        background: var(--papier); border-radius: 20px; padding: .05rem .38rem;
        font-variant-numeric: tabular-nums; line-height: 1.5;
      }
      /* Accrochee au dessin, comme la pastille d une application. Le fond est celui de
         la barre pour que le nombre se detache du trait de l icone. */
      /* ⚠️ A COTE DU DESSIN, PAS DESSUS. Posee en pastille d application, dans le coin,
         elle marchait pour « 7 » et ruinait « 28/29 » : cinq caracteres recouvraient
         entierement une icone de dix-neuf pixels, et il ne restait du dessin que le bas.
         Accrochee par son bord gauche elle se detachait au contraire trop.
         Cote a cote sur la meme ligne : rien ne se cache, et la barre garde ses deux
         lignes — une troisieme l aurait portee a soixante-quinze pixels, collee en haut
         d un ecran de telephone. */
      .volet-dessin .volet-compte {
        padding: .02rem .3rem; font-size: .6rem; line-height: 1.4;
      }
      .bascule-volet ~ .volets > .volet { display: none; }
      /* ⚠️ LES RANGS, PAS LES CLES : six paires de regles servent toutes les pages. */
      .bascule-volet:nth-of-type(1):checked ~ .volets > .volet:nth-child(1),
      .bascule-volet:nth-of-type(2):checked ~ .volets > .volet:nth-child(2),
      .bascule-volet:nth-of-type(3):checked ~ .volets > .volet:nth-child(3),
      .bascule-volet:nth-of-type(4):checked ~ .volets > .volet:nth-child(4),
      .bascule-volet:nth-of-type(5):checked ~ .volets > .volet:nth-child(5),
      .bascule-volet:nth-of-type(6):checked ~ .volets > .volet:nth-child(6) { display: block; }
      .bascule-volet:nth-of-type(1):checked ~ .barre-volets > .volet-mot:nth-child(1),
      .bascule-volet:nth-of-type(2):checked ~ .barre-volets > .volet-mot:nth-child(2),
      .bascule-volet:nth-of-type(3):checked ~ .barre-volets > .volet-mot:nth-child(3),
      .bascule-volet:nth-of-type(4):checked ~ .barre-volets > .volet-mot:nth-child(4),
      .bascule-volet:nth-of-type(5):checked ~ .barre-volets > .volet-mot:nth-child(5),
      .bascule-volet:nth-of-type(6):checked ~ .barre-volets > .volet-mot:nth-child(6),
      .barre-liens > .volet-mot.actif {
        background: none; color: var(--encre); font-weight: 650;
      }
      /* ⚠️ LE TRAIT SOUS L ONGLET OUVERT, en plus de l encre pleine. La seule couleur ne
         suffit pas : elle disparait pour un daltonien, et c est la meme regle que sur la
         barre du bas. */
      .bascule-volet:nth-of-type(1):checked ~ .barre-volets > .volet-mot:nth-child(1)::after,
      .bascule-volet:nth-of-type(2):checked ~ .barre-volets > .volet-mot:nth-child(2)::after,
      .bascule-volet:nth-of-type(3):checked ~ .barre-volets > .volet-mot:nth-child(3)::after,
      .bascule-volet:nth-of-type(4):checked ~ .barre-volets > .volet-mot:nth-child(4)::after,
      .bascule-volet:nth-of-type(5):checked ~ .barre-volets > .volet-mot:nth-child(5)::after,
      .bascule-volet:nth-of-type(6):checked ~ .barre-volets > .volet-mot:nth-child(6)::after,
      .barre-liens > .volet-mot.actif::after {
        content: ""; position: absolute; left: 20%; right: 20%; bottom: 0;
        height: 3px; border-radius: 3px 3px 0 0; background: var(--accent);
      }
      .bascule-volet:nth-of-type(1):checked ~ .barre-volets > .volet-mot:nth-child(1) .volet-compte,
      .bascule-volet:nth-of-type(2):checked ~ .barre-volets > .volet-mot:nth-child(2) .volet-compte,
      .bascule-volet:nth-of-type(3):checked ~ .barre-volets > .volet-mot:nth-child(3) .volet-compte,
      .bascule-volet:nth-of-type(4):checked ~ .barre-volets > .volet-mot:nth-child(4) .volet-compte,
      .bascule-volet:nth-of-type(5):checked ~ .barre-volets > .volet-mot:nth-child(5) .volet-compte,
      .bascule-volet:nth-of-type(6):checked ~ .barre-volets > .volet-mot:nth-child(6) .volet-compte,
      .barre-liens > .volet-mot.actif .volet-compte {
        color: var(--accent-fonce); background: var(--accent-pale);
      }
      /* Au clavier, c est le bouton radio qui prend le focus et il est invisible. */
      .bascule-volet:nth-of-type(1):focus-visible ~ .barre-volets > .volet-mot:nth-child(1),
      .bascule-volet:nth-of-type(2):focus-visible ~ .barre-volets > .volet-mot:nth-child(2),
      .bascule-volet:nth-of-type(3):focus-visible ~ .barre-volets > .volet-mot:nth-child(3),
      .bascule-volet:nth-of-type(4):focus-visible ~ .barre-volets > .volet-mot:nth-child(4),
      .bascule-volet:nth-of-type(5):focus-visible ~ .barre-volets > .volet-mot:nth-child(5),
      .bascule-volet:nth-of-type(6):focus-visible ~ .barre-volets > .volet-mot:nth-child(6) {
        outline: 2px solid var(--accent); outline-offset: 2px;
      }

      /* ---- Les onglets du tableau de bord, sur telephone ----
         Le panneau est transparent par defaut : la grille a deux colonnes revoit
         exactement les enfants qu elle avait avant qu il existe. */
      .panneau-bord { display: contents; }

      @media (min-width: 1100px) {
        .espace-agent .grille-bord {
          display: grid; grid-template-columns: 1.6fr 1fr;
          gap: 0 var(--e7); align-items: start;
        }
        /* La colonne de droite se lit, elle ne se remplit pas : son premier titre
           s aligne sur celui de gauche plutot que de flotter plus bas. */
        .espace-agent .colonne-lire > *:first-child,
        .espace-agent .colonne-lire > .panneau-bord:first-child > *:first-child { margin-top: 0; }
      }

      /* ---- La liste de demarrage ----

         ⚠️ ELLE OCCUPE LA PLACE DES SECTIONS QU UN COMPTE NEUF N A PAS. Pas de demande,
         pas de visite, pas de message : sans elle l ecran se reduit a trois zeros. Elle
         s efface au dernier point coche, et ne revient jamais. */
      .depart {
        background: var(--surface); border-radius: var(--r);
        box-shadow: var(--ombre-relief);
        border: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        padding: var(--e5); margin: 0 0 var(--e6);
        display: flex; flex-direction: column; gap: var(--e5);
      }
      .depart-tete { display: flex; align-items: baseline; gap: var(--e2); flex-wrap: wrap; }
      .espace-agent .depart-tete h2 { margin: 0; }
      .depart-compte {
        font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
        color: var(--accent); margin-left: auto; white-space: nowrap;
      }
      .depart-groupe { display: flex; flex-direction: column; gap: .2rem; }
      /* Le titre du groupe dit la CONSEQUENCE, pas la categorie : « sans quoi rien ne
         part » se comprend sans mode d emploi, « parametres obligatoires » non. */
      .depart-titre { margin: 0; font-weight: 700; font-size: .95rem; }
      .depart-aide { margin: 0 0 var(--e2); font-size: .87rem; color: var(--encre-3); }
      .depart-liste { list-style: none; margin: 0; padding: 0;
                      display: flex; flex-direction: column; gap: .45rem; }
      .depart-liste li { display: flex; align-items: flex-start; gap: var(--e2); }

      /* La coche : un rond vide qui se remplit. Un point deja fait reste visible, il
         montre le chemin parcouru ; il passe simplement en gris et perd son lien. */
      .depart-coche {
        width: 20px; height: 20px; border-radius: 50%; flex: none; margin-top: .12rem;
        display: grid; place-items: center;
        border: 2px solid var(--trait-fort, var(--trait));
      }
      .depart-ok {
        background: var(--succes); border-color: var(--succes); color: #fff;
      }
      .depart-corps { display: flex; flex-direction: column; gap: .05rem; min-width: 0; }
      .depart-texte { font-weight: 600; font-size: .95rem; }
      a.depart-texte { color: var(--accent); }
      .depart-pourquoi { font-size: .85rem; color: var(--encre-3); }
      .depart-liste li.fait .depart-texte { color: var(--encre-3); font-weight: 400; }
      /* Fait ou non, le point mene quelque part : le survol le dit dans les deux cas. */
      a.depart-texte:hover { text-decoration: underline; }
      .depart-liste li.fait .depart-pourquoi { display: none; }

      /* ---- Le prochain rendez-vous ----

         ⚠️ IL NE RESSEMBLE A AUCUNE AUTRE LIGNE DE L ECRAN, et c est voulu : tout le
         reste vieillit, lui approche. Le fond sombre le sort de la file des relances au
         premier coup d oeil, sans qu on ait ecrit « urgent ».

         Le vert de la marque une seconde fois sur l ecran, apres l en-tete : c est le
         maximum. Une couleur qui revient trois fois cesse de signaler quoi que ce soit. */
      .rdv-proche {
        position: relative;
        display: grid; grid-template-columns: auto 1fr auto;
        gap: var(--e4); align-items: center;
        padding: var(--e3) var(--e4);
        margin: 0 0 var(--e5);
        border-radius: var(--r);
        background: linear-gradient(120deg, #0a3d2e, #127054);
        color: #fff;
        box-shadow: var(--ombre-relief);
      }
      .rdv-ouvre { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
      .rdv-ouvre:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
      .rdv-proche > *:not(.rdv-ouvre) { position: relative; z-index: 2; pointer-events: none; }
      .rdv-proche .rdv-actions { pointer-events: auto; }

      /* ⚠️ L HEURE EST LE PREMIER MOT, et c est la seule ligne de l ecran ou elle l est.
         Partout ailleurs on cherche un NOM ; ici on cherche a savoir de combien de temps
         on dispose. */
      .rdv-quand {
        font-size: 1.35rem; font-weight: 700; line-height: 1.05;
        text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums;
      }
      .rdv-quand small {
        display: block; font-family: inherit; font-size: .6rem; font-weight: 700;
        letter-spacing: .07em; text-transform: uppercase;
        color: rgba(255,255,255,.7); margin-top: .2rem;
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
      }
      .rdv-corps { min-width: 0; }
      .rdv-nom { margin: 0; font-weight: 650; font-size: 1rem; }
      .rdv-bien { color: rgba(255,255,255,.75); font-weight: 400; }
      .rdv-quoi { margin: .1rem 0 0; font-size: .85rem; color: rgba(255,255,255,.78); }
      .rdv-actions { display: flex; gap: var(--e2); flex-wrap: wrap; }
      .rdv-b {
        font-size: .85rem; font-weight: 600; padding: .4rem .75rem; border-radius: 8px;
        white-space: nowrap; text-decoration: none;
        background: rgba(255,255,255,.14); color: #fff;
        border: 1px solid rgba(255,255,255,.28);
        transition: background .15s var(--vif);
      }
      .rdv-b:hover { background: rgba(255,255,255,.24); color: #fff; }
      .rdv-b:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

      /* ---- Les listes de personnes ----

         ⚠️ UN SEUL BLOC, DES FILETS, PLUS DE CARTES EMPILEES. Sept cartes bordees
         chacune de sa marge deviennent sept lignes dans un meme cadre : la densite
         double sans que rien ne devienne illisible. */
      .liste-lignes {
        border-radius: var(--r); overflow: hidden; background: var(--surface);
        box-shadow: var(--ombre-relief);
        border: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
      }
      .ligne-vendeur {
        display: grid; grid-template-columns: auto 1fr auto auto;
        gap: var(--e3); align-items: center;
        padding: .8rem var(--e4); border-bottom: 1px solid var(--trait);
        position: relative;
        transition: background .16s var(--vif), transform .16s var(--vif);
      }
      .ligne-vendeur:last-child { border-bottom: 0; }
      /* Le filet d accent se deploie au survol : le mouvement dit ce qui est vivant,
         sans deplacer le texte que l oeil est en train de lire. */
      .ligne-vendeur::before {
        content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
        background: var(--accent); transform: scaleY(0); transform-origin: center;
        transition: transform .2s var(--vif);
      }
      .ligne-vendeur:hover { background: var(--papier); transform: translateX(2px); }
      .ligne-vendeur:hover::before { transform: scaleY(1); }
      .ligne-corps { min-width: 0; }
      .ligne-nom { margin: 0; font-weight: 650; font-size: .97rem; }
      /* ⚠️ UNE LIGNE DE TEXTE, ET NON UN CONTENEUR SOUPLE. En disposition souple, chaque
         morceau passe a la ligne pour son propre compte : le point median se retrouvait
         seul sur une ligne entiere, entre l anciennete et le qualificatif, et la ligne
         d information montait a trois hauteurs. En texte ordinaire, le point reste colle
         au mot qui le precede par son espace insecable, et la coupure tombe la ou une
         phrase se coupe. */
      .ligne-meta {
        margin: .12rem 0 0; font-size: .84rem; color: var(--encre-3);
        font-variant-numeric: tabular-nums; line-height: 1.45;
      }
      .ligne-actions { display: flex; gap: var(--e2); flex-wrap: wrap; align-items: center; }

      /* ⚠️ LA LIGNE ENTIERE OUVRE LE DOSSIER, ET LE LIEN PASSE PAR-DESSOUS. Un lien dans
         un lien est interdit en HTML : la ligne ne peut donc pas etre un lien elle-meme
         si elle porte aussi un appel. Ce lien-ci couvre toute la surface en position
         absolue, sous le contenu ; l icone d appel repasse au-dessus.

         C est aussi la seule construction qui garde le clavier : le lien reste un vrai
         lien, il prend le focus et s ouvre avec Entree. */
      .ligne-ouvre {
        position: absolute; inset: 0; z-index: 1;
        border-radius: inherit; text-decoration: none;
      }
      .ligne-ouvre:focus-visible {
        outline: 2px solid var(--accent); outline-offset: -3px;
      }
      /* ⚠️ LE CONTENU NE DOIT PAS CAPTER LE CLIC, sinon toucher le NOM n ouvre rien : le
         lien est dessous, et le texte passe devant. Constate en interrogeant le point
         central de la ligne, qui rendait « ligne-nom » au lieu du lien.

         Le contenu devient donc transparent au pointeur, et seule l icone d appel le
         reprend. Le texte cesse d etre selectionnable dans la ligne : c est le prix, et
         il est juste, personne ne copie un nom depuis un tableau de bord. */
      .ligne-vendeur > *:not(.ligne-ouvre) {
        position: relative; z-index: 2; pointer-events: none;
      }
      .ligne-vendeur .ligne-tel { pointer-events: auto; }

      /* L appel, en icone seule : c est le geste le plus frequent du metier et le seul
         qui ne mene pas au dossier. Quarante pixels, la cible minimale au pouce. */
      .ligne-tel {
        width: 40px; height: 40px; border-radius: var(--r-petit);
        border: 1px solid var(--trait); background: var(--surface);
        display: grid; place-items: center; color: var(--encre-2);
        transition: border-color .15s var(--vif), color .15s var(--vif);
      }
      .ligne-tel:hover { border-color: var(--accent-bord); color: var(--accent); }
      .ligne-chevron { color: var(--encre-3); display: flex; align-items: center; }
      .ligne-vendeur:hover .ligne-chevron { color: var(--accent); }

      /* ⚠️ LES BOUTONS D UNE LIGNE SONT PLUS PETITS QUE CEUX D UNE PAGE, et c est ce qui
         separait le rendu de la maquette. A leur taille normale ils font quarante-huit
         pixels de haut : ils dominaient la ligne au lieu de la servir, et l ecran
         paraissait grossier. Ici ils accompagnent un nom, ils ne sont pas l action
         principale d une page. */
      .ligne-actions .bouton {
        font-size: .85rem; font-weight: 600; line-height: 1.3;
        padding: .4rem .75rem; border-radius: 8px;
        min-height: 0;
      }
      /* L icone du telephone disparait dans une liste : le mot « Appeler » suffit, et
         l icone ajoutait douze pixels a chaque ligne pour ne rien dire de plus. */
      .ligne-actions .bouton svg { display: none; }

      /* Une ligne de message : elle garde son champ de reponse, donc elle s empile au
         lieu de se ranger en colonnes. Meme cadre, meme filet, meme survol que les
         autres lignes ; seule la mise en page interne differe. */
      .ligne-message {
        padding: var(--e3) var(--e4); border-bottom: 1px solid var(--trait);
        position: relative;
      }
      .ligne-message:last-child { border-bottom: 0; }
      .ligne-message-tete {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        margin-bottom: var(--e2);
      }
      .ligne-message-tete .discret { margin-left: auto; font-size: .82rem; }
      .ligne-message-tete .initiales { width: 30px; height: 30px; font-size: .7rem; }
      .ligne-message-texte { margin: 0 0 var(--e2); font-size: .94rem; }
      .ligne-message textarea { margin: 0; }
      .ligne-actions .bouton { margin: 0; }

      /* Les initiales. La couleur vient du nom, jamais du hasard : elle doit etre la
         meme d un ecran a l autre, sinon la pastille cesse d aider a reconnaitre
         quelqu un. Aucune des quatre teintes n est celle d un etat. */
      .initiales {
        width: 38px; height: 38px; border-radius: 50%;
        display: grid; place-items: center; flex: none;
        font-weight: 800; font-size: .8rem; letter-spacing: .02em; color: #fff;
        box-shadow: var(--ombre);
      }
      /* ⚠️ LES QUATRE TEINTES SONT DES CLASSES, ET NON DES DEGRADES ECRITS DANS
         L ATTRIBUT DE STYLE. Ecrites la, elles l emportaient sur toute regle d ecran :
         impossible d alleger la pastille sur telephone. Voir la fonction initiales. */
      .initiales.teinte-1 { background: linear-gradient(145deg,#2f6f57,#164a38); }
      .initiales.teinte-2 { background: linear-gradient(145deg,#3d5f8a,#22405f); }
      .initiales.teinte-3 { background: linear-gradient(145deg,#8a5f3d,#5f3d22); }
      .initiales.teinte-4 { background: linear-gradient(145deg,#6a4a80,#432f52); }

      /* ⚠️ L ANCIENNETE SE VOIT, ELLE NE SE LIT PLUS. Seize jours et deux jours
         s ecrivaient dans la meme encre grise. La jauge chauffe avec le temps, et la
         ligne a traiter se repere sans lire un seul chiffre. Quatorze jours pour le
         plein : au-dela d une quinzaine sans rappel, un vendeur est perdu. */
      /* ⚠️ « jauge-attente » ET NON « jauge » : le nom court etait DEJA pris par la barre
         de progression du formulaire, huit cents lignes plus bas. La regle voisine
         gagnait, et cette barre s affichait a dix pixels de haut au lieu de trois, en
         pilule. Trouve en mesurant l element dans le navigateur : la hauteur calculee ne
         correspondait a aucune des valeurs que j avais ecrites. */
      /* La jauge suit le texte au lieu d etre un element de la disposition souple :
         posee en ligne, elle se cale sur le milieu des lettres. */
      .jauge-attente {
        display: inline-block; vertical-align: middle; margin-right: .4rem;
        width: 60px; height: 3px; border-radius: 2px; flex: none;
        background: var(--trait); overflow: hidden;
      }
      .jauge-attente i { display: block; height: 100%; width: var(--part); border-radius: 2px; }
      .jauge-froid i { background: #1a8464; }
      .jauge-tiede i { background: #c08a1e; }
      .jauge-chaud i { background: #b3462c; }

      @media (prefers-reduced-motion: reduce) {
        .ligne-vendeur { transition: none; }
        .ligne-vendeur:hover { transform: none; }
      }

      /* ---- L en-tete du tableau de bord ----

         ⚠️ LE SEUL BLOC DE L APPLICATION QUI PORTE LE VERT DE L EDITEUR. Essaye en
         accent d interface le 20/08/2026 puis annule : il volait la couleur qui dit
         « c est fait » sur les pastilles d etape. Sur ce fond sombre il ne concurrence
         rien. Cote vendeur cette regle ne s applique jamais, la marque y est celle de
         l agent. */
      /* ⚠️ LE BANDEAU DEBORDE LE REMBOURRAGE DE LA PAGE, il ne s y range pas.
         Le conteneur pose deux rem de blanc sur ses quatre cotes : le bandeau y
         flottait comme une carte parmi d autres, avec du blanc tout autour. Une marge
         negative de la meme valeur le fait toucher les bords du conteneur, et ses coins
         hauts reprennent le rayon de celui-ci pour s y emboiter exactement.

         ⚠️ LES COINS BAS RESTENT DROITS : le bandeau se prolonge dans la page, il ne s y
         pose pas. Ce sont les cartes de chiffres qui viennent le fermer. */
      /* ⚠️ LE MEME CREUX QUE `.tete-ecran`, ET NON 5,2 rem. « Il faut qu on ait la
         meme epaisseur de barre a chaque fois » — Rodolphe, 28/08/2026. Mesure : le
         tableau de bord faisait 177 px de haut contre 183 aux quatre autres ecrans, et
         ses cases se posaient donc six pixels plus haut. Six pixels ne se voient pas
         seuls ; d un onglet a l autre, ils font sauter la ligne. */
      .espace-agent .tete-bord {
        position: relative; overflow: hidden;
        margin: calc(var(--e6) * -1) calc(var(--e6) * -1) var(--e5);
        padding: var(--e6) var(--e5) 4.5rem;
        border-radius: var(--r-grand) var(--r-grand) 0 0;
        background: linear-gradient(150deg, #0a3d2e 0%, #0d5c46 52%, #127054 100%);
        color: #fff;
        box-shadow: var(--ombre-haute);
      }
      .espace-agent .tete-bord { min-height: 11.4rem; }
      /* Le halo : sans lui le degrade est plat, avec lui la surface a une source de
         lumiere. C est ce qui distingue un fond colore d un en-tete.

         ⚠️ IL COUVRE TOUT LE BANDEAU, ET SA TAILLE EST DONNEE EN POURCENTAGE DE CE
         BANDEAU. Il vivait dans une boite decalee, plus haute que large, posee a
         droite : le cercle n avait pas fini de s eteindre en atteignant le bord
         GAUCHE de cette boite, et cette boite s arretait net au milieu de l ecran.
         Il en resultait un trait vertical, en plein milieu du vert — deux verts
         colles l un a l autre plutot qu un degrade. « Le bandeau vert n a pas
         vraiment degrade », Rodolphe, 22/08/2026. Mesure : la boite commencait a
         168 px sur un ecran de 375, exactement ou passait le trait.

         Une ellipse dimensionnee sur la boite qu elle remplit s eteint toujours
         avant d en atteindre le bord, quelle que soit la largeur de l ecran. */
      .espace-agent .tete-bord::after {
        content: ""; position: absolute; inset: 0; pointer-events: none;
        background: radial-gradient(58% 130% at 78% 8%,
          rgba(150,235,200,.20), transparent 72%);
      }
      .tete-bord-haut {
        position: relative; display: flex; align-items: flex-end;
        justify-content: space-between; gap: var(--e4); flex-wrap: wrap;
      }
      /* 1,85 rem comme les titres des autres ecrans, et non 2 : la meme police
         ecrite deux tailles differentes sur deux onglets voisins se voyait. */
      .espace-agent .tete-bord-jour {
        margin: 0; font-size: 1.85rem; line-height: 1.02; letter-spacing: -.03em; color: #fff;
      }
      .tete-bord-sous { margin: .4rem 0 0; font-size: .9rem; color: rgba(255,255,255,.75); }
      .tete-bord-cta {
        display: inline-flex; align-items: center; gap: .4rem;
        font-size: .92rem; font-weight: 700; text-decoration: none; white-space: nowrap;
        padding: .6rem 1.05rem; border-radius: var(--r-petit);
        background: #fff; color: #0d5c46; box-shadow: var(--ombre-relief);
        transition: transform .18s var(--vif), box-shadow .18s var(--vif);
      }
      .tete-bord-cta:hover { transform: translateY(-2px); box-shadow: var(--ombre-haute); }
      .tete-bord-cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

      /* ⚠️ LES CHIFFRES CHEVAUCHENT L EN-TETE, et c est ce recouvrement qui fait la
         profondeur, bien plus qu une ombre posee a plat. La marge negative doit rester
         inferieure au rembourrage bas de l en-tete, sinon les cartes debordent au-dessus
         du titre.

         ⚠️ ET LE CHEVAUCHEMENT SE COMPTE APRES LA MARGE BASSE DU BANDEAU. Elle vaut
         vingt-quatre pixels, et elle mangeait la marge negative : sur telephone, les
         -1.5rem l annulaient EXACTEMENT et les cartes se posaient SOUS le vert sans
         jamais le toucher ; sur ordinateur il ne restait que dix-huit pixels de
         recouvrement sur des cartes de cent quinze. « Le bandeau vert descend pas assez
         au milieu des autres cases, et sur mobile et sur PC », Rodolphe, 22/08/2026.

         Les nombres visent la MOITIE de la carte, mesuree : soixante-dix pixels sur
         telephone, cent quinze sur ordinateur. D ou -3.7rem et -5.1rem, les
         vingt-quatre pixels compris. Le rembourrage bas du bandeau grandit d autant,
         sinon les cartes viendraient buter contre « Inviter un vendeur ». */
      /* ⚠️ LE RETRAIT LATERAL FAIT LE CHEVAUCHEMENT. Alignees sur les bords du bandeau,
         les cartes se lisent comme sa suite ; posees en retrait, elles se lisent comme
         posees DESSUS. Deux centimetres de vert de chaque cote, et la profondeur
         apparait. Releve par Rodolphe en comparant la maquette a l ecran. */
      .espace-agent .chiffres-bord {
        display: grid; gap: var(--e3);
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        margin-top: -5.1rem; position: relative;
        padding: 0 var(--e4);
        /* ⚠️ ET UNE MARGE SOUS LES CARTES. Elles n en avaient aucune : la barre de
           recherche venait se coller a leur bord, et leur ombre debordait dessus. De
           loin, on lisait un chevauchement. Releve par Rodolphe le 20/08/2026. */
        margin-bottom: var(--e5);
      }

      /* ⚠️ BLANCHES, PAS GRISES, DES QU ELLES CHEVAUCHENT LE VERT. Le fond de second
         niveau les detachait bien d une page claire ; pose sur le bandeau sombre, il les
         y fondait. Une carte qui flotte au-dessus d autre chose doit etre la surface la
         plus claire de l ecran, et porter l ombre la plus haute. */
      .espace-agent .chiffres-bord .carte-chiffre {
        background: #fff; border-color: transparent;
        box-shadow: var(--ombre-relief);
      }
      .espace-agent .chiffres-bord .carte-chiffre:hover {
        box-shadow: var(--ombre-haute); border-color: transparent;
      }

      @media (prefers-reduced-motion: reduce) {
        .tete-bord-cta { transition: none; }
        .tete-bord-cta:hover { transform: none; }
      }

      /* Les chiffres du tableau de bord. Un total ne se lit pas comme une fiche : fond
         teinte plutot que blanc, chiffre large, libelle en petites capitales. Sans quoi
         « 21 dossiers en cours » et « Claire Lefevre » portent le meme habillage. */
      .carte-chiffre {
        display: flex; flex-direction: column; gap: .15rem;
        padding: var(--e3) var(--e4); border-radius: var(--r2);
        background: var(--fond-2); border: 1px solid var(--trait);
        text-decoration: none; color: inherit;
        transition: border-color .12s ease, transform .12s ease;
      }
      .carte-chiffre:hover { border-color: var(--accent-bord); transform: translateY(-1px); }
      .carte-chiffre:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
      /* Le chiffre etait en serif « comme le site vitrine ». Il rejoint la police du
         systeme avec tout le reste : c est sa taille et sa graisse qui le font annoncer,
         pas son dessin. */
      .espace-agent .carte-chiffre .chiffre {
        font-weight: 700; letter-spacing: -.035em; font-size: 2.4rem;
      }
      .carte-chiffre .chiffre {
        font-size: 2.1rem; font-weight: 700; line-height: 1;
        letter-spacing: -.02em; font-variant-numeric: tabular-nums;
      }
      .carte-chiffre .quoi {
        font-size: .74rem; font-weight: 600; letter-spacing: .05em;
        text-transform: uppercase; color: var(--encre-3);
      }
      @media (prefers-reduced-motion: reduce) {
        .carte-chiffre { transition: none; }
        .carte-chiffre:hover { transform: none; }
      }

      /* Le titre d une section qui porte son propre compte, depuis que les rappels
         menant vers le bas de la meme page ont ete retires. Le compte se lit comme une
         etiquette posee contre le titre, pas comme un bouton : rien a cliquer ici, la
         liste est juste en dessous. */
      .tete-section {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        margin: var(--e5) 0 var(--e2);
      }
      /* ⚠️ LE COMPTEUR VA A DROITE, PAS CONTRE LE TITRE. Colle au titre il se lit comme
         un morceau de la phrase ; pousse au bout de la ligne il devient une etiquette,
         et l oeil retrouve tous les comptes de la page sur une meme verticale. */
      .compteur-section {
        font-size: .72rem; font-weight: 800; letter-spacing: .06em; white-space: nowrap;
        text-transform: uppercase; margin-left: auto;
        padding: .2rem .6rem; border-radius: 20px;
        background: var(--attention-pale, #fdf5e6); color: var(--attention);
        box-shadow: 0 1px 2px rgba(138,90,0,.12);
      }
      /* La raison d etre de la section, entre son titre et sa liste. Elle vient du
         bandeau qu on a supprime : elle se lit une fois, juste avant les noms. */
      .pourquoi-section { margin: 0 0 var(--e3); max-width: 64ch; }

      /* ---- La courbe des sept derniers jours, dans l en-tete ----

         Elle dit ce qu aucun total ne dit : quatre reponses deposees lundi ou une par
         jour font le meme chiffre et deux semaines tres differentes. Le trace se dessine
         en une seconde a l ouverture, puis s arrete. */
      .tete-bord-courbe {
        position: relative; margin: var(--e4) 0 0;
        display: flex; align-items: flex-end; gap: var(--e3);
      }
      .tete-bord-courbe svg { display: block; width: 100%; height: 44px; overflow: visible; }
      .tete-bord-cle {
        font-size: .7rem; letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
        color: rgba(255,255,255,.6); white-space: nowrap;
      }
      .courbe-trace {
        fill: none; stroke: rgba(190,255,225,.9); stroke-width: 2;
        stroke-linecap: round; stroke-linejoin: round;
        stroke-dasharray: 600; stroke-dashoffset: 600;
        animation: courbe-trace 1.1s var(--vif) .35s forwards;
      }
      .courbe-aire { fill: url(#degrade-courbe); opacity: 0;
                     animation: apparait .7s var(--vif) .95s forwards; }
      .courbe-pointe { fill: #fff; opacity: 0;
                       animation: apparait .35s var(--vif) 1.25s forwards; }
      @keyframes courbe-trace { to { stroke-dashoffset: 0; } }
      @keyframes apparait { to { opacity: 1; } }

      /* La carte du chiffre gagne : celui que l outil a rempli sans personne. Un degrade
         a peine visible et le vert de la marque, une seule fois sur l ecran. */
      /* ⚠️ ASSEZ VERT POUR SE VOIR. La premiere valeur, presque blanche, ne se
         distinguait pas des deux autres cartes : la carte du chiffre gagne doit se
         reconnaitre sans qu on lise son libelle. */
      .carte-chiffre.carte-gagne {
        background: linear-gradient(160deg, #e7f5ee, #f7fcfa);
      }
      .carte-chiffre.carte-gagne .chiffre { color: #0d5c46; }
      .note-chiffre {
        font-size: .72rem; font-weight: 700; color: #0d5c46; margin-top: .3rem;
        display: block;
      }

      /* ---- L ecran se construit en cascade ----

         Chaque bloc arrive a soixante millisecondes du precedent : on voit l ordre de
         lecture au lieu de recevoir tout d un coup. Rien ne dure plus d une demi-seconde.

         ⚠️ L ANIMATION PART D UNE OPACITE NULLE, ce qui rend le bloc INVISIBLE si le style
         ne s applique pas. C est pourquoi elle ne porte que sur des blocs decoratifs de
         l en-tete, jamais sur une liste : un ecran de donnees ne doit jamais dependre
         d une animation pour s afficher. */
      /* ⚠️ UNE DEMI-SECONDE ETAIT TROP LONGUE, ET LE DEFAUT N ETAIT PAS L EFFET MAIS
         SON DEPART A OPACITE NULLE. Mesure le 28/08/2026 : le tableau de bord est
         utilisable a 79 ms, et son titre restait invisible jusqu a 500. On voyait donc
         une page a moitie vide pendant six fois le temps qu elle avait mis a arriver.
         A 180 ms le mouvement se lit encore, sans jamais faire attendre. */
      .monte { animation: monte .18s var(--vif) both; }
      .monte-2 { animation: monte .18s var(--vif) .04s both; }
      .monte-3 { animation: monte .18s var(--vif) .08s both; }
      @keyframes monte {
        from { opacity: 0; transform: translateY(10px); }
        to   { opacity: 1; transform: none; }
      }

      @media (prefers-reduced-motion: reduce) {
        .monte, .monte-2, .monte-3 { animation: none; }
        .courbe-trace { animation: none; stroke-dashoffset: 0; }
        .courbe-aire, .courbe-pointe { animation: none; opacity: 1; }
      }
      .recolte-titre { margin: 0 0 .3rem; font-weight: 650; }
      .recolte .discret { margin: 0 0 .6rem; }
      .recolte button { margin: 0; }
      .proposition-valeur { margin: 0; }
      .proposition-valeur strong { font-size: 1.05rem; }
      .proposition-precision { margin: .3rem 0 0; font-size: .85rem; }
      /* Les deux reponses cote a cote, jamais l'une sous l'autre : on compare mal
         deux valeurs separees par trois lignes de texte. */
      .proposition-deux { display: flex; gap: var(--e4); flex-wrap: wrap; margin: 0 0 .2rem; }
      .proposition-choix { display: flex; flex-direction: column; gap: .1rem; }
      .proposition-etiquette { font-size: .8rem; color: var(--encre-3); }
      .proposition-boutons { display: flex; gap: var(--e3); align-items: center;
        margin-top: .6rem; flex-wrap: wrap; }
      .proposition-boutons button { margin: 0; }
      /* Refuser doit rester possible sans etre mis en avant : un lien, pas un bouton,
         pour que le geste attendu reste celui de valider. */
      .lien-discret {
        background: none; border: 0; padding: .2rem 0; color: var(--encre-3);
        text-decoration: underline; cursor: pointer; font-size: .9rem; font-family: inherit;
      }
      .lien-discret:hover { color: var(--encre); }

      /* « Document bien recu, mais pas lu » : une information, pas une alerte.
         En jaune ou en rouge, le vendeur croirait avoir rate son depot alors que la
         piece est bien la et compte dans son dossier. */
      .proposition-avert {
        margin: .5rem 0 0; padding: .6rem .8rem;
        border-radius: var(--r2); background: var(--fond-2);
        border-left: 3px solid var(--trait-fort, var(--trait));
      }
      .proposition-avert p { margin: 0; font-size: .9rem; }
      .proposition-avert p + p { margin-top: .25rem; }

      /* L ecart entre le document et le dossier. Un peu plus appuye que le simple
         « pas pu lire », parce qu il appelle une verification, mais toujours pas une
         alerte rouge : neuf fois sur dix l explication est banale. */
      .proposition-ecart {
        margin: .5rem 0 0; padding: .6rem .8rem;
        border-radius: var(--r2); background: var(--fond-2);
        border-left: 3px solid var(--attente, #c98a1e);
      }
      .proposition-ecart p { margin: 0; font-size: .9rem; }
      .proposition-ecart p + p { margin-top: .25rem; }

      /* Les lots au choix, quand l acte en decrit plusieurs sans dire lequel est le
         sien. L un SOUS l autre et non cote a cote : ce sont deux descriptions a lire
         en entier, pas deux valeurs a comparer d un coup d oeil, et sur telephone
         deux boutons larges cote a cote deviennent deux colonnes illisibles. */
      .proposition-lots { flex-direction: column; align-items: stretch; gap: var(--e2); }
      .proposition-lots button {
        display: flex; flex-direction: column; align-items: flex-start; gap: .15rem;
        text-align: left; width: 100%; padding: .55rem .75rem; line-height: 1.35;
      }
      .proposition-lot-titre { font-weight: 600; }
      /* Le nom de l attributaire est ce qui permet de se reconnaitre quand le
         rapprochement a echoue : lisible, mais sous la description du lot. */
      .proposition-lot-nom { font-size: .85rem; color: var(--encre-3); font-weight: 400; }

      /* Ce que les documents contredisent, sur la carte de l etape de l agent.
         Plus appuye que chez le vendeur : c est lui qui doit aller verifier, et il
         lit cette carte avant d appeler. Mais pas rouge non plus, l explication est
         banale neuf fois sur dix. */
      .ecart-agent {
        margin: var(--e3) 0 0; padding: .65rem .85rem;
        border-radius: var(--r2); background: var(--fond-2);
        border-left: 3px solid var(--attente, #c98a1e);
      }
      .ecart-agent-titre { margin: 0 0 .3rem; font-weight: 650; font-size: .95rem; }
      .ecart-agent-liste { margin: 0; padding-left: 1.1rem; }
      .ecart-agent-liste li { font-size: .9rem; margin: .2rem 0; }

      /* Le recapitulatif d avant-mandat. Meme famille que l encart d ecart, dont il
         devient le contenant sur cette carte-la. */
      .recap-mandat {
        margin: var(--e3) 0 0; padding: .65rem .85rem;
        border-radius: var(--r2); background: var(--fond-2);
        border-left: 3px solid var(--attente, #c98a1e);
      }
      /* Vert quand il n y a rien a dire : c est une reponse, pas une absence. */
      .recap-mandat-ok { border-left-color: var(--succes, #0a7d32); }
      /* Un dossier complet dont les documents se contredisent : il reste complet, il
         n'est simplement plus tranquille. Posé par ecartsDossier.js, une seconde apres
         l affichage, quand la lecture des pieces a rendu son verdict. */
      .recap-mandat-attention { border-left-color: var(--attention, #b8860b); }
      .recap-mandat-note {
        margin: .45rem 0 0; font-size: .9rem; color: var(--attention, #b8860b);
        font-weight: 600;
      }
      .recap-mandat-titre { margin: 0 0 .3rem; font-weight: 650; font-size: .95rem; }
      .recap-mandat-liste { margin: 0; padding-left: 1.1rem; }
      .recap-mandat-liste li { font-size: .9rem; margin: .2rem 0; }

      /* Ce qui reste a renseigner sur la fiche de redaction. Visible sans etre
         alarmant : c est une case a remplir, pas une erreur. */
      .manque-mandat { color: var(--attente, #c98a1e); font-weight: 550; }
      .surtitre {
        font-size: .74rem; font-weight: 700; letter-spacing: .09em;
        text-transform: uppercase; color: var(--encre-3);
      }
      a { color: var(--accent); text-underline-offset: 2px; }
      a:hover { color: var(--accent-fonce); }

      /* --- En-tête --- */
      /* ⚠️ CE QUI TOUCHE LE HAUT DE L ECRAN SE REMBOURRE DE LA MARGE DE SECURITE.
            Depuis que la page se declare en « viewport-fit=cover », elle s etend sous
            l horloge et sous l encoche : le fond colore doit y monter — c est ce qu on
            veut, une barre d application ne s arrete pas au milieu du noir — mais son
            CONTENU doit rester dessous. Sans cette ligne, le nom du conseiller passait
            sous l horloge. « C est passe sous », Rodolphe, 22/08/2026.

            La valeur vaut zero partout ailleurs : sur un ordinateur, dans un
            navigateur ordinaire, et sur tout appareil sans encoche. Rien ne bouge. */
      header.principal {
        background: var(--surface); border-bottom: 1px solid var(--trait);
        position: sticky; top: 0; z-index: 30;
        padding-top: env(safe-area-inset-top, 0px);
      }
      /* La bande d une conversation prend la place de l en-tete des qu il s efface :
         elle touche donc le haut a son tour, et suit la meme regle. */
      .tete-conv { padding-top: env(safe-area-inset-top, 0px); }
      .barre {
        max-width: 68rem; margin: 0 auto; padding: var(--e3) var(--e5);
        display: flex; align-items: center; justify-content: space-between; gap: var(--e4);
      }


      /* ── L EN-TETE DU VENDEUR CONNECTE ────────────────────────────────────────────
         Une bande de la couleur de son conseiller, une ligne, et le bouton des
         messages au bout. Elle remplace un en-tete blanc de cent vingt et un pixels
         qui portait la photo, le nom, le metier et un bouton « Menu » dans un cadre —
         un menu qui ne contenait que deux entrees deja atteignables.

         MESURE A 375 px LE 22/08/2026 : le premier bien du vendeur commencait a 378
         pixels, soit pres de la moitie de l ecran. Maquette validee, option B. */
      /* ⚠️ LE SELECTEUR PORTE L ELEMENT ET LES DEUX CLASSES. Ecrit « .entete-client »,
         il pesait moins que « header.principal » quelques lignes plus haut, qui pose le
         fond blanc : la bande restait blanche sans qu aucune erreur ne le signale. */
      /* ⚠️ UN APLAT, ET NON UN DEGRADE. Le dessin valide montre une bande unie ; le
         degrade y ajoutait un reflet qui se lit comme une decoration de page web. Une
         barre d application est une surface, pas un ciel. Rodolphe, 22/08/2026 : « la
         bande du haut n est pas exactement comme sur la capture ». */
      header.principal.entete-client {
        background: var(--accent); border-bottom: 0;
      }
      .entete-client .barre { padding: .55rem var(--e4); gap: var(--e3); }
      .entete-client .marque { color: #fff; }
      .entete-client .nom-marque { font-size: .92rem; font-weight: 650; }
      .entete-client .qualite-marque { color: rgba(255,255,255,.74); }
      .entete-client .sceau {
        background: rgba(255,255,255,.18); color: #fff;
        border: 1px solid rgba(255,255,255,.3);
      }
      .entete-client .sceau-photo { border: 1px solid rgba(255,255,255,.34); }
      /* Le bouton des messages : un rond de verre, la pastille des non-lus dessus. */
      .vers-messages {
        position: relative; flex: none; width: 38px; height: 38px; border-radius: 50%;
        display: grid; place-items: center; color: #fff; text-decoration: none;
        background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.3);
      }
      .vers-messages:hover { background: rgba(255,255,255,.26); color: #fff; }
      /* ⚠️ LA PASTILLE EST DEFINIE ICI, ET NON SEULEMENT DANS LE BLOC TELEPHONE. Elle
         y vivait pour la barre d onglets de l agent ; l en-tete du vendeur s en sert a
         toutes les largeurs, et sur ordinateur elle n aurait ete qu un chiffre nu pose
         a cote de l icone. */
      .pastille-onglet {
        position: absolute; top: -5px; left: 12px; min-width: 16px; height: 16px;
        padding: 0 .2rem; border-radius: 9px; background: var(--danger); color: #fff;
        font-size: .58rem; font-weight: 800; display: grid; place-items: center;
      }
      .vers-messages .pastille-onglet { top: -4px; left: auto; right: -4px; }

      .marque {
        display: inline-flex; align-items: center; gap: var(--e2);
        font-weight: 700; font-size: 1.02rem; letter-spacing: -.014em;
        color: var(--encre); text-decoration: none;
      }
      /* Le logo du produit, identique à celui du site vitrine : même serif, même
            graisse, même encre. La graisse est bien 800 et non 700 — Iowan Old Style
            ne distingue pas 600 de 700, les deux rendent exactement la même largeur
            (mesuré). C'est à 800 seulement que le nom s'épaissit vraiment. */
      .marque-produit {
        font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
        font-weight: 800; font-size: 1.12rem; letter-spacing: -.02em;
        gap: .5rem; color: var(--encre);
      }
      .marque-produit svg { flex: none; }
      .marque .sceau {
        width: 30px; height: 30px; border-radius: 9px; flex: none;
        background: linear-gradient(145deg, var(--accent), var(--accent-fonce));
        display: grid; place-items: center; color: #fff;
        font-size: .82rem; font-weight: 700; letter-spacing: 0;
      }
      /* La photo prend la place exacte du sceau : meme taille, meme arrondi. Le
         recadrage evite qu un portrait vertical se deforme — un visage etire est
         pire qu une initiale.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .marque .sceau-photo { object-fit: cover; background: var(--papier); }
      /* `flex-shrink: 0` : sans lui, le menu se laisse comprimer par la barre AVANT
            de manquer de place, et se replie sur deux lignes alors qu'il tiendrait
            (mesuré : 567 px de contenu pour 605 px disponibles). En dessous de 760 px
            il disparaît de toute façon au profit du bouton, donc rien ne peut déborder. */
      /* ── Frise d'avancement d'un bien (friseEtapes.js) ───────────────────────
            Elle DÉBORDE volontairement : douze étapes ne tiennent pas sur la largeur
            d'un téléphone, et les tasser les rendrait illisibles. On glisse. Le script
            recentre l'étape en cours au chargement, sinon on arrive sur « Nouveau »
            alors que l'affaire en est au mandat.                                    */
      /* La frise NE DÉFILE PAS. Les pastilles rétrécissent en s'éloignant de
            l'étape lue, jusqu'à n'être que des points aux extrémités : les douze
            étapes tiennent alors dans la largeur d'un téléphone. On ne distingue pas
            les plus lointaines, et ce n'est pas le but — elles disent qu'il reste du
            chemin. C'est ce qui permet de se passer d'une barre de défilement. */
      .frise-etapes {
        display: block; overflow: hidden;
        padding: var(--e2) 0 var(--e3); margin: 0 0 var(--e3);
      }
      .frise-piste {
        display: flex; align-items: flex-start; justify-content: center; gap: .2rem;
        width: max-content; margin: 0 auto;
        transition: transform .22s ease;
      }
      .etape-frise {
        flex: none; display: flex; flex-direction: column; align-items: center; gap: .3rem;
        padding: .2rem .1rem; text-align: center; min-width: 0;
        text-decoration: none; color: inherit; border-radius: var(--r-petit);
        transition: transform .22s ease, opacity .22s ease;
      }
      .rond-frise {
        border-radius: 50%; display: grid; place-items: center;
        font-weight: 700; flex: none;
        border: 2px solid var(--trait); background: var(--papier); color: var(--encre-3);
        transition: width .22s ease, height .22s ease, font-size .22s ease;
      }
      .nom-frise {
        font-size: .68rem; line-height: 1.2; color: var(--encre-3);
        max-width: 74px; overflow: hidden;
      }

      /* La perspective. `data-loin` vaut la distance en étapes — 0 pour celle qu'on
            lit, 4 au-delà. Le léger décalage vertical dessine l'arc.               */
      .etape-frise[data-loin="0"] .rond-frise { width: 34px; height: 34px; font-size: .92rem; }
      .etape-frise[data-loin="1"] .rond-frise { width: 27px; height: 27px; font-size: .76rem; }
      .etape-frise[data-loin="2"] .rond-frise { width: 20px; height: 20px; font-size: .62rem; }
      .etape-frise[data-loin="3"] .rond-frise { width: 14px; height: 14px; font-size: 0; }
      .etape-frise[data-loin="4"] .rond-frise { width: 9px; height: 9px; font-size: 0; border-width: 1px; }

      .etape-frise[data-loin="1"] { transform: translateY(3px); }
      .etape-frise[data-loin="2"] { transform: translateY(7px); opacity: .8; }
      .etape-frise[data-loin="3"] { transform: translateY(11px); opacity: .6; }
      .etape-frise[data-loin="4"] { transform: translateY(14px); opacity: .45; }

      /* Le nom ne s'affiche qu'au voisinage immédiat : au-delà il serait illisible
            et volerait la place qui manque aux autres. */
      .etape-frise[data-loin="2"] .nom-frise,
      .etape-frise[data-loin="3"] .nom-frise,
      .etape-frise[data-loin="4"] .nom-frise { display: none; }
      .etape-frise[data-loin="1"] .nom-frise { font-size: .6rem; max-width: 58px; }


      .etape-frise.faite .rond-frise { background: var(--accent); border-color: var(--accent); color: #fff; }
      .etape-frise.faite .nom-frise { color: var(--encre-2); }
      /* L'étape en cours porte sa COULEUR et son cerclage, jamais sa taille : la
            taille dit « c'est ce que je lis », le cercle dit « c'est là que j'en
            suis ». Deux informations différentes. En lui fixant 34 px ici, elle
            restait grosse même quand on regardait ailleurs, et la perspective
            s'écroulait. */
      .etape-frise.encours .rond-frise {
        border-color: var(--accent); color: var(--accent);
        box-shadow: 0 0 0 3px var(--accent-pale);
      }
      .etape-frise.encours .nom-frise { color: var(--encre); font-weight: 700; }
      /* Estompées, pas éteintes : on doit pouvoir les lire et les atteindre. */
      .etape-frise.avenir { opacity: .5; }
      .etape-frise:hover { background: var(--accent-pale); }
      .etape-frise:hover .nom-frise { color: var(--encre); }
      .etape-frise.avenir:hover { opacity: 1; }
      /* L'étape REGARDÉE n'est pas l'étape en cours : le trait sous le nom dit
            « c'est ce que vous consultez », le cercle dit « c'est là qu'on en est ». */
      .etape-frise.regarde .nom-frise {
        color: var(--encre); box-shadow: 0 2px 0 var(--accent); padding-bottom: 2px;
      }
      .etape-frise:focus-visible { outline: 3px solid var(--accent-bord); outline-offset: 2px; }

      /* ── Carrousel des étapes ────────────────────────────────────────────────
            Le glissement est NATIF : `scroll-snap` et rien d'autre. Le doigt entraîne
            la carte avec l'inertie du système, et le carrousel continue de fonctionner
            si un script échoue. Une animation faite en JavaScript aurait été moins
            fluide et plus fragile, pour le même résultat.                          */
      .rail-etapes {
        /* ⚠️ CE COMMENTAIRE DISAIT LE CONTRAIRE JUSQU AU 27/08/2026, et il était
              devenu faux deux fois.

              Il expliquait que les cartes gardaient toutes la hauteur de la plus
              chargée, sous peine de « mal de mer sur un téléphone ». Or le rail n est
              PLUS un carrousel sur téléphone depuis longtemps : il y passe en
              `display: block` et n affiche qu une seule carte (voir plus bas,
              `.rail-etapes > .carte-etape { display: none }`). Le glissement qu il
              redoutait n existe plus là où il le redoutait.

              Restait l ordinateur, où le rail glisse encore — mais à la souris, sur
              une page qui ne suit pas le doigt. La hauteur commune n y achetait donc
              rien, et coûtait trois à quatre cents pixels de blanc sous les cartes
              courtes. Elle tombe (voir `align-items: flex-start` plus bas).

              Vérifié à l écran, les douze étapes, en 375 px et en 1150 px. */
        display: flex; gap: var(--e3);
        overflow-x: auto; overscroll-behavior-x: contain;
        scroll-snap-type: x mandatory; scroll-padding: 0 var(--e2);
        padding: var(--e2) 0 var(--e3); margin: 0 calc(-1 * var(--e2));
        scrollbar-width: thin;
      }
      .carte-etape {
        flex: 0 0 100%;
        /* Une ombre portee tres douce plutot qu un simple trait : les cartes se
           detachent du rail sans que la bordure s epaississe. */
        box-shadow: 0 1px 2px rgba(20, 30, 25, .04), 0 10px 26px -18px rgba(20, 30, 25, .3);
        /* `always` et non `normal` : le défilement est OBLIGÉ de s'arrêter à chaque
              carte. Sans lui, un geste un peu vif en saute trois et l'on atterrit
              n'importe où — le cran freine et repositionne. */
        scroll-snap-align: center; scroll-snap-stop: always;
        border: 1px solid var(--trait); border-radius: var(--r);
        /* ⚠️ BLANC, ET NON PLUS GRIS. « Je n aime pas le fond gris sur les cartes » —
           Rodolphe, 28/08/2026. Le gris etait EXACTEMENT celui du fond de page
           (mesure : les deux a oklab 0.936) : la carte ne se detachait que par sa
           bordure, et l ombre portee travaillait dans le vide. Les cartes « faite »
           etaient deja blanches — une carte sur deux d un meme rail changeait donc de
           couleur selon son etat, ce qui se lisait comme deux objets differents. */
        padding: var(--e4); background: #fff;
        margin: 0 var(--e2);
      }
      /* L'étape en cours porte un cerclage : sur un rail où toutes les cartes se
            ressemblent, c'est le seul repère qui dise « c'est ici qu'on en est ». */
      .carte-etape.encours { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-pale); }
      /* Estompées, jamais éteintes — et l'estompage se lève au survol comme au
            toucher : on doit pouvoir les lire pour de bon. */
      .carte-etape.avenir { opacity: .62; }
      .carte-etape.avenir:hover, .carte-etape.avenir:focus-within { opacity: 1; }
      /* `faite` n a plus rien a redire : toutes les cartes sont blanches. Son etat se
         lit a la coche de son en-tete, pas a un fond. */

      /* La carte est une colonne : son pied se colle en bas quelle que soit la
            hauteur du contenu, sans quoi le bouton de validation flotterait au
            milieu sur les cartes courtes et en bas sur les longues. */
      .carte-etape { display: flex; flex-direction: column; }
      /* ── Zone 3 : les gestes ──────────────────────────────────────────────────
         Ils etaient disperses entre les encadres. Regroupes, ils se comptent d un
         regard, et l on voit tout de suite quand une carte en propose trop.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ EN COLONNE, CHAQUE BOUTON PRENAIT SA PROPRE LARGEUR ET SA PROPRE LIGNE.
         « Remplir la fiche » au-dessus d « Aide a l estimation », l un large l autre
         etroit, alignes a gauche : un escalier. Les boutons se rangent donc sur une
         ligne et passent a la suivante quand la place manque, comme partout ailleurs
         dans l application. Les BLOCS — un formulaire de depot, un depliant — gardent
         la largeur entiere : ce ne sont pas des boutons, et les mettre a cote d un
         bouton ferait croire qu ils se valent.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .zone-gestes {
        display: flex; flex-wrap: wrap; align-items: flex-start;
        gap: var(--e2); margin: var(--e4) 0 0;
      }
      .zone-gestes > * { margin-top: 0; }
      /* Un paragraphe ne porte qu un bouton : il se met a sa taille et s aligne. */
      .zone-gestes > p { margin-bottom: 0; }
      /* Tout le reste occupe la ligne : formulaires, depliants, encadres. */
      .zone-gestes > div, .zone-gestes > details, .zone-gestes > form,
      .zone-gestes > ul { flex: 1 0 100%; }

      /* ── Zone 4 : le repli ────────────────────────────────────────────────────
         L aide, les scripts, les relances. Rien n est retire : tout ce qui vivait
         sur la carte y est encore, mais ferme. Ces blocs se consultent une fois sur
         dix et occupaient la carte dix fois sur dix. */
      .zone-repli {
        margin: var(--e4) 0 0; border: 1px solid var(--trait);
        border-radius: var(--r-petit); background: transparent;
      }
      .zone-repli > summary {
        display: flex; align-items: center; gap: var(--e2);
        padding: var(--e3) var(--e4); cursor: pointer;
        font-size: .9rem; font-weight: 650; color: var(--encre-2);
        list-style: none;
      }
      .zone-repli > summary::-webkit-details-marker { display: none; }
      .zone-repli > summary::after {
        content: ""; margin-left: auto;
        width: .5rem; height: .5rem; border-right: 2px solid var(--encre-3);
        border-bottom: 2px solid var(--encre-3); transform: rotate(45deg);
        transition: transform .15s;
      }
      .zone-repli[open] > summary::after { transform: rotate(-135deg); }
      .zone-repli[open] > summary { border-bottom: 1px solid var(--trait); }
      .zone-repli-corps { padding: var(--e4); background: var(--papier); }
      .zone-repli-corps > *:first-child { margin-top: 0; }
      .zone-repli-corps > *:last-child { margin-bottom: 0; }
      @media (prefers-reduced-motion: reduce) {
        .zone-repli > summary::after { transition: none; }
      }

      /* ═══════════ LA BARRE DE CASES — LE COMPOSANT UNIQUE ═══════════
         Rendu par `barreCases()` dans rendu/layout.js. Un seul objet pour tous les
         ecrans : un nombre, ce qu il compte, une icone, et parfois un lien.

         ⚠️ TROIS FAMILLES EXISTAIENT POUR LA MEME CHOSE — les « carte-chiffre » du
         tableau de bord, les « compteur-case » de la liste, les pastilles des onglets.
         Elles ont diverge sur la hauteur, le rond, la couleur de l active, et chaque
         correction demandait trois retouches. Celle-ci les remplace.

         ⚠️ LE TON COLORE LE ROND ET LE CHIFFRE, JAMAIS LE FOND. Un aplat colore
         derriere un nombre le rend plus dur a lire et fait de la case un panneau d
         alerte ; la teinte sur le chiffre suffit a dire ce qu il faut regarder.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .barre-cases {
        display: grid;
        grid-template-columns: repeat(var(--cases, auto-fit), minmax(9.5rem, 1fr));
        gap: var(--e3); margin: var(--e4) 0;
      }
      .case-ind {
        /* ⚠️ UNE ETIQUETTE N EST PAS UN LIBELLE DE FORMULAIRE. Sur l Agenda les cases
           sont des `label` — ce sont des volets a bascule — et ailleurs des `a`. La
           regle generale `label { margin-bottom: var(--e1) }` ajoutait donc quatre
           pixels sous les seules cases de l Agenda : mesure au telephone, 102,7 px de
           bande contre 98,7 partout ailleurs, pour des cases hautes de 76,3 des deux
           cotes. La meme etiquette ne peut pas changer de taille selon la balise qui
           la porte. Mesure du 02/09/2026. */
        margin-bottom: 0;
        min-height: 5.95rem;
        display: flex; align-items: center; gap: var(--e3);
        padding: var(--e4);
        border: 1px solid var(--trait); border-radius: var(--r);
        background: #fff; color: inherit; text-decoration: none;
        box-shadow: 0 1px 2px rgba(20,30,25,.04), 0 10px 26px -18px rgba(20,30,25,.3);
        transition: border-color .12s, box-shadow .12s;
      }
      a.case-ind:hover { border-color: var(--case-teinte, var(--encre-3)); }
      /* L active se designe par un seul trait plus fonce. Rien d autre ne bouge :
         meme fond, meme rond, meme hauteur — sans quoi la case choisie devient un
         autre objet et l oeil compare des formes au lieu de lire des chiffres. */
      a.case-ind.actif { border-color: var(--encre); }
      @media (prefers-reduced-motion: reduce) { .case-ind { transition: none; } }

      /* `--surface` vaut #ffffff : sans teinte, il faut un gris explicite, sinon le
         rond est blanc sur blanc et seule l icone flotte. */
      .case-rond {
        display: inline-flex; align-items: center; justify-content: center;
        width: 2.6rem; height: 2.6rem; flex: none; border-radius: 50%;
        background: var(--case-fond, color-mix(in oklab, var(--encre-3) 14%, #fff));
        color: var(--case-teinte, var(--encre-3));
      }
      .case-texte { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
      .case-texte b {
        font-size: 1.6rem; font-weight: 700; line-height: 1.1;
        font-variant-numeric: tabular-nums; color: var(--case-teinte, var(--encre));
      }
      .case-texte small {
        font-size: .82rem; margin-top: .15rem;
        color: var(--case-teinte, var(--encre-3));
      }
      /* Les cinq tons. Les quatre temps du parcours reutilisent leurs variables :
         un dossier au mandat porte la meme ambre ici et sur sa carte d etape. */
      .case-ind.succes    { --case-teinte: var(--succes); --case-fond: var(--succes-pale); }
      .case-ind.attention { --case-teinte: var(--attention); --case-fond: #fdf3e0; }
      .case-ind.danger    { --case-teinte: var(--danger); --case-fond: var(--danger-pale); }
      .case-ind.info      { --case-teinte: #1d5fb4; --case-fond: #e9f1fb; }
      .case-ind[class*="temps-"] { --case-teinte: var(--temps); --case-fond: var(--temps-fond); }
      /* A zero, la teinte s eteint : une alerte permanente cesse d etre lue. */
      .case-ind.case-vide { --case-teinte: var(--encre-3); --case-fond: var(--surface); }
      .case-ind.case-vide .case-texte b { color: var(--encre); }
      /* ⚠️ LES DEUX COLONNES ONT ETE RETIREES, PAS OUBLIEES. Elles empilaient les
         cases en rangees, ce que la ligne glissante remplace (voir le bloc
         `max-width: 760px`). Ne restent que les tailles, qui valent pour les deux. */
      @media (max-width: 560px) {
        .case-rond { width: 1.9rem; height: 1.9rem; }
        .case-texte b { font-size: 1.2rem; }
      }

      /* ── Ce que l application a fait a la place de l agent ────────────────────
         Une ligne, sous la barre de cases. Ni une case — elle ne filtre rien — ni une
         note de bas de page, ou elle se lisait avant. Le seul chiffre de l ecran qui
         parle de l outil et non du portefeuille.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .gain-semaine { margin: calc(var(--e2) * -1) 0 var(--e4); }
      .gain-semaine a {
        display: inline-flex; align-items: center; gap: var(--e2);
        padding: .5rem .85rem; border-radius: 999px;
        background: var(--succes-pale); color: var(--succes);
        font-size: .9rem; text-decoration: none;
        border: 1px solid color-mix(in oklab, var(--succes) 20%, transparent);
      }
      .gain-semaine a:hover { border-color: var(--succes); }
      .gain-semaine strong { font-weight: 700; font-variant-numeric: tabular-nums; }

      /* ── La barre de compteurs, en tete de la liste des vendeurs ──────────────
         « 9 vendeurs · 14 dossiers » disait la taille du portefeuille, pas son etat.
         Cinq cases disent ce qui attend, et la couleur porte l information avant que
         le chiffre soit lu. Reprise d une maquette validee par Rodolphe le 27/08/2026.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .compteurs-liste {
        display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
        gap: var(--e3); margin: var(--e4) 0 var(--e4);
      }
      /* ⚠️ UNE HAUTEUR MINIMALE COMMUNE, ET NON UN CALCUL QUI RETOMBE JUSTE.
         Meme rembourrage, meme rond, meme rayon — et pourtant 95 px ici contre 83
         ailleurs : ce sont les interlignes du chiffre et du libelle qui differaient de
         douze pixels. Chercher a les accorder aurait tenu tant que personne ne touche a
         une taille de police. Le plancher, lui, tient tout seul, et le contenu se
         centre dedans. Mesure sur les deux familles avant d etre fixe. */
      .compteur-case {
        min-height: 5.95rem;
        display: flex; align-items: center; gap: var(--e3);
        /* Hautes et aerees : elles etaient au meme gabarit qu une ligne de liste, et
           se lisaient comme une ligne de plus au lieu d un resume. */
        padding: var(--e4) var(--e4);
        border: 1px solid var(--trait); border-radius: var(--r);
        background: #fff;
        box-shadow: 0 1px 2px rgba(20, 30, 25, .04);
      }
      /* Le rond prend la teinte du temps auquel la case se rapporte : les memes
         quatre couleurs que les cartes d etape et les pastilles de la liste. */
      /* ⚠️ `--surface` VAUT #FFFFFF : le rond etait blanc sur blanc, et seule l icone
         se voyait. Il fallait un gris pour la case qui n a pas de couleur de temps —
         « Tous », « Rendez-vous », « Notes ». Tire de l encre plutot qu ecrit en dur :
         il suit le theme si les tokens changent. */
      .compteur-rond {
        display: inline-flex; align-items: center; justify-content: center;
        width: 2.6rem; height: 2.6rem; flex: none; border-radius: 50%;
        background: var(--temps-fond, color-mix(in oklab, var(--encre-3) 14%, #fff));
        color: var(--temps, var(--encre-3));
      }
      .compteur-texte { display: flex; flex-direction: column; line-height: 1.15; }
      .compteur-texte b {
        font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums;
        line-height: 1.1;
      }
      .compteur-texte small { font-size: .82rem; color: var(--encre-3); margin-top: .15rem; }
      /* Ce qui reclame un geste porte le rouge, et lui seul. A zero il redevient
         gris : une alerte permanente cesse d etre lue. */
      .compteur-alerte .compteur-rond { background: var(--danger-pale); color: var(--danger); }
      .compteur-alerte .compteur-texte b { color: var(--danger); }
      .compteur-vide.compteur-alerte .compteur-rond {
        background: var(--surface); color: var(--encre-3);
      }
      .compteur-vide.compteur-alerte .compteur-texte b { color: var(--encre); }
      @media (max-width: 560px) {
        .compteurs-liste { grid-template-columns: repeat(2, 1fr); gap: var(--e2); }
        .compteur-case { padding: var(--e2) var(--e3); gap: var(--e2); }
        .compteur-rond { width: 1.8rem; height: 1.8rem; }
        .compteur-texte b { font-size: 1.15rem; }
      }

      /* ── Joindre le vendeur, depuis le bandeau ────────────────────────────────
         Deux icones a cote de son nom. Elles occupaient deux places sur sept cartes
         d etape, alors que joindre quelqu un ne depend pas de l etape du dossier.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .joindre-vendeur {
        display: inline-flex; align-items: center; gap: var(--e2);
        margin-left: var(--e2); vertical-align: middle;
      }
      .joindre-vendeur a {
        display: inline-flex; align-items: center; justify-content: center;
        width: 1.9rem; height: 1.9rem; border-radius: 50%;
        background: rgba(255, 255, 255, .14); color: #fff;
        border: 1px solid rgba(255, 255, 255, .22);
        transition: background .12s;
      }
      .joindre-vendeur a:hover, .joindre-vendeur a:focus-visible {
        background: rgba(255, 255, 255, .26);
      }
      @media (prefers-reduced-motion: reduce) { .joindre-vendeur a { transition: none; } }

      /* ── Le journal des visites, sur la carte de commercialisation ────────────
         Ce qui manque quand le vendeur appelle pour savoir ou en est son bien.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .resume-visites {
        display: flex; align-items: center; gap: var(--e2);
        margin: 0; font-size: .95rem; color: var(--encre-2);
      }
      .resume-visites svg { flex: none; }
      .liste-visites {
        list-style: none; margin: var(--e3) 0 0; padding: 0;
        display: flex; flex-direction: column; gap: var(--e2);
      }
      .visite-acq {
        display: flex; align-items: flex-start; gap: var(--e2);
        padding: var(--e2) var(--e3); border: 1px solid var(--trait);
        border-radius: var(--r-petit); background: var(--surface);
        font-size: .9rem;
      }
      .visite-acq > div { flex: 1; min-width: 0; }
      .visite-acq strong { font-variant-numeric: tabular-nums; }
      /* La suite se lit avant le commentaire : c est elle qui dit s il faut rappeler
         ce visiteur, le commentaire dit seulement pourquoi. */
      .visite-suite {
        margin-left: var(--e2); font-size: .78rem; font-weight: 650;
        padding: .1rem .45rem; border-radius: 20px;
        background: var(--accent-pale); color: var(--accent);
      }

      /* Le pied se detache du contenu : un filet et un fond a peine teinte. Sans
         eux le bouton de validation flottait au milieu des blocs, et rien ne
         disait que la carte s arretait la. Redessine le 27/08/2026. */
      .pied-carte {
        display: flex; justify-content: flex-end; align-items: center;
        gap: var(--e2); flex-wrap: wrap; margin-top: auto; padding-top: var(--e4);
      }
      /* ⚠️ LE FILET ET LE FOND NE VALENT QUE POUR LE PIED D UNE CARTE D ETAPE, et le
         selecteur doit le dire. `.pied-carte` seul touche onze endroits — les
         fenetres de confirmation, la fiche du bien, et jusqu a l espace vendeur — qui
         n ont pas le rembourrage de la carte : les marges negatives y debordaient et
         posaient une bande grise au milieu de la page. Constate par Rodolphe le
         27/08/2026, capture a l appui, sur l onglet « Le bien ».
         L enfant DIRECT, en plus : une fenetre ouverte DANS une carte d etape porte
         son propre pied, qui n a pas de carte a fermer. */
      .carte-etape > .pied-carte {
        /* Pas de fond : le filet ferme la carte, et un aplat gris de plus sur un
           écran qui en compte déjà l alourdissait sans rien dire. */
        padding: var(--e4) var(--e4) 0;
        border-top: 1px solid var(--trait);
        margin-left: calc(-1 * var(--e4)); margin-right: calc(-1 * var(--e4));
      }
      /* Sur téléphone, le bord droit est le point le plus difficile à atteindre
            d'une seule main : le geste de validation passe au centre. */
      @media (max-width: 760px) {
        .pied-carte { justify-content: center; }
      }

      /* Résultats d'estimation figés pendant une coupure réseau.
         Volontairement VISIBLE : le danger n'est pas de perdre l'affichage, c'est de
         lire un montant périmé en le croyant à jour — devant un propriétaire. On
         atténue donc les chiffres pour qu'aucun regard rapide ne s'y trompe, tout en
         les laissant lisibles : ils restent la dernière valeur connue. */
      .resultats-geles > *:not(.resultats-avis) { opacity: .55; }
      .resultats-geles .resultats-avis { opacity: 1; margin: 0 0 var(--e3); }
      /* Les champs de pondération RESTENT utilisables, bien qu'atténués : leur saisie
         part dans la file comme les autres. Les désactiver la perdrait — c'est
         exactement ce qu'on cherche à éviter. */

      /* Invitation à installer l'application — espace agent, téléphone ET ordinateur.
         Révélée par /installer.js, seul à savoir si le navigateur peut installer
         quelque chose. Voir le commentaire près de son emplacement dans le corps. */
      /* Visible sur téléphone ET sur ordinateur : l'application s'installe aussi sur
         Mac et sur PC. C'est le SCRIPT qui décide s'il y a lieu de la montrer — lui
         seul sait si le navigateur peut installer quoi que ce soit.

         La règle vise :not([hidden]) et non l'élément seul : sans cela la frise
         s'afficherait avant que le script ait pu décider. */
      /* --- La fenetre d installation ---
         Le bandeau vivait dans le flux : on le depassait sans l avoir lu. C est
         pourtant LA reponse a « je ne retrouve plus l application ».
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .fenetre-installer {
        width: min(26rem, calc(100vw - 2rem));
        padding: var(--e5); border: 1px solid var(--trait);
        border-radius: var(--r-grand); background: var(--surface);
        box-shadow: var(--ombre-relief); color: var(--encre);
      }
      .fenetre-installer::backdrop { background: rgba(16, 20, 28, .45); }

      .tete-installer { display: flex; align-items: center; gap: var(--e3); }
      .tete-installer strong { display: block; font-size: 1.1rem; line-height: 1.2; }
      .tete-installer p { margin: .2rem 0 0; font-size: .9rem; color: var(--encre-3); }
      .logo-installer {
        width: 52px; height: 52px; border-radius: 14px; flex: none;
        object-fit: cover; background: var(--papier);
      }
      .logo-installer-lettre {
        display: grid; place-items: center; color: #fff; font-size: 1.4rem; font-weight: 700;
        background: linear-gradient(145deg, var(--accent), var(--accent-fonce));
      }

      .atouts-installer {
        list-style: none; margin: var(--e4) 0 0; padding: 0;
        display: flex; flex-direction: column; gap: var(--e3);
      }
      .atouts-installer li {
        display: flex; align-items: flex-start; gap: .55rem;
        font-size: .93rem; line-height: 1.35;
      }
      .atouts-installer svg { width: 18px; height: 18px; flex: none; margin-top: .1rem;
        color: var(--accent); }

      /* Le geste, illustre. Sur iPhone c est tout ce qu on peut faire : Apple
         interdit a un site de declencher l installation ou d ouvrir le menu
         Partager. Autant montrer l icone exacte a chercher. */
      .geste-installer:not(:empty) {
        margin: var(--e4) 0 0; padding: var(--e3) var(--e4);
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r-petit); font-size: .9rem; line-height: 1.45;
      }
      .etape-geste { display: flex; align-items: center; gap: .5rem; margin: .35rem 0; }
      .etape-geste svg { width: 20px; height: 20px; flex: none; color: var(--accent); }
      .numero-geste {
        display: grid; place-items: center; width: 20px; height: 20px; flex: none;
        border-radius: 50%; background: var(--accent); color: #fff;
        font-size: .72rem; font-weight: 700;
      }

      .pied-installer {
        display: flex; gap: var(--e2); margin-top: var(--e5);
      }
      .pied-installer button { flex: 1; margin: 0; }

      /* Fenêtre de confirmation, ouverte par le navigateur (attribut « popover ») :
            la politique de sécurité interdit le script dans la page. Même raison que
            la fenêtre de relecture des emails. */
      .fenetre-confirm {
        width: min(28rem, 92vw); padding: var(--e5); border: 0;
        border-radius: var(--r-grand); background: var(--papier); color: var(--encre);
        box-shadow: 0 1.4rem 3rem rgb(0 0 0 / .28);
      }
      .fenetre-confirm::backdrop { background: rgb(0 0 0 / .45); }
      .fenetre-confirm .pied-carte { padding-top: 0; }

      /* L'APERÇU D'UN EMAIL, dans une fenêtre qu'on ferme.
            Il s'ouvrait dans un onglet : on lisait le message, puis on se retrouvait
            coincé sur une page sans retour ni menu — il fallait fermer l'onglet pour
            revenir au dossier. Une fenêtre par-dessus la page garde le dossier
            derrière, et se referme d'un bouton ou de la touche Échap.

            Le message vit dans un cadre isolé : ce sont des styles d'email, écrits
            pour des messageries, et les laisser au contact de la page les ferait
            hériter des nôtres — on ne verrait pas ce que le vendeur voit. */
      .fenetre-apercu {
        width: min(44rem, 94vw); height: min(46rem, 88vh);
        padding: 0; border: 0; border-radius: var(--r-grand);
        background: var(--papier); color: var(--encre);
        box-shadow: 0 1.4rem 3rem rgb(0 0 0 / .28);
        overflow: hidden;
      }
      .fenetre-apercu::backdrop { background: rgb(0 0 0 / .45); }
      .fenetre-apercu > .tete-apercu {
        display: flex; align-items: center; justify-content: space-between;
        gap: var(--e3); padding: var(--e3) var(--e4);
        border-bottom: 1px solid var(--trait); background: var(--surface);
      }
      .fenetre-apercu > iframe {
        display: block; width: 100%; height: calc(100% - 3.6rem);
        border: 0; background: #f4f6f8;
      }

      /* Variante à contenu propre — une aide longue plutôt qu'un email encadré.
            Hauteur LIBRE dans la limite de l'écran : une aide de trois paragraphes
            ne doit pas occuper 46 rem de vide, alors qu'un email en a besoin. */
      /* `display` UNIQUEMENT quand la fenêtre est ouverte. Un popover fermé est
            caché par une règle du navigateur (display:none) ; lui donner un display
            depuis la feuille de style l'emporte sur cette règle, et la fenêtre
            reste affichée en permanence au milieu de la page. */
      .fenetre-info { height: auto; max-height: 88vh; }
      .fenetre-info:popover-open { display: flex; flex-direction: column; }
      .fenetre-info > .corps-fenetre {
        padding: var(--e4); overflow-y: auto;
      }
      .fenetre-info > .corps-fenetre > :first-child { margin-top: 0; }
      .fenetre-info > .corps-fenetre > :last-child { margin-bottom: 0; }

      /* Le bouton qui ouvre une fenêtre d'aide : discret, à sa taille, pas un
            appel à l'action. Il annonce une lecture, pas un geste. */
      .ouvrir-fenetre {
        min-height: 38px; padding: .35rem .8rem; font-size: .92rem;
      }

      /* Une étape franchie l'annonce clairement. Ses boutons restent actifs :
            « Passer à cette étape » sur une carte franchie est le chemin de RETOUR,
            celui qu'on prend quand une visite s'annule. */
      .etape-validee {
        display: flex; align-items: center; gap: var(--e2);
        margin: 0 0 var(--e3); font-size: .88rem; font-weight: 650;
        color: var(--succes); 
      }

      /* ── La tete de carte ────────────────────────────────────────────────────
         Trois lignes de meme poids ne disaient pas laquelle lire en premier : un
         surtitre gris, un titre, une aide grise. Le rang devient une pastille, le
         moment du parcours prend sa couleur, le titre grossit, et un filet ferme
         la tete avant les blocs. Redessine le 27/08/2026.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .tete-etape {
        margin: 0 0 var(--e4); padding-bottom: var(--e3);
        border-bottom: 1px solid var(--trait);
      }
      .rang-etape {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        margin: 0 0 var(--e2);
      }
      /* Le rang en pastille : un chiffre se repere avant un mot, et c est la
         premiere chose qu on cherche en ouvrant une carte. */
      .rang-jeton {
        display: inline-flex; align-items: baseline; gap: .1em;
        font-variant-numeric: tabular-nums; font-weight: 700; font-size: .82rem;
        line-height: 1; padding: .28rem .5rem; border-radius: var(--r-petit);
        /* Elle porte la couleur de son moment, comme le mot qui la suit : deux
           signes de la même chose, et plus un jeton gris posé à côté. */
        background: var(--temps-fond, var(--papier)); color: var(--temps, var(--encre-2));
        border: 1px solid currentColor;
      }
      .rang-sur { font-size: .68rem; font-weight: 600; opacity: .6; }
      .carte-etape.encours .rang-jeton {
        background: var(--accent); border-color: var(--accent); color: #fff;
      }
      /* Le moment du parcours, dans la couleur qui teinte deja les cartes de la
         liste des vendeurs : un dossier au mandat porte l ambre des deux cotes.
         Les variables --temps viennent du meme endroit (voir .temps-*). */
      .moment-etape {
        font-size: .7rem; font-weight: 700; letter-spacing: .07em;
        text-transform: uppercase; color: var(--temps, var(--encre-3));
      }
      /* Franchie, en cours, a venir : l etat se lit en dernier parce qu il se
         devine deja au cerclage de la carte. */
      .etat-etape {
        margin-left: auto; font-size: .7rem; font-weight: 600;
        letter-spacing: .04em; text-transform: uppercase; color: var(--encre-3);
      }
      .etat-encours { color: var(--accent); }
      .etat-faite { color: var(--succes); }

      .nom-etape {
        margin: 0 0 var(--e1); font-size: 1.28rem; line-height: 1.2;
        letter-spacing: -.01em;
      }
      .aide-etape { margin: 0; font-size: .92rem; color: var(--encre-2); }

      /* Sur grand écran, on laisse deviner la carte suivante : sans ce débord, rien
            n'indique qu'il y a quelque chose à côté et personne ne pense à glisser. */
      @media (min-width: 761px) {
        .carte-etape { flex-basis: calc(100% - var(--e7)); }

        /* ⚠️ ET LA HAUTEUR COMMUNE TOMBE ICI, MAIS ICI SEULEMENT.
           Le commentaire du rail dit pourquoi elle existe : à taille libre, la page
           sautait à chaque glissement et donnait le mal de mer sur un téléphone.
           C est vrai du geste tactile, pas de la souris — sur ordinateur on clique la
           frise ou la flèche, la page ne suit pas le doigt. Le prix, lui, se voyait :
           trois cents à quatre cents pixels de blanc sous les cartes courtes, mesuré
           le 27/08/2026 en parcourant les douze étapes une par une.
           Le mobile garde la hauteur commune. */
        .rail-etapes { align-items: flex-start; }
      }

      /* ── Sur téléphone, le module sort de son cadre ──────────────────────────
            Une carte dans une carte : le module avait sa bordure, et chaque étape la
            sienne à l'intérieur. Deux encadrements imbriqués sur un écran étroit, ce
            sont surtout deux fois moins de place pour le contenu.

            Le module s'étend donc d'un bord à l'autre de l'écran et abandonne son
            propre cadre ; seules les cartes d'étape gardent le leur. La marge
            négative annule le rembourrage du conteneur parent, dont on ne connaît
            pas la valeur ici — d'où les 100vw plutôt qu'un calcul.                */
      /* Le fond et la marge basse viennent d'ici et non d'un style en ligne : un
            `margin` écrit sur l'élément l'emporte sur la feuille de style, et il
            annulait la sortie de cadre du téléphone ci-dessous. */
      /* Meme raison que les cartes d etape : ce gris etait celui du fond de page. */
      .carte.module-avancement { background: #fff; margin: 0 0 var(--e5); }

      @media (max-width: 760px) {
        .carte.module-avancement {
          border-left: 0; border-right: 0; border-radius: 0;
          margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw);
          padding-left: var(--e3); padding-right: var(--e3);
        }
        /* Le rail déborde jusqu'aux bords : la carte suivante s'annonce au ras de
              l'écran, ce qui est le signe qu'il y a quelque chose à côté. */
        .module-avancement .rail-etapes {
          margin-left: calc(-1 * var(--e3)); margin-right: calc(-1 * var(--e3));
          padding-left: var(--e3); padding-right: var(--e3);
          scroll-padding: 0 var(--e3);
        }
        /* Pleine largeur, et le cran l'y ramène : sur un écran étroit, laisser
              dépasser un bout de la carte suivante rognait la carte lue sans rien
              apprendre — la frise dit déjà qu'il y a d'autres étapes. */
        .carte-etape { margin: 0; flex-basis: 100%; }
      }

      nav.menu { display: flex; gap: var(--e1); flex-wrap: wrap; flex-shrink: 0; }
      nav.menu a {
        color: var(--encre-2); text-decoration: none; padding: .45rem .7rem;
        border-radius: var(--r-petit); font-size: .93rem; font-weight: 500; white-space: nowrap;
        transition: background .15s ease, color .15s ease;
      }
      nav.menu a:hover { background: var(--papier); color: var(--encre); }
      nav.menu a.actif { background: var(--accent-pale); color: var(--accent-fonce); font-weight: 650; }
      /* Entrée détachée (« Me connecter ») : même famille visuelle qu'un bouton
         secondaire, pour se distinguer des pages sans voler la vedette au CTA. */
      nav.menu a.a-part {
        margin-left: var(--e3); border: 1px solid var(--trait);
        color: var(--encre); font-weight: 600;
      }
      nav.menu a.a-part:hover { border-color: var(--accent-bord); background: var(--accent-pale);
        color: var(--accent-fonce); }

      .bascule-menu { position: absolute; opacity: 0; width: 1px; height: 1px; }
      .bouton-menu { display: none; }

      /* --- Contenu --- */
      /* ⚠️ L OMBRE LA PLUS HAUTE VA AU CONTENEUR, pas aux cartes qu il porte. C est lui
         qui flotte au-dessus du fond gris, et le reste se pose dessus. Avec l ombre
         basse il restait colle a la page, et la profondeur s arretait aux petites
         cartes. Releve par Rodolphe en comparant l ecran a la maquette. */
      /* ⚠️ QUATRE-VINGTS REM ET NON SOIXANTE-HUIT. Sur un ecran de deux mille pixels, le
         contenu en occupait onze cents et le reste etait du vide. On ne va pas plus loin
         pour autant : au-dela, une ligne de texte depasse la longueur ou l oeil retrouve
         seul le debut de la suivante. C est la grille a deux colonnes qui exploite le
         reste, pas l etirement. */
      main.contenu {
        max-width: 80rem; margin: var(--e5) auto; padding: var(--e6);
        background: var(--surface); border: 0;
        border-radius: var(--r-grand); box-shadow: var(--ombre-haute);
      }
      main.contenu > *:first-child { margin-top: 0; }
      /* ⚠️ LE BANDEAU EST L EXCEPTION A LA REGLE DU DESSUS. « premier enfant, marge du
         haut a zero » annulait sa marge negative : il redescendait de deux rem et une
         bande blanche restait au-dessus de lui. Les deux selecteurs ont la meme force,
         c est donc l ordre qui tranche, et celui-ci vient apres. */
      main.contenu > .tete-bord:first-child { margin-top: calc(var(--e6) * -1); }

      /* --- Formulaires --- */
      label { display: block; font-weight: 600; font-size: .95rem; margin-bottom: var(--e1); }
      /* Une liste de types à rallonger à chaque fois finit par en oublier un : c'est ce
         qui est arrivé à « datetime-local », resté au rendu brut du navigateur — une
         petite boîte grise à côté de champs ronds et pleine largeur. On désigne donc
         les champs par ce qu'ils NE sont pas, et tout nouveau type est habillé d'office. */
      input:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]),
      select, textarea {
        width: 100%; min-height: 46px; padding: .65rem .8rem;
        font-size: 1rem; font-family: inherit; color: var(--encre);
        background: var(--surface); border: 1px solid color-mix(in oklab, var(--trait) 70%, var(--encre-3));
        border-radius: var(--r-petit); transition: border-color .15s ease, box-shadow .15s ease;
      }
      /* Le petit calendrier du champ date : à peine visible au gris par défaut, alors
         que c'est lui qu'on vise pour ouvrir le sélecteur. */
      input[type=datetime-local]::-webkit-calendar-picker-indicator,
      input[type=date]::-webkit-calendar-picker-indicator {
        cursor: pointer; opacity: .55; padding: .2rem;
      }
      input[type=datetime-local]:hover::-webkit-calendar-picker-indicator,
      input[type=date]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
      input:hover, select:hover, textarea:hover { border-color: var(--encre-3); }
      input:focus-visible, select:focus-visible, textarea:focus-visible, a:focus-visible {
        outline: none; border-color: var(--accent);
        box-shadow: 0 0 0 3px var(--accent-bord);
      }
      textarea { min-height: 92px; resize: vertical; }

      /* Champ « fichier ». Il n'était pas habillé et s'affichait en bouton natif
         minuscule — sur mobile, un carré gris de quelques millimètres, que
         personne n'identifie comme l'endroit où déposer un document. Il porte
         donc la même bordure que les autres champs, et son bouton interne est
         redessiné : c'est le seul contrôle dont le navigateur impose une partie
         du rendu. */
      input[type=file] {
        width: 100%; padding: .55rem .7rem;
        font-size: .95rem; font-family: inherit; color: var(--encre-2);
        background: var(--surface);
        border: 1px dashed color-mix(in oklab, var(--trait) 55%, var(--encre-3));
        border-radius: var(--r-petit); cursor: pointer;
        transition: border-color .15s ease, background .15s ease;
      }
      input[type=file]:hover {
        border-color: var(--accent); background: var(--accent-pale);
      }
      input[type=file]::file-selector-button {
        margin-right: .8rem; padding: .5rem .9rem;
        font: inherit; font-weight: 600; color: var(--encre);
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r-petit); cursor: pointer;
      }
      input[type=file]::file-selector-button:hover {
        background: var(--surface); border-color: var(--encre-3);
      }
      select {
        appearance: none; padding-right: 2.4rem; cursor: pointer;
        background-image: linear-gradient(45deg, transparent 50%, var(--encre-3) 50%),
                          linear-gradient(135deg, var(--encre-3) 50%, transparent 50%);
        background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
        background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
      }

      /* --- Boutons --- */
      button, .bouton {
        display: inline-flex; align-items: center; justify-content: center; gap: var(--e2);
        min-height: 46px; padding: .65rem 1.15rem;
        font-size: .97rem; font-weight: 600; font-family: inherit;
        color: #fff; background: var(--accent); border: 1px solid transparent;
        border-radius: var(--r-petit); cursor: pointer; text-decoration: none;
        transition: background .15s ease, box-shadow .15s ease, transform .06s ease;
      }
      button:hover:not(:disabled), .bouton:hover { background: var(--accent-fonce); color: #fff; }
      button:active:not(:disabled), .bouton:active { transform: translateY(1px); }
      button:focus-visible, .bouton:focus-visible {
        outline: none; box-shadow: 0 0 0 3px var(--accent-bord);
      }
      button:disabled { background: color-mix(in oklab, var(--encre-3) 35%, #fff);
        color: color-mix(in oklab, var(--encre-3) 80%, #fff); cursor: not-allowed; }
      /* Les variantes portent « :not(:disabled) » pour la même raison que la règle
         générale ci-dessus, et pas seulement par symétrie : sans lui, « .bouton-2:hover »
         pèse moins que « button:hover:not(:disabled) », qui l'emporte et repeint le
         bouton en ardoise foncée. Un bouton secondaire, un bouton discret et un bouton
         de suppression viraient tous au même gris sombre au survol — visible partout
         dans l'application, y compris sur les fiches de dossier. */
      .bouton-2 { background: var(--surface); color: var(--encre); border-color: var(--trait); }
      .bouton-2:hover:not(:disabled) { background: var(--papier); color: var(--encre); }
      /* ⚠️ LA HAUTEUR DE CIBLE EST TENUE PAR LE REMBOURRAGE, PAS PAR LE TEXTE. Sans
         hauteur minimale, ce bouton faisait vingt-huit pixels de haut : sous le pouce, on
         vise a cote. Le fond reste transparent — c est un lien qui a la forme d un
         bouton, sa cible n a pas a se voir pour exister. Mesure du 22/08/2026. */
      .bouton-discret { background: none; border: 0; color: var(--accent);
        padding: .5rem 0; min-height: 40px; font-weight: 600; text-decoration: underline; }
      .bouton-discret:hover:not(:disabled) { background: none; color: var(--accent-fonce); }
      .bouton-danger { background: var(--danger); }
      .bouton-danger:hover:not(:disabled) {
        background: color-mix(in oklab, var(--danger) 82%, #000);
      }

      /* --- Blocs --- */
      /* ⚠️ LA CARTE PORTE UNE OMBRE, PLUS UN TRAIT SEUL. Un bloc cerne d un filet gris
         reste colle a sa page ; un bloc qui projette une ombre s en decolle. La bordure
         reste, tres claire, pour tenir le bord sur les ecrans qui rendent mal les
         ombres. Direction validee par Rodolphe le 20/08/2026. */
      .carte {
        background: var(--surface);
        border: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        border-radius: var(--r); padding: var(--e4) var(--e5); margin-bottom: var(--e3);
        box-shadow: var(--ombre);
      }
      .carte-relief { box-shadow: var(--ombre); }
      /* ⚠️ `.cartouche` N ETAIT PAS UNE CARTE, ET DIX ECRANS LE CROYAIENT. Seule
            `.cartouche-reglages` existait ; `.cartouche` seul ne peignait rien, et les
            quatre blocs de la fiche d un rendez-vous se suivaient sans separation
            visible — mesure : fond transparent, bordure a zero. Le mot est employe dans
            les horaires, les connexions et la fiche d un rendez-vous : plutot que de le
            renommer partout, il devient ce qu il pretendait etre. */
      .cartouche {
        background: var(--surface);
        border: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        border-radius: var(--r); padding: var(--e4) var(--e5);
        margin-bottom: var(--e3);
        box-shadow: var(--ombre);
      }
      .cartouche > :first-child { margin-top: 0; }
      .cartouche > :last-child { margin-bottom: 0; }
      fieldset {
        border: 1px solid var(--trait); border-radius: var(--r);
        padding: var(--e4) var(--e5) var(--e2); margin: 0 0 var(--e5);
      }
      legend { font-weight: 650; padding: 0 var(--e2); font-size: .98rem; }
      hr { border: 0; border-top: 1px solid var(--trait); margin: var(--e5) 0; }

      /* --- Signalements --- */
      .erreur { color: var(--danger); font-weight: 600; }
      .ok { color: var(--succes); font-weight: 600; }
      .avis {
        display: flex; gap: var(--e3); align-items: flex-start; flex-wrap: wrap;
        padding: var(--e3) var(--e4); border-radius: var(--r); margin-bottom: var(--e4);
        border: 1px solid;
      }
      /* Le texte garde une largeur lisible : l'action passe dessous si nécessaire. */
      .avis > span { flex: 1 1 15rem; min-width: 0; }
      .avis-succes { background: var(--succes-pale); border-color: color-mix(in oklab, var(--succes) 25%, #fff); color: color-mix(in oklab, var(--succes) 85%, #000); }
      .avis-danger { background: var(--danger-pale); border-color: color-mix(in oklab, var(--danger) 25%, #fff); color: color-mix(in oklab, var(--danger) 85%, #000); }
      .avis-info   { background: var(--accent-pale); border-color: var(--accent-bord); color: var(--accent-fonce); }
      /* Constat sans gravité (lien périmé) : ni alarme rouge, ni faux air de succès. */
      .avis-neutre { background: var(--papier); border-color: var(--trait); color: var(--encre-2); }
      /* Ce qui mérite qu'on s'arrête sans que rien ne soit cassé : une chambre sans
         fenêtre, un diagnostic qui approche de sa fin. Le rouge dirait « erreur ». */
      .avis-attention {
        background: color-mix(in oklab, var(--attention) 8%, #fff);
        border-color: color-mix(in oklab, var(--attention) 30%, #fff);
        color: color-mix(in oklab, var(--attention) 85%, #000);
      }
      .avis svg { flex: none; margin-top: 2px; }

      /* ─────────────────────────────────────────────────────────────────────────
            DEUX FACONS DE TRAVAILLER, POSEES AVANT LE FORMULAIRE.
            Le choix decide de tout ce qui suit : ce qui est obligatoire, ce qui part,
            ce qui s ouvre. Il a donc la taille d une decision, pas celle d une case.
            ───────────────────────────────────────────────────────────────────────── */
      .grille-voies {
        display: grid; gap: var(--e4); margin-top: var(--e5);
        grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
      }
      .carte-voie {
        display: flex; flex-direction: column; margin: 0;
        padding: var(--e5); text-decoration: none;
        border-radius: var(--r-grand);
        transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
      }
      .carte-voie:hover {
        text-decoration: none; transform: translateY(-2px);
        box-shadow: var(--ombre-haute); border-color: var(--accent);
      }
      /* La voie ordinaire du produit est teintee : proposee, jamais imposee. */
      .carte-voie-vive {
        background: var(--accent-pale);
        border-color: color-mix(in oklab, var(--accent) 22%, #fff);
      }
      .carte-voie-rond {
        display: inline-flex; align-items: center; justify-content: center;
        width: 46px; height: 46px; border-radius: 999px;
        background: #fff; color: var(--accent); box-shadow: var(--ombre-relief);
      }
      .carte-voie-titre {
        font-size: 1.3rem; font-weight: 700; color: var(--encre);
        margin: var(--e4) 0 0; line-height: 1.2;
      }
      .carte-voie-phrase { margin: var(--e3) 0 0; color: var(--encre-2); line-height: 1.55; }
      .carte-voie-sous {
        margin: var(--e3) 0 0; font-size: .86rem; color: var(--encre-3);
        padding-left: .7rem; border-left: 2px solid var(--trait);
      }
      /* `auto` en haut : les deux pieds s alignent quelle que soit la longueur du
         texte au-dessus, sans quoi les deux « Choisir » flottaient a des hauteurs
         differentes et les cartes semblaient mal decoupees. */
      .carte-voie-pied {
        display: inline-flex; align-items: center; gap: .4rem;
        margin: auto 0 0; padding-top: var(--e4);
        font-weight: 650; color: var(--accent);
      }
      /* Dans la liste, la pastille suit le nom sans le pousser : elle se pose sur la
         ligne de base du titre et ne grossit pas la carte. */
      .pastille-vendeur { vertical-align: middle; margin-left: .45rem; font-weight: 600; }
      /* ─────────────────────────────────────────────────────────────────────────
            LE RAPPEL QU UNE NOTE PORTE.
            « Le client est en vacances et nous dit de le rappeler dans trois
            semaines » — Rodolphe, 26/08/2026. La date est facultative et le dit ;
            les quatre raccourcis existent parce que personne ne calcule le 16
            septembre de tete en raccrochant.
            ───────────────────────────────────────────────────────────────────────── */
      .rappel-ligne {
        display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
        margin: var(--e4) 0 0;
      }
      .rappel-ligne label { font-weight: 600; margin: 0; white-space: nowrap; }
      .rappel-ligne input[type="date"] { width: auto; min-width: 11rem; margin: 0; }
      .raccourcis { display: flex; flex-wrap: wrap; gap: .4rem; margin: var(--e2) 0 0; }
      .raccourci {
        border: 1px solid var(--trait); background: #fff; border-radius: 999px;
        padding: .25rem .7rem; font-size: .86rem; color: var(--encre-2);
        cursor: pointer; min-height: 0; width: auto; font-weight: 400;
      }
      .raccourci:hover { border-color: var(--accent); color: var(--accent); }
      .raccourci.actif {
        background: var(--accent-pale); border-color: var(--accent);
        color: var(--accent); font-weight: 600;
      }
      /* Ambre et non rouge : un rappel n est pas une alerte, c est une promesse tenue
         a l heure. Le rouge est reserve a ce qui bloque. */
      .badge-rappel {
        display: inline-flex; align-items: center; gap: .35rem;
        background: #fff7e8; border: 1px solid #f0dcb4; color: var(--attention);
        border-radius: 999px; padding: .15rem .6rem; font-size: .82rem; font-weight: 600;
      }
      .badge-rappel-tard { background: #fdecec; border-color: #f3c4c4; color: var(--danger); }
      .badge-rappel-fait {
        background: var(--papier); border-color: var(--trait); color: var(--encre-3);
        font-weight: 500;
      }

      /* Le bloc « A rappeler » du tableau de bord : la date en gros a gauche, parce
         qu on lit d abord QUAND, et les deux gestes sous le texte. */
      .rappel-carte {
        display: flex; gap: var(--e4); align-items: flex-start;
        padding: var(--e4) 0; border-top: 1px solid var(--trait);
      }
      .rappel-carte:first-of-type { border-top: 0; padding-top: 0; }
      .rappel-jour { flex: 0 0 4.2rem; text-align: center; }
      .rappel-jour b {
        display: block; font-size: 1.35rem; line-height: 1; font-weight: 700;
      }
      .rappel-jour span {
        font-size: .76rem; color: var(--encre-3);
        text-transform: uppercase; letter-spacing: .05em;
      }
      .rappel-corps { flex: 1 1 auto; min-width: 0; }
      .rappel-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin: .5rem 0 0; }
      /* `width: auto` : les boutons de l application sont pleine largeur par defaut, et
         deux boutons pleine largeur empilent deux lignes pour deux mots. */
      .rappel-actions button {
        display: inline-flex; align-items: center; gap: .3rem; width: auto;
        margin: 0; padding: .3rem .8rem; font-size: .88rem; min-height: 0;
      }
      /* La bande de l agenda : un rappel n est pas un rendez-vous, il ne prend pas de
         creneau et ne se dessine donc pas dans la grille. */
      .bande-rappel {
        display: flex; align-items: center; gap: .5rem;
        background: #fff7e8; border: 1px solid #f0dcb4; border-left: 3px solid #c98a1e;
        border-radius: var(--r-petit); padding: .45rem .7rem;
        margin: 0 0 var(--e2); font-size: .9rem;
      }
      .interrupteur {
        display: flex; align-items: flex-start; gap: .7rem;
        padding: var(--e4) 0; border-top: 1px solid var(--trait); cursor: pointer;
      }
      .interrupteur:first-of-type { border-top: 0; padding-top: 0; }
      .interrupteur input { width: auto; min-height: 0; margin-top: .25rem; }

      /* ─────────────────────────────────────────────────────────────────────────
            LE RAIL DE GAUCHE, SUR ORDINATEUR.
            « J aimerais que sur PC on puisse avoir un menu a gauche » — Rodolphe,
            26/08/2026. Il n existe QU au-dessus de 1024 pixels : plus bas, quinze rem
            de rail prendraient un tiers de la largeur, et la barre du bas fait deja le
            travail sur telephone.
            ───────────────────────────────────────────────────────────────────────── */
      .rail-app { display: none; }
      @media (min-width: 1024px) {
        /* ⚠️ LE RAIL EST SOMBRE. « J aimerais bien que la colonne a gauche soit noir
           fonce, avec un degrade moderne, le logo et les ecritures en blanc — je pense
           que graphiquement ce sera plus joli » — Rodolphe, 27/08/2026.

           Un degrade tres lent, assez pour que la colonne ne soit pas un aplat mort,
           assez peu pour qu on ne le remarque pas. Le bord droit devient une ligne
           claire tres attenuee — sur ce fond, le trait gris de l application
           disparaitrait.

           ⚠️ ANTHRACITE, ET NON NOIR. Le premier jet etait un noir bleute : mesure en
           teinte, il tombait a 216 degres, soit CINQUANTE-TROIS degres du vert du
           bandeau, qui est a 163. Deux masses sombres cote a cote, de deux familles
           differentes, et leur jonction se lisait comme un accident plutot que comme un
           choix — « la coupure du noir au vert, c est pas un peu trop violent ? »,
           Rodolphe, 27/08/2026.

           Un vert tres sombre reglait la jonction mais faisait « trop de vert » : la
           colonne fait toute la hauteur de l ecran, elle serait devenue la marque a la
           place du bandeau. Celui-ci est a 144 degres — dix-neuf du vert, donc de la
           meme famille — mais a QUATORZE POUR CENT de saturation : il se lit comme un
           anthracite neutre, et la coupure devient un changement d intensite et non de
           couleur. */
        .espace-agent .rail-app {
          display: flex; flex-direction: column;
          position: fixed; left: 0; top: 0; bottom: 0; width: 15rem; z-index: 40;
          background: linear-gradient(170deg, #171d1a 0%, #101512 55%, #0b100e 100%);
          /* ⚠️ PLUS DE BORDURE A DROITE. Elle valait quand le contenu commencait en
             gris clair : un trait blanc a 7 % marquait la limite sans se voir. Depuis
             que le bandeau demarre lui aussi en noir, ce meme trait est la SEULE chose
             visible entre les deux — « il y a toujours une barre entre les deux »,
             Rodolphe, 27/08/2026, capture entouree a l appui.
             La limite reste dite par le contenu clair, plus bas dans la page. */
          padding: var(--e4) 0; overflow-y: auto;
          color: rgba(255,255,255,.72);
        }
        /* Le corps se decale d autant. `padding` et non `margin` : la marge aurait
           reduit la largeur de reference des elements pleine largeur, et les bandeaux
           auraient cesse de toucher le bord droit. */
        .espace-agent { padding-left: 15rem; }
        /* ⚠️ ET LA BARRE DU HAUT DISPARAIT. La garder aurait fait deux menus a l ecran
           pour les memes destinations, ce qui est exactement le defaut qu on vient de
           corriger deux fois aujourd hui sur la fiche vendeur. Le logo vit desormais en
           tete du rail. */
        .espace-agent header.principal { display: none; }

        /* ⚠️ LA PAGE REMPLIT L ESPACE, ELLE NE FLOTTE PLUS SUR DU GRIS. « Ca serait
           bien que la fenetre qui affiche l onglet soit pleine dans fond gris » —
           Rodolphe, 26/08/2026, capture a l appui.

           La carte blanche arrondie posee sur un fond gris avait un sens quand le menu
           etait en haut : elle delimitait la page. Avec un rail a gauche, la
           delimitation est deja faite par le rail, et la gouttiere grise ne fait plus
           que retrecir le contenu — sur la grille de l agenda, qui manque deja de
           place, c est une centaine de pixels perdus de chaque cote.

           `min-height` : sans lui, une page courte laissait reapparaitre le gris
           sous elle, ce qui donnait l impression que le correctif n avait pris qu a
           moitie. */
        .espace-agent main.contenu {
          max-width: none; margin: 0; min-height: 100vh;
          border-radius: 0; box-shadow: none;
        }
        /* ⚠️ ET LE BANDEAU PERD SES DEUX COINS ARRONDIS. « Sur PC en haut du bandeau
           vert on voit les angles arrondis a gauche et a droite, ca rendrait mieux
           sans » — Rodolphe, 27/08/2026. Ils avaient un sens quand la page etait une
           carte blanche posee sur du gris : le bandeau en epousait le haut. Depuis que
           la page remplit l espace, ils dessinent deux encoches grises dans un vert qui
           devrait toucher le bord. */
        .espace-agent .tete-ecran { border-radius: 0; }
      }
      /* Le logo et les mots passent au blanc : sur ce noir, l encre de l application
         et la couleur d accent du conseiller ne se lisent plus. */
      .rail-marque {
        display: flex; align-items: center; gap: .55rem;
        padding: 0 var(--e4) var(--e5); color: #fff; text-decoration: none;
      }
      .rail-marque:hover { text-decoration: none; }
      .rail-marque b {
        font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
        font-size: 1.15rem; color: #fff; font-weight: 800;
      }
      .rail-lien {
        display: flex; align-items: center; gap: .7rem;
        padding: .6rem var(--e4); margin: .1rem var(--e3);
        border-radius: var(--r-petit); color: rgba(255,255,255,.72);
        text-decoration: none; font-weight: 500;
      }
      .rail-lien:hover {
        background: rgba(255,255,255,.07); color: #fff; text-decoration: none;
      }
      /* ⚠️ L ENTREE COURANTE NE PREND PAS LA COULEUR D ACCENT DU CONSEILLER. Elle est
         choisie pour se lire sur du blanc : sur ce noir, un bleu marine devient un trou.
         Une pastille claire, et le mot en blanc franc. */
      /* ⚠️ L ACTIF PREND LE VERT DE L APPLICATION, ET NON UN VOILE BLANC.
         Sur la bande noire, `rgba(255,255,255,.12)` donnait un gris a peine plus clair
         que ses voisins : on cherchait ou l on etait. Le vert plein le designe, et la
         barre de gauche le confirme au bord de l ecran. Maquette du 27/08/2026.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ LE TRAIT VERTICAL A GAUCHE A ETE RETIRE. « Enleve la petite barre a gauche
         quand un onglet est selectionne, ca fait moche » — Rodolphe, 28/08/2026. Il
         disait deux fois la meme chose que la pastille pleine, et il se posait a
         l exterieur du coin arrondi : un petit rectangle vert qui depassait de la
         forme au lieu d en faire partie.

         ⚠️ ET LA TEINTE SUIT CELLE DE LA MAQUETTE. #145c45 etait un vert franc qui ne
         se retrouvait nulle part ailleurs sur l ecran ; la pastille prend maintenant le
         vert du bandeau, #0d5c46 — la bande du haut et l onglet choisi portent donc
         exactement la meme couleur, ce qui est ce qui les relie. */
      .rail-lien.actif {
        background: #0d5c46; color: #fff; font-weight: 650;
      }
      .rail-lien.actif .rail-dessin { color: #fff; }
      .rail-dessin { display: inline-flex; color: rgba(255,255,255,.55); }
      .rail-lien:hover .rail-dessin { color: rgba(255,255,255,.85); }
      .rail-mot { flex: 1 1 auto; }
      /* Le rouge des messages non lus : c est la seule pastille du rail, et elle dit
         qu on attend une reponse de vous. */
      .rail-compte {
        background: var(--danger); color: #fff; border-radius: 999px;
        font-size: .74rem; font-weight: 700; padding: .05rem .4rem;
        min-width: 1.15rem; text-align: center;
      }
      .rail-separation {
        height: 1px; background: rgba(255,255,255,.09); margin: var(--e3) var(--e4);
      }
      /* `auto` en haut : les deux entrees rares se collent au bas du rail quel que soit
         le nombre de pages au-dessus. */
      .rail-pied { margin-top: auto; }

      .cartouche-voie { display: grid; gap: var(--e3); }
      .cartouche-voie .carte-voie-rond { width: 40px; height: 40px; }
      /* Plusieurs pastilles sous un titre de bandeau se rangent en ligne. */
      .tete-ecran-dessous { display: flex; gap: .5rem; flex-wrap: wrap; }

      /* Pastille d'état : le statut se lit d'un coup d'œil, pas seulement au texte. */
      .pastille {
        display: inline-flex; align-items: center; gap: .4rem;
        padding: .2rem .6rem; border-radius: 999px;
        font-size: .8rem; font-weight: 650; white-space: nowrap;
        background: var(--papier); border: 1px solid var(--trait); color: var(--encre-2);
      }
      .pastille-succes { background: var(--succes-pale); border-color: color-mix(in oklab, var(--succes) 22%, #fff); color: color-mix(in oklab, var(--succes) 88%, #000); }
      .pastille-attente { background: #fff7e8; border-color: #f0dcb4; color: var(--attention); }
      /* Un diagnostic périmé, une échéance dépassée : ce qui bloque, et non ce qui
         attend. Le rouge n'est employé nulle part ailleurs sur une pastille. */
      .pastille-danger { background: #fdecec; border-color: #f3c4c4; color: var(--danger); }

      /* Barre de progression */
      .jauge { height: 10px; border-radius: 999px; background: var(--trait); overflow: hidden; }
      .jauge > span { display: block; height: 100%; border-radius: 999px;
        background: linear-gradient(90deg, var(--accent), var(--accent-fonce));
        transition: width .35s ease; }

      /* --- Contacts : boutons d'action --- */
      .contacts { display: flex; gap: var(--e2); flex-wrap: wrap; margin: var(--e3) 0; }
      .contacts a {
        display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
        min-height: 46px; padding: .6rem 1rem; border-radius: var(--r-petit);
        font-weight: 600; font-size: .95rem; text-decoration: none; border: 1px solid transparent;
        transition: filter .15s ease, background .15s ease;
      }
      .contacts .whatsapp { background: #1faf54; color: #fff; }
      .contacts .appeler  { background: var(--accent); color: #fff; }
      .contacts .courriel { background: var(--surface); color: var(--encre); border-color: var(--trait); }
      .contacts a:hover { filter: brightness(.94); }
      .contacts a:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-bord); }

      /* --- Carte d'un bien : une action principale, le reste en retrait --- */
      /* --- La carte d un bien, cote vendeur ---
         Elle empilait un compartiment gris dans une carte blanche, un bouton
         « Ouvrir » qui menait ou le compartiment menait deja, et l avancement dit
         trois fois. Ce qui reste : le nom, l etape, une barre, ce qu il reste a
         faire — et TOUTE la carte est le lien, la plus grande cible possible.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .carte-bien-v2 {
        position: relative; background: var(--surface);
        border: 1px solid var(--trait); border-radius: var(--r);
        padding: var(--e4) var(--e5); margin-bottom: var(--e3);
        transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
      }
      .carte-bien-v2:hover {
        border-color: var(--accent-bord); box-shadow: var(--ombre);
        transform: translateY(-1px);
      }
      /* Le lien s etend a toute la carte SANS l enfermer dans un <a> : ce qui vit
         au-dessus (le repli « Gerer ce bien ») reste cliquable pour lui-meme. */
      .carte-bien-v2 .lien-etendu { text-decoration: none; color: inherit; }
      .carte-bien-v2 .lien-etendu::after { content: ""; position: absolute; inset: 0; z-index: 0; }
      .carte-bien-v2:focus-within { border-color: var(--accent); }

      /* La place reservee au coin superieur droit est desormais celle des trois
         points, plus large que la fleche qu elle abritait. */
      .titre-bien-v2 {
        display: block; font-size: 1.08rem; font-weight: 700;
        line-height: 1.25; padding-right: 2.6rem;
      }

      /* L etape : un rond numerote et son nom, la meme grammaire que la frise du
         formulaire. Le rang se lit sans etre lu — deux biens se comparent d un
         coup d oeil, ce qu un libelle seul ne permettait pas. */
      .etat-bien-v2 {
        display: flex; align-items: center; gap: .45rem; flex-wrap: wrap;
        margin: var(--e3) 0 var(--e2);
      }
      .rond-etape-v2 {
        width: 22px; height: 22px; border-radius: 50%; flex: none;
        display: grid; place-items: center;
        background: var(--accent-pale); color: var(--accent-fonce);
        font-size: .74rem; font-weight: 700;
      }
      .nom-etape-v2 { font-size: .92rem; font-weight: 600; color: var(--encre-2); }

      .jauge-bien-v2 { height: 6px; margin: 0 0 var(--e2); }
      /* Vert des que tout est reuni : la couleur dit l etat avant que la phrase
         soit lue, et c est le seul moment ou le vendeur n a plus rien a faire. */
      .bien-pret .jauge-bien-v2 > span { background: var(--succes); }
      .bien-pret .rond-etape-v2 { background: var(--succes-pale); color: var(--succes); }

      .reste-bien-v2 {
        display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
        margin: 0; font-size: .9rem; color: var(--encre-2);
      }
      .reste-bien-v2 svg { width: 14px; height: 14px; color: var(--succes); flex: none; }

      /* Les trois points : le signe universel du « et quoi d autre ». Poses en bas
         a droite, AU-DESSUS du lien etendu — sinon le repli s ouvrirait en suivant
         le lien de la carte, piege deja tombe deux fois sur ce projet.
         Cible de 34 px : on le touche du pouce sans viser. */
      .gerer-bien-v2 { position: absolute; right: var(--e3); top: var(--e3); z-index: 1; }
      /* ⚠️ QUARANTE PIXELS, ET NON TRENTE-QUATRE. Mesure sur telephone le 22/08/2026 :
         c est la cible d un pouce, et celle-ci ouvre le seul endroit ou l on supprime
         un bien. Une cible trop petite y fait rater le menu, pas la suppression. */
      .gerer-bien-v2 > summary {
        display: grid; place-items: center;
        width: 40px; height: 40px; border-radius: 50%;
        font-size: 1.1rem; line-height: 1; color: var(--encre-3);
        cursor: pointer; list-style: none;
        transition: background .15s ease, color .15s ease;
      }
      .gerer-bien-v2 > summary::-webkit-details-marker { display: none; }
      .gerer-bien-v2 > summary::marker { content: ""; }
      .gerer-bien-v2 > summary:hover,
      .gerer-bien-v2[open] > summary { background: var(--papier); color: var(--encre); }
      /* Le menu s ouvre PAR-DESSUS, ancre a droite : depliee dans le flux, la carte
         changeait de hauteur et poussait les biens suivants vers le bas. */
      /* Le menu s ouvre vers le BAS depuis que les trois points sont en haut : ancre
         au sommet, il serait sorti par le plafond de la carte. */
      .gerer-bien-v2 > div {
        position: absolute; right: 0; top: calc(100% + .3rem); z-index: 2;
        display: flex; flex-direction: column; align-items: flex-start; gap: .2rem;
        padding: var(--e2) var(--e3); white-space: nowrap;
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r-petit); box-shadow: var(--ombre-relief);
      }

      /* La fleche ne fait qu accompagner : elle avance au survol de la carte. */
      /* La fleche descend en bas a droite, les trois points montent en haut : le
         geste principal — ouvrir le bien — se lit a la fin de la carte, la ou le
         regard arrive ; les actions rares restent en tete, hors du chemin. */
      .fleche-bien-v2 {
        position: absolute; bottom: var(--e4); right: var(--e4);
        display: flex; color: var(--encre-3);
        transition: transform .15s ease, color .15s ease;
      }
      .carte-bien-v2:hover .fleche-bien-v2 { transform: translateX(3px); color: var(--accent); }

      @media (prefers-reduced-motion: reduce) {
        .carte-bien-v2, .fleche-bien-v2 { transition: none; }
        .carte-bien-v2:hover { transform: none; }
        .carte-bien-v2:hover .fleche-bien-v2 { transform: none; }
      }

      /* --- Le bouton de l avis de valeur ---
         Il s affichait comme une piece jointe : un lien souligne, en petit, dans un
         encadre colore. Or c est LA chose que le vendeur attend depuis trois
         semaines. Il occupe donc la largeur, porte son icone et sa date, et se
         touche du pouce sans viser.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .bouton-avis {
        display: flex; align-items: center; gap: var(--e3);
        margin: var(--e3) 0 0; padding: var(--e3) var(--e4);
        border-radius: var(--r); text-decoration: none;
        background: var(--accent); color: #fff;
        box-shadow: var(--ombre);
        transition: transform .15s ease, box-shadow .15s ease;
      }
      .bouton-avis:hover {
        color: #fff; transform: translateY(-1px); box-shadow: var(--ombre-relief);
      }
      .bouton-avis-icone {
        display: grid; place-items: center; flex: none;
        width: 40px; height: 40px; border-radius: 10px;
        background: rgba(255, 255, 255, .18);
      }
      .bouton-avis-icone svg { width: 22px; height: 22px; }
      .bouton-avis-texte { display: flex; flex-direction: column; gap: .1rem; min-width: 0; flex: 1; }
      .bouton-avis-texte strong { font-size: 1rem; line-height: 1.2; }
      /* La classe discrete est grise sur fond clair : ici le fond est l accent, il
         faut du blanc attenue sans quoi la date devient illisible. */
      .bouton-avis-texte .discret { color: rgba(255, 255, 255, .8); font-size: .82rem; }
      .bouton-avis-fleche { display: flex; flex: none; transition: transform .15s ease; }
      .bouton-avis:hover .bouton-avis-fleche { transform: translateX(3px); }
      @media (prefers-reduced-motion: reduce) {
        .bouton-avis, .bouton-avis-fleche { transition: none; }
        .bouton-avis:hover { transform: none; }
        .bouton-avis:hover .bouton-avis-fleche { transform: none; }
      }

      /* --- L onglet « Pieces » du conseiller ---
         Meme forme que le bouton de l avis de valeur cote vendeur : pastille d icone,
         titre, sous-titre, chevron. TROIS TONS, parce que ce sont trois gestes :
         ce qui est recu est calme, ce qui manque est en pointille, ce que le
         conseiller a produit porte l accent — c est sous cette forme-la que le
         vendeur le voit chez lui.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* Le filtre : des pastilles sur une piste grise. FORME DIFFERENTE DE LA BARRE
         D ONGLETS au-dessus, et c est tout l interet — une seconde barre identique
         collee sous la premiere, et l on ne sait plus a quel etage on se trouve. */
      .pieces-classeur { display: block; }
      .pieces-bascule { position: absolute; opacity: 0; width: 1px; height: 1px; }
      .pieces-filtre {
        display: flex; gap: .2rem; margin: 0 0 var(--e3);
        padding: .2rem; border-radius: 999px; background: var(--papier);
      }
      .pieces-filtre-mot {
        flex: 1; display: inline-flex; align-items: center; justify-content: center;
        gap: .35rem; margin: 0; padding: .35rem .5rem; border-radius: 999px;
        font-size: .85rem; font-weight: 500; color: var(--encre-3); cursor: pointer;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        -webkit-user-select: none; user-select: none;
      }
      .pieces-filtre-mot:hover { color: var(--encre-2); }
      /* ⚠️ SUR TELEPHONE, « A fournir 16 » NE TENAIT PAS DANS SON TIERS et se faisait
         couper a gauche : on lisait « A fournir » ampute de son accent. Le mot et son
         nombre retrecissent ensemble plutot que de deborder. */
      @media (max-width: 560px) {
        .pieces-filtre { gap: .1rem; padding: .15rem; }
        .pieces-filtre-mot { gap: .25rem; padding: .35rem .25rem; font-size: .76rem; }
        .pieces-filtre-mot .pastille { padding: .02rem .3rem; font-size: .65rem; }
      }
      .pieces-vue { display: none; }
      /* Les rangs, pas les cles : trois paires servent tous les biens de la page. */
      .pieces-bascule:nth-of-type(1):checked ~ .pieces-vue-recues,
      .pieces-bascule:nth-of-type(2):checked ~ .pieces-vue-manquantes,
      .pieces-bascule:nth-of-type(3):checked ~ .pieces-vue-envoyees { display: block; }
      .pieces-bascule:nth-of-type(1):checked ~ .pieces-filtre > .pieces-filtre-mot:nth-child(1),
      .pieces-bascule:nth-of-type(2):checked ~ .pieces-filtre > .pieces-filtre-mot:nth-child(2),
      .pieces-bascule:nth-of-type(3):checked ~ .pieces-filtre > .pieces-filtre-mot:nth-child(3) {
        background: var(--surface); color: var(--encre); font-weight: 650;
        box-shadow: var(--ombre);
      }
      /* Le clavier doit voir ou il est : la radio est invisible, c est donc son
         etiquette qui porte le contour. */
      .pieces-bascule:nth-of-type(1):focus-visible ~ .pieces-filtre > .pieces-filtre-mot:nth-child(1),
      .pieces-bascule:nth-of-type(2):focus-visible ~ .pieces-filtre > .pieces-filtre-mot:nth-child(2),
      .pieces-bascule:nth-of-type(3):focus-visible ~ .pieces-filtre > .pieces-filtre-mot:nth-child(3) {
        outline: 2px solid var(--accent); outline-offset: 1px;
      }
      /* La carte et son retrait : le formulaire vit A COTE du lien, jamais dedans. */
      .piece-avec-retrait { display: block; }
      .piece-rangee { display: flex; align-items: center; gap: .3rem; }
      .piece-rangee > .bouton-piece { flex: 1; min-width: 0; }
      /* Ce que la liasse tient lieu de : sous sa carte, en retrait, du cote du contenu
         et non du titre. Vert, parce que c est une bonne nouvelle : rien a reclamer. */
      .piece-contenu {
        margin: .2rem 0 0 2.9rem; font-size: .82rem;
        color: color-mix(in oklab, var(--succes) 80%, #000);
        display: flex; align-items: baseline; gap: .3rem; flex-wrap: wrap;
      }
      .piece-contenu svg { flex: none; transform: translateY(2px); }
      /* Une presomption, pas un constat : le ton est celui d une remarque, pas d une
         alerte. Rien ne se supprime tout seul, la croix est juste a cote. */
      .piece-doublon {
        margin: .2rem 0 0 2.9rem; font-size: .82rem; color: var(--encre-3);
        display: flex; align-items: baseline; gap: .3rem; flex-wrap: wrap;
      }
      .piece-doublon svg { flex: none; transform: translateY(2px); }
      .piece-retrait { flex: none; margin: .4rem 0 0; }
      .piece-retrait button { color: var(--encre-3); padding: .35rem; }
      .piece-retrait button:hover { color: var(--danger); }
      .bouton-piece {
        display: flex; align-items: center; gap: var(--e3);
        margin: .4rem 0 0; padding: .6rem .8rem;
        border-radius: var(--r); text-decoration: none;
        border: 1px solid var(--trait); background: var(--surface); color: var(--encre);
        transition: transform .15s ease, box-shadow .15s ease;
      }
      a.bouton-piece:hover {
        color: var(--encre); transform: translateY(-1px); box-shadow: var(--ombre);
      }
      .bouton-piece .bouton-avis-icone {
        width: 34px; height: 34px; border-radius: 9px;
        background: var(--papier); color: var(--encre-3);
      }
      .bouton-piece .bouton-avis-icone svg { width: 18px; height: 18px; }
      .bouton-piece .bouton-avis-texte strong { font-size: .95rem; }
      .bouton-piece .bouton-avis-texte .discret { color: var(--encre-3); font-size: .8rem; }
      .bouton-piece .bouton-avis-fleche { color: var(--encre-3); }

      /* Recue : elle est la, il n y a rien a faire. */
      .bouton-piece-recue .bouton-avis-icone {
        background: var(--succes-pale); color: color-mix(in oklab, var(--succes) 80%, #000);
      }
      /* Manquante : en pointille, c est un trou. Elle ne s ouvre pas, donc pas de
         chevron ni de survol qui promettrait une page. */
      .bouton-piece-manquante, .bouton-piece-facultative {
        border-style: dashed; background: none;
      }
      .bouton-piece-manquante .bouton-avis-icone {
        background: #fff7e8; color: var(--attention);
      }
      .bouton-piece-facultative { opacity: .75; }
      /* Envoyee : le fond de l accent, comme chez le vendeur. */
      .bouton-piece-envoyee {
        background: var(--accent); border-color: var(--accent); color: #fff;
      }
      a.bouton-piece-envoyee:hover { color: #fff; }
      .bouton-piece-envoyee .bouton-avis-icone {
        background: rgba(255, 255, 255, .18); color: #fff;
      }
      .bouton-piece-envoyee .bouton-avis-texte .discret { color: rgba(255, 255, 255, .8); }
      .bouton-piece-envoyee .bouton-avis-fleche { color: #fff; }
      @media (prefers-reduced-motion: reduce) {
        .bouton-piece { transition: none; }
        a.bouton-piece:hover { transform: none; }
      }

      /* --- La carte d accueil du vendeur ---
         Trois promesses, une par ligne, avec leur coche. Les puces natives du
         navigateur s ajoutaient aux coches : deux marqueurs pour un seul element.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .accueil-vendeur {
        list-style: none; margin: var(--e3) 0 0; padding: 0;
        display: flex; flex-direction: column; gap: var(--e2);
      }
      .accueil-vendeur li {
        display: flex; align-items: flex-start; gap: .5rem;
        font-size: .95rem; line-height: 1.4;
      }
      .accueil-vendeur svg {
        width: 15px; height: 15px; flex: none; margin-top: .2rem; color: var(--succes);
      }
      /* L invitation a installer : presente sans etre un bouton de plus. Le seul
         geste de cette carte reste « Demarrer mon dossier ». */
      .rappel-installer {
        display: flex; align-items: flex-start; gap: .5rem;
        margin: var(--e4) 0 0; padding: var(--e3);
        border-radius: var(--r-petit); font-size: .9rem; line-height: 1.4;
        background: var(--accent-pale); color: var(--encre-2);
      }
      .rappel-installer svg { width: 16px; height: 16px; flex: none; margin-top: .15rem;
        color: var(--accent); }
      .rappel-installer strong { color: var(--encre); }

      /* --- La fiche d un bien, presentee comme une annonce (ficheBien.js) ---
         Les reponses s affichaient en deux colonnes, repliees section par section :
         la forme d un formulaire relu, pas celle d un bien.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .fiche-bien { margin-top: var(--e4); }
      .tete-fiche { margin-bottom: var(--e4); }
      .titre-fiche { font-size: 1.3rem; font-weight: 800; margin: 0; line-height: 1.2; }
      .adresse-fiche { margin: .2rem 0 0; color: var(--encre-3); font-size: .95rem; }

      /* La bande de caracteristiques : ce qu on lit en premier sur une annonce. Une
         grille qui se remplit toute seule — trois par ligne sur telephone, plus si
         la place le permet, sans point de rupture a maintenir. */
      .cles-bien {
        display: grid; gap: .5rem; margin-bottom: var(--e4);
        grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
      }
      .cle-bien {
        display: flex; flex-direction: column; align-items: center; gap: .15rem;
        padding: var(--e3) .4rem; text-align: center;
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r-petit);
      }
      .cle-bien svg { width: 20px; height: 20px; color: var(--accent); }
      .cle-valeur { font-size: 1.05rem; font-weight: 800; line-height: 1.1; }
      .cle-libelle { font-size: .74rem; color: var(--encre-3); }

      /* Les etiquettes DPE et GES, dessinees comme sur le diagnostic : la lettre
         dans sa couleur se lit sans etre lue, c est l image que tout le monde a
         deja vue sur les annonces. */
      .energie-bien { display: flex; gap: .5rem; margin-bottom: var(--e5); }
      .etiquette-dpe {
        display: inline-flex; align-items: center; gap: .5rem;
        padding: .35rem .5rem .35rem .7rem; border-radius: var(--r-petit);
        font-weight: 700;
      }
      .etiquette-titre { font-size: .74rem; letter-spacing: .06em; opacity: .85; }
      .etiquette-lettre {
        display: grid; place-items: center; width: 1.5rem; height: 1.5rem;
        border-radius: 6px; background: rgba(255, 255, 255, .3); font-size: 1rem;
      }

      .bloc-fiche { margin-top: var(--e5); }
      .titre-bloc-fiche {
        display: flex; align-items: center; gap: .4rem;
        font-size: 1rem; font-weight: 700; margin: 0 0 var(--e2);
        padding-bottom: var(--e2); border-bottom: 1px solid var(--trait);
      }
      .titre-bloc-fiche svg { width: 17px; height: 17px; color: var(--encre-3); }
      .compte-docs {
        margin-left: auto; padding: .1rem .5rem; border-radius: 999px;
        background: var(--papier); font-size: .8rem; color: var(--encre-3);
      }

      /* Une ligne par reponse : le libelle a gauche, la valeur a droite. L oeil
         descend la colonne des valeurs sans relire les libelles. */
      .liste-fiche { margin: 0; }
      .ligne-fiche {
        display: flex; justify-content: space-between; align-items: baseline;
        gap: var(--e3); padding: .4rem 0; border-bottom: 1px solid var(--papier);
      }
      .ligne-fiche:last-child { border-bottom: none; }
      .ligne-fiche dt { color: var(--encre-3); font-size: .92rem; }
      .ligne-fiche dd { margin: 0; font-weight: 600; text-align: right; }

      .docs-fiche { display: flex; flex-direction: column; gap: var(--e3); }
      .nom-cat-docs {
        margin: 0 0 .2rem; font-size: .8rem; font-weight: 700;
        color: var(--encre-3); text-transform: uppercase; letter-spacing: .04em;
      }
      .doc-fiche {
        display: flex; align-items: center; gap: .45rem;
        padding: .45rem .6rem; margin-bottom: .2rem; border-radius: var(--r-petit);
        background: var(--papier); text-decoration: none; color: var(--encre);
        font-size: .92rem;
      }
      .doc-fiche svg { width: 16px; height: 16px; flex: none; color: var(--accent); }
      .doc-fiche:hover { background: var(--accent-pale); color: var(--encre); }

      /* La classe intro-ecriture a ete remplacee par note-ecriture : quatre lignes
         au-dessus du champ sont devenues une ligne sous le bouton. Voir bulleAide.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer une classe. */
      .note-ecriture {
        margin: var(--e2) 0 0; font-size: .8rem; line-height: 1.35;
        color: var(--encre-3); text-align: center;
      }

      /* Les trois facons de joindre son conseiller, au bas de la bulle. L agent a
         les siennes sur chaque fiche depuis longtemps ; le vendeur n avait que le
         message ecrit — parfait le soir, inutile quand on veut une reponse tout de
         suite. Cibles de 44 px : on les touche du pouce sans viser.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .canaux-conseiller { margin-top: var(--e3); padding-top: var(--e3);
        border-top: 1px solid var(--trait); }
      .boutons-canaux { display: flex; gap: var(--e2); flex-wrap: wrap; margin-top: var(--e2); }
      .canal {
        flex: 1 1 4.5rem; display: flex; flex-direction: column; align-items: center;
        gap: .2rem; min-height: 44px; padding: .5rem .3rem;
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        background: var(--surface); color: var(--encre-2);
        text-decoration: none; font-size: .74rem; font-weight: 600;
        -webkit-tap-highlight-color: transparent;
      }
      .canal svg { width: 20px; height: 20px; color: var(--accent); }
      .canal:hover { border-color: var(--accent); background: var(--accent-pale);
        color: var(--accent); }

      /* Les pages qui vivaient dans le menu du vendeur, recueillies au bas de la
         bulle d aide : elle est a portee de pouce sur chaque ecran, le pied de page
         demande de descendre tout en bas.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .pied-aide {
        display: flex; flex-wrap: wrap; gap: var(--e3);
        margin-top: var(--e3); padding-top: var(--e3);
        border-top: 1px solid var(--trait);
      }
      .pied-aide a { font-size: .88rem; color: var(--encre-3); text-decoration: none; }
      .pied-aide a:hover { color: var(--accent); text-decoration: underline; }

      /* Le nom du conseiller, et sous lui son metier et son reseau. L en-tete ne
         portait qu un prenom : le vendeur ouvrait un espace au nom de quelqu un dont
         il ne savait ni le metier ni l enseigne, alors qu il s apprete a lui confier
         la vente de son logement.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .identite-marque {
        display: flex; flex-direction: column; gap: .05rem; min-width: 0;
        line-height: 1.15;
      }
      .nom-marque { font: inherit; }
      .qualite-marque {
        font-size: .68rem; font-weight: 500; letter-spacing: 0;
        color: var(--encre-3); white-space: nowrap;
        overflow: hidden; text-overflow: ellipsis;
      }

      /* --- Le retour arriere, taille pour le pouce ---
         C etait un lien gris de treize pixels, colle en haut a gauche : sur un
         telephone tenu d une main, il faut viser. La cible fait maintenant 44 px de
         haut — le minimum au-dela duquel on ne touche plus a cote — et porte une
         surface qui dit qu on peut appuyer.
         ATTENTION : aucun accent grave dans ce bloc, meme pour citer du code. */
      .lien-retour {
        display: inline-flex; align-items: center; gap: .4rem;
        min-height: 44px; margin: 0 0 var(--e3); padding: .5rem .9rem .5rem .7rem;
        border-radius: 999px; background: var(--papier); border: 1px solid var(--trait);
        color: var(--encre-2); font-size: .92rem; font-weight: 600; text-decoration: none;
        -webkit-tap-highlight-color: transparent;
        transition: background .15s ease, border-color .15s ease, color .15s ease;
      }
      .lien-retour svg { width: 18px; height: 18px; flex: none; }
      .lien-retour:hover {
        background: var(--accent-pale); border-color: var(--accent-bord); color: var(--accent);
      }
      /* La fleche recule au survol : le geste est dit avant d etre fait. */
      .lien-retour:hover svg { transform: translateX(-2px); }
      .lien-retour svg { transition: transform .15s ease; }
      @media (prefers-reduced-motion: reduce) {
        .lien-retour, .lien-retour svg { transition: none; }
        .lien-retour:hover svg { transform: none; }
      }

      /* Une étiquette lue par les lecteurs d'écran, invisible à l'oeil : le champ de
         recherche porte déjà son intention dans son texte d'exemple, mais celui-ci
         disparaît dès la première lettre tapée et n'est pas une étiquette. */
      .visuellement-cache {
        position: absolute; width: 1px; height: 1px; overflow: hidden;
        clip-path: inset(50%); white-space: nowrap;
      }
      /* Le champ prend toute la largeur disponible, le bouton juste la sienne. Sur un
         téléphone les deux se rangent l'un sous l'autre plutôt que de se serrer. */
      .barre-recherche {
        display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap;
        margin: 0 0 var(--e3);
      }
      .barre-recherche input[type="search"] { flex: 1; min-width: 12rem; margin: 0; }
      .barre-recherche .bouton { margin: 0; flex: none; }
      /* La loupe ne sert que sur telephone, ou le mot « Chercher » cede sa place au
         champ. Sur ordinateur le mot est ecrit, et un dessin en plus serait du bruit. */
      .loupe-chercher { display: none; }

      .carte-bien { transition: border-color .15s ease, box-shadow .15s ease; }
      .carte-bien:hover { border-color: var(--accent-bord); box-shadow: var(--ombre); }
      .entete-bien {
        display: flex; justify-content: space-between; align-items: flex-start;
        gap: var(--e3); flex-wrap: wrap;
      }
      .actions-bien {
        display: flex; justify-content: space-between; align-items: center;
        gap: var(--e3); flex-wrap: wrap;
      }
      .actions-secondaires { display: flex; align-items: center; gap: var(--e4); }
      .lien-supprimer {
        color: var(--encre-3); font-size: .9rem; font-weight: 600; text-decoration: underline;
        display: inline-flex; align-items: center; min-height: 40px;
      }
      .lien-supprimer:hover { color: var(--danger); }
      @media (max-width: 760px) {
        .actions-bien { flex-direction: column; align-items: stretch; }
        .actions-bien > .bouton { justify-content: center; }
        .actions-secondaires { justify-content: space-between; }
      }

      /* ── L EN-TETE D UNE CONVERSATION ─────────────────────────────────────────────
         Une ligne : la fleche de retour, la pastille, le nom, et dessous le bien et
         l avancement. La ligne entiere ouvre la fiche du dossier. Elle remplace un
         titre et une carte « le dossier en bref » qui prenaient a eux deux la moitie
         d un ecran de telephone. */
      .tete-conv {
        display: flex; align-items: center; gap: var(--e2);
        margin: 0 0 var(--e4); padding-bottom: var(--e3);
        border-bottom: 1px solid var(--trait);
      }
      .conv-retour {
        display: grid; place-items: center; width: 40px; height: 40px; flex: none;
        border-radius: 50%; color: var(--encre-2);
      }
      .conv-retour:hover { background: var(--papier); color: var(--accent); }
      .conv-vers-fiche {
        flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--e3);
        padding: .3rem .4rem; border-radius: var(--r-petit);
        text-decoration: none; color: inherit;
      }
      .conv-vers-fiche:hover { background: var(--papier); text-decoration: none; color: inherit; }
      .conv-titres { min-width: 0; display: flex; flex-direction: column; gap: .05rem; }
      .conv-qui {
        font-weight: 600; font-size: 1rem;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .conv-quoi {
        font-size: .78rem; color: var(--encre-3);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .chev-conv { color: var(--encre-4); flex: none; display: grid; place-items: center; }
      /* L avancement et l etape ne paraissent que la ou ils tiennent. Sur telephone,
         quatre faits demandent quatre cents pixels et n en ont que deux cent six. */
      .quoi-long { display: none; }
      @media (min-width: 561px) { .quoi-long { display: inline; } }

      /* ── L EN-TETE D UNE CONVERSATION SE FIGE ─────────────────────────────────────
         Il defilait avec le fil : au troisieme message on ne savait plus a qui l on
         ecrivait, ni comment revenir. Demande par Rodolphe le 21/08/2026 pour le
         telephone, etendu a l ordinateur le meme jour — le defaut y etait le meme, et
         un ecran qui se tient d un cote ne peut pas lacher de l autre.

         DEUX CHOSES COLLEES EN HAUT DEMANDENT UNE HAUTEUR CONNUE POUR LA SECONDE :
         celle-ci est donc fixee a soixante pixels, et les onglets s en servent.

         ⚠️ ET LES DEUX SE POSENT SOUS L EN-TETE DE L APPLICATION, PAS DESSUS. Sur
         ordinateur, celui-ci est colle en haut lui aussi : --h-entete dit sa hauteur,
         et vaut zero la ou il est masque. */
      /* ⚠️ LA HAUTEUR DE LA BANDE CONTIENT LA MARGE DE SECURITE, elle ne se contente
            pas d en etre rembourree. Soixante pixels fixes plus un rembourrage haut de
            cinquante-neuf sur un iPhone recent, avec le modele de boite de cette
            feuille : la boite de contenu tombait a UN pixel, et la pastille comme le
            nom du vendeur debordaient par-dessous, sous la barre d onglets. C est le
            « petit bug d affichage en haut » signale par Rodolphe le 22/08/2026, et
            c est ma marge de securite qui l a cause.

            Le decalage des onglets suit la meme addition : ils se calent sous la bande,
            donc sous sa hauteur REELLE. */
      body:has([data-au-dernier]) .tete-conv {
        position: sticky; top: var(--h-entete, 0px); z-index: 31;
        height: calc(60px + env(safe-area-inset-top, 0px));
        margin-bottom: var(--e3);
        background: var(--surface); border-bottom: 1px solid var(--trait);
      }
      body:has([data-au-dernier]) .bascule-volet ~ .barre-volets {
        top: calc(var(--h-entete, 0px) + 60px + env(safe-area-inset-top, 0px));
      }


      /* ── L ECRAN DE CONVERSATION DU VENDEUR ───────────────────────────────────────
         Le meme que celui de son conseiller, dans SA couleur a lui : l espace vendeur
         est en marque blanche, le vert de DossFlow n y a pas sa place. Maquette validee
         par Rodolphe le 22/08/2026, option B. */
      /* ⚠️ LE SELECTEUR PORTE LES DEUX CLASSES ET LA CONDITION. Ecrit court,
         il pesait moins que la regle qui fige la bande en haut de l ecran, laquelle pose
         un fond blanc : la bande restait blanche, sans qu aucune erreur ne le signale.
         C est le meme piege que l en-tete du vendeur, deux heures plus tot. */
      .tete-conv-client .conv-vers-fiche { cursor: default; }
      .tete-conv-client .conv-vers-fiche:hover { background: none; }
      .tete-conv-client .initiales { width: 40px; height: 40px; font-size: .76rem; }
      /* ⚠️ LA BANDE N EST COLOREE QUE SUR TELEPHONE, ou elle REMPLACE l en-tete de
         l application. Sur ordinateur, celui-ci reste — il y porte la navigation — et
         deux bandes de la meme couleur se suivaient en annoncant deux fois le meme nom :
         « Rodolphe Petyt · Agent commercial », puis « Rodolphe Petyt · Votre
         conseiller ». Ici la bande redevient une ligne blanche sous un trait. */
      @media (max-width: 760px) {
        body:has([data-au-dernier]) .tete-conv.tete-conv-client {
          background: var(--accent); color: #fff; border-bottom: 0;
        }
        .tete-conv-client .conv-retour { color: rgba(255,255,255,.82); }
        .tete-conv-client .conv-retour:hover { background: rgba(255,255,255,.14); color: #fff; }
        .tete-conv-client .conv-qui { color: #fff; }
        .tete-conv-client .conv-quoi { color: rgba(255,255,255,.74); }
        .tete-conv-client .initiales {
          font-weight: 700;
          background: rgba(255,255,255,.16); color: #fff;
          border: 1px solid rgba(255,255,255,.34);
        }
        .tete-conv-client .rond-conseiller { border-color: rgba(255,255,255,.34); }
      }
      /* La photo du conseiller a la place de ses initiales quand il en a une : c est
         elle que le vendeur reconnait, et elle est deja servie par /photo-conseiller. */
      .rond-conseiller {
        width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none;
        border: 1px solid var(--trait);
      }
      /* Celle de la carte du conseiller, plus grande : meme forme, meme repli. */
      .rond-conseiller-large { width: 64px; height: 64px; font-size: 1.3rem; }
      /* ⚠️ LES BULLES SONT INVERSEES DE CE COTE-CI. La classe teintee va aux messages
         du VENDEUR et le gris a ceux du conseiller : c est ce qu on ecrit soi-meme qui
         est colore, sur chacun des deux ecrans. L inversion est faite par la route en
         posant la classe a l envers, et non par une seconde regle ici — deux jeux de
         couleurs pour deux ecrans finiraient par diverger. */

      /* ⚠️ LA LIGNE « VOTRE CONVERSATION » ET SON STYLE ONT ETE RETIRES le 22/08/2026.
         Elle dessinait « Votre conversation » en tete de l espace vendeur ; l onglet
         « Messages » de la barre du bas fait la meme chose sur toutes les pages, avec
         sa pastille. Ce qui reste de ce bloc — le rond a initiale — sert encore a
         l ecran du conseiller. */
      .rond-lettres {
        display: grid; place-items: center; font-weight: 700; font-size: .82rem;
        background: var(--accent); color: #fff;
      }

      /* Le lien vers les reglages, au pied de l espace vendeur : une ligne discrete,
         pas une section. Trois gestes rares mis a leur place. */
      .ligne-compte {
        display: flex; align-items: center; gap: var(--e2);
        margin-top: var(--e6); padding: .55rem .7rem;
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        color: var(--encre-2); text-decoration: none; font-size: .88rem;
      }
      .ligne-compte:hover { background: var(--papier); color: var(--encre); text-decoration: none; }
      /* Le libelle ne se coupe pas, la legende se coupe : « Mon compte » sur deux
         lignes pendant que « deconnexion, emails, mes donnees » en tenait deux aussi,
         c etait la legende qui poussait le titre. Mesure a 375 px. */
      .ligne-compte > span:first-of-type { flex: none; white-space: nowrap; }
      .ligne-compte .discret {
        margin-left: auto; font-size: .78rem; min-width: 0;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .ligne-compte svg { color: var(--encre-3); flex: none; }

      /* ── LES REGLAGES, EN GROUPES ────────────────────────────────────────────────
            Le modele est celui des reglages d un telephone, et Rodolphe l a nomme :
            « on pourrait classer les parametres un peu comme c est fait sur iPhone
            avec differentes parties », 22/08/2026.

            Ce que cette forme apporte et qu une page de formulaire n apporte pas : on
            n y lit RIEN. On y cherche un mot, dans un groupe dont le titre a deja
            elimine les trois autres. Chaque rangee est une porte, jamais un reglage a
            comprendre sur place.

            ⚠️ LE TITRE DU GROUPE EST DEHORS, PAS DEDANS. Pose a l interieur de la
            carte il devient sa premiere rangee et se touche du doigt sans rien ouvrir.
            Dehors, en petites capitales grises, il se lit comme une etiquette de
            classeur — et c est exactement son role. */
      .groupe-reglages { margin: 0 0 var(--e5); }
      .groupe-reglages > .surtitre { margin: 0 0 var(--e2); padding-left: .2rem; }
      .cartouche-reglages {
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r); overflow: hidden;
      }
      /* La rangee : un dessin, un mot, sa legende, un chevron. Cinquante-deux pixels
            de haut — la cible d un pouce, et la mesure du modele. */
      .rang-reglage {
        display: flex; align-items: center; gap: var(--e3);
        width: 100%; padding: .7rem var(--e4); min-height: 52px;
        color: var(--encre); text-decoration: none; font-size: .95rem;
        background: none; border: 0; text-align: left; font-family: inherit;
        /* ⚠️ LA GRAISSE EST ECRITE, PAS HERITEE. Une rangee qui est un BOUTON — se
           deconnecter, deconnecter les autres appareils — prenait le gras que le
           navigateur donne aux boutons : deux rangees en gras au milieu de douze en
           romain, sans que rien ne le justifie. */
        font-weight: 400; cursor: pointer;
      }
      /* Le trait separe les rangees SANS toucher les bords : pose bord a bord il
            coupait la carte en tranches et lui otait son unite. Il commence apres le
            dessin, la ou commence le texte, comme dans les reglages d un telephone. */
      .rang-reglage + .rang-reglage { box-shadow: inset 0 1px 0 var(--trait); }
      .rang-reglage:hover { background: var(--papier); text-decoration: none; }
      .rang-reglage > svg { color: var(--encre-3); flex: none; }
      .rang-mot { flex: 1; min-width: 0; }
      /* La legende passe A LA LIGNE sous le mot plutot que de le pousser : « Durees
            de conservation, registre des traitements » est une phrase, pas une
            valeur. */
      .rang-legende {
        display: block; font-size: .8rem; color: var(--encre-3);
        margin-top: .1rem;
      }
      /* La valeur du reglage, a droite, avant le chevron : « Complet », « 3
            appareils ». Elle se coupe avant le mot, jamais l inverse. */
      .rang-valeur {
        flex: 0 1 auto; min-width: 0; color: var(--encre-3); font-size: .86rem;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .rang-chevron { flex: none; color: var(--encre-4); display: inline-flex; }

      /* ── LE CALENDRIER DE LA SEMAINE ──────────────────────────────────────────────
            Sept colonnes, une par jour, et les heures en regard. C est la forme que tout
            le monde connait — « un vrai calendrier avec les colonnes », « en vue comme
            Google Agenda », Rodolphe, 24/08/2026 — et elle apporte ce qu une liste ne
            peut pas : les TROUS. Une liste dit ce qui est pris, une grille montre ce qui
            est libre, et c est pour cela qu on ouvre son agenda avant de proposer une
            heure.

            ⚠️ LA GRILLE DEFILE DANS SON CADRE, PAS AVEC LA PAGE. Sept colonnes lisibles
            demandent au moins six cents pixels : sur un telephone, la seule alternative
            a un defilement lateral serait de reduire les colonnes a quarante pixels, ou
            un rendez-vous ne tient plus un mot. On defile donc horizontalement, et la
            colonne des heures reste collee a gauche pour qu on sache toujours a quelle
            heure on regarde. */
      /* ⚠️ LE CADRE DEFILE DANS LES DEUX SENS, ET C EST CE QUI REND LES EN-TETES
            COLLANTS. Ecrit `overflow-y: hidden`, il restait malgre tout le conteneur de
            defilement vertical de la grille : un `position: sticky; top: 0` s y mesurait
            contre un cadre qui ne defile jamais, donc ne collait a rien. Mesure sur
            iPhone : en descendant la page de trois cents pixels, la ligne des jours
            partait a moins cinquante-six, et l on lisait une colonne sans savoir quel
            jour on regardait. En bornant la hauteur, c est le cadre qui defile, et les
            jours comme les heures restent en vue. */
      .cadre-agenda {
        overflow: auto;
        max-height: calc(100dvh - 13rem);
        border: 1px solid var(--trait); border-radius: var(--r);
        background: var(--surface);
        -webkit-overflow-scrolling: touch;
        /* Arrive en bas de la grille, le geste ne doit pas emporter la page derriere :
              on cherchait vingt heures, on se retrouvait au pied de l ecran. */
        overscroll-behavior: contain;
      }
      .agenda {
        display: grid;
        grid-template-columns: 3.2rem repeat(7, minmax(6.2rem, 1fr));
        min-width: 46rem;
        position: relative;
      }
      /* L en-tete des jours reste visible quand on descend dans les heures. */
      .agenda-jour, .agenda-coin {
        position: sticky; top: 0; z-index: 3;
        background: var(--surface); border-bottom: 1px solid var(--trait);
        padding: .45rem .3rem; text-align: center;
      }
      .agenda-coin { z-index: 4; left: 0; }
      .agenda-jour-nom {
        display: block; font-size: .68rem; font-weight: 700; letter-spacing: .05em;
        text-transform: uppercase; color: var(--encre-3);
      }
      .agenda-jour-chiffre {
        display: block; font-size: 1.05rem; font-weight: 650; color: var(--encre);
        line-height: 1.2;
      }
      /* Aujourd hui se reconnait sans lire : le chiffre dans une pastille pleine, la
            meme que partout ailleurs dans l application. */
      .agenda-jour.aujourdhui .agenda-jour-chiffre {
        background: var(--accent); color: #fff;
        border-radius: 999px; width: 1.7rem; height: 1.7rem;
        margin: 0 auto; display: grid; place-items: center;
      }
      .agenda-jour.week-end { background: var(--papier); }

      /* La colonne des heures : collee a gauche, elle survit au defilement lateral. */
      .agenda-heures {
        position: sticky; left: 0; z-index: 2;
        background: var(--surface); border-right: 1px solid var(--trait);
      }
      .agenda-heure {
        height: 2.6rem; padding: 0 .35rem; text-align: right;
        font-size: .7rem; color: var(--encre-4);
        position: relative; z-index: 1;
        /* Le chiffre se pose SUR le trait, pas dans la case : c est la ligne qui
              marque l heure, et un nombre centre dans sa case designe la demie. */
        transform: translateY(-.45rem);
      }
      /* ⚠️ SAUF LA PREMIERE, QUI PASSERAIT SOUS LA LIGNE DES JOURS. Remontee comme les
            autres, « 8 h » venait se glisser derriere l en-tete collant et la grille
            s ouvrait sur une heure sans nom. Elle se pose donc SOUS son trait, seule de
            la colonne a le faire : c est le prix pour qu on la lise. */
      .agenda-heure:first-child { transform: translateY(.15rem); }
      /* Une colonne par jour : elle empile ses douze cases et porte ses rendez-vous en
            absolu. Voir la note de rendu/agendaSemaine.js — la premiere version posait
            quatre-vingt-quatre cases et sept colonnes superposees, et la grille
            s effondrait. */
      .agenda-colonne { position: relative; }
      .agenda-colonne.week-end { background: var(--papier); }
      /* ⚠️ LE GRIS DIT « HORS DE MES HORAIRES », PAS « INTERDIT ». La case reste
            cliquable : le rendez-vous du samedi matin que le vendeur est le seul a
            pouvoir tenir doit pouvoir se poser, sinon l agenda finit contourne sur un
            carnet. Voir la note de rendu/agenda.js. */
      .agenda-case.hors-plage {
        background: color-mix(in oklab, var(--trait) 22%, transparent);
      }
      .agenda-case {
        border-top: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        height: 2.6rem; position: relative;
      }
      /* Toute la case est cliquable pour poser un rendez-vous a cette heure-la : c est
            le geste de Google Agenda, et celui qu on cherche en ouvrant la page. */
      .agenda-case > a {
        position: absolute; inset: 0; display: block;
      }
      .agenda-case > a:hover { background: var(--accent-pale); }

      /* Le rendez-vous se pose PAR-DESSUS la grille, en absolu : sa hauteur dit sa
            duree, et deux rendez-vous d une demi-heure ne prennent pas la place de deux
            heures. */
      .agenda-rdv {
        position: absolute; left: 2px; right: 2px; z-index: 1;
        border-radius: var(--r-petit); padding: .2rem .35rem;
        font-size: .72rem; line-height: 1.25; overflow: hidden;
        color: #fff; text-decoration: none;
        background: var(--accent);
        box-shadow: 0 1px 2px rgb(0 0 0 / .18);
      }
      .agenda-rdv:hover { text-decoration: none; filter: brightness(1.08); }
      .agenda-rdv strong { display: block; font-weight: 650; }
      /* Chaque nature sa teinte, pour distinguer d un coup d oeil une estimation d une
            remise d avis de valeur. Le vert de marque reste a l estimation, qui est le
            rendez-vous principal du metier. */
      .agenda-rdv.rdv-suivi { background: #6b7280; }
      .agenda-rdv.rdv-avis_de_valeur { background: #b45309; }
      /* ⚠️ PAS UN GRIS DE PLUS. Ecrit en #475569, il etait a un cheveu de l accent de
            l espace agent — mesure : #334155 contre #475569 — et l on ne distinguait
            plus un rendez-vous libre d une estimation. L indigo n est employe nulle
            part ailleurs dans l application. */
      .agenda-rdv.rdv-autre { background: #4f46e5; }
      .agenda-rdv.passe { opacity: .55; }

      /* ⚠️ L OCCUPATION PERSONNELLE EST UN DECOR, PAS UNE CARTE. Elle ne porte aucun
            nom — on n a garde que des heures — elle ne mene nulle part, et elle passe
            DERRIERE les rendez-vous DossFlow : ceux-la sont ce qu on vient lire, elle
            est le fond qui dit « pas la ». Les hachures la distinguent d une case
            grisee hors horaires, qui n est qu une preference. */
      .agenda-perso {
        position: absolute; left: 2px; right: 2px; z-index: 0;
        border-radius: var(--r-petit);
        pointer-events: none;
        background: repeating-linear-gradient(
          -45deg,
          color-mix(in oklab, var(--encre-4) 20%, transparent) 0 4px,
          transparent 4px 8px);
        border: 1px solid color-mix(in oklab, var(--encre-4) 22%, transparent);
      }
      /* Les rendez-vous passent devant : sans z-index, l ordre du HTML suffirait, mais
            la bande est posee avant eux justement pour rester dessous. */
      .agenda-rdv { z-index: 1; }

      /* La barre de l heure actuelle, sur la colonne du jour : elle situe le regard
            avant meme qu on ait lu un chiffre. */
      .agenda-maintenant {
        position: absolute; left: 0; right: 0; height: 2px;
        background: var(--danger); z-index: 2; pointer-events: none;
      }
      .agenda-maintenant::before {
        content: ""; position: absolute; left: -3px; top: -3px;
        width: 8px; height: 8px; border-radius: 50%; background: var(--danger);
      }

      /* ─────────────────────────────────────────────────────────────────────────
            LE MOIS. Il ne porte pas d heures, voir la note de rendu/agenda.js : a
            l echelle ou trente jours tiennent sur un ecran, un rendez-vous d une heure
            mesurerait un pixel et demi. Des pastilles, donc, et un clic vers le jour.
            ───────────────────────────────────────────────────────────────────────── */
      .cadre-mois { max-height: none; overflow: visible; }
      .agenda-mois {
        display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
      }
      .mois-entete {
        padding: .45rem .3rem; text-align: center;
        font-size: .68rem; font-weight: 700; letter-spacing: .05em;
        text-transform: uppercase; color: var(--encre-3);
        border-bottom: 1px solid var(--trait);
      }
      /* ⚠️ UNE HAUTEUR MINIMALE, ET NON UNE HAUTEUR. Fixee, la case coupait la
            troisieme pastille sans le dire ; libre, une journee chargee etirait toute
            sa ligne et les six autres cases devenaient hautes et vides. Le minimum
            tient trois pastilles, et le rendu s arrete a trois. */
      .mois-case {
        min-height: 5.4rem; padding: .25rem;
        border-top: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        border-left: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
        display: flex; flex-direction: column; gap: .12rem;
        color: inherit; text-decoration: none;
        overflow: hidden;
      }
      .mois-case:nth-child(7n + 1) { border-left: none; }
      a.mois-case:hover { background: var(--papier); text-decoration: none; }
      .mois-case.week-end { background: var(--papier); }
      /* Les jours du mois voisin restent LISIBLES, seulement estompes : ils ferment
            la semaine, et un rendez-vous du 1er septembre doit se voir depuis aout. */
      .mois-case.hors-mois { opacity: .45; }
      .mois-chiffre {
        font-size: .78rem; font-weight: 650; color: var(--encre-2);
        align-self: flex-end; line-height: 1.4;
      }
      .mois-chiffre.aujourdhui {
        background: var(--accent); color: #fff; border-radius: 999px;
        width: 1.45rem; height: 1.45rem; display: grid; place-items: center;
      }
      .mois-puce {
        display: block; font-size: .66rem; line-height: 1.35;
        padding: .08rem .28rem; border-radius: var(--r-petit);
        background: var(--accent); color: #fff;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      }
      .mois-puce.rdv-suivi { background: #6b7280; }
      .mois-puce.rdv-avis_de_valeur { background: #b45309; }
      .mois-puce.rdv-autre { background: #4f46e5; }
      .mois-reste { font-size: .64rem; color: var(--encre-3); padding-left: .28rem; }

      /* Le jour, en tete de son paquet de rendez-vous dans le planning. Sur la
            premiere ligne il ne doit pas ecarter le haut de la liste, d ou le
            `:first-child`. */
      .jour-planning {
        margin: var(--e4) 0 var(--e2); padding: 0 .1rem;
        font-size: .72rem; font-weight: 700; letter-spacing: .05em;
        text-transform: uppercase; color: var(--encre-3);
      }
      .jour-planning:first-child { margin-top: 0; }

      /* Les horaires de la semaine : sept rangees, une case a cocher et deux heures.
            ⚠️ LA CASE ET LE NOM DU JOUR SONT DANS LE MEME LABEL, et la rangee ne se
            replie qu en dessous de quatre cent vingt pixels : au-dessus, les deux heures
            restent sur la ligne du jour, ou l on lit la semaine d une colonne. */
      .liste-horaires { margin: var(--e4) 0; }
      .rang-horaire {
        display: flex; align-items: center; gap: var(--e3);
        padding: .55rem .1rem;
        border-bottom: 1px solid color-mix(in oklab, var(--trait) 60%, transparent);
      }
      .rang-horaire:last-child { border-bottom: none; }
      .horaire-jour {
        display: flex; align-items: center; gap: .5rem;
        flex: 0 0 9rem; margin: 0; cursor: pointer; font-weight: 550;
      }
      .horaire-jour input { margin: 0; }
      .horaire-heures { display: flex; align-items: center; gap: .5rem; }
      .horaire-heures input {
        margin: 0; width: auto; min-width: 6.5rem;
        font-variant-numeric: tabular-nums;
      }
      /* ⚠️ LES HEURES S ESTOMPENT QUAND LE JOUR EST DECOCHE, ELLES NE DISPARAISSENT
            PAS. Retirees, la rangee changeait de hauteur a chaque clic et la liste
            sautait sous le doigt. */
      .horaire-jour:has(input:not(:checked)) + .horaire-heures {
        opacity: .4;
      }
      @media (max-width: 420px) {
        .rang-horaire { flex-direction: column; align-items: flex-start; gap: .4rem; }
        .horaire-jour { flex: 0 0 auto; }
      }

      /* ─────────────────────────────────────────────────────────────────────────
            LE CHOIX DE CRENEAU. Voir rendu/choixCreneau.js : la grille est un confort
            pose SUR un champ `datetime-local` qui fait foi et fonctionne sans elle.
            ───────────────────────────────────────────────────────────────────────── */
      .creneaux-cadre { margin: var(--e3) 0 0; }
      .creneaux-tete {
        display: flex; align-items: center; gap: var(--e2); margin: 0 0 var(--e2);
      }
      .creneaux-intitule {
        flex: 1 1 auto; text-align: center; font-size: .88rem; color: var(--encre-2);
      }
      /* ⚠️ LA GRILLE DEFILE VERTICALEMENT DANS SON CADRE, ET NON DANS LA FENETRE. Une
            journee de dix heures fait vingt creneaux : laisses libres, ils poussaient le
            bouton Enregistrer hors de l ecran, et l on choisissait une heure sans plus
            pouvoir la valider. */
      .creneaux-grille {
        display: flex; gap: .25rem;
        max-height: 13rem; overflow-y: auto; overflow-x: auto;
        overscroll-behavior: contain;
        border: 1px solid var(--trait); border-radius: var(--r);
        padding: .3rem; background: var(--surface);
      }
      .creneaux-colonne {
        flex: 1 1 0; min-width: 3.6rem; display: flex; flex-direction: column; gap: .15rem;
      }
      .creneaux-jour {
        position: sticky; top: 0; z-index: 1; margin: 0; padding: .1rem 0 .25rem;
        background: var(--surface); text-align: center; line-height: 1.15;
      }
      .creneaux-jour span {
        display: block; font-size: .6rem; letter-spacing: .05em;
        text-transform: uppercase; color: var(--encre-3);
      }
      .creneaux-jour strong { font-size: .85rem; color: var(--encre); }
      .creneau {
        display: block; width: 100%; padding: .22rem .1rem;
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        background: var(--surface); color: var(--encre-2);
        font: inherit; font-size: .72rem; font-variant-numeric: tabular-nums;
        cursor: pointer;
      }
      .creneau:hover { border-color: var(--accent); color: var(--encre); }
      /* Pris et hors horaires se distinguent : le premier est un conflit reel, le
            second une simple preference. Le raye ne se lit pas de la meme facon qu un
            gris. */
      .creneau-pris {
        background: color-mix(in oklab, var(--trait) 35%, transparent);
        color: var(--encre-4); text-decoration: line-through;
      }
      .creneau-hors { background: color-mix(in oklab, var(--trait) 18%, transparent); }
      .creneau-choisi, .creneau-choisi:hover {
        background: var(--accent); border-color: var(--accent); color: #fff;
        font-weight: 650; text-decoration: none;
      }
      .creneaux-note { margin: var(--e2) 0 0; font-size: .78rem; }

      /* La barre de navigation de l agenda. La periode est ENTRE les fleches, qui
            agissent sur elle ; « Aujourd hui » se tient a l ecart, c est un retour au
            point fixe et non un pas de plus. */
      .nav-agenda {
        display: flex; align-items: center; gap: var(--e2);
        margin: 0 0 var(--e3);
      }
      .nav-agenda .bouton-2 { margin: 0; }
      .nav-agenda-fleche { flex: 0 0 auto; }
      /* ⚠️ LA PERIODE NE CENTRE PAS SUR LA BARRE, ELLE SE POSE ENTRE LES DEUX FLECHES.
            Centree sur toute la largeur, elle s ecartait de la fleche de droite des que
            « Aujourd hui » changeait de largeur — et le trio ne se lisait plus comme un
            seul objet. `flex: 0 1 auto` la laisse coller aux fleches. */
      .nav-agenda-periode {
        flex: 0 1 auto; padding: 0 var(--e2);
        font-size: .95rem; white-space: nowrap;
        overflow: hidden; text-overflow: ellipsis;
      }
      .nav-agenda-aujourdhui { margin-left: auto !important; flex: 0 0 auto; }

      /* ⚠️ CE QU ON REPLIE DOIT SE VOIR COMME UN REPLI, PAS COMME UN TITRE. Ecrit en
            gras sans marqueur, le resume d un `details` se lisait comme une section
            fermee par erreur : personne ne cliquait dessus. */
      .repli-lien { margin: var(--e3) 0 0; }
      .repli-lien > summary {
        cursor: pointer; font-size: .88rem; color: var(--encre-2);
        padding: .3rem 0; list-style: none;
      }
      .repli-lien > summary::-webkit-details-marker { display: none; }
      .repli-lien > summary::before {
        content: "▸"; display: inline-block; width: 1em;
        color: var(--encre-3); transition: transform .12s ease;
      }
      .repli-lien[open] > summary::before { content: "▾"; }
      .repli-lien > summary:hover { color: var(--encre); }

      /* ─────────────────────────────────────────────────────────────────────────
            LES DEUX CHOIX DE RACCORDEMENT. Deux `details` portant le meme `name` :
            c est l accordeon natif du navigateur, ouvrir l un referme l autre, sans
            une ligne de JavaScript.
            ───────────────────────────────────────────────────────────────────────── */
      .choix-connexion {
        border: 1px solid var(--trait); border-radius: var(--r);
        margin: var(--e3) 0 0; background: var(--surface);
      }
      /* ⚠️ LE RESUME EST UNE RANGEE CLIQUABLE, PAS UN TITRE. Ecrit comme un titre, on
            ne devinait pas qu il s ouvrait : c est la meme forme que les rangees de
            Reglages, dessin a gauche, mot et legende au milieu, chevron a droite. */
      .choix-connexion > summary {
        display: flex; align-items: center; gap: var(--e3);
        padding: var(--e3); cursor: pointer; list-style: none;
      }
      .choix-connexion > summary::-webkit-details-marker { display: none; }
      .choix-connexion > summary:hover { background: var(--papier); }
      .choix-connexion[open] > summary {
        border-bottom: 1px solid var(--trait);
      }
      .choix-dessin {
        flex: 0 0 auto; display: grid; place-items: center;
        width: 2.4rem; height: 2.4rem; border-radius: var(--r-petit);
        background: var(--papier); color: var(--encre-2);
      }
      .choix-mots { flex: 1 1 auto; min-width: 0; }
      .choix-mots strong { display: block; font-weight: 650; line-height: 1.3; }
      .choix-legende {
        display: block; font-size: .82rem; color: var(--encre-3); line-height: 1.35;
      }
      /* Le chevron du resume : il tourne a l ouverture, comme partout ailleurs. */
      .choix-connexion > summary::after {
        content: "›"; flex: 0 0 auto; font-size: 1.4rem; line-height: 1;
        color: var(--encre-4); transform: rotate(90deg); transition: transform .12s ease;
      }
      .choix-connexion[open] > summary::after { transform: rotate(-90deg); }
      .choix-corps { padding: var(--e3); }
      .choix-corps > :first-child { margin-top: 0; }

      /* Le tutoriel : des etapes numerotees, pas une liste a puces. L ordre compte —
            on ne trouve pas l adresse secrete avant d avoir ouvert les parametres. */
      .tuto-titre {
        margin: var(--e4) 0 var(--e2); font-size: .72rem; font-weight: 700;
        letter-spacing: .05em; text-transform: uppercase; color: var(--encre-3);
      }
      .tuto { margin: 0; padding-left: 1.3rem; }
      .tuto > li {
        margin: 0 0 var(--e2); font-size: .88rem; line-height: 1.5;
        color: var(--encre-2);
      }
      .tuto > li:last-child { margin-bottom: 0; }
      /* Ce qui suit le tutoriel s en detache : colle a la derniere etape, la remarque
            se lisait comme une quatrieme. */
      .tuto + p { margin-top: var(--e3); }

      /* Une rangee de la fiche d un rendez-vous : l etiquette a gauche, la valeur a
            droite. En colonne sous quatre cent vingt pixels, ou la valeur — une adresse,
            une note — n a plus la place de tenir sur la meme ligne. */
      .rang-fiche {
        display: flex; gap: var(--e3); align-items: baseline;
        padding: .45rem 0;
        border-bottom: 1px solid color-mix(in oklab, var(--trait) 55%, transparent);
      }
      .rang-fiche:last-child { border-bottom: none; }
      .rang-fiche > .rang-legende { flex: 0 0 7rem; }
      .rang-fiche > span:last-child { flex: 1 1 auto; min-width: 0; }
      @media (max-width: 420px) {
        .rang-fiche { flex-direction: column; gap: .1rem; }
        .rang-fiche > .rang-legende { flex: 0 0 auto; }
      }
      /* La pastille du mois devient un lien : elle garde exactement son allure. */
      a.mois-puce { text-decoration: none; }
      a.mois-puce:hover { filter: brightness(1.08); text-decoration: none; }
      @media (max-width: 420px) {
        .nav-agenda-periode { font-size: .85rem; padding: 0 .2rem; }
      }

      /* ─────────────────────────────────────────────────────────────────────────
            LE MENU DES VUES.
            ⚠️ COLONNE SUR ORDINATEUR, RANGEE SUR TELEPHONE. Un menu lateral de dix
            centimetres sur un ecran de trois cent soixante-quinze pixels, c est un
            tiers de la largeur pris a la grille — celle-la meme qui defile deja
            horizontalement faute de place. Il se couche donc en rangee au-dessus.
            ───────────────────────────────────────────────────────────────────────── */
      .agenda-avec-rail { display: flex; gap: var(--e4); align-items: flex-start; }
      .rail-agenda {
        flex: 0 0 9.5rem; display: flex; flex-direction: column; gap: .15rem;
      }
      .rail-agenda a {
        display: flex; align-items: center; gap: .5rem;
        padding: .5rem .7rem; border-radius: var(--r-petit);
        font-size: .9rem; color: var(--encre-2); text-decoration: none;
        white-space: nowrap;
      }
      .rail-agenda a:hover { background: var(--papier); text-decoration: none; }
      .rail-agenda a.actif {
        background: var(--papier); color: var(--encre); font-weight: 650;
      }
      /* Ce a quoi l agenda est raccorde, sous le mot qui y mene. En seconde ligne :
         neuf rem et demie de rail ne prennent pas « Connecter Compte Google » de front,
         et `white-space: nowrap` l aurait fait deborder au lieu de le replier. */
      .rail-agenda .rail-etat {
        display: block; font-size: .74rem; font-weight: 400; color: var(--encre-3);
      }
      /* Le raccordement d un agenda n est pas une vue : un trait l en separe. */
      .rail-agenda .rail-trait {
        height: 1px; background: var(--trait); margin: var(--e3) .4rem;
      }
      .agenda-corps { flex: 1 1 auto; min-width: 0; }

      /* ⚠️ CE QUI MANQUE SE VOIT AVANT D ENTRER. Le compte d une rangee etait gris
            comme les autres : « 0 / 8 » sur les references du reseau se lisait comme
            « 4 / 4 » sur les informations legales, et rien ne disait laquelle des neuf
            empechait de publier ses pages legales. Le rouge n est pose que sur les
            groupes dont il MANQUE un champ obligatoire — pas sur ceux dont il manque
            un champ facultatif, sinon il crie partout et cesse d etre lu. */
      .rang-valeur.rang-manque {
        color: var(--danger); font-weight: 650;
      }
      /* Le champ obligatoire vide, sur sa page : le meme rouge, sur son etiquette.
            Une page de cinq champs dont un seul bloque la publication doit dire
            LEQUEL. */
      .champ-manque > label,
      label.champ-manque { color: var(--danger); }
      .champ-manque input, .champ-manque select, .champ-manque textarea {
        border-color: color-mix(in oklab, var(--danger) 45%, var(--trait));
      }

      /* ⚠️ SE DECONNECTER N EST PAS UNE PORTE : pas de chevron, le mot est centre et
            rouge. Une rangee qui ressemble aux autres et qui, elle, TERMINE la session
            est le pire bouton qu on puisse poser dans une liste de portes. */
      .rang-reglage.rang-partir {
        justify-content: center; color: var(--danger); font-weight: 600;
      }
      .rang-reglage.rang-partir:hover { background: #fdecec; }

      /* ⚠️ IL Y A EU UN ACCORDEON ICI, ET IL A VECU DEUX HEURES. Les groupes de
            reglages s ouvraient sur place, sous la rangee touchee : « je voyais plus un
            truc ou on clique dessus et ca ouvre une nouvelle page, un peu comme sur
            l iPhone », Rodolphe, 22/08/2026 — et c est mieux. Un accordeon deplace ce
            qu on lisait pendant qu on le lit, la liste ne dit plus ou l on en est, et
            sur un telephone la moitie du groupe ouvert nait deja sous le pli.

            Chaque rangee mene donc a une page, et il ne reste rien a plier : les
            quarante lignes de style de l accordeon sont parties avec lui. */

      /* Le champ du code recu par email : six chiffres espaces, lus d un coup d oeil.
         La police a chasse fixe evite que les chiffres dansent pendant la frappe. */
      /* ⚠️ LE BOUTON « NOUVEAU MESSAGE » A ETE RETIRE LE JOUR MEME OU IL EST APPARU.
         Il servait a ne pas recharger la page sous les doigts de quelqu un qui ecrit —
         un pansement sur le rechargement lui-meme. Depuis que les bulles s ajoutent au
         lieu que la page se refasse, il n y a plus rien a interrompre : le message
         arrive pendant qu on tape, et personne n a besoin d appuyer sur quoi que ce
         soit. Rodolphe, 22/08/2026 : « si je suis en train d ecrire et que l autre
         repond, je ne la recois pas tant que je n ai pas envoye mon message ». */

      .champ-code {
        font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
        font-size: 1.5rem; letter-spacing: .35em; text-align: center;
        max-width: 11rem; padding: .5rem .6rem;
      }

      /* L ecran du conseiller : sa photo, son nom, et les cinq facons de le joindre.
         Centre, parce qu il n y a qu une chose a regarder. */
      .carte-conseiller { text-align: center; padding: var(--e5) 0 var(--e2); }
      .carte-conseiller .rond-conseiller { margin: 0 auto var(--e3); display: block; }
      .carte-conseiller .rond-lettres { display: grid; }
      .carte-conseiller h1 { margin: 0; font-size: 1.4rem; }
      /* Le pied remonte n existe que la ou le vrai est masque, c est-a-dire sur
         telephone : deux pieds de page sur un meme ecran se liraient comme une erreur. */
      .pied-mobile { display: none; }

      /* Ce qu il reste a fournir, repli sous une ligne. Il vit en tete d un formulaire
         de deux cent soixante champs : cela se consulte, cela ne se relit pas. */
      .manquants-repli > summary {
        cursor: pointer; list-style: none; display: inline-flex; align-items: center;
        gap: .35rem; min-height: 34px; color: var(--encre-2);
      }
      .manquants-repli > summary::-webkit-details-marker { display: none; }
      .manquants-repli > summary::marker { content: ""; }
      .manquants-repli > summary::after {
        content: "voir"; font-size: .78rem; color: var(--accent);
        text-decoration: underline;
      }
      .manquants-repli[open] > summary::after { content: "masquer"; }
      .manquants-detail { margin-top: .3rem; }

      .autres-canaux { margin-top: var(--e5); }
      .autres-canaux .surtitre { margin-bottom: var(--e2); }

      /* La marge du fil, reprise du style en ligne qu il portait : la mise en page a
         deux volets a besoin de la retirer, et un style ecrit sur l element ne se retire pas. */
      .fil-conv { margin: var(--e5) 0; }

      /* ⚠️ PAS DE PIED DE PAGE SOUS UNE CONVERSATION, NI SUR TELEPHONE NI SUR
         ORDINATEUR. La page se terminait par la barre d envoi, puis les mentions
         legales, puis du gris : la barre remontait d autant, et l on ecrivait au milieu
         de l ecran. Sur ordinateur, depuis que la messagerie tient dans la fenetre,
         c est pire — le pied de page est la seule chose qui fasse encore defiler la
         page, et defiler decolle la barre d envoi du bas.

         Une messagerie n a pas de pied de page. Le sien est atteignable depuis les
         quatre autres ecrans, ou les mentions legales restent entieres. */
      body:has([data-au-dernier]) footer.principal { display: none; }

      /* ⚠️ ET LA PAGE NE SE RESERVE PLUS RIEN EN BAS. Elle gardait la hauteur de la
         bulle d aide et celle de la barre d onglets : sur ordinateur, ces
         quatre-vingt-seize pixels etaient la derniere chose qui faisait encore defiler
         une page ou plus rien ne doit bouger. Sur telephone, c est la zone de reponse
         qui porte la reserve — un seul des deux la compte. */
      /* ⚠️ LA CLASSE DE L ESPACE EST DANS LE SELECTEUR, ET CE N EST PAS DECORATIF.
            Ecrite « body:has(...) », cette regle pese autant que « body.espace-agent »,
            qui reserve neuf rem et demie plus bas dans la feuille : a poids egal, c est
            la derniere qui gagne, et sur telephone cent cinquante pixels de gris
            revenaient entre la barre d envoi et les onglets. Mesure a 375 px. */
      body.espace-agent:has([data-au-dernier]),
      body.espace-client:has([data-au-dernier]) { padding-bottom: 0; }
      /* Et la marge du conteneur avec, pour la meme raison : c est le dernier blanc
         entre la barre d envoi et la barre d onglets. Mesure : trente-six pixels. */
      body:has([data-au-dernier]) main.contenu { margin-bottom: 0; }

      /* ⚠️ ET PAS DE BULLE D AIDE FLOTTANTE SUR UNE CONVERSATION. Elle se pose
         exactement sur le bouton d envoi : le dernier endroit ou l on veut d un rond
         qui flotte est celui ou l on ecrit. L aide reste a un doigt depuis les quatre
         autres ecrans. */

      /* ── LA BARRE D ENVOI ─────────────────────────────────────────────────────────
         La forme d une messagerie : le champ s etire, le bouton est un rond au bout.
         Elle remplace un libelle, un champ de trois lignes et un bouton pleine largeur,
         deux cents pixels au bas de chaque conversation. */
      .barre-envoi {
        display: flex; align-items: flex-end; gap: var(--e2); margin: 0;
      }
      /* ⚠️ LE CHAMP GRANDIT AVEC LE TEXTE, JUSQU A UNE LIMITE. Fige a quarante pixels,
         il gardait une seule ligne visible pendant que trois etaient ecrites : mesure a
         375 px, le contenu demandait cent vingt-huit pixels et le champ en montrait
         quarante. On ecrivait a l aveugle.

         ⚠️ ET LA LIMITE N EST PAS QUARANTE POUR CENT DE L ECRAN. Sur un telephone cela
         fait trois cent vingt pixels : le champ aurait mange la conversation qu on est
         en train de lire. Neuf rem et demie, soit six lignes environ ; au-dela le texte
         defile dans le champ, comme sur n importe quelle messagerie.
         « Pour pas cacher toute la conversation », Rodolphe, 22/08/2026.

         La hauteur est posee par public/fil.js. Sans script, le champ garde sa ligne et
         le texte y defile : on ecrit toujours, on voit moins. */
      .barre-envoi textarea {
        flex: 1; min-width: 0; margin: 0; resize: none;
        min-height: 40px; max-height: 9.5rem; padding: .5rem var(--e4);
        border-radius: 20px; line-height: 1.4;
      }
      .barre-envoi .envoyer {
        flex: none; width: 40px; height: 40px; min-height: 40px; padding: 0;
        border-radius: 50%; display: grid; place-items: center; margin: 0;
      }
      /* ── JOINDRE UNE PHOTO OU UN FICHIER ──────────────────────────────────────────
         Le « + » a gauche, la ou la main le cherche sur les messageries que les
         vendeurs utilisent. Le champ de fichier est cache A L OEIL SEULEMENT : il
         reste dans l ordre de tabulation, et c est ce label qui l ouvre. */
      .champ-piece {
        position: absolute; width: 1px; height: 1px; margin: -1px;
        padding: 0; border: 0; overflow: hidden; clip-path: inset(50%);
      }
      .joindre {
        flex: none; width: 40px; height: 40px; margin: 0; padding: 0;
        display: grid; place-items: center; cursor: pointer;
        border-radius: 50%; color: var(--encre-2);
        border: 1px solid var(--trait); background: var(--surface);
      }
      .joindre:hover { background: var(--papier); color: var(--encre); }
      /* Le contour de mise au point vit sur le label : le champ, lui, est invisible,
         et son contour ne se verrait donc nulle part. */
      .champ-piece:focus-visible + .joindre {
        outline: none; box-shadow: 0 0 0 2px var(--accent-bord);
      }
      /* Le nom du fichier choisi, sous la barre. Rempli par public/fil.js. */
      .piece-choisie {
        display: flex; align-items: center; gap: var(--e2);
        margin: var(--e2) 0 0; font-size: .78rem; color: var(--encre-2);
      }
      .piece-choisie[hidden] { display: none; }
      .piece-choisie > span {
        min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .piece-retirer {
        flex: none; margin: 0; padding: .1rem .5rem; min-height: 0;
        font-size: .74rem; background: none; color: var(--encre-3);
        border: 1px solid var(--trait); border-radius: 999px;
      }
      .piece-retirer:hover { background: var(--papier); color: var(--encre); }

      /* ── LA PIECE JOINTE DANS LA BULLE ────────────────────────────────────────────
         Une image se montre, un autre fichier se nomme : on s envoie une photo pour
         qu elle soit vue tout de suite, un PDF pour qu il soit ouvert. */
      .piece-image {
        display: block; margin-top: var(--e2);
        border-radius: var(--r-petit); overflow: hidden;
      }
      .piece-image img {
        display: block; width: 100%; height: auto; max-height: 320px;
        object-fit: cover; background: var(--papier);
      }
      .piece-fichier {
        display: flex; align-items: center; gap: var(--e2);
        margin-top: var(--e2); padding: var(--e2) var(--e3);
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        background: var(--surface); color: inherit; text-decoration: none;
      }
      .piece-fichier:hover { background: var(--papier); text-decoration: none; color: inherit; }
      .piece-nom {
        min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        font-size: .86rem;
      }
      .piece-poids { flex: none; font-size: .76rem; color: var(--encre-3); }

      /* ── LA BARRE DES MESSAGES NON LUS ────────────────────────────────────────────
         Un trait qui traverse le fil, avec deux mots au milieu. Elle ne marque que le
         DEBUT : ce qui est au-dessus n a pas besoin d etre nomme, c est le passe, et
         l ecrire ferait deux etiquettes pour une seule information. */
      .separateur-non-lus {
        display: flex; align-items: center; gap: var(--e3);
        margin: var(--e5) 0 var(--e4); color: var(--accent-fonce);
      }
      .separateur-non-lus::before, .separateur-non-lus::after {
        content: ""; flex: 1; height: 1px; background: var(--accent-bord);
      }
      .separateur-non-lus span {
        font-size: .72rem; font-weight: 700; letter-spacing: .08em;
        text-transform: uppercase; white-space: nowrap;
      }

      /* Zone de réponse d'une conversation : elle reste à portée pendant qu'on
         fait défiler les messages. Écrire ne doit jamais obliger à remonter. */
      .zone-reponse {
        position: sticky; bottom: 0; z-index: 5;
        background: var(--surface); padding: var(--e3) 0 var(--e2);
        border-top: 1px solid var(--trait);
      }

      /* --- Sections repliables du dossier --- */
      details[data-groupe] {
        border: 1px solid var(--trait); border-radius: var(--r);
        margin-bottom: var(--e3); background: var(--surface); overflow: hidden;
      }
      details[data-groupe] > summary {
        display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
        padding: var(--e4) var(--e5); cursor: pointer; list-style: none;
        font-weight: 650; user-select: none;
      }
      details[data-groupe] > summary::-webkit-details-marker { display: none; }
      details[data-groupe] > summary:hover { background: var(--papier); }
      details[data-groupe] > summary:focus-visible {
        outline: none; box-shadow: inset 0 0 0 2px var(--accent-bord);
      }
      .titre-section { display: flex; align-items: center; gap: var(--e2); }

      /* Ce qu'on attend à cette étape, dit en tête de carte. Un filet à gauche
         plutôt qu'un encadré : c'est une phrase à lire, pas un bloc à traiter, et
         un cadre de plus au milieu de cartes déjà encadrées se lit comme du bruit. */
      /* ── L'ÉTAT DE L'ÉTAPE PORTE LA SEULE COULEUR DE FOND DE LA CARTE ──────
            Tout était gris : carte blanche sur page grise, bloc gris clair sur
            carte blanche, jauge grise, boutons gris. Rien ne se détachait, et
            l'œil n'avait aucun point d'entrée.

            UN SEUL fond teinté, et il dit quelque chose : neutre quand ça avance,
            ambré quand ça dort depuis plus d'une semaine, vert quand c'est
            complet. Colorer chaque bloc « pour égayer » aurait dilué le code
            couleur que le reste de l'application respecte — vert pour un jalon
            franchi, ambre pour ce qui demande attention, rouge pour un problème —
            et le carrousel enchaîne douze cartes : douze fonds colorés se lisent
            comme un patchwork, plus comme une information. */
      .question-etape {
        margin: 0 0 var(--e4); padding: var(--e3) var(--e4);
        border-left: 4px solid var(--accent);
        border-radius: 0 var(--r-petit) var(--r-petit) 0;
        background: var(--accent-pale);
      }
      .question-etape.etape-attente {
        border-left-color: var(--attention); background: #fff7e8;
      }
      .question-etape.etape-attente > p:first-child { color: var(--attention); }
      .question-etape.etape-ok {
        border-left-color: var(--succes); background: var(--succes-pale);
      }
      .question-etape.etape-ok > p:first-child { color: var(--succes); }

      /* La jauge devient verte quand tout est là : le chiffre dit « 100 % », la
            couleur le dit avant qu'on le lise. */
      .question-etape.etape-ok .jauge > span {
        background: linear-gradient(90deg, var(--succes),
          color-mix(in oklab, var(--succes) 75%, #000));
      }

      /* Le ton employé avec un client : une seule ligne dans sa carte, comme on
         lirait « joignable au 06… ». Sur téléphone la ligne se casse, et les deux
         choix passent l'un sous l'autre plutôt que de se serrer. */
      .ligne-ton {
        display: flex; flex-wrap: wrap; align-items: center;
        gap: var(--e2) var(--e4);
      }
      @media (max-width: 30rem) {
        .ligne-ton { flex-direction: column; align-items: flex-start; gap: var(--e2); }
      }

      /* Un diagnostic périmé se signale AVANT d'être lu : bordure et fond d'alerte.
         Ce bloc ne s'affiche que dans ce cas, il peut donc porter la couleur du
         danger sans risque de la banaliser. */
      details[data-groupe].bloc-perime { border-color: var(--danger); }
      details[data-groupe].bloc-perime > summary { background: var(--danger-pale); }
      details[data-groupe].bloc-perime > summary:hover {
        background: color-mix(in oklab, var(--danger) 12%, #fff);
      }

      /* Le « i » qui DÉPLIAIT son texte sur place a été retiré : toute l'application
      ouvre désormais la même bulle (`bulleInfo`). Deux gestes pour la même
      promesse laissaient croire à deux sortes d'aide — et le dépliement repoussait
      le champ vers le bas au moment précis où l'on allait le remplir. */

      .filtres-dossiers select { width: auto; min-width: 11rem; margin: 0; }
      .filtres-dossiers label { margin: 0; font-weight: 500; }
      @media (max-width: 620px) {
        .filtres-dossiers { flex-direction: column; align-items: stretch; }
        .filtres-dossiers select, .filtres-dossiers button { width: 100%; }
      }

      /* Choix manuel du statut : reste sur une ligne tant que la place le permet. */
      .choix-statut { display: flex; align-items: center; gap: var(--e2); margin: 0; flex-wrap: wrap; }
      .choix-statut select { width: auto; min-width: 14rem; margin: 0; }
      @media (max-width: 620px) {
        .choix-statut { width: 100%; }
        .choix-statut select, .choix-statut button { width: 100%; }
      }

      /* Bloc « Ma page publique » : l'adresse et ses trois usages côte à côte. */
      .ma-page { display: flex; gap: var(--e5); align-items: flex-start; flex-wrap: wrap; }
      .ma-page input[readonly] { background: var(--papier); cursor: text; }
      .actions-page { display: flex; gap: var(--e2); flex-wrap: wrap; align-items: center;
        margin-top: var(--e3); }
      .bloc-qr > summary { list-style: none; cursor: pointer; display: inline-flex;
        align-items: center; gap: var(--e2); }
      .bloc-qr > summary::-webkit-details-marker { display: none; }
      @media (max-width: 620px) {
        .ma-page { flex-direction: column; }
        .bloc-qr { width: 100%; }
        .actions-page > * { flex: 1 1 auto; justify-content: center; }
      }

      /* Carte entièrement cliquable : toute la surface mène au dossier. */
      .carte-dossier { display: block; text-decoration: none; color: inherit;
        transition: border-color .15s ease, box-shadow .15s ease; }
      .carte-dossier:hover { border-color: var(--accent-bord); box-shadow: var(--ombre); color: inherit; }

      /* CARTE CLIQUABLE QUI CONTIENT UN DÉPLIANT.
            La carte du vendeur ne peut plus être un <a> : elle porte un <details>
            pour ses autres biens, et un dépliant enfermé dans un lien s'ouvre en
            suivant le lien — donc jamais.

            Le lien du nom s'étend donc à toute la carte par un ::after, et le
            dépliant repasse au-dessus avec sa propre couche. C'est le seul moyen
            de garder les deux : la carte cliquable partout, et le dépliant qui
            déplie. */
      /* ── La carte d'un vendeur, faite pour être BALAYÉE ────────────────────
            On ne lit pas cette liste, on la parcourt : « qui dois-je rappeler
            aujourd'hui ». Trois principes, et rien d'autre.

            UNE SEULE CHOSE EN GRAS par carte — le nom. Quand le nom du vendeur et
            celui du bien étaient tous deux en gras, ils se disputaient l'œil et
            aucun ne ressortait.

            LA COULEUR PORTE L'ÉTAPE, le texte ne fait que la confirmer : un jalon
            franchi se repère sans être lu.

            LA DENSITÉ EST TENUE. Chaque ligne coûte un défilement, et un agent qui
            fait défiler pour trouver un nom a déjà perdu. */
      .carte-vendeur { position: relative; padding: var(--e4); }
      .carte-vendeur + .carte-vendeur { margin-top: var(--e3); }

      /* `center` et non `baseline` : le rond d initiales est un bloc, une ligne de
         base l aurait fait flotter au-dessus du nom. */
      .tete-vendeur {
        display: flex; align-items: center; justify-content: space-between;
        gap: var(--e3); flex-wrap: wrap; margin-bottom: var(--e3);
      }
      .nom-vendeur { font-size: 1.18rem; font-weight: 700; letter-spacing: -.01em; }

      /* ═══════════ L ECRAN DES VENDEURS, SUR ORDINATEUR ═══════════
         « Je veux que tout soit exactement comme ca, version PC uniquement »
         — Rodolphe, 27/08/2026, maquette a l appui.

         ⚠️ TOUT EST DANS UN `@media (min-width: 761px)`, ET C EST LA CONDITION DE
         L ACCORD. Sur telephone le bandeau vert sert de repere entre les cinq ecrans
         du menu du bas : le retirer la casserait ce repere pour gagner un dessin que
         personne ne demande sur un ecran de 375 px.

         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ LE BANDEAU BLANC A VECU UNE HEURE, ET SON RETRAIT EST LA CORRECTION.
         Il avait ete pose le 27/08/2026 pour copier une maquette ; le meme jour :
         « j aimais bien la bande verte en haut, celle qu on a sur tous les onglets ».
         Elle revient donc, et avec le degrade qui la raccorde au rail (voir plus bas).

         CE QUI RESTE DE CE PASSAGE : les cinq cases, les initiales, les trois outils,
         la loupe. Le blanc etait le seul morceau qui coupait cet ecran des sept
         autres. */


      /* ═══════════ LES ONGLETS DEVIENNENT DES CASES, PARTOUT ═══════════
         « Ce serait bien de garder le meme style de filtre onglet sur toutes les pages
         avec des cases, bande du haut a moitie, si autre bande l enlever et garder que
         celle du haut » — Rodolphe, 27/08/2026.

         La liste des vendeurs a recu ses cinq cases ; les autres ecrans gardaient des
         pastilles blanches posees sur une SECONDE bande verte, sous la premiere. Deux
         bandes vertes empilees pour un seul bandeau : c est cette seconde qui disparait,
         et les onglets prennent la forme des cases, a cheval sur la bande du haut.

         ⚠️ ON CHANGE LE COMPOSANT, PAS LES QUATRE PAGES. `barre-volets-vert` est rendu
         par `ongletsLiens` et `ongletsPage` : la fiche d un vendeur, celle d un dossier,
         l agenda et la messagerie le portent toutes. Les modifier une par une aurait
         garanti qu une des quatre soit oubliee, et qu elle diverge au premier reglage.

         ⚠️ SUR ORDINATEUR SEULEMENT. Le telephone garde ses pastilles : quatre cases de
         quatre-vingts pixels de haut y mangeraient le premier ecran, et Rodolphe a dit
         « sur tel on verra plus tard ».
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ 1024 ET NON 761 : LE SEUIL EST CELUI DU RAIL. « Il faudrait que la bande
         d etiquettes prenne toute la largeur sur mobile ET TABLETTE » — Rodolphe,
         28/08/2026. Une tablette en portrait fait 768 px : elle tombait donc du cote
         ordinateur, ou cinq cases de 9,5 rem minimum ne tiennent pas sur une ligne et
         repassaient en rangees. Le rail lateral apparait a 1024 ; c est lui qui dit
         qu on est sur un ordinateur, et les cases suivent maintenant le meme seuil. */
      @media (min-width: 1024px) {
        /* ⚠️ CE BLOC A FONDU DE SOIXANTE LIGNES A DIX, ET C EST LA VRAIE CORRECTION.
           Il rhabillait les `.volet-mot` en cases : grille, rond, chiffre, libelle,
           hauteur, etat actif — tout redit une seconde fois, en parallele de
           `.case-ind`. Les deux ont diverge sur chacun de ces points, et chaque ecart
           a coute un aller-retour.

           `ongletsLiens` et `ongletsPage` rendent desormais `case-ind` directement
           (voir rendu/layout.js) : le CSS des cases s applique, il n y a plus rien a
           redire ici. Ne restent que la place de la barre et la seconde bande verte
           qui s efface.
           ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
        .espace-agent .bascule-volet ~ .barre-volets.barre-volets-vert,
        .espace-agent .barre-volets.barre-volets-vert {
          background: none; border-bottom: 0; gap: var(--e3);
          position: relative; z-index: 5;
          /* A cheval sur la bande du haut, comme les cases de la liste. */
          /* ⚠️ LE REMBOURRAGE REND EXACTEMENT CE QUE LA MARGE A PRIS. La barre sort
             des marges du contenu de `--e6` et n en rendait que `--e5` : sa premiere
             etiquette commencait donc huit pixels a gauche du titre, quand celle de la
             liste des vendeurs tombe pile dessus. Mesure a 1280 px, 02/09/2026 :
             264 px sur l Agenda et les Messages, 272 sur Aujourd hui et Vendeurs. */
          margin: -4.4rem calc(var(--e6) * -1) var(--e5);
          padding: 0 var(--e6);
        }
        /* ══════ LA BANDE DE LA FICHE, SANS SON VIDE ══════
           « La bande de la fiche fait 302 px quand toutes les autres en font 183 »,
           reste de la revue du 28/08/2026. Mesure du 02/09/2026 a 1280 px : 307 contre
           182,4 partout ailleurs.

           ⚠️ ET CES 182,4 SONT UN PLANCHER, PAS UNE MESURE. Les autres ecrans n ont pas
           tant de contenu : c est `min-height: 11,4rem` qui les tient. La fiche, elle,
           porte vraiment son numero, son titre, son adresse, son vendeur, son etiquette
           et sa frise de douze etapes. La ramener a 183 demanderait d en retirer, ce
           que la note de `.tete-ecran` refuse deja, et avec raison : on ne coupe pas du
           contenu pour tenir une ligne.

           CE QUI SE RETIRE SANS RIEN PERDRE, C EST LE VIDE. L etiquette occupait une
           ligne pour elle seule, tout a droite, avec un demi-ecran de vert vide a sa
           gauche ; elle se pose maintenant au bout du rail, ou elle est deja censee
           etre — « tout basculer a droite », 27/08/2026. Et les deux marges qui
           separaient le titre de la frise en faisaient vingt-huit a elles deux. */
        /* ⚠️ SEULEMENT LA BANDE QUI PORTE UNE FRISE. `dessous` sert aussi a la fiche
           d un contact, ou il empile un bloc « le joindre » et une ligne de vie : mis
           en ligne, ces deux-la se seraient retrouves cote a cote. Le `:has` limite la
           regle a la seule bande qui a un rail. */
        .espace-agent .tete-ecran-dessous:has(.frise-etapes) {
          display: flex; align-items: center; gap: var(--e4);
          margin-top: var(--e2);
        }
        .espace-agent .tete-ecran-dessous .frise-etapes {
          flex: 1; min-width: 0; padding-top: 0;
        }
        /* ⚠️ ET APRES LE RAIL, PAS AVANT. Le document la pose en premier parce qu elle
           le NOMME — elle doit se lire avant lui quand ils sont l un sous l autre. Sur
           une seule ligne, c est sa place a l ecran qui compte : « tout basculer a
           droite », 27/08/2026. `order` deplace le dessin sans toucher a la lecture. */
        .espace-agent .tete-ecran-dessous .etape-bandeau { flex: 0 0 auto; order: 2; }
        .espace-agent .tete-ecran:has(.tete-ecran-dessous .frise-etapes) .tete-ecran-haut {
          margin-bottom: var(--e2);
        }

        /* Elles se partagent la largeur, comme les cinq cases de la liste. */
        .espace-agent .barre-volets.barre-volets-vert > .case-ind { flex: 1 1 0; }
        /* L active d un onglet a bouton radio : la meme bordure que `.case-ind.actif`,
           que le CSS pur ne peut pas atteindre autrement. */
        .espace-agent .bascule-volet:nth-of-type(1):checked ~ .barre-volets > .case-ind:nth-child(1),
        .espace-agent .bascule-volet:nth-of-type(2):checked ~ .barre-volets > .case-ind:nth-child(2),
        .espace-agent .bascule-volet:nth-of-type(3):checked ~ .barre-volets > .case-ind:nth-child(3),
        .espace-agent .bascule-volet:nth-of-type(4):checked ~ .barre-volets > .case-ind:nth-child(4),
        .espace-agent .bascule-volet:nth-of-type(5):checked ~ .barre-volets > .case-ind:nth-child(5),
        .espace-agent .bascule-volet:nth-of-type(6):checked ~ .barre-volets > .case-ind:nth-child(6) {
          border-color: var(--encre);
        }
        /* Le bandeau descend d autant, pour que les cases aient ou mordre. */
        .espace-agent .tete-ecran:has(+ .bascule-volet),
        .espace-agent .tete-ecran:has(+ .barre-volets-vert) { padding-bottom: 4.5rem; }

        /* ⚠️ ET LA LISTE DES VENDEURS AUTANT QUE LES AUTRES. « Il faut qu on ait la
           meme epaisseur de barre a chaque fois — la barre verte et l emplacement des
           onglets » — Rodolphe, 28/08/2026. Mesure : les onglets de l agenda et de la
           messagerie commencaient a 137 px, les cases de la liste et du tableau de bord
           a 207 — soixante-dix pixels plus bas, donc posees SOUS la bande au lieu de
           mordre dessus. La regle qui devait les remonter visait `.compteurs-liste`, un
           nom que le composant ne porte plus depuis qu il rend `.barre-cases`. */
        .espace-agent .tete-ecran + .barre-cases,
        .espace-agent .tete-bord + .barre-cases {
          position: relative; z-index: 5;
          margin-top: -4.4rem;
        }
        .espace-agent .tete-ecran + .barre-cases > .case-ind,
        .espace-agent .tete-bord + .barre-cases > .case-ind {
          border-color: rgba(255,255,255,.14);
          box-shadow: 0 1px 2px rgba(10,30,22,.08), 0 10px 24px -14px rgba(10,30,22,.45);
        }
      }

      /* ══════ SUR TELEPHONE ET TABLETTE : UNE SEULE BANDE, UNE SEULE LIGNE ══════

         « Il y a deux barres vertes dans les onglets agenda et messages — garde la
         premiere uniquement », et « ce n est pas hyper ergo de mettre en dessous ceux
         qui depassent sur mobile et tablette » — Rodolphe, 28/08/2026.

         DEUX DEFAUTS, UNE SEULE ORIGINE : la mise en page telephone n avait jamais ete
         reprise depuis que les onglets sont devenus des cases. Elle gardait la seconde
         bande verte que l ordinateur avait perdue, et elle empilait les cases en
         rangees — cinq cases faisaient 233 px sur trois lignes, mesure a 375 px, soit
         un tiers de l ecran avant d avoir vu un seul dossier.

         ⚠️ UNE LIGNE QUI GLISSE, ET NON DES RANGEES QUI S EMPILENT. C est le geste que
         le telephone connait, et il coute zero pixel de hauteur : la derniere case est
         coupee par le bord, ce qui dit qu il y en a d autres sans avoir a l ecrire.
         Une rangee de plus, elle, repousse le contenu et ne dit rien.

         ⚠️ CE QU ON PERD, ET C EST ASSUME : la barre d onglets ne colle plus en haut
         quand on descend. Elle ne pouvait pas rester collante ET transparente — une
         barre qui se colle sans fond devient illisible des qu elle passe sur le texte.
         Entre une bande verte de trop en permanence et des onglets qu on retrouve en
         remontant, c est la premiere qui genait.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      @media (max-width: 1023px) {
        /* ⚠️ LE MEME PLANCHER, MAIS A LA MESURE DU TELEPHONE. Celui de l ordinateur
           (11,4 rem) laissait 75 px de vert vide sous « 12 vendeurs · 19 dossiers ».
           Les bandes du telephone tournaient autour de 107 px : 8,4 rem les aligne
           sans creuser. */
        .espace-agent .tete-ecran, .espace-agent .tete-bord { min-height: 8.4rem; }

        .espace-agent .bascule-volet ~ .barre-volets.barre-volets-vert,
        .espace-agent .barre-volets.barre-volets-vert {
          background: none; border-bottom: 0;
          position: relative; top: auto; z-index: 5;
          /* Elle reste dans les marges du contenu, comme les cases de la liste : sortie
             des deux bords, sa premiere case se retrouvait coupee a gauche et l on
             croyait avoir deja fait glisser la ligne. */
          /* ⚠️ D UN BORD A L AUTRE DE L ECRAN. « Il faudrait que la bande d etiquettes
             prenne toute la largeur sur mobile et tablette, pour que les ombrages
             tombent bien » — Rodolphe, 28/08/2026. Arretee aux marges du contenu, la
             derniere case etait coupee par un bord invisible a seize pixels du vrai,
             et son ombre butait dessus. Elle sort donc des marges et les redonne en
             rembourrage : la premiere case reste alignee sur le texte, la derniere se
             perd sous le bord de l ecran, ce qui est le seul signe honnete qu il y en
             a d autres. */
          /* ⚠️ LA MARGE EST CELLE DU CONTENU, ET NON `50% - 50vw`. `100vw` compte la
             barre de defilement : mesure a 768 px, la bande sortait de sept pixels de
             chaque cote et la PAGE ENTIERE se mettait a defiler de travers. On reprend
             donc exactement le rembourrage de `main.contenu` — 2 rem ici, 1 rem sous
             560 px, ou il vaut lui-meme 1 rem. */
          margin: -2.8rem calc(-1 * var(--e6)) .2rem;
          padding: .5rem var(--e6) .9rem;
          /* ⚠️ LE MEME ECART QUE LA LISTE DES VENDEURS, ET POUR LA MEME RAISON.
             `.barre-cases` espace ses etiquettes de `--e3` sans condition ; les deux
             barres a volets heritaient de leur passe d onglets colles — zero sur
             Messages, un quart de rem sur l Agenda. Mesure au telephone : douze
             pixels entre les cases de Vendeurs, zero entre « Toutes » et « Non lues »,
             quatre sur l Agenda. Trois onglets, trois ecarts, pour un objet qui est
             le meme. « Ca serait bien de centrer les etiquettes avec des ecarts qui
             correspondent sur chaque onglet » — Rodolphe, 02/09/2026. */
          gap: var(--e3);
        }
        .espace-agent .tete-ecran:has(+ .bascule-volet),
        .espace-agent .tete-ecran:has(+ .barre-cases),
        .espace-agent .tete-bord:has(+ .barre-cases),
        .espace-agent .tete-ecran:has(+ .barre-volets-vert) { padding-bottom: 2.7rem; }
        /* La liste des vendeurs porte `.barre-cases` en direct, sans onglets : elle
           doit mordre sur la bande comme les autres, sinon elle seule flotte en
           dessous. Meme decalage, meme moitie. */
        .espace-agent .tete-ecran + .barre-cases,
        .espace-agent .tete-bord + .barre-cases {
          position: relative; z-index: 5;
          margin: -2.8rem calc(-1 * var(--e6)) .2rem;
          padding: .5rem var(--e6) .9rem;
        }

        /* La meme ligne glissante pour les deux : les cinq cases de la liste des
           vendeurs et les onglets-cases des autres ecrans sont le meme objet. */
        /* ⚠️ UN DEFILEMENT HORIZONTAL COUPE AUSSI CE QUI DEBORDE EN HAUT ET EN BAS.
           `overflow-x: auto` force `overflow-y` a `auto` : le navigateur ne sait pas
           faire l un sans l autre. L ombre des cases se trouvait donc tranchee net au
           ras du conteneur — « les cartes qui defilent sur mobile ont l air d etre dans
           une bande avec de l ombre », Rodolphe, 28/08/2026. Mesure : conteneur et case
           a 80 px tous les deux, zero rembourrage.

           On rend a l ombre la place de retomber, et on la reprend en marge pour que
           rien ne bouge d un pixel a l ecran. */
        .barre-cases,
        .espace-agent .barre-volets.barre-volets-vert {
          display: flex; flex-wrap: nowrap;
          overflow-x: auto; overscroll-behavior-x: contain;
          scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
          scrollbar-width: none;
          padding-top: .5rem; padding-bottom: .9rem;
          /* ⚠️ SANS CE `scroll-padding`, LE CRAN MANGE LE REMBOURRAGE. Le navigateur
             cale la premiere case sur le debut de la zone de defilement, rembourrage
             non compris : mesure, il partait tout seul a 16 px de defilement et la
             premiere case se collait au bord de l ecran. */
          scroll-padding-left: var(--e6);
        }
        .barre-cases::-webkit-scrollbar,
        .espace-agent .barre-volets.barre-volets-vert::-webkit-scrollbar { display: none; }
        /* ⚠️ LE DESSIN ET LE NOMBRE SUR LA MEME LIGNE, LE MOT SOUS LES DEUX. « Mettre
           le dessin a gauche a cote, mettre le numero, et en dessous des deux
           l ecriture : comme ca ca eviterait que l ecriture depasse du cadran » —
           Rodolphe, 28/08/2026. Cote a cote, le mot n avait que la moitie de la case :
           « Prise de contact » y tombait sur deux lignes serrees. Sous les deux, il a
           toute la largeur.

           ⚠️ EN GRILLE, ET SANS TOUCHER AU HTML. Le mot vit dans le meme bloc que le
           nombre ; `display: contents` efface ce bloc de la mise en page pour que ses
           deux enfants se posent directement dans la grille. Le HTML reste celui de
           l ordinateur, donc un seul composant, comme demande depuis le 27/08.

           La colonne du dessin est en `auto` : une case sans dessin la reduit a zero et
           le nombre revient a gauche, sans regle de plus. */
        .barre-cases > .case-ind,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind {
          flex: 0 0 auto; width: 8.6rem; min-height: 4.4rem;
          padding: var(--e3);
          scroll-snap-align: start;
          /* ⚠️ TOUT EST CENTRE DANS LA CASE. « Si tu peux centrer les ecritures, ce
             serait magnifique, pour qu il soit au milieu de l etiquette » — Rodolphe,
             28/08/2026. Les colonnes passent en `auto auto` et la grille se centre :
             sans cela la seconde colonne prenait toute la place restante et le nombre
             restait cale a gauche, sous un mot centre. */
          display: grid; grid-template-columns: auto auto;
          justify-content: center; align-items: center; gap: .15rem .45rem;
        }
        .barre-cases > .case-ind > .case-rond,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind > .case-rond {
          grid-column: 1; grid-row: 1;
        }
        .barre-cases > .case-ind > .case-texte,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind > .case-texte {
          display: contents;
        }
        .barre-cases > .case-ind .case-texte b,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind .case-texte b {
          grid-column: 2; grid-row: 1;
        }
        .barre-cases > .case-ind .case-texte small,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind .case-texte small {
          grid-column: 1 / -1; grid-row: 2;
          text-align: center; max-width: 100%;
        }
        /* Sur le vert, la bordure grise ne se voit pas : c est l ombre qui detache,
           exactement comme sur ordinateur. Uniquement pour les barres QUI MORDENT sur
           la bande : posee sur du gris, une bordure blanche ferait flotter la case. */
        .espace-agent .tete-ecran + .barre-cases > .case-ind,
        .espace-agent .tete-bord + .barre-cases > .case-ind,
        .espace-agent .barre-volets.barre-volets-vert > .case-ind {
          border-color: rgba(255,255,255,.14);
          box-shadow: 0 1px 2px rgba(10,30,22,.08), 0 10px 24px -14px rgba(10,30,22,.45);
        }
      }

      /* ⚠️ SOUS 560 PX, `main.contenu` NE GARDE QU UN REM DE REMBOURRAGE. La bande qui
         va d un bord a l autre doit reprendre exactement cette valeur : mesuree a
         2 rem, elle sortait de seize pixels a gauche et la page entiere se mettait a
         defiler de travers.
         ⚠️ ET CE BLOC EST ECRIT APRES CELUI DU DESSUS, PAS AILLEURS. A poids egal la
         derniere regle gagne ; place plus haut dans la feuille, il ne servait a rien. */
      @media (max-width: 560px) {
        /* ⚠️ ET LA VARIANTE A VOLETS DOIT ETRE NOMMEE ICI AUSSI, AVEC SON `~`.
           Le bloc du dessus la designe deux fois : `.espace-agent .barre-volets
           .barre-volets-vert`, et la meme precedee de `.bascule-volet ~`. La seconde
           pese une classe de plus, et c est elle qui gagnait : l Agenda gardait donc
           les 2 rem du dessus quand les autres passaient a 1 rem. Mesure au telephone,
           02/09/2026 : premiere etiquette a 0 px au lieu de 16, marge a -32 au lieu de
           -16, et la PAGE ENTIERE large de 391 px pour un ecran de 375 — elle defilait
           de travers. L Agenda est le seul ecran a porter des volets a bascule, donc
           le seul ou le defaut se voyait. */
        .barre-cases,
        .espace-agent .tete-ecran + .barre-cases,
        .espace-agent .tete-bord + .barre-cases,
        .espace-agent .bascule-volet ~ .barre-volets.barre-volets-vert,
        .espace-agent .barre-volets.barre-volets-vert {
          margin-left: calc(-1 * var(--e4)); margin-right: calc(-1 * var(--e4));
          padding-left: var(--e4); padding-right: var(--e4);
          scroll-padding-left: var(--e4);
        }
      }

      /* ══════ LA TABLETTE FINIT DE RESSEMBLER AUX DEUX AUTRES ══════
         Le menu parti, restaient trois details qui la distinguaient encore : la page
         flottait a 24 px du haut avec des coins arrondis — donc une bande grise entre
         le bord de l ecran et la bande verte —, et son bas ne reservait pas la place
         de la barre d onglets, qui passait donc sur le dernier vendeur. Le telephone
         et l ordinateur ne font ni l un ni l autre.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      @media (min-width: 561px) and (max-width: 1023px) {
        .espace-agent main.contenu { margin-top: 0; border-radius: 0; }
        .espace-agent .tete-ecran, .espace-agent .tete-bord { border-radius: 0; }
        /* ⚠️ UN PLANCHER PAR TAILLE DE TEXTE, ET NON UN SEUL POUR TOUT CE QUI N EST PAS
           UN ORDINATEUR. Le titre de la tablette est plus grand que celui du telephone :
           une bande de titre plus une ligne y demande 154 px, quand le plancher commun
           en annonce 134. Trois onglets sur cinq le depassaient donc, et la bande
           changeait d epaisseur d un onglet a l autre — Reglages a 134, Vendeurs a 154.
           Mesure a 768 px, 02/09/2026. */
        .espace-agent .tete-ecran, .espace-agent .tete-bord { min-height: 9.65rem; }
        body.espace-agent {
          padding-bottom: calc(var(--h-onglets) + var(--e5) + env(safe-area-inset-bottom, 0px));
        }
      }

      /* ⚠️ SUR TABLETTE, LE MENU DU HAUT SORTAIT DE L ECRAN. Trouve en verifiant la
         bande d etiquettes a 768 px : la page debordait de 167 pixels, et la cause
         n etait pas la bande mais le menu — sept liens sur une ligne. Il porte bien
         `flex-wrap: wrap`, mais aussi `flex-shrink: 0`, qui lui laisse sa largeur
         naturelle : il ne se replie donc jamais, il pousse. Entre le telephone, ou une
         barre du bas le remplace, et l ordinateur, ou le rail lateral le remplace, il
         restait cette zone ou il etait seul et trop long. */
      @media (min-width: 561px) and (max-width: 1023px) {
        .espace-agent header.principal nav.menu { flex-shrink: 1; min-width: 0; }
      }

      /* ── Le bandeau part du rail et va vers le vert ───────────────────────────
         « Qu elle parte de la couleur de la bande laterale gauche en degrade vers le
         vert quand elle va vers la droite » — Rodolphe, 27/08/2026. Le noir du rail
         et le vert du bandeau se touchaient sur une arete franche ; ils se rejoignent
         maintenant. L angle est proche de l horizontale : c est la largeur qui porte
         le degrade, pas la hauteur.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ LA PREMIERE COULEUR EST CELLE DU RAIL, AU CODE PRES : #171d1a, exactement
         ce que porte `.rail-app`. Un ton approchant laissait une arete visible la ou
         les deux se touchent — « ce serait bien de pas voir de separation entre la
         barre laterale et le haut de page », Rodolphe, 27/08/2026. Deux noirs voisins
         se voient ; le meme noir ne se voit pas.

         Le degrade demarre donc a l identique et ne verdit qu apres un cinquieme de
         largeur, le temps que l oeil ait quitte la jointure. */
      /* ⚠️ ET LE TABLEAU DE BORD AVEC, MOT POUR MOT. « Les bords arrondis ne
         correspondent pas a la meme couleur que sur les autres onglets » — Rodolphe,
         28/08/2026. Mesure : sa bande partait d un degrade a 150 degres commencant a
         #0a3d2e, quand les quatre autres partent a 96 degres du noir du rail. Deux
         verts voisins mais differents sur le meme ecran, et la jointure avec la barre
         laterale redevenait visible la ou on l avait justement effacee. */
      .espace-agent .tete-ecran,
      .espace-agent .tete-bord {
        background: linear-gradient(96deg,
          #171d1a 0%, #12332a 20%, #0b3b2d 40%, #0d5c46 72%, #127054 100%);
      }
      /* Les coins suivent : 22 px en haut sur le seul tableau de bord, a plat
         partout ailleurs — l arrondi laissait passer deux triangles de fond gris
         que les autres ecrans n ont pas. */
      .espace-agent .tete-bord { border-radius: 0; }
      /* Sur le vert, l ambre du sous-titre devient illisible : ce qui presse passe en
         clair, et c est le poids qui le distingue. */
      .espace-agent .tete-ecran-sous .a-traiter {
        color: #ffd9a8; font-weight: 700;
      }

      /* ── Les cases chevauchent le bandeau ─────────────────────────────────────
         « Il faudrait la descendre pour qu elle arrive a la moitie des cases filtres »
         — Rodolphe, 27/08/2026. Le bandeau gagne en hauteur, les cases remontent
         d autant : elles se posent a cheval, moitie sur le vert, moitie sur le fond.

         ⚠️ MEME MOTIF QUE LES CARTES DU TABLEAU DE BORD, et ce n est pas un hasard :
         c est lui qui a ete arbitre en premier, et deux ecrans qui font la meme chose
         doivent la faire pareil.

         ⚠️ ET C EST L ORDRE D EMPILEMENT QUI DECIDE. Sans `position: relative` et un
         `z-index` au-dessus du bandeau, les cases passeraient DESSOUS : le meme piege
         que la barre posee avant `.monte-bandeau`, rencontre quatre fois sur ce
         projet. Elles montent devant, pas derriere.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ CE BLOC A ETE RETIRE LE 28/08/2026, ET IL EXPLIQUE LE DEFAUT SIGNALE.
         « Sur les onglets agenda et messages sur tablette, la bande verte est un peu
         decalee et ca fait une bande blanche en haut. » Mesure a 820 px : la bande de
         la liste des vendeurs faisait 183 px, celles de l agenda et de la messagerie
         154 — les cases y mordaient donc de 9 px au lieu de 21, et leur moitie basse
         tombait plus bas dans le blanc.

         La cause : ce bloc imposait 4,5 rem de creux a la SEULE liste des vendeurs des
         761 px, quand tous les autres ecrans passent a 2,7 sous 1024. Ses deux autres
         regles visaient `.compteurs-liste` et `.compteur-case`, des noms que le
         composant ne porte plus depuis qu il rend `.barre-cases` et `.case-ind` :
         verifie sur tout le depot, plus un seul appel. Le creux est desormais donne
         par la regle commune `:has(+ .barre-cases)`, qui vaut pour les cinq ecrans. */

      /* ── Les cinq cases sont les onglets ──────────────────────────────────────
         Elles filtrent, donc elles se comportent comme des liens : survol, etat actif,
         et la couleur du temps qu elles designent. */
      .compteur-case {
        text-decoration: none; color: inherit;
        transition: border-color .12s, box-shadow .12s, transform .12s;
      }
      a.compteur-case:hover {
        border-color: var(--temps, var(--encre-3));
        box-shadow: 0 1px 2px rgba(20,30,25,.06), 0 6px 16px -12px rgba(20,30,25,.4);
      }
      /* ⚠️ L ACTIVE GARDE EXACTEMENT L APPARENCE DES AUTRES. « Il faut que les bulles
         aient exactement le meme style qu elles soient cliquees ou non » — Rodolphe,
         27/08/2026. Elle prenait un fond colore et son rond passait au blanc : la case
         choisie devenait un autre objet, et l oeil comparait deux formes au lieu de
         cinq chiffres.

         Ce qui la designe tient donc en un seul trait : la bordure fonce, doublee a l
         interieur pour l epaissir sans deplacer d un pixel ce qu il y a autour. */
      /* ⚠️ UN SEUL TRAIT, PAS DEUX. La bordure foncee et le trait interieur se
         cumulaient : deux pixels de contour la ou la maquette en montre un, et la case
         choisie paraissait plus lourde que ses voisines au lieu d etre simplement
         designee. « L onglet selectionne n est pas pareil » — Rodolphe, 27/08/2026.
         L ombre commune est reprise telle quelle : sans elle, l active perdait le
         relief que les autres gardaient. */
      a.compteur-case.actif {
        border-color: var(--encre);
        box-shadow: 0 1px 2px rgba(20,30,25,.04), 0 10px 26px -18px rgba(20,30,25,.3);
      }
      @media (prefers-reduced-motion: reduce) { .compteur-case { transition: none; } }

      /* ── Les trois outils de la liste ─────────────────────────────────────────
         Filtres, Trier, Exporter, cote a cote a droite de la recherche. Les deux
         premiers ouvrent le meme panneau : filtrer et trier se validant ensemble, les
         separer aurait fait valider deux fois pour un geste qu on fait d un coup.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .outils-liste { display: flex; gap: var(--e2); flex: none; }
      /* ⚠️ FOND BLANC ET LIBELLE SOMBRE, REPRIS SUR LA CAPTURE DU 28/08/2026.
         Ils etaient gris sur gris : le bouton se confondait avec la page, et le mot
         se lisait plus clair que le texte qui l entoure — un bouton qui a l air
         desactive. Le blanc les detache du fond, l encre pleine les rend cliquables
         a l oeil. La bordure reste fine : ce sont des outils, pas des actions. */
      .outil-liste {
        display: inline-flex; align-items: center; gap: .45rem;
        padding: .55rem .95rem; border-radius: .75rem;
        border: 1px solid var(--trait); background: #fff;
        color: var(--encre); font-size: .92rem; font-weight: 600;
        font-family: inherit; cursor: pointer; white-space: nowrap;
        text-decoration: none;
      }
      .outil-liste svg { width: 18px; height: 18px; }
      .outil-liste:hover { border-color: var(--encre-3); background: var(--papier); }
      .outil-liste b { color: var(--accent); }
      /* Le panneau prend la ligne entiere quand il s ouvre, sous les trois boutons. */
      .ligne-recherche > .bloc-filtres { flex: 1 0 100%; margin-top: var(--e2); }
      /* ⚠️ SON PROPRE RESUME DISPARAIT, MAIS SEULEMENT SI LE SCRIPT A CHARGE.
         Les trois boutons le remplacent — le laisser affichait « Filtrer, trier,
         exporter » une ligne sous trois boutons qui disent la meme chose. Mais sans
         JavaScript les boutons ne font rien : le resume reste alors le seul moyen
         d ouvrir le panneau, et il doit rester visible. `outilsListe.js` pose la
         classe sur le document des qu il tourne. */
      .resume-filtres { font-size: .85rem; color: var(--encre-3); }
      .outils-actifs .resume-filtres { display: none; }
      @media (max-width: 700px) {
        .outils-liste { width: 100%; }
        .outil-liste { flex: 1 1 auto; justify-content: center; }
      }

      /* ── La loupe dans le champ de recherche ──────────────────────────────────
         Elle dit ce que fait le champ sans qu on lise le texte gris. Le champ recule
         d autant : sans ce retrait, le curseur se poserait sous l icone.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .barre-recherche { position: relative; }
      .loupe-recherche {
        position: absolute; left: .85rem; top: 50%; transform: translateY(-50%);
        display: inline-flex; color: var(--encre-3); pointer-events: none;
      }
      .barre-recherche input[type="search"] { padding-left: 2.5rem; }
      /* ⚠️ MESURE, PAS ESTIMATION : la regle generale des champs aligne six `:not()`,
         soit une specificite de (0,6,1). Une classe plus un attribut ne la battent
         pas — le coin restait a 10 px pendant que les boutons passaient a 12. On vise
         donc l identifiant du champ, qui passe devant sans `!important`. */
      .barre-recherche #q { border-radius: .75rem; }
      .barre-recherche .loupe-recherche svg { width: 18px; height: 18px; }

      /* ── « Complet », a la place du pourcentage ───────────────────────────────
         Un « 100 % » se lit comme les autres pourcentages : il faut le comparer pour
         comprendre qu il est au bout. Le mot et sa coche se lisent sans comparer. */
      .bien-complet {
        display: inline-flex; align-items: center; gap: .3rem; flex: none;
        font-size: .82rem; font-weight: 600; color: var(--succes);
      }

      /* Le compte de la liste, sous les cartes. */
      .compte-bas {
        margin: var(--e4) 0 0; font-size: .85rem; color: var(--encre-3);
      }

      /* ── Le nom du bien reprend la place ──────────────────────────────────────
         `flex: 0 1 auto` le laissait retrecir jusqu a 147 px et couper « Appartement
         T4 · Perpignan » en « Appart... ». Il pousse maintenant les autres colonnes
         avant de se couper lui-meme, et la jauge cede la sienne en premier : un
         pourcentage se lit aussi bien sur trente pixels que sur cent.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      @media (min-width: 761px) {
        .espace-agent .ecran-vendeurs .ligne-bien .nom-bien { flex: 1 1 auto; }
        /* ⚠️ L ETIQUETTE NE SE CALE PLUS A DROITE. Elle y avait ete poussee le matin,
           quand elle occupait seule le bout de la ligne ; la capture du soir la remet
           au milieu, suivie du rang, de la jauge et du pourcentage. Gardee au bout avec
           ses treize rem, elle ecrasait le nom du bien — « 2026-006 A... ».
           Elle reprend sa largeur de mot, et c est le nom qui pousse les autres. */
        .espace-agent .ecran-vendeurs .ligne-bien .etiquette-etape {
          flex: none; justify-content: flex-start;
        }
        .espace-agent .ecran-vendeurs .ligne-bien .bien-complet { min-width: 5.5rem; }
        /* Le resserrement a 13 rem partait avec les deux colonnes : sous 1024 px la
           carte empile le vendeur et ses biens. */
      }

      /* ── Le vendeur a gauche, ses biens a droite ──────────────────────────────
         Empiles, le nom et les biens se lisaient comme une seule liste ou l on ne
         savait plus qui possedait quoi des qu un vendeur en avait trois. Un filet vert
         separe les deux. Sur telephone ils se remettent l un sous l autre : deux
         colonnes de 170 px ne tiennent pas.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* ⚠️ 1024 ET NON 761 : LA TABLETTE EMPILE, COMME LE TELEPHONE. Mesure a 805 px :
         la colonne du vendeur prenait 240 px et il n en restait que 451 pour les biens
         — huit noms sur dix-sept se coupaient en « Appartement T4 · P... ». Empiles,
         ils disposent de 691 px et aucun ne se coupe. Le seuil rejoint celui du rail :
         deux colonnes demandent un ecran d ordinateur. */
      @media (min-width: 1024px) {
        .espace-agent .ecran-vendeurs .carte-vendeur {
          display: grid; grid-template-columns: 15rem 1fr; gap: var(--e4);
          align-items: start;
        }
        .espace-agent .ecran-vendeurs .colonne-biens {
          border-left: 2px solid var(--succes); padding-left: var(--e4);
          min-width: 0;
        }
      }
      .colonne-vendeur .tete-vendeur { margin-bottom: var(--e2); }
      .meta-vendeur { margin: 0; font-size: .85rem; color: var(--encre-3); }
      /* La derniere activite, avec son point : vert quand le vendeur bouge, gris
         quand il dort, ambre au-dela de deux semaines. */
      .activite-vendeur {
        display: flex; align-items: center; gap: var(--e2);
        margin: .2rem 0 0; font-size: .85rem; color: var(--encre-3);
      }
      .point-activite {
        width: .5rem; height: .5rem; border-radius: 50%; flex: none;
        background: var(--succes);
      }
      .activite-vendeur.en-souffrance { color: var(--attention); font-weight: 600; }
      .activite-vendeur.en-souffrance .point-activite { background: var(--attention); }

      /* ── Les lignes de dossier, reprises sur la capture du 27/08/2026 ─────────
         Fond blanc et non gris : sur une carte deja blanche, un aplat gris par ligne
         faisait trois blocs empiles au lieu d une liste. Un filet separe, c est tout.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .espace-agent .ecran-vendeurs .ligne-bien {
        background: transparent; border: 0; border-radius: 0;
        padding: var(--e3) 0;
      }
      .espace-agent .ecran-vendeurs .bloc-ligne-bien + .bloc-ligne-bien {
        border-top: 1px solid var(--trait);
      }
      .espace-agent .ecran-vendeurs .ligne-bien:hover { background: var(--surface); }
      /* Le numero du dossier, devant le nom : gris, et il ne bouge pas d une ligne a
         l autre — c est ce qui rend la colonne lisible en diagonale. */
      .espace-agent .ecran-vendeurs .nom-bien { color: var(--encre); font-weight: 600; }
      .espace-agent .ecran-vendeurs .nom-bien .discret { font-weight: 400; }
      /* Le nom et son adresse forment un bloc : c est lui qui pousse les autres
         colonnes, et l adresse ne doit pas les repousser plus que le nom. */
      .espace-agent .ecran-vendeurs .bloc-ligne-bien .bloc-nom-bien {
        display: flex; flex-direction: column; gap: .1rem;
        flex: 1 1 auto; min-width: 0;
      }
      .espace-agent .ecran-vendeurs .bloc-nom-bien .nom-bien { flex: none; }
      .adresse-bien {
        font-size: .78rem; color: var(--encre-3);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }

      /* ⚠️ LES TROIS RACCOURCIS, REPRIS SUR LA CAPTURE. Carres arrondis, bordure fine,
         et WhatsApp seul garde sa couleur — bordure ET icone vertes. Les deux autres
         restent gris : le telephone et l enveloppe sont des gestes, WhatsApp est une
         marque, et c est sa couleur qui la fait reconnaitre sans lire. Trois couleurs
         auraient fait trois taches la ou une seule porte une information. */
      /* ⚠️ `align-self` N EST PAS UN DETAIL ICI. Sans lui, le bouton s etire sur
         toute la hauteur de la ligne (44 px mesures pour 35 demandes) : le carre
         devient un rectangle, et la capture montre des carres. */
      .espace-agent .ecran-vendeurs .gestes-ligne .canal {
        width: 2.2rem; height: 2.2rem; min-height: 0; padding: 0;
        align-self: center; flex: none;
        border-radius: .7rem; background: #fff; color: var(--encre);
        border-color: color-mix(in oklab, var(--trait) 75%, #fff);
      }
      .espace-agent .ecran-vendeurs .gestes-ligne .canal:hover {
        background: var(--papier); border-color: var(--encre-3);
      }
      .espace-agent .ecran-vendeurs .gestes-ligne .canal[href^="https://wa.me"] {
        color: #1faa53; border-color: color-mix(in oklab, #1faa53 45%, #fff);
      }
      .espace-agent .ecran-vendeurs .gestes-ligne .canal[href^="https://wa.me"]:hover {
        color: #17843f; border-color: #1faa53; background: color-mix(in oklab, #1faa53 8%, #fff);
      }

      /* « Etape 4/12 », en clair et non serre dans la pastille. */
      .rang-clair {
        flex: none; font-size: .82rem; color: var(--encre-3);
        font-variant-numeric: tabular-nums; white-space: nowrap;
      }
      /* La jauge prend la couleur de son temps : une barre grise partout aurait remis
         le defaut que les etiquettes colorees venaient de corriger. */
      .espace-agent .ecran-vendeurs .mini-jauge {
        flex: 0 1 5.5rem; min-width: 2.5rem; height: .4rem;
        border-radius: 999px; background: color-mix(in oklab, var(--encre-3) 18%, #fff);
        overflow: hidden;
      }
      .espace-agent .ecran-vendeurs .mini-jauge > span {
        display: block; height: 100%; border-radius: 999px;
        background: var(--temps, var(--encre-2));
      }
      .part-bien {
        flex: none; font-size: .82rem; color: var(--encre-3);
        font-variant-numeric: tabular-nums; min-width: 2.6rem;
      }
      /* ⚠️ CE QUI CEDE, ET DANS QUEL ORDRE. La ligne porte huit choses — numero, nom,
         etiquette, rang, jauge, pourcentage, trois gestes, chevron. A la largeur de la
         capture elles tiennent ; a 1180 px le nom se coupait en « Appart... », et c est
         lui qu on lit en premier.

         On retire donc du moins utile vers le plus utile, et jamais le nom : le
         pourcentage part d abord — la jauge le dit deja —, puis le rang, puis la jauge.
         Mesure a chaque palier, pas devine. */
      @media (max-width: 1500px) {
        .espace-agent .ecran-vendeurs .ligne-bien .part-bien { display: none; }
      }
      @media (max-width: 1420px) {
        /* ⚠️ LE NOM COURT DE L ETAPE ARRIVE AVANT LE TELEPHONE. Il existait deja, mais
           ne sortait qu en dessous de 560 px : entre les deux, « Visite d estimation
           planifiee » mangeait la moitie de la ligne et coupait le nom du bien en
           « Appart... ». Six lignes sur dix-sept, mesurees a 1180 px.
           « Rendez-vous » dit la meme chose en trois fois moins de place. */
        .espace-agent .ecran-vendeurs .ligne-bien .etape-longue { display: none; }
        .espace-agent .ecran-vendeurs .ligne-bien .etape-courte { display: inline; }
      }
      @media (max-width: 1360px) {
        .espace-agent .ecran-vendeurs .ligne-bien .rang-clair { display: none; }
      }
      @media (max-width: 1240px) {
        .espace-agent .ecran-vendeurs .ligne-bien .mini-jauge { display: none; }
      }
      /* ⚠️ SUR TELEPHONE, L ETIQUETTE RESTE SUR LA LIGNE DU NOM. Mesure a 375 px : le
         nom passait sur deux lignes — ce qui est juste, il faut le lire en entier — et
         l etiquette basculait DESSOUS, faisant 99 px par bien. Trois biens tenaient
         donc 300 px pour trois informations. En interdisant le retour a la ligne, le
         nom garde ses deux lignes et l etiquette se pose en face : 65 px.

         ⚠️ ET LE NOM N EST PAS TRONQUE POUR AUTANT. Le tenir sur une seule ligne avec
         des points de suspension aurait rendu « Appartement T2 · 61 m²... » — c est
         exactement ce qui avait ete corrige sur ordinateur le 27/08. Deux lignes
         completes valent mieux qu une ligne coupee. */
      @media (max-width: 560px) {
        .espace-agent .ecran-vendeurs .ligne-bien {
          flex-wrap: nowrap; align-items: flex-start; gap: var(--e2);
        }
        .espace-agent .ecran-vendeurs .ligne-bien .bloc-nom-bien {
          flex: 1 1 auto; min-width: 0;
        }
        .espace-agent .ecran-vendeurs .ligne-bien .etiquette-etape { flex: none; }
      }
      /* Le chevron reste visible : sur une ligne blanche il ne surcharge rien, et il
         dit qu on peut ouvrir. Il etait cache jusqu au survol, ce qui ne se devine pas
         sur un ecran tactile. */
      .espace-agent .ecran-vendeurs .fleche-bien {
        opacity: .45; flex: none; transition: opacity .12s, transform .12s;
      }
      .espace-agent .ecran-vendeurs .ligne-bien:hover .fleche-bien {
        opacity: 1; transform: translateX(2px);
      }
      @media (prefers-reduced-motion: reduce) {
        .espace-agent .ecran-vendeurs .fleche-bien { transition: none; }
      }

      /* ── Une ligne de bien et ses gestes ──────────────────────────────────────
         Ils sont FRERES, jamais imbriques : un lien dans un lien est du HTML invalide
         que le navigateur defait, et les boutons partiraient ailleurs dans la page. */
      .bloc-ligne-bien {
        display: flex; align-items: center; gap: var(--e2);
        margin-bottom: var(--e2);
      }
      .bloc-ligne-bien > .ligne-bien { flex: 1 1 auto; min-width: 0; margin: 0; }
      /* Le point « du nouveau », a droite de la ligne, juste avant les raccourcis.
         Le halo le detache du fond blanc sans l agrandir : a 7 px pleins il se
         confondait avec un point de ponctuation, a 11 px il pesait plus lourd que
         l etiquette d etape a cote. */
      .pastille-ligne {
        flex: none; align-self: center; width: .55rem; height: .55rem;
        border-radius: 999px; background: var(--danger);
        box-shadow: 0 0 0 3px color-mix(in oklab, var(--danger) 16%, #fff);
        margin-right: .15rem;
      }
      .gestes-ligne { display: inline-flex; align-items: center; gap: .35rem; flex: none; }
      .gestes-ligne .canal {
        display: inline-flex; align-items: center; justify-content: center;
        width: 2rem; height: 2rem; border-radius: var(--r-petit);
        border: 1px solid var(--trait); background: var(--papier);
        color: var(--encre-2);
      }
      .gestes-ligne .canal:hover {
        border-color: var(--encre-3); color: var(--encre); background: #fff;
      }
      /* ⚠️ WHATSAPP GARDE SA COULEUR, LES DEUX AUTRES NON. Ce n est pas une
         decoration : c est le seul des trois canaux qui soit une marque, et son vert
         est ce qui le fait reconnaitre sans lire. Le telephone et l enveloppe sont des
         gestes, pas des marques — les colorer aurait fait trois taches la ou une seule
         porte une information. Repris de la capture du 27/08/2026. */
      .gestes-ligne .canal[href^="https://wa.me"] { color: #1faa53; }
      .gestes-ligne .canal[href^="https://wa.me"]:hover {
        color: #17843f; border-color: #1faa53;
      }
      @media (max-width: 560px) { .gestes-ligne { display: none; } }

      /* ── Les etiquettes d etape, dans la liste des vendeurs ───────────────────
         Elles etaient toutes vertes : la couleur ne disait donc rien, et il fallait
         lire chaque mot d une liste qu on parcourt justement pour reperer. Elles
         prennent la teinte de leur moment — la meme que les cartes d etape et que la
         barre de compteurs. Les variables viennent de `.temps-*`, on n en invente pas.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .ligne-bien .pastille[class*="temps-"] {
        background: var(--temps-fond); color: var(--temps);
        border: 1px solid color-mix(in oklab, var(--temps) 22%, transparent);
        font-weight: 600;
      }
      .ligne-bien .pastille[class*="temps-"] .rang-pastille {
        background: color-mix(in oklab, var(--temps) 12%, transparent);
        color: var(--temps);
      }

      /* ── La recherche et les outils sur une ligne ─────────────────────────────
         Le champ prenait une ligne, le depliant des filtres une autre : cent pixels
         avant le premier vendeur, pour deux gestes qu on fait rarement. Le champ
         s etire, les outils tiennent a droite. Sur telephone ils repassent dessous.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .ligne-recherche {
        /* `wrap` : le panneau des filtres passe SOUS la ligne quand il s ouvre, il ne
           s intercale pas entre le champ et les boutons. */
        display: flex; align-items: flex-start; gap: var(--e3); flex-wrap: wrap;
        margin: 0 0 var(--e3);
      }
      .ligne-recherche > .barre-recherche { flex: 1 1 auto; margin: 0; }
      @media (max-width: 700px) {
        .ligne-recherche { flex-direction: column; }
        .ligne-recherche > .barre-recherche,
        .ligne-recherche > .bloc-filtres { width: 100%; }
      }

      /* ── Le rond d initiales ──────────────────────────────────────────────────
         Une photo aurait demande un champ, un stockage et le consentement d un
         vendeur qui n en envoie pas. Deux lettres font le meme travail de reperage.
         La teinte se tire du nom : le meme vendeur garde sa couleur partout.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .rond-initiales {
        display: inline-flex; align-items: center; justify-content: center;
        width: 2.3rem; height: 2.3rem; flex: none; border-radius: 50%;
        font-size: .82rem; font-weight: 700; letter-spacing: .02em;
        background: var(--i-fond, var(--surface)); color: var(--i-encre, var(--encre-2));
      }
      .rond-initiales[data-teinte="0"] { --i-fond: #e9f1fb; --i-encre: #1d5fb4; }
      .rond-initiales[data-teinte="1"] { --i-fond: #e8f4ee; --i-encre: #0f7a3d; }
      .rond-initiales[data-teinte="2"] { --i-fond: #fdf3e0; --i-encre: #8a5a00; }
      .rond-initiales[data-teinte="3"] { --i-fond: #f3edfa; --i-encre: #6b3fa0; }
      .rond-initiales[data-teinte="4"] { --i-fond: #fbeceb; --i-encre: #a4231c; }
      .rond-initiales[data-teinte="5"] { --i-fond: #e6f3f4; --i-encre: #14666e; }
      .meta-vendeur {
        margin: -.15rem 0 var(--e3); font-size: .82rem; color: var(--encre-3);
      }
      /* La ligne qui dort se signale elle-même. Pas une alerte — l'agent décide —
            mais une couleur d'attente, qu'on repère en parcourant sans la lire. */
      .meta-vendeur.en-souffrance { color: var(--attention); font-weight: 600; }

      /* Joindre le vendeur depuis la liste : les trois canaux à droite de son nom.
            `z-index` au-dessus du lien étendu, sinon un clic sur « Appeler »
            ouvrirait la fiche au lieu de composer le numéro — même piège que le
            dépliant des autres biens. */
      /* ── Les deux signaux d'une carte ──────────────────────────────────────
            ROUGE : du nouveau à lire. C'est une bonne nouvelle — le vendeur
            travaille — et le compte dit combien de biens ont bougé.
            ORANGE : quelque chose cloche. Diagnostic à surveiller, ou dossier qui
            dort depuis plus de deux semaines.

            Deux couleurs parce que ce sont deux gestes différents : on ouvre l'un
            pour lire, l'autre pour agir. Les fondre ferait ouvrir un dossier
            vivant en craignant un problème. */
      .signaux-vendeur {
        display: inline-flex; align-items: center; gap: var(--e2);
        margin-left: auto; flex: 0 0 auto;
      }
      .signe-attention { display: inline-flex; color: var(--attention); }

      /* Le point sur la ligne du bien : 7 px, sans texte. Il dit « celui-ci » —
            savoir qu'il y a du nouveau sans savoir où oblige à ouvrir les trois. */
      /* Le point se colle AU NOM du bien : il le qualifie. Posé avant, en
            élément libre, il flottait dans la gouttière et se lisait comme une
            puce de liste. */
      .point-nouveau {
        display: inline-block; width: 7px; height: 7px; margin-right: .35rem;
        border-radius: 999px; background: var(--danger);
        vertical-align: .08em;
      }

      /* Deux libellés d'étape, un seul visible. Le long par défaut, le court dès
            que la place manque : « Visite d'estimation planifiée » occupe deux
            lignes sur un téléphone, et une carte de trois biens en devient
            illisible. */
      .etape-courte { display: none; }

      .gestes-rapides {
        position: relative; z-index: 1;
        display: inline-flex; gap: var(--e2); flex: 0 0 auto;
      }
      .gestes-rapides .canal {
        width: 36px; min-width: 36px; height: 36px; min-height: 36px;
        padding: 0; justify-content: center;
      }
      .gestes-rapides .canal:hover { border-color: var(--accent); color: var(--accent); }

      /* Les filtres, repliés tant qu'ils ne servent pas. */
      .bloc-filtres { margin-bottom: var(--e4); }
      .bloc-filtres > summary {
        display: inline-flex; align-items: center; gap: var(--e2);
        padding: .3rem 0; cursor: pointer; list-style: none;
        font-size: .9rem; font-weight: 600; color: var(--encre-2);
      }
      .bloc-filtres > summary::-webkit-details-marker { display: none; }
      .bloc-filtres > summary:hover { color: var(--accent); }
      .bloc-filtres[open] > summary { margin-bottom: var(--e3); }
      /* Ouvert, le bloc devient un panneau : sans cadre, les menus flottaient
            au-dessus des cartes sans qu'on voie où finissaient les réglages. */
      .bloc-filtres[open] {
        padding: var(--e3) var(--e4) var(--e4);
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        background: var(--papier);
      }
      .bloc-filtres > summary::after {
        content: "▸"; display: inline-block; transition: transform .15s ease;
      }
      .bloc-filtres[open] > summary::after { transform: rotate(90deg); }

      /* Les exports : le libellé, puis ce qu'il contient. Deux boutons nommés
            « Exporter » ne se distinguaient pas — il fallait les essayer. */
      .exports-liste {
        display: grid; grid-template-columns: auto 1fr; gap: .35rem var(--e3);
        align-items: baseline; margin: var(--e4) 0 0;
        padding-top: var(--e3); border-top: 1px solid var(--trait);
        font-size: .88rem;
      }
      .exports-liste > a { display: inline-flex; align-items: center; gap: .3rem; }
      @media (max-width: 34rem) {
        .exports-liste { grid-template-columns: 1fr; gap: .1rem var(--e2); }
        .exports-liste > span { margin-bottom: var(--e2); }
      }

      /* Une ligne de bien : nom, étape, avancement. `min-width:0` sur le nom lui
            permet de se tronquer plutôt que de pousser la pastille hors de la
            carte — un titre long ne doit pas casser la mise en page. */
      /* Chaque bien est un COMPARTIMENT cliquable, qui mène droit à son dossier.
            Fond très léger et bordure au survol seulement : à quatre biens, quatre
            cadres pleins feraient une grille, et l'on ne lirait plus les noms.
            `z-index` au-dessus du lien étendu du nom — sans lui, un clic sur un
            bien ouvrirait la fiche du vendeur. */
      /* UNE LIGNE QUI RESTE UNE LIGNE.
            Elle passait à deux dès que son contenu dépassait d'un cheveu : le nom
            gardait sa largeur entière et c'est le pourcentage, ou la flèche, qui
            tombait à la ligne suivante. Une barre devenait alors deux fois plus
            haute que ses voisines sans que rien ne l'explique à l'oeil — l'ajout du
            numéro de dossier a suffi à le déclencher.

            Sur cet écran, c'est le NOM qui doit céder : l'étape, l'avancement et le
            pourcentage sont de largeur fixe et se lisent d'un coup d'oeil, alors
            qu'un nom tronqué reste reconnaissable — et il commence justement par le
            numéro. Sur téléphone, le nom prend une ligne entière à lui seul (voir
            plus bas) : le retour à la ligne y est voulu, il reste autorisé.

            La flèche, elle, sort du flux : décorative et visible au seul survol,
            elle n'a pas à peser dans le calcul. Sa place est réservée à droite. */
      .ligne-bien {
        position: relative; z-index: 1;
        display: flex; align-items: center; gap: var(--e2) var(--e3);
        flex-wrap: nowrap; padding: .4rem 1.6rem .4rem .6rem;
        border: 1px solid transparent; border-radius: var(--r-petit);
        background: var(--papier); text-decoration: none; color: inherit;
        transition: border-color .12s ease, background .12s ease;
      }
      .ligne-bien + .ligne-bien { margin-top: .25rem; }
      .ligne-bien:hover {
        border-color: var(--accent-bord); background: var(--accent-pale);
        color: inherit;
      }
      .ligne-bien .nom-bien {
        min-width: 0; flex: 0 1 auto; color: var(--encre-2); font-size: .95rem;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      /* Tout le reste garde sa taille : c'est le nom, et lui seul, qui rétrécit. */
      .ligne-bien .pastille, .ligne-bien .discret { flex: 0 0 auto; }
      /* La flèche n'apparaît qu'au survol : présente en permanence sur chaque
            ligne, elle ferait quatre chevrons alignés qui n'apprennent rien. */
      .ligne-bien .fleche-bien {
        position: absolute; right: .6rem; top: 50%; transform: translateY(-50%);
        display: inline-flex; opacity: 0;
        color: var(--accent); transition: opacity .12s ease;
      }
      .ligne-bien:hover .fleche-bien { opacity: 1; }
      /* TOUTES LES LIGNES SE VALENT, y compris quand il n'y en a qu'une. Le gras
            du bien unique venait d'une version où l'un d'eux était « le » bien du
            vendeur : il ne restait plus qu'un reliquat, qui faisait croire à une
            hiérarchie là où il n'y a rien à hiérarchiser. */

      /* L'avancement se VOIT avant de se lire : une barre de 3 px suffit à
            distinguer 16 % de 80 % d'un coup d'œil, là où deux chiffres demandent
            de s'arrêter. Le chiffre reste à côté pour la valeur exacte. */
      .mini-jauge {
        display: inline-block; width: 3.2rem; height: 4px; flex: 0 0 auto;
        border-radius: 999px; background: var(--trait); overflow: hidden;
      }
      .mini-jauge > span {
        display: block; height: 100%; border-radius: 999px;
        background: var(--accent);
      }

      /* Le rang de l'étape, dans la pastille elle-même : « 5/12 · Avis de valeur
            transmis ». Séparé par un filet vertical plutôt que par un point — il se
            lit comme un compteur, pas comme un mot de plus. */
      .rang-pastille {
        padding-right: .4rem; margin-right: .1rem;
        border-right: 1px solid currentColor;
        opacity: .55; font-variant-numeric: tabular-nums;
      }

      .liste-autres-biens {
        display: flex; flex-direction: column; gap: .1rem;
        margin: var(--e2) 0 0; padding-left: var(--e3);
        border-left: 2px solid var(--trait);
      }

      /* SUR TÉLÉPHONE, la ligne se cassait en trois — nom, puis pastille, puis
            pourcentage — et une carte occupait un tiers de l'écran. Le nom prend
            sa ligne, tout le reste tient sur la suivante. */
      /* ── SUR TÉLÉPHONE : deux lignes par bien, jamais trois ────────────────
            Le nom sur la première, l'étape et l'avancement sur la seconde. Chaque
            ligne de plus coûte un défilement, et une carte de trois biens qui
            occupe un écran entier fait perdre la liste de vue.

            La box se resserre aussi : moins de rembourrage, coins moins ronds —
            à cette taille, un grand arrondi mange le texte qu'il encadre. */
      @media (max-width: 34rem) {
        .etape-longue { display: none; }
        .etape-courte { display: inline; }

        .ligne-bien {
          gap: .3rem var(--e2); padding: .45rem 1.5rem .45rem .55rem;
          border-radius: 10px; flex-wrap: wrap;
        }
        /* Le nom prend une ligne pour lui : sur un téléphone, le tronquer
              couperait la commune, qui est justement ce qui distingue deux biens. */
        .ligne-bien .nom-bien {
          flex: 1 0 100%; font-size: .92rem; overflow: visible; white-space: normal;
        }
        .ligne-bien .pastille { font-size: .76rem; padding: .12rem .5rem; }
        .ligne-bien .mini-jauge { width: 2.4rem; }
        .ligne-bien .fleche-bien { display: none; }

        .tete-vendeur { gap: var(--e2); }
        .meta-vendeur { white-space: normal; }
        .carte-vendeur { padding: var(--e3); }
      }

      .carte-vendeur .lien-etendu { text-decoration: none; color: inherit; }
      .carte-vendeur .lien-etendu::after {
        content: ""; position: absolute; inset: 0; z-index: 0;
      }
      .carte-vendeur .autres-biens { position: relative; z-index: 1; }
      .carte-vendeur .autres-biens > summary {
        display: inline-flex; align-items: center; gap: var(--e2);
        margin-top: var(--e2); padding: .15rem 0;
        font-size: .88rem; font-weight: 600; color: var(--accent);
        cursor: pointer; list-style: none;
      }
      .carte-vendeur .autres-biens > summary::-webkit-details-marker { display: none; }
      .carte-vendeur .autres-biens > summary::before {
        content: "▸"; display: inline-block; transition: transform .15s ease;
      }
      .carte-vendeur .autres-biens[open] > summary::before { transform: rotate(90deg); }

      /* Barre d'actions d'une fiche : toujours à portée, jamais après le contenu. */
      .actions-dossier { display: flex; gap: var(--e3); flex-wrap: wrap; align-items: center; }
      @media (max-width: 620px) {
        .actions-dossier { flex-direction: column; align-items: stretch; }
        .actions-dossier > *, .actions-dossier button, .actions-dossier .bouton { width: 100%; }
      }

      /* Résumé du bien, qui se construit au fil de la saisie. */
      .resume-bien {
        display: flex; flex-wrap: wrap; gap: var(--e2); margin: 0 0 var(--e3);
      }
      .resume-bien span {
        padding: .25rem .7rem; border-radius: 999px; font-size: .87rem; font-weight: 600;
        background: var(--accent-pale); color: var(--accent-fonce);
      }

      /* --- Bandeau de progression, colle sous l en-tete pendant la saisie ---
         SA POSITION SUIT LA HAUTEUR REELLE DE L EN-TETE, publiee dans --h-entete par
         public/entete.js. Elle a longtemps valu 62px en dur. C etait juste, puis on a
         ajoute la photo du conseiller, sa fonction et le nom de son reseau : l en-tete
         est passe a 121px sur telephone et la jauge verte est passee DERRIERE le nom.
         Il n existe pas de bon nombre fixe, la hauteur dependant de la longueur du nom
         du reseau, qui passe a la ligne ou non selon l agent et selon l ecran.
         Le repli de 121px sert quand le script ne tourne pas : approximatif, pas casse.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .bandeau-progression {
        /* COLLE A L EN-TETE, sans le moindre interstice. Il y a eu un var(--e2) ici,
           pour l aerer : dans ces huit pixels, le texte du formulaire defilait a
           decouvert entre deux blocs blancs. L aeration se fait par le capitonnage,
           a l interieur, ou elle ne laisse rien passer. */
        position: sticky; top: var(--h-entete, 121px);
        z-index: 10; background: var(--surface);
        padding: var(--e4) 0 var(--e3); margin-bottom: var(--e4);
        border-bottom: 1px solid var(--trait);
      }

      /* --- Le bouton d estimation, dans le bandeau et non plus colle en bas ---
         Il vivait dans une barre fixe au bas de l ecran, toujours presente, grisee et
         libellee « Encore N informations ». Trois defauts : elle mangeait une bande de
         l ecran du debut a la fin, elle poussait la bulle d aide vers le haut, et le
         vendeur touchait un bouton mort. Ce qui restait a faire est deja ecrit juste
         au-dessus, dans la liste des manquants.
         Ici, il n apparait qu au moment ou il devient cliquable, et le bandeau etant
         colle en haut, il reste a portee ou qu on soit dans le formulaire. */
      .action-palier { margin: var(--e3) 0 0; }
      .action-palier button { display: block; width: 100%; margin: 0; }

      /* --- LA PLEINE LARGEUR A ETE ANNULEE le 2026-08-04 ---
         Le bandeau debordait jusqu aux bords de l ecran, pour supprimer les deux
         bandes de fond visibles de chaque cote quand il se collait en haut. Le
         resultat cassait l alignement : le bandeau depassait de la carte du
         formulaire, et le regard ne suivait plus une seule colonne.
         On garde donc la largeur du compartiment. Les bandes de chaque cote ne sont
         pas un defaut, c est la carte qui continue derriere. */

      /* --- Frise des parties du formulaire de saisie (agent) ---
         La premiere version alignait des boutons ovales : rien ne disait qu ils se
         suivent. Un numero dans un rond, un fil qui relie les ronds, une coche quand
         la partie est faite. C est la grammaire de la frise des etapes du dossier,
         celle que l agent lit deja tous les jours.
         Sans le script, toutes les parties sont affichees a la suite : la frise reste
         lisible comme un sommaire, ce qu elle est aussi.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .frise-parties {
        overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
        margin: 0 calc(-1 * var(--e3)) var(--e4); padding: var(--e3) var(--e3) var(--e2);
      }
      .frise-parties::-webkit-scrollbar { display: none; }
      /* Le fil passe DERRIERE les ronds, sur toute la largeur deroulee : c est lui
         qui transforme des boutons voisins en une suite. */
      .piste-parties {
        position: relative; display: flex; align-items: flex-start;
        gap: .15rem; width: max-content; min-width: 100%;
      }
      .piste-parties::before {
        content: ""; position: absolute; top: 15px; left: 2.2rem; right: 2.2rem;
        height: 2px; background: var(--trait); z-index: 0;
      }
      .etape-partie {
        position: relative; z-index: 1; flex: none;
        display: flex; flex-direction: column; align-items: center; gap: .25rem;
        width: 5.6rem; padding: 0 .1rem; min-height: 0;
        border: none; background: none; cursor: pointer; text-align: center;
        /* Le texte d une etape se selectionnait au clic : on passait d une partie a
           l autre en laissant derriere soi des libelles surlignes en bleu. Un bouton
           n est pas du texte a copier. */
        -webkit-user-select: none; user-select: none;
        -webkit-tap-highlight-color: transparent;
      }
      .rond-partie {
        width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
        border: 2px solid var(--trait); background: var(--surface); color: var(--encre-3);
        font-size: .9rem; font-weight: 700; flex: none;
        transition: background .18s ease, border-color .18s ease, color .18s ease;
      }
      .rond-partie svg { width: 15px; height: 15px; }
      /* Deux lignes reservees : sans cette hauteur, « Equipements et confort » passait
         a la ligne et poussait son compteur sous celui des voisins — la frise perdait
         son alignement, donc sa lecture d un coup d oeil. */
      .nom-partie {
        font-size: .72rem; line-height: 1.15; color: var(--encre-3); font-weight: 600;
        min-height: 2.3em; display: flex; align-items: flex-start; justify-content: center;
      }

      /* Le titre repetait mot pour mot la partie selectionnee dans la frise, compteur
         compris. On ne l efface qu une fois la frise en fonctionnement : sans le
         script, ce sont ces titres qui separent les parties. */
      /* CE VERS QUOI ON DEFILE DOIT S ARRETER SOUS CE QUI COLLE EN HAUT.
         « Suivant » amenait le haut de la partie au haut de la fenetre, donc SOUS
         l en-tete et sous le bandeau de progression, qui la recouvraient : on
         croyait avoir saute un bout du formulaire. --h-collant vaut la hauteur des
         deux reunis, mesuree par public/entete.js. Le repli de 200px sert quand le
         script ne tourne pas : approximatif, jamais recouvrant.
         ATTENTION : aucun accent grave dans ce bloc. */
      .partie-saisie, .procedure-appareil, [data-partie] {
        scroll-margin-top: var(--h-collant, 200px);
      }

      .partie-saisie .titre-partie {
        display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
        font-size: 1.05rem; margin: 0 0 var(--e3);
      }
      .onglets-actifs .titre-partie { display: none; }
      .compteur-partie { font-size: .65rem; font-weight: 400; color: var(--encre-3); }

      /* Faite : le rond se remplit et porte sa coche. Le compteur disparait — il n a
         plus rien a compter, et son absence est deja une reponse. */
      .etape-partie.faite .rond-partie {
        background: var(--succes); border-color: var(--succes); color: #fff;
      }
      .etape-partie.faite .nom-partie { color: var(--encre-2); }
      /* En cours : cerclee, jamais remplie. Le remplissage veut dire « fait ». */
      .etape-partie.encours .rond-partie {
        border-color: var(--accent); color: var(--accent);
        box-shadow: 0 0 0 3px var(--accent-pale);
      }
      .etape-partie.encours .nom-partie { color: var(--encre); font-weight: 700; }
      .etape-partie.encours .compteur-partie { color: var(--accent); font-weight: 600; }
      /* « button:hover:not(:disabled) » repeint TOUT bouton en ardoise foncee : c est
         la regle generale, et elle pese plus lourd qu un simple « .etape-partie:hover ».
         Sans ce « :not(:disabled) » ici, survoler la frise couvrait l etape d un gros
         rectangle gris. Le meme piege est deja documente plus haut, aux variantes de
         boutons. Le survol ne doit toucher que le rond et le nom. */
      .etape-partie:hover:not(:disabled) { background: none; color: inherit; }
      .etape-partie:hover .nom-partie { color: var(--encre); }
      .etape-partie:hover .rond-partie { border-color: var(--accent); }

      /* SUR TELEPHONE, LA FRISE NE TIENT PAS. Neuf etapes font 642 px de piste sur un
         ecran de 375 : on en voyait quatre, et il fallait la faire glisser du doigt pour
         savoir ou l on en etait. La ligne compacte le dit en toutes lettres, et la frise
         entiere s ouvre d une pression dessus.
         Elle est fabriquee par public/frisePartie.js. Sans script, elle n existe pas et
         la frise reste affichee : c est le sommaire du repli. */
      .etape-compacte { display: none; }
      @media (max-width: 719px) {
        .etape-compacte {
          display: flex; align-items: center; gap: var(--e2); width: 100%;
          margin: 0 0 var(--e3); padding: .55rem .7rem;
          border: 1px solid var(--trait); border-radius: var(--r2);
          background: var(--surface); text-align: left; cursor: pointer;
        }
        .etape-compacte:hover:not(:disabled) { background: var(--surface); color: inherit; }
        .ec-rang {
          flex: none; font-size: .68rem; font-weight: 700; color: var(--accent);
          text-transform: uppercase; letter-spacing: .04em;
        }
        .ec-nom {
          font-size: .85rem; font-weight: 600; color: var(--encre);
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        .etape-compacte::after {
          content: ""; flex: none; margin-left: auto; margin-right: .2rem;
          width: .45rem; height: .45rem;
          border-right: 2px solid var(--encre-3); border-bottom: 2px solid var(--encre-3);
          transform: rotate(45deg) translateY(-2px); transition: transform .18s ease;
        }
        .frise-deroulee .etape-compacte::after {
          transform: rotate(-135deg) translateY(-2px);
        }
        .frise-parties { display: none; }
        .frise-deroulee .frise-parties { display: block; }
      }

      /* Repere d enregistrement. Il etait en gris, de la taille du texte autour :
         on ne le voyait pas, et un formulaire sans bouton doit dire lui-meme que le
         travail est en securite. Une pastille verte, a cote de la jauge. */
      .etat-saisie {
        display: none; align-items: center; gap: .3rem;
        padding: .2rem .6rem; border-radius: 999px;
        font-size: .8rem; font-weight: 600;
        background: var(--succes-pale); color: var(--succes);
      }
      .etat-saisie[data-etat] { display: inline-flex; }
      .etat-saisie[data-etat="cours"] { background: var(--papier); color: var(--encre-3); }
      .etat-saisie[data-etat="erreur"] { background: var(--danger-pale); color: var(--danger); }

      /* Passer d une partie a l autre depuis le bas de la page : c est la que le
         regard arrive une fois la derniere question repondue. */
      .navigation-parties {
        display: flex; align-items: center; justify-content: space-between;
        gap: var(--e3); margin-top: var(--e5);
        padding-top: var(--e4); border-top: 1px solid var(--trait);
      }
      .navigation-parties button {
        display: inline-flex; align-items: center; gap: .4rem;
        padding: .6rem 1rem; min-height: 0;
        border: 1px solid var(--trait); border-radius: 999px;
        background: var(--surface); color: var(--encre); font-weight: 600;
      }
      .navigation-parties button:hover:not(:disabled) {
        background: var(--accent-pale); border-color: var(--accent); color: var(--accent);
      }
      .navigation-parties button:disabled { opacity: .35; cursor: default; }
      /* « Terminer » n est pas un deplacement de plus : c est la sortie du
         formulaire, et elle doit se voir comme telle. */
      .navigation-parties button.nav-fin {
        background: var(--accent); border-color: var(--accent); color: #fff;
      }
      .navigation-parties button.nav-fin:hover:not(:disabled) {
        background: var(--encre); border-color: var(--encre); color: #fff;
      }
      .navigation-parties button svg { width: 16px; height: 16px; }
      .navigation-parties [data-position] { font-size: .82rem; text-align: center; }

      /* La mention qui remplace le bouton « Enregistrer ». Discrete par nature : elle
         confirme ce que la pastille verte dit deja en haut, elle ne le repete que
         parce que le bas de page est l endroit ou l on cherchait le bouton. */
      .mention-auto {
        display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
        margin-top: var(--e5); padding-top: var(--e4); border-top: 1px solid var(--trait);
      }
      .mention-auto > span { display: inline-flex; align-items: baseline; gap: .4rem; }
      .mention-auto svg { width: 15px; height: 15px; color: var(--succes); flex: none; }

      /* --- La declaration du vendeur, pre-saisie dans le constat ---
         Elle est ecrite d avance dans le champ mais PAS enregistree : la marque
         ambre dit exactement cela — « voici ce qu on m a dit, confirmez ou
         corrigez ». Sans elle, une valeur pre-saisie passerait pour un constat
         deja fait, et c est precisement ce que la fiche de visite existe pour
         eviter.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .champ-declare {
        border-color: var(--attention) !important;
        box-shadow: inset 3px 0 0 var(--attention);
        background: color-mix(in oklab, var(--attention) 5%, #fff);
      }
      .echelle.champ-declare {
        border: none !important; box-shadow: none; background: none;
        padding-left: .5rem; border-left: 3px solid var(--attention) !important;
      }
      .echelle.champ-declare label:has(input:checked),
      .echelle.champ-declare label.choisi {
        background: var(--attention); border-color: var(--attention);
      }
      .mention-declare {
        display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
        margin: .25rem 0 0; font-size: .82rem; color: var(--attention);
      }
      .mention-declare svg { width: 14px; height: 14px; flex: none; }

      /* --- La coche de relecture ---
         Posee sur une case qu un document a remplie tout seul. Discrete mais pas
         invisible : c est un geste attendu, pas une decoration. Elle disparait des
         qu on la coche, et la case redevient une case ordinaire.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS). */
      .a-valider { margin: .25rem 0 0; font-size: .82rem; }
      .a-valider label {
        display: inline-flex; align-items: center; gap: .35rem;
        cursor: pointer; color: var(--attention); font-weight: 600;
        padding: .15rem .45rem .15rem .3rem; border-radius: var(--r2);
        border: 1px solid var(--attention);
      }
      .a-valider label:hover { background: var(--attention); color: #fff; }
      .a-valider input { margin: 0; accent-color: var(--attention); }

      /* --- Une etape encore en chantier ---
         Elle reste utilisable : le suivi d un bien vendu doit fonctionner meme
         sans outil dedie. La mention dit seulement qu il n y a rien de plus a
         attendre de cet ecran aujourd hui.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .mention-chantier {
        display: flex; gap: var(--e2); align-items: flex-start;
        margin: 0 0 var(--e3); padding: var(--e2) var(--e3);
        background: var(--papier); border: 1px dashed var(--trait);
        border-radius: var(--r-petit);
        color: var(--encre-3); font-size: .85rem; line-height: 1.4;
      }
      .mention-chantier svg { flex: none; margin-top: .15rem; }

      /* --- Les confirmations passageres, en haut a droite ---
         Elles poussaient le contenu vers le bas au moment ou l on regardait
         ailleurs, et restaient bien apres avoir servi. Les pastilles d ETAT des
         pieces, elles, ne bougent pas : elles decrivent le dossier, pas ce qui
         vient de se passer.
         Les clics traversent la pile et non la bulle : la colonne ne doit pas
         intercepter les clics de la page derriere elle.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .pile-bulles {
        position: fixed; top: var(--e4); right: var(--e4); z-index: 60;
        display: flex; flex-direction: column; gap: var(--e2);
        pointer-events: none; max-width: min(22rem, calc(100vw - 2rem));
      }
      .bulle-passagere {
        pointer-events: auto; cursor: pointer;
        padding: var(--e3) var(--e4);
        background: var(--succes); color: #fff;
        border-radius: var(--r-petit); box-shadow: var(--ombre-relief);
        font-size: .95rem; font-weight: 600; line-height: 1.35;
        opacity: 0; transform: translateY(-6px);
        transition: opacity .2s ease, transform .2s ease;
      }
      .bulle-passagere.visible { opacity: 1; transform: none; }

      /* Sur telephone la pile occupe la largeur : une bulle de 22 rem collee a
         droite y masquerait la moitie de l en-tete. */
      @media (max-width: 600px) {
        .pile-bulles { left: var(--e3); right: var(--e3); max-width: none; }
      }

      @media (prefers-reduced-motion: reduce) {
        .bulle-passagere { transition: none; transform: none; }
      }

      /* --- Les chiffres convenus, sur la carte du mandat ---
         Quatre lignes qu on recopie dans l outil du reseau. Un encadre sobre :
         c est une antisèche, pas une alerte.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .chiffres-mandat {
        margin: var(--e3) 0 0; padding: var(--e3) var(--e4);
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r-petit);
      }

      /* --- Le compte a rebours du mandat ---
         Trois tons, et le ton porte l information avant que le texte soit lu :
         gris tant que le terme est loin, ambre a trois semaines, rouge une fois
         depasse. La ligne reste dans l encadre des chiffres, elle n en sort pas :
         c est une precision sur le mandat, pas une alerte de plus sur la carte.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .echeance-compte {
        display: flex; align-items: center; gap: var(--e2);
        font-size: .85rem; color: var(--encre-3);
        padding-top: var(--e2); border-top: 1px solid var(--trait);
      }
      .echeance-compte.attention { color: var(--attention); font-weight: 600; }
      .echeance-compte.danger { color: var(--danger); font-weight: 600; }
      .echeance-compte svg { flex: none; }

      /* --- Le prix qui se deduit des deux autres ---
         Prix affiche = net vendeur + honoraires. Celui des deux qui decoule des
         autres se lit, il ne se saisit plus : fond gris, curseur de lecture, et
         l operation ecrite dessous. Voir metier/honoraires.js.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      /* !important : le champ porte son style en attribut (STYLE_CHAMP), et une
         regle de feuille ne passe pas devant sans cela. */
      input[data-calcule] {
        background: color-mix(in oklab, var(--encre-3) 13%, #fff) !important;
        border-color: transparent !important;
        box-shadow: inset 3px 0 0 var(--encre-3);
        color: var(--encre); cursor: default; font-weight: 600;
      }
      input[data-calcule]:focus { outline: none; }
      .note-prix {
        margin: .3rem 0 0; font-size: .82rem; color: var(--encre-2); font-weight: 500;
      }
      .note-prix[hidden] { display: none; }

      /* Suggestions d adresse (Base Adresse Nationale). La boite est positionnee
         par le script juste sous le champ ; ici on ne fait que l habiller. */
      .suggestion-adresse {
        display: block; width: 100%; text-align: left; min-height: 0;
        padding: .55rem .7rem; border: 1px solid var(--trait); border-top: none;
        background: var(--surface); color: var(--encre); font-size: .9rem;
        font-weight: 400; border-radius: 0; cursor: pointer;
      }
      .suggestion-adresse:first-child { border-top: 1px solid var(--trait); border-radius: 8px 8px 0 0; }
      .suggestion-adresse:last-child { border-radius: 0 0 8px 8px; }
      .suggestion-adresse:hover:not(:disabled), .suggestion-adresse:focus {
        background: var(--accent-pale); color: var(--encre);
      }

      /* --- Les 100 % atteints ---
         Tout se jouait sur un libelle de bouton qui changeait en bas de l ecran : on
         pouvait remplir la derniere question sans rien remarquer. La jauge passe au
         vert, une phrase apparait, et le bouton s eclaire UNE fois — au passage, pas
         a chaque frappe, sans quoi le signal devient une gene.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .bandeau-progression.complet .jauge > span { background: var(--succes); }
      .annonce-complet {
        display: flex; align-items: center; gap: .4rem;
        margin: var(--e2) 0 0; padding: .45rem .7rem;
        border-radius: var(--r-petit); font-size: .9rem; font-weight: 600;
        background: var(--succes-pale); color: var(--succes);
      }
      .annonce-complet svg { width: 16px; height: 16px; flex: none; }

      @keyframes souvre {
        0%, 100% { transform: none; box-shadow: none; }
        30%, 70% { transform: translateY(-2px); box-shadow: 0 0 0 4px var(--accent-bord); }
      }
      .vient-de-souvrir { animation: souvre 1.2s ease 2; }
      /* Rien ne bouge pour qui a demande a ce que rien ne bouge. */
      @media (prefers-reduced-motion: reduce) {
        .vient-de-souvrir { animation: none; box-shadow: 0 0 0 4px var(--accent-bord); }
      }

      /* Compteur d'éléments en attente dans le menu */
      .badge {
        display: inline-block; min-width: 19px; padding: 0 5px; margin-left: 3px;
        border-radius: 999px; background: var(--danger); color: #fff;
        font-size: .72rem; font-weight: 700; line-height: 19px; text-align: center;
      }

      /* --- Échelle à crans, et cartes de choix ---
         Une liste déroulante masque l'étendue du choix au moment précis où l'on veut
         la comparer : « Calme » ne veut rien dire sans voir « Très bruyant » à côté.
         Les deux se replient tout seuls sur un écran étroit, sans point de rupture à
         maintenir. ATTENTION : pas d'accent grave dans ce bloc (CONVENTIONS §7). */
      .echelle { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .2rem; }
      .echelle label {
        flex: 1 1 5.5rem; text-align: center; cursor: pointer;
        padding: .55rem .4rem; border: 1px solid var(--trait); border-radius: 8px;
        font-size: .88rem; font-weight: 400; margin: 0; min-height: 2.6rem;
        display: flex; align-items: center; justify-content: center;
        /* Meme raison que la frise : un choix qu on tape ne doit pas se surligner. */
        -webkit-user-select: none; user-select: none;
        -webkit-tap-highlight-color: transparent;
      }
      .echelle input, .cartes-choix input { position: absolute; opacity: 0; width: 1px; height: 1px; }
      /* Variante « lettres » : les classes A a G du DPE. Des cases carrees et serrees,
         parce qu'une lettre seule n'a pas besoin d'une colonne entiere — et que la
         bande ainsi formee est celle que le vendeur a sous les yeux sur son document.
         « Non realise » garde sa largeur : ce n'est pas une lettre. */
      .echelle-lettres label { flex: 0 0 2.6rem; font-weight: 600; }
      .echelle-lettres label.large { flex: 1 1 7rem; font-weight: 400; }
      .echelle label:hover { border-color: var(--accent); }
      .echelle label:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
      .echelle label:has(input:checked), .echelle label.choisi {
        background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600;
      }

      /* Variante a choix multiples. La coche dit ce que la rangee ne dit pas : qu on
         peut en prendre plusieurs. Sans elle, on repond une fois et l on passe a la
         question suivante, persuade d avoir fini.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .echelle-multi label { gap: .35rem; }
      .echelle-multi label:has(input:checked)::before,
      .echelle-multi label.choisi::before { content: "✓"; font-weight: 700; }

      /* Effacer un choix. Un bouton radio coche ne se decoche pas : la liste
         deroulante avait son tiret, les boutons ont ce lien. Discret, car il ne sert
         qu apres une erreur. */
      .effacer-choix {
        display: inline-block; margin-top: .35rem; padding: 0; min-height: 0;
        border: none; background: none; text-decoration: underline;
        font-size: .82rem; font-weight: 400; cursor: pointer;
      }
      .effacer-choix:hover:not(:disabled) { color: var(--accent); background: none; }

      .cartes-choix {
        display: grid; gap: .5rem; margin-top: .2rem;
        grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
      }
      .cartes-choix label {
        display: flex; flex-direction: column; align-items: center; justify-content: center;
        gap: .3rem; padding: .9rem .4rem; cursor: pointer; margin: 0;
        border: 1px solid var(--trait); border-radius: 10px; text-align: center;
      }
      .cartes-choix label span { display: flex; color: var(--encre-3); }
      .cartes-choix label span svg { width: 30px; height: 30px; }
      .cartes-choix label:has(input:checked) span { color: var(--accent); }
      .cartes-choix label em { font-style: normal; font-size: .82rem; font-weight: 400; }
      .cartes-choix label:has(input:checked), .cartes-choix label.choisi {
        border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent);
        background: var(--accent-doux, rgba(13, 92, 70, .07));
      }
      .cartes-choix label:has(input:checked) em { font-weight: 600; color: var(--accent); }

      /* --- La case « Ne sais pas » et sa suite ---
         La phrase « votre conseiller verifiera sur place » restait affichee meme case
         decochee : elle se lisait alors comme un fait attache au champ, et non comme
         la consequence de la case. Elle n apparait donc qu une fois cochee — ou elle
         confirme que le choix etait le bon, ce qui est le moment ou elle sert.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .nsp {
        display: inline-flex; gap: .35rem; align-items: baseline;
        margin-top: .4rem; cursor: pointer;
      }
      .nsp .nsp-suite { display: none; opacity: .75; }
      .nsp:has(input:checked) .nsp-suite { display: inline; }

      /* --- Sélecteur de bien, côté vendeur ---
         Un menu qui tient sur une ligne, quel que soit le nombre de biens et la
         longueur de leurs noms. Le triangle du navigateur est masque : on met le
         notre, qui pivote a l ouverture.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .choix-bien { position: relative; margin: 0 0 var(--e4); max-width: 34rem; }
      .choix-bien > summary {
        display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
        padding: .65rem .9rem; cursor: pointer; list-style: none;
        border: 1px solid var(--trait); border-radius: var(--r-grand);
        background: var(--surface);
      }
      .choix-bien > summary::-webkit-details-marker { display: none; }
      .choix-bien > summary::marker { content: ""; }
      .choix-bien > summary::after {
        content: ""; flex: none; width: .5rem; height: .5rem;
        border-right: 2px solid var(--encre-3); border-bottom: 2px solid var(--encre-3);
        transform: rotate(45deg) translate(-2px, -2px); transition: transform .15s;
      }
      .choix-bien[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
      .choix-bien > summary:hover { border-color: var(--accent); }
      /* Le :not(.ligne-bien) ci-dessous : depuis que la liste deroulee affiche des
         compartiments,
         cette regle leur imposait une colonne — nom, pastille, jauge et fleche
         s empilaient et debordaient de la boite. Le compartiment sait se mettre en
         page tout seul. */
      .choix-bien > summary > span, .choix-bien-liste a:not(.ligne-bien) {
        display: flex; flex-direction: column; gap: .1rem; min-width: 0; flex: 1 1 auto;
      }
      .choix-bien summary strong, .choix-bien-liste strong {
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      .choix-bien summary .discret, .choix-bien-liste .discret { font-size: .85rem; }

      .choix-bien-liste {
        position: absolute; left: 0; right: 0; top: calc(100% + .3rem); z-index: 30;
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r-grand); box-shadow: var(--ombre-relief);
        padding: .3rem; display: grid; gap: .15rem;
      }
      .choix-bien-liste a:not(.ligne-bien) {
        padding: .55rem .6rem; border-radius: 8px; text-decoration: none; color: var(--encre);
      }
      .choix-bien-liste a:not(.ligne-bien):hover { background: var(--papier); }
      /* La liste ne depasse jamais l ecran : au-dela de quatre ou cinq biens elle
         defile au lieu de sortir par le bas. */
      .choix-bien-liste { max-height: 60vh; overflow-y: auto; }
      .choix-bien-pied { border-top: 1px solid var(--trait); padding: .4rem .6rem .2rem; }

      /* --- Onglets d'un bien, côté vendeur ---
         Deux entrées seulement : il n'y a que deux questions qu'il se pose. La barre
         défile horizontalement si la place manque, plutôt que de casser sur deux
         lignes. ATTENTION : pas d'accent grave dans ce bloc (CONVENTIONS §7). */
      /* --- Les onglets d un bien : des segments, plus un soulignement ---
         Un texte gris souligne de deux pixels se noyait sur un fond blanc : on ne
         voyait pas qu il y avait deux vues, et « Mon bien » n etait jamais ouvert.
         Un bloc segmente se lit comme un interrupteur — on voit les deux choix ET
         celui qui est actif, sans avoir a chercher le trait.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .onglets {
        display: flex; gap: .2rem; margin: 0 0 var(--e5);
        padding: .25rem; border-radius: 999px;
        background: var(--papier); border: 1px solid var(--trait);
        overflow-x: auto; scrollbar-width: none;
      }
      .onglets::-webkit-scrollbar { display: none; }
      .onglet {
        flex: 1 1 0; min-width: max-content;
        padding: .55rem 1rem; border-radius: 999px;
        text-align: center; white-space: nowrap; text-decoration: none;
        color: var(--encre-3); font-weight: 600; font-size: .95rem;
        transition: background .15s ease, color .15s ease;
        -webkit-user-select: none; user-select: none;
      }
      .onglet:hover { color: var(--encre); }
      /* L actif est REMPLI, pas souligne : c est ce qui se voit du coin de l oeil. */
      .onglet.actif {
        background: var(--surface); color: var(--accent);
        box-shadow: 0 1px 2px rgba(16, 20, 28, .08);
      }

      /* Le titre du bien, en tete de son espace. Il tenait sur trois lignes — le
         selecteur, le titre, l adresse — pour dire la meme chose. */
      /* Un h1, mais a la taille d un titre de bloc : c est le nom d un bien, pas
         celui de l application. Le poids fait le titre, pas la hauteur. */
      .titre-bien-entete {
        display: block; font-size: 1.35rem; font-weight: 800;
        line-height: 1.2; margin: 0;
      }
      .sous-titre-bien {
        display: block; margin: .15rem 0 0;
        font-size: .9rem; font-weight: 400; color: var(--encre-3);
      }
      /* LE SELECTEUR DOIT SE VOIR. Sans fond ni bordure, on le prenait pour un titre
         decore d un chevron : le vendeur a deux biens ne trouvait pas comment
         passer de l un a l autre. Il garde son allure de titre, mais reprend une
         surface, une bordure et un compteur qui dit ce qu il y a derriere. */
      .choix-bien-titre { margin-bottom: var(--e4); max-width: none; }
      .choix-bien-titre > summary {
        gap: var(--e2); padding: .7rem .9rem;
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r);
        transition: border-color .15s ease, background .15s ease;
      }
      .choix-bien-titre > summary:hover {
        border-color: var(--accent-bord); background: var(--accent-pale);
      }
      .choix-bien-titre[open] > summary { border-color: var(--accent); }
      /* Le compteur porte l accent : c est LUI qui dit qu il y a autre chose a voir,
         et il se lit avant le chevron. */
      .indice-changer {
        display: inline-flex; align-items: center; gap: .3rem; flex: none;
        margin-left: auto; margin-right: .2rem;
      }
      .indice-changer-texte {
        padding: .2rem .55rem; border-radius: 999px;
        background: var(--accent); color: #fff;
        font-size: .78rem; font-weight: 700; white-space: nowrap;
      }

      /* --- Le « i » et sa bulle ---
         La pastille reste discrète tant qu'on ne la cherche pas ; la bulle s'ouvre
         dans la couche supérieure du navigateur, donc au-dessus de tout et jamais
         rognée par une carte. Fermeture au clic à côté ou avec Échap, sans script.
         ATTENTION : pas d'accent grave dans ce bloc (CONVENTIONS §7). */
      .pastille-i {
        display: inline-flex; align-items: center; justify-content: center;
        /* min-height:0 est INDISPENSABLE : la règle générale des boutons impose
           46 px, et un min-height l'emporte toujours sur un height. Sans lui, la
           pastille s'étire en capsule verticale au lieu de rester ronde. */
        width: 1.2rem; height: 1.2rem; min-height: 0; padding: 0; margin-left: .4rem;
        vertical-align: middle; border: 1px solid var(--trait); border-radius: 999px;
        background: none; font-size: .72rem; font-weight: 700; font-style: italic;
        color: var(--encre-3); cursor: pointer; line-height: 1;
      }
      .pastille-i:hover { border-color: var(--accent); color: var(--accent); }
      .pastille-i:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

      /* --- Ce que l'application enverra toute seule ---
         Encadré et légèrement en retrait du fond de la carte : ce bloc ne décrit
         pas un geste de l'agent mais ce qui part sans lui. La distinction doit se
         voir avant d'être lue, sinon « Prochaine le 12 août » se confond avec un
         bouton qu'on croit devoir cliquer. */
      /* La zone Contact ressort en BLANC sur la carte, et non en gris clair sur
            blanc : deux gris voisins ne se distinguent pas, et le bloc se fondait
            dans la carte au lieu de s'en détacher. */
      .carte-relances {
        margin: var(--e3) 0 0; padding: var(--e4);
        border: 1px solid var(--trait); border-radius: var(--r-petit);
        background: var(--surface);
        box-shadow: 0 1px 2px rgb(0 0 0 / .04);
      }
      .tete-relances {
        display: flex; gap: var(--e3); align-items: center;
        justify-content: space-between; flex-wrap: wrap;
        margin-bottom: var(--e2);
      }
      .liste-relances {
        list-style: none; margin: 0; padding: 0;
        display: flex; flex-direction: column;
        font-size: .92rem;
      }
      /* Une ligne par relance, séparées par un filet plutôt que par du vide : à
         trois lignes serrées, l'œil doit pouvoir suivre une ligne sans glisser sur
         la suivante. Le lien « voir » est poussé au bout, colonne stable. */
      .liste-relances li {
        display: flex; gap: var(--e2); align-items: baseline;
        padding: .4rem 0; border-top: 1px solid var(--trait);
      }
      .liste-relances li:first-child { border-top: 0; padding-top: 0; }
      .liste-relances li > span:nth-child(2) { flex: 1 1 auto; }

      /* C'est un <button> (il ouvre une fenêtre), il doit se lire comme un lien.
            min-height:0 et le fond transparent sont OBLIGATOIRES : la règle générale
            des boutons impose 46 px et un aplat de couleur — sans ça, trois pavés
            bleus se posent au bout des trois lignes. */
      .voir-relance {
        flex: 0 0 auto; width: auto; min-height: 0; padding: 0;
        border: 0; background: none; color: var(--accent);
        font-size: .85rem; font-weight: 600; font-family: inherit;
        text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
      }
      .voir-relance:hover { color: var(--encre); }

      /* Les canaux d'envoi : une rangée qui se casse proprement sur téléphone.
         La classe .actions-dossier imposait des boutons pleine largeur, ce qui
         faisait trois barres empilées pour trois gestes équivalents.
         DEUX PIÈGES DANS UN COMMENTAIRE CSS ÉCRIT À MÊME LE TEMPLATE LITERAL, et
         les deux ont été payés ici :
         · un accent grave le referme au milieu, et l'erreur JavaScript tombe
           ailleurs dans le fichier ;
         · une fin de commentaire citée en exemple ferme le commentaire pour de
           bon — la règle qui suit est alors avalée en silence, sans erreur, et
           l'on cherche longtemps pourquoi une mise en page ne prend pas.
         Les commentaires portés par une expression JS n'ont ni l'un ni l'autre
         de ces défauts : ils ne touchent jamais au CSS produit. */
      .canaux-contact {
        display: flex; flex-wrap: wrap; gap: var(--e2);
      }
      .canaux-contact .bouton, .canaux-contact button {
        min-height: 40px; padding: .4rem .8rem; font-size: .92rem;
      }

      /* Un canal = une icône, carrée, sans légende. La cible reste à 42 px : en
            dessous, un pouce sur téléphone touche le bouton d'à côté (44 px est le
            minimum recommandé, on n'en descend pas). */
      .canaux-contact .canal {
        width: 42px; min-width: 42px; height: 42px; min-height: 42px;
        padding: 0; justify-content: center;
      }
      /* L'envoi par email passe par un <form> — un bloc, qui prenait donc toute
            la largeur et renvoyait les deux autres icônes à la ligne suivante. Le
            réduire à son contenu le remet dans la rangée. */
      .canaux-contact form { margin: 0; display: flex; flex: 0 0 auto; }
      .canaux-contact .canal:hover {
        border-color: var(--accent); color: var(--accent);
      }

      .bulle-i {
        max-width: min(30rem, calc(100vw - 2.5rem));
        padding: var(--e4); border: 1px solid var(--trait); border-radius: var(--r-grand);
        background: var(--surface); color: var(--encre);
        box-shadow: var(--ombre-relief); font-size: .95rem; line-height: 1.5;
      }
      .bulle-i p { margin: 0 0 var(--e3); }
      .bulle-i::backdrop { background: rgba(0, 0, 0, .25); }

      /* --- LA BARRE D ACTION COLLEE EN BAS A ETE SUPPRIMEE le 2026-08-04 ---
         Elle portait le bouton « Demander mon estimation » sur toute la duree de la
         saisie, grise, libelle « Encore N informations ». On l avait posee la pour
         que le vendeur voie le moment ou le bouton s allume, au lieu de le decouvrir
         en arrivant au bas d un formulaire de soixante questions.
         Elle coutait plus qu elle ne rapportait : une bande de l ecran mangee du
         debut a la fin sur un telephone, la bulle d aide poussee vers le haut, et un
         bouton mort a toucher. Le bandeau de progression, lui, est deja colle sous
         l en-tete : le bouton y reste a portee sans rien couter, et n y apparait
         qu a 100 %. Voir .action-palier, plus haut.
         Le decompte des manquants n est pas perdu, il vit dans #manquants. */

      /* OU TROUVER UN DOCUMENT. Distingue de la description : l une dit ce que
         c est, l autre ou aller le chercher, et ce sont deux questions differentes
         qu on se pose a deux moments differents. */
      .ou-trouver {
        display: flex; align-items: flex-start; gap: var(--e2);
        margin: var(--e2) 0 0; font-size: .87rem; line-height: 1.4;
        color: var(--encre-2);
      }
      .ou-trouver svg { flex: none; margin-top: .15rem; color: var(--accent); }

      /* LES DOCUMENTS D UN PROPRIETAIRE, sous son nom.
         Une indivision a trois donnait six depots d affilee, a charge de suivre les
         numeros de ligne en ligne. Groupes, on traite une personne a la fois, et
         l on voit ce qui manque POUR QUI. */
      .bloc-personne {
        margin: var(--e4) 0 0; padding: var(--e4) 0 0;
        border-top: 1px solid var(--trait);
      }
      .titre-personne {
        display: flex; align-items: center; gap: var(--e2);
        margin: 0 0 var(--e3); font-size: 1rem; color: var(--encre-2);
      }
      .titre-personne svg { color: var(--accent); }

      /* --- Un bloc de questions qui se repondent ensemble ---
         « Conditions de la vente » alignait treize questions de suite. Le bloc
         porte un titre et se detache du fond : on voit d un coup d oeil ou
         commence le prix et ou commence le mandat.
         Flex en colonne : les deux prix s intervertissent avec la propriete
         order selon qui paie les honoraires, et cela demande un contexte flex.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .bloc-champs {
        display: flex; flex-direction: column;
        margin: var(--e4) 0; padding: var(--e4);
        background: var(--papier); border: 1px solid var(--trait);
        border-radius: var(--r);
      }
      .titre-bloc {
        order: -2;
        margin: 0 0 var(--e2); font-size: 1rem; color: var(--encre);
      }
      .note-bloc { order: -1; margin: 0 0 var(--e4); font-size: .85rem; }
      .bloc-champs > [data-wrapper]:last-child { margin-bottom: 0 !important; }

      /* CE QUE LE VENDEUR DOIT FAIRE, sur la carte de l etape en cours.
         Detachee du texte gris qui la precede : celui-la decrit un etat, celle-ci
         appelle un geste, et les confondre revenait a n en lire aucun. */
      .a-faire {
        display: flex; align-items: flex-start; gap: var(--e2);
        margin: var(--e3) 0 0; padding: var(--e3) var(--e4);
        border-left: 3px solid var(--accent); border-radius: 0 var(--r-petit) var(--r-petit) 0;
        background: var(--accent-pale); color: var(--encre);
        font-size: .93rem; line-height: 1.45;
      }
      .a-faire svg { flex: none; margin-top: .15rem; color: var(--accent); }

      /* --- La page d installation ---
         Elle alignait quatre sections depliables, une par appareil : on arrivait sur
         quatre titres fermes en devant deviner lequel ouvrir, pour une page ou l on
         vient faire UNE chose, sur UN appareil, celui qu on tient. Le script ne garde
         desormais que la procedure utile ; ce qui suit lui donne l allure d une page
         de telechargement plutot que d un sommaire.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .tete-installation { text-align: center; margin-bottom: var(--e5); }
      /* L ecusson porte la PHOTO DU CONSEILLER : c est son application. Une icone de
         telephone generique y trônait, seule chose de toute l application a ne porter
         la marque de personne. Sans photo au profil, l initiale sur le degrade de sa
         couleur, comme dans l en-tete et dans la fenetre d invitation. */
      .ecusson-installation {
        display: inline-block; width: 64px; height: 64px; border-radius: 18px;
        margin-bottom: var(--e3); object-fit: cover;
        background: var(--papier); box-shadow: var(--ombre-relief);
      }
      .ecusson-lettre {
        display: inline-grid; place-items: center;
        color: #fff; font-size: 1.7rem; font-weight: 700;
        background: linear-gradient(145deg, var(--accent), var(--accent-fonce));
      }

      /* Le bouton de telechargement : VERT, et non de la couleur de l agent.
         Le vert dit « c est parti, et c est sans risque » la ou le bleu de la marque
         se confond avec tous les autres boutons de la page. C est aussi le seul
         bouton qui n envoie rien, n engage rien, et ne se defait pas. */
      .zone-telecharger { text-align: center; margin: 0 0 var(--e5); }
      .bouton-telecharger {
        display: inline-flex; align-items: center; justify-content: center; gap: var(--e2);
        margin: 0; width: 100%; max-width: 22rem;
        padding: var(--e4) var(--e5); font-size: 1.05rem; font-weight: 700;
        color: #fff; background: var(--succes); border: 0; border-radius: var(--r);
        box-shadow: 0 6px 18px rgba(15, 122, 61, .28);
      }
      .bouton-telecharger:hover:not(:disabled) {
        background: #0c6633; box-shadow: 0 8px 22px rgba(15, 122, 61, .34);
      }
      .bouton-telecharger svg { flex: none; }
      .tete-installation h1 { font-size: 1.6rem; }
      .tete-installation .plomb { max-width: 30rem; margin-inline: auto; }

      .atouts-installation {
        list-style: none; margin: 0 0 var(--e5); padding: 0;
        display: flex; flex-direction: column; gap: var(--e2);
        max-width: 26rem; margin-inline: auto;
      }
      .atouts-installation li {
        display: flex; align-items: center; gap: var(--e3);
        padding: var(--e3) var(--e4); border-radius: var(--r);
        background: var(--papier); font-size: .93rem;
      }
      .atouts-installation svg { flex: none; color: var(--accent); }

      /* Les quatre appareils, en cartes touchables plutot qu en titres a deplier.
         Deux colonnes sur telephone : quatre lignes auraient repousse la procedure
         hors de l ecran, et c est elle qu on vient lire. */
      .choix-appareil {
        display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--e3);
        margin: 0 0 var(--e5);
      }
      @media (min-width: 620px) {
        .choix-appareil { grid-template-columns: repeat(4, 1fr); }
      }
      .carte-appareil {
        display: flex; flex-direction: column; align-items: center; gap: var(--e2);
        padding: var(--e4) var(--e2); min-height: 92px; justify-content: center;
        border: 1px solid var(--trait); border-radius: var(--r);
        background: var(--surface); color: var(--encre);
        text-decoration: none; text-align: center; font-size: .85rem; font-weight: 600;
        line-height: 1.25;
        transition: border-color .15s ease, transform .12s ease, box-shadow .15s ease;
      }
      .carte-appareil svg { color: var(--encre-3); }
      .carte-appareil:hover {
        border-color: var(--accent-bord); text-decoration: none;
        transform: translateY(-1px); box-shadow: var(--ombre);
      }
      .carte-appareil:hover svg { color: var(--accent); }

      /* L appareil reconnu, ou celui qu on vient de toucher. La detection met en
         avant, elle n enferme pas : les trois autres restent cliquables. */
      .carte-appareil.appareil-choisi {
        border-color: var(--accent); background: var(--accent-pale);
        color: var(--accent-fonce); box-shadow: 0 0 0 1px var(--accent);
      }
      .carte-appareil.appareil-choisi svg { color: var(--accent); }

      /* LA CARTE QUI INSTALLE VRAIMENT le dit sur elle-meme.
         Un encadre au-dessus annoncait « votre navigateur sait l installer tout
         seul » : il expliquait ce que le clic allait faire, au lieu de le faire.
         Cette pastille n apparait que si le navigateur a tendu son evenement, donc
         seulement quand la promesse est vraie. */
      /* LE FOND PLEIN NE VAUT QUE POUR LA CARTE SELECTIONNEE.
         La classe etait posee une fois, au moment ou le navigateur tend son
         evenement, et plus jamais retiree : la carte Android restait bleue meme
         apres qu on eut choisi iPhone, et deux cartes paraissaient actives a la
         fois. La mention reste sur les autres, en petit : elles peuvent encore
         installer, elles ne sont simplement plus celle qu on regarde. */
      .carte-appareil.carte-installe::after {
        content: "Installer en un clic";
        font-size: .72rem; font-weight: 700; letter-spacing: .02em;
        text-transform: uppercase; color: var(--accent);
      }
      .carte-appareil.carte-installe.appareil-choisi {
        border-color: var(--accent); background: var(--accent);
        color: #fff; box-shadow: var(--ombre-relief);
      }
      .carte-appareil.carte-installe.appareil-choisi svg { color: #fff; }
      .carte-appareil.carte-installe.appareil-choisi::after { color: #fff; opacity: .9; }
      .carte-appareil.carte-installe.appareil-choisi:hover { background: var(--accent-fonce); }

      .etat-installation {
        margin: 0 0 var(--e5); text-align: center;
        font-size: .92rem; color: var(--succes-fonce, #0a7d32); font-weight: 600;
      }

      /* LE BLOC ENCADRE « votre navigateur sait l installer » A ETE RETIRE :
         voir .carte-installe ci-dessus, la carte porte elle-meme sa promesse. */

      .procedure-appareil { margin-bottom: var(--e4); }
      .titre-procedure {
        display: flex; align-items: center; gap: var(--e3);
        margin: 0 0 var(--e3); font-size: 1.05rem;
      }
      .titre-procedure svg { flex: none; color: var(--accent); }

      /* Un bouton qui doit passer pour un lien : il ouvre les autres procedures, ce
         qui n est pas l action principale de la page. */
      .lien-nu {
        background: none; border: 0; padding: 0; margin: 0;
        color: var(--accent); font: inherit; text-decoration: underline; cursor: pointer;
        min-height: 44px;
      }
      .lien-nu:hover:not(:disabled) { background: none; color: var(--accent-fonce); }

      /* --- Bulle d'aide, toujours à portée de main --- */
      /* LA BULLE FLOTTE AU-DESSUS DE LA PAGE, DONC ELLE EN CACHE LE BAS.
         Sur un téléphone, le dernier champ d'un formulaire passait derrière : on le
         voyait à moitié, et le doigt tombait sur « Aide » en voulant le remplir. La
         page se réserve donc la hauteur de la bulle, une fois pour toutes. */
      body { padding-bottom: 5.5rem; }
      @media (min-width: 720px) { body { padding-bottom: 4.5rem; } }

      /* Le panneau se répartit en trois : l'en-tête et le formulaire restent en place,
         seule la conversation défile. On n'a jamais à remonter pour écrire. */
      /* LA CONVERSATION EST CE QU ON VIENT LIRE : elle prend toute la place que le
         reste ne prend pas, et jamais moins de treize lignes. Elle plafonnait a huit
         rem, soit deux messages visibles sur douze, pendant qu une explication de
         quatre lignes occupait le dessus du panneau. */
      /* Questions fréquentes repliées quand une conversation est en cours. */
      .faq-repliable > summary {
        cursor: pointer; list-style: none; font-size: .9rem; font-weight: 600;
        color: var(--encre-2); padding: .35rem 0;
      }
      .faq-repliable > summary::-webkit-details-marker { display: none; }
      .faq-repliable > summary::before { content: "＋ "; color: var(--encre-3); }
      .faq-repliable[open] > summary::before { content: "－ "; }
      /* Le « + » a gauche du champ, comme cote agent : deux ecrans differents, le
         meme geste. Le champ garde ses deux lignes — ici on ecrit une question, on
         ne repond pas du tac au tac. */
      .ligne-ecriture { display: flex; align-items: flex-end; gap: var(--e2); }
      .ligne-ecriture textarea { flex: 1; min-width: 0; margin: 0; }
      .ligne-ecriture .joindre { margin-bottom: 0; }
      .bulle-msg { padding: .55rem .8rem; border-radius: 10px; margin-bottom: var(--e2); font-size: .93rem; }
      /* Reprises du style ecrit sur chaque bulle : ecrites la, elles l emportaient sur
         toute regle d ecran, et rien ne pouvait les resserrer sur un grand ecran. */
      .fil-conv .bulle-msg { max-width: 78%; }
      .fil-conv .bulle-msg.de-agent { margin-left: auto; }
      /* « Lu », sous le dernier message qu on a envoye — et sous lui seul. Discret et
         aligne a droite : c est une confirmation, pas une parole. */
      .accuse-lu {
        display: block; margin-top: .15rem; text-align: right;
        font-size: .68rem; font-weight: 600; letter-spacing: .04em;
        color: var(--encre-3);
      }
      .fil-conv #dernier { scroll-margin-top: 90px; }
      /* ⚠️ CE QU ON ECRIT SOI-MEME EST VERT, ET C EST LA COULEUR QUI DIT QUI PARLE.
         Les deux fonds etaient a deux points l un de l autre : sur une capture d ecran
         comme au premier coup d oeil, on ne voyait pas qui avait ecrit quoi, et il
         fallait lire « Vous » en petit gris pour le savoir. Le vert est celui de la
         marque, deja porte par les bandeaux et les onglets. « Essaie de faire un peu de
         vert comme tu as fait ailleurs pour le design », Rodolphe, 21/08/2026.

         L encre reste foncee : ce vert est un aplat pale, pas un fond sature — du texte
         blanc dessus serait illisible des que l agent choisit une couleur claire. */
      .bulle-msg.de-agent {
        background: color-mix(in oklab, var(--accent) 20%, #fff);
        border: 1px solid color-mix(in oklab, var(--accent) 28%, #fff);
      }
      .bulle-msg.de-moi { background: var(--papier); border: 1px solid var(--trait); }

      /* ── UN ENVOI DANS L ONGLET « ENVOIS » ────────────────────────────────────────
         Trois elements, dans l ordre ou l oeil les cherche : la date a gauche, en
         colonne — c est ce qui se balaie verticalement ; la nature en etiquette ; puis
         le sujet. L ouverture est un point de couleur, pas une phrase.

         AVANT : une enveloppe, un sujet long, « voir » colle au bout, et une ligne grise
         « envoye le lundi 27 juillet a 18:34 · pas encore ouvert ». Il fallait lire
         chaque bloc en entier pour savoir de quoi il s agissait. */
      /* ⚠️ DES CARTES, ET NON DES LIGNES SEPAREES PAR UN TRAIT. Un trait ne dit pas ou
         commence et ou finit une chose : sur un ecran de quinze envois, l oeil compte
         des traits au lieu de voir des objets. Une carte se prend d un bloc, et sa
         surface entiere se touche. « Toute la zone de la notification cliquable, avec
         des ombres pour faire plus moderne », Rodolphe, 22/08/2026. */
      .ligne-envoi {
        display: flex; align-items: flex-start; gap: var(--e3);
        padding: var(--e3); margin-bottom: var(--e2);
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r); box-shadow: var(--ombre);
        color: inherit; text-decoration: none;
        transition: transform .12s var(--vif), box-shadow .12s var(--vif);
      }
      a.ligne-envoi:hover {
        text-decoration: none; color: inherit;
        transform: translateY(-1px); box-shadow: var(--ombre-relief);
      }
      a.ligne-envoi:hover .envoi-voir { color: var(--accent); }
      a.ligne-envoi:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-bord); }
      /* La colonne des dates : largeur fixe, chiffres alignes. C est elle qu on parcourt
         du regard, et une colonne qui danse ne se parcourt pas. */
      .envoi-quand {
        flex: none; width: 4.2rem; text-align: right;
        display: flex; flex-direction: column; gap: .05rem;
        font-variant-numeric: tabular-nums;
      }
      .envoi-jour {
        font-size: .8rem; font-weight: 650; color: var(--encre-2); white-space: nowrap;
      }
      .envoi-heure { font-size: .72rem; color: var(--encre-4); white-space: nowrap; }
      .envoi-corps { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
      .envoi-tete { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }
      .envoi-nature {
        font-size: .64rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
        color: var(--accent-fonce); background: var(--accent-pale);
        padding: .12rem .4rem; border-radius: 999px;
      }
      /* L etat : un point, deux mots, et rien de plus. */
      .envoi-etat {
        font-size: .7rem; color: var(--encre-3);
        display: inline-flex; align-items: center; gap: .3rem;
      }
      .envoi-etat::before {
        content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--encre-4);
      }
      .envoi-etat.etat-ouvert::before { background: var(--succes); }
      .envoi-etat.etat-clique::before { background: var(--succes); }
      .envoi-etat.etat-clique { color: var(--succes); font-weight: 600; }
      .envoi-etat.etat-echec::before { background: var(--danger); }
      .envoi-etat.etat-echec { color: var(--danger); font-weight: 600; }
      .envoi-sujet {
        font-size: .88rem; line-height: 1.3; color: var(--encre);
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
        overflow: hidden;
      }
      .envoi-voir {
        flex: none; display: grid; place-items: center; width: 32px; height: 32px;
        border-radius: 50%; color: var(--encre-4); text-decoration: none;
      }
      .envoi-voir:hover { background: var(--papier); color: var(--accent); }
      .envoi-echec .envoi-sujet { color: var(--encre-2); }

      /* ── LE JOURNAL DES MODIFICATIONS ─────────────────────────────────────────────
         Meme forme que les envois : la date a gauche en colonne, l auteur en etiquette,
         puis ce qui a change. L ancienne valeur est barree, la nouvelle en clair — c est
         le geste que fait l oeil, il n a pas besoin d une fleche pour le comprendre. */
      .liste-journal { margin-top: var(--e2); }
      /* Le journal prend la meme carte, sans l ombre : il n y a rien a ouvrir, et une
         ombre sur ce qui ne se touche pas promet un geste qui n existe pas. */
      .ligne-journal {
        display: flex; align-items: flex-start; gap: var(--e3);
        padding: var(--e3); margin-bottom: var(--e2);
        background: var(--surface); border: 1px solid var(--trait);
        border-radius: var(--r-petit);
      }
      /* L auteur prend une teinte neutre : ce n est pas une nature d envoi, et le vert
         de marque y ferait croire a une categorie. */
      .ligne-journal .envoi-nature { background: var(--papier); color: var(--encre-2); }
      .journal-champ { font-size: .82rem; font-weight: 650; color: var(--encre); }
      .journal-valeurs {
        display: flex; align-items: baseline; gap: var(--e2); flex-wrap: wrap;
        font-size: .84rem;
      }
      .journal-avant { color: var(--encre-4); text-decoration-thickness: 1px; }
      .journal-apres { color: var(--encre); font-weight: 500; }

      /* ── CE QUI A CHANGE DEPUIS LA DERNIERE VISITE ────────────────────────────
            Le meme journal, mais borne dans le temps, et pose en tete du dossier. Il
            repond a la question qu on se pose en ouvrant sur un point rouge : quoi ?

            Un liseré a gauche et rien d autre. La carte porte deja son fond et son
            trait ; un second fond colore sur toute sa surface l aurait fait crier plus
            fort que le bien qu elle annonce, et c est le bien qu on vient voir. */
      .carte-nouveautes {
        border-left: 3px solid var(--accent);
        margin-bottom: var(--e4);
      }
      /* Le dessin se cale sur la PREMIERE ligne du titre, pas sur son milieu : quand
         le titre passe a la ligne, un eclair centre verticalement se retrouve entre
         les deux et ne designe plus rien. */
      .carte-nouveautes .surtitre {
        display: flex; align-items: flex-start; gap: var(--e2);
        margin: 0; color: var(--accent-fonce);
      }
      .carte-nouveautes .surtitre svg { flex: none; margin-top: .1rem; }
      /* Une adresse web n a pas d espace ou se couper : sans ceci elle passe par-dessus
         le bord de la carte. */
      .carte-nouveautes .journal-apres { overflow-wrap: anywhere; }
      .carte-nouveautes .liste-journal { margin-top: var(--e3); }
      /* La derniere ligne ne pousse pas le bas de la carte. */
      .carte-nouveautes .liste-journal .ligne-journal:last-child { margin-bottom: 0; }
      .repli-nouveautes > summary {
        cursor: pointer; padding-top: var(--e2);
        font-size: .84rem; font-weight: 600; color: var(--accent-fonce);
      }
      .repli-nouveautes > summary:hover { text-decoration: underline; }

      /* --- Un email dans le fil de conversation ---
         Ce n est pas une bulle : une bulle est une parole echangee, et se colle a
         gauche ou a droite selon qui parle. Un email parti de l application est un
         EVENEMENT — il traverse la largeur, porte une enveloppe, et se lit en gris.
         C est ce qui empeche de confondre les deux natures dans un meme fil.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      .ligne-email {
        margin: var(--e3) 0; padding: var(--e2) 0 var(--e2) var(--e3);
        border-left: 2px solid var(--trait);
        color: var(--encre-2); font-size: .9rem;
      }
      .ligne-email svg { color: var(--encre-3); flex: none; }
      .ligne-email strong { font-weight: 600; color: var(--encre-2); }

      @media (max-width: 760px) {
      }

      /* --- Tableaux --- */
      table { width: 100%; border-collapse: collapse; }
      .tableau-defilant { overflow-x: auto; }

      /* --- Fil d'activité des clients (§11.5) --- */
      .fil-activite { display: flex; flex-direction: column; gap: .1rem; }
      /* ⚠️ LE MEME REMBOURRAGE QUE LES LIGNES DE VENDEURS, depuis que le fil vit dans
         un bloc borde comme elles. A deux dixiemes de rem, le texte touchait le bord du
         cadre alors que les listes voisines respiraient. */
      .fil-ligne {
        display: flex; gap: .7rem; align-items: flex-start;
        padding: .7rem var(--e4); border-bottom: 1px solid var(--trait);
      }
      .fil-ligne:last-child { border-bottom: 0; }
      .fil-icone {
        flex: none; display: flex; align-items: center; justify-content: center;
        width: 1.7rem; height: 1.7rem; border-radius: 50%;
        background: color-mix(in oklab, var(--accent) 10%, transparent);
        color: var(--accent);
      }
      /* Un email qui n'est pas parti n'est pas une nouvelle parmi d'autres : c'est
         la seule ligne du fil sur laquelle l'agent doit agir. */
      .fil-ligne-alerte .fil-icone {
        background: color-mix(in oklab, var(--danger) 12%, transparent);
        color: var(--danger);
      }
      /* La taille est posée sur le bloc, non sur le seul titre : ce qui s'y ajoute —
         le lien vers le message, aujourd'hui — hérite alors de la bonne taille sans
         qu'on ait à la lui redire. Portée par le titre seul, elle laissait le lien
         retomber sur celle du corps de page, plus grande que la ligne au-dessus. */
      .fil-corps { min-width: 0; flex: 1 1 auto; font-size: .93rem; }
      .fil-titre { margin: 0; line-height: 1.45; }
      .fil-quoi { color: var(--encre-2); }
      .fil-quand { margin: .1rem 0 0; font-size: .82rem; color: var(--encre-3); }
      /* --- Alerte qui porte ses cas dans le même encadré (§11.5) --- */
      /* Le motif et les personnes concernées ne font qu'un objet. Séparés, l'encadré
         annonçait « un vendeur » et la carte en dessous le nommait : deux blocs, deux
         fois la hauteur, pour une seule nouvelle. */
      .alerte-bloc {
        border: 1px solid color-mix(in oklab, var(--danger) 25%, #fff);
        border-radius: var(--r); background: var(--danger-pale);
        margin-bottom: var(--e4); overflow: hidden;
      }
      .alerte-entete {
        display: flex; gap: var(--e3); align-items: flex-start;
        padding: var(--e3) var(--e4);
        color: color-mix(in oklab, var(--danger) 85%, #000);
      }
      .alerte-entete svg { flex: none; margin-top: 2px; }
      /* Le texte explicatif garde la couleur du bloc, sans quoi « discret » le rendrait
         gris sur fond rose — illisible. */
      .alerte-entete .discret { color: inherit; opacity: .82; }

      /* Chaque cas sur fond clair : l'œil distingue le commentaire de ce sur quoi il
         faut agir, sans que le bloc se scinde en deux. */
      .alerte-ligne {
        display: flex; justify-content: space-between; align-items: center;
        gap: var(--e3); flex-wrap: wrap;
        padding: var(--e4); background: var(--surface);
        border-top: 1px solid color-mix(in oklab, var(--danger) 18%, #fff);
        color: var(--encre);
      }

      /* L'adresse qu'on est venu vérifier. En chasse fixe : toutes les lettres y
         occupent la même largeur, ce qui fait sauter aux yeux le caractère en trop ou
         le point manquant — « julie.matin@ » au lieu de « julie.martin@ ». Dans une
         police ordinaire, la différence de largeur cache l'erreur. */
      .adresse-verif {
        margin: .25rem 0 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
        font-size: .9rem; color: var(--encre); overflow-wrap: anywhere;
      }

      /* Un bouton qui se lit comme un lien : ouvrir la fenêtre du message est une
         consultation, pas une action — lui donner l'allure d'un bouton plein le
         mettrait au même rang que « Relancer » ou « Publier ».
         Il reprend donc trait pour trait l'apparence d'un « a » : même couleur, même
         soulignement, et surtout la TAILLE DU TEXTE QUI L'ENTOURE. Une taille fixe le
         faisait détonner d'une ligne à l'autre selon le contexte où il apparaît.
         « min-height » est remis à zéro : la règle générale impose 46 px aux boutons,
         hauteur faite pour le pouce, qui creusait un trou dans le fil. */
      .lien-bouton {
        background: none; border: 0; padding: 0; margin: .15rem 0 0; min-height: 0;
        width: auto; font: inherit; color: var(--accent);
        text-decoration: underline; text-underline-offset: 2px;
        text-align: left; cursor: pointer; display: inline-flex; align-items: center; gap: .3rem;
      }
      /* Un lien ne se remplit pas d'un rectangle quand la souris passe dessus : il se
         souligne. Le fond est remis à néant explicitement, faute de quoi la règle
         générale des boutons le peint en ardoise foncée. */
      .lien-bouton:hover:not(:disabled) { background: none; color: var(--accent-fonce); }

      /* --- Fenêtre de relecture d'un email --- */
      /* Ouverte par le navigateur (attribut "popover") : la politique de sécurité
         interdit le script dans la page, et une boîte de dialogue ne justifiait pas
         un fichier de script à elle seule. */
      .fenetre-mail {
        width: min(46rem, 94vw); max-height: 86vh; padding: 0; border: 0;
        border-radius: var(--r-grand); background: var(--papier);
        box-shadow: 0 1.4rem 3rem rgb(0 0 0 / .28);
        flex-direction: column; overflow: hidden;
      }
      /* La mise en page ne s'applique qu'à la fenêtre OUVERTE. Un « display » posé
         sur la règle générale écraserait le « display:none » que le navigateur
         applique aux fenêtres fermées : elles s'empileraient toutes sur la page,
         visibles et superposées. */
      .fenetre-mail:popover-open { display: flex; }
      .fenetre-mail::backdrop { background: rgb(0 0 0 / .45); }
      .fenetre-mail-tete {
        display: flex; align-items: center; justify-content: space-between; gap: var(--e4);
        padding: var(--e4); border-bottom: 1px solid var(--trait); flex: none;
      }
      .fenetre-mail-tete strong { font-size: .95rem; min-width: 0; overflow-wrap: anywhere; }
      .fenetre-mail-tete button { flex: none; width: auto; margin: 0; }
      /* Fond blanc imposé : un message est composé pour une boîte de réception, sur
         fond clair. Le laisser hériter d'un thème sombre rendrait illisible du texte
         écrit en gris foncé. */
      .fenetre-mail-cadre {
        flex: 1 1 auto; width: 100%; min-height: 24rem; border: 0; background: #fff;
      }

      /* Le meme message, mais dans un ecran a lui, avec un retour au-dessus.
         Meme fond blanc impose, et meme raison : un email est compose pour une
         boite de reception. */
      .cadre-email {
        border: 1px solid var(--trait); border-radius: var(--r-grand);
        overflow: hidden; background: #fff; box-shadow: var(--ombre);
      }
      .cadre-email-page {
        display: block; width: 100%; height: 70vh; min-height: 22rem; border: 0;
        background: #fff;
      }
      @media (max-width: 560px) {
        .cadre-email-page { height: 68vh; }
      }

      /* --- Fiche de visite terrain (§10.6) --- */
      /* Tout est dimensionné pour un pouce, debout, une main occupée par le télémètre.
         Rien ici ne descend en dessous de 44 px de cible. */
      .etat-saisie { font-size: .85rem; font-weight: 600; }
      .etat-saisie.ok { color: var(--succes); }
      .etat-saisie.attente { color: var(--attention); }

      .liste-points { margin: .4rem 0 0; padding-left: 1.1rem; }
      .liste-points li { margin: .15rem 0; }

      /* Les quatre surfaces côte à côte : c'est leur COMPARAISON qui fait le travail,
         les empiler l'une sous l'autre obligerait à faire défiler pour comparer. */
      .totaux {
        display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--e2);
        margin: 0 0 var(--e2); padding: var(--e3);
        background: var(--papier); border: 1px solid var(--trait); border-radius: var(--r);
      }
      .totaux > div { text-align: center; min-width: 0; }
      .totaux-nom { display: block; font-size: .72rem; text-transform: uppercase;
        letter-spacing: .06em; color: var(--encre-3); font-weight: 700; }
      .totaux strong { font-size: 1.05rem; }
      @media (max-width: 560px) { .totaux { grid-template-columns: repeat(2, 1fr); } }

      .ecart { margin: 0 0 var(--e4); font-size: .9rem; color: var(--encre-3); }
      /* L'écart au-delà du seuil n'est pas une information de plus : il change le prix,
         et doit se voir avant qu'on ait fini de mesurer. */
      .ecart-alerte {
        color: color-mix(in oklab, var(--danger) 85%, #000); font-weight: 650;
        background: var(--danger-pale); padding: .55rem .8rem; border-radius: var(--r-petit);
      }

      /* ═══════════ LE RELEVE DES SURFACES ═══════════
         Une piece tient sur UNE ligne : icone, nom, metres carres, options, croix.
         Quatre lignes par piece faisaient quarante-huit lignes pour un T4 avec ses
         annexes, a faire defiler d une main en tenant le telemetre de l autre. */
      .piece {
        border: 1px solid var(--trait); border-radius: var(--r);
        padding: .55rem .7rem; margin-bottom: .35rem; background: var(--surface);
      }
      .piece-ligne { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }

      /* La pastille de l icone : c est elle qui rend la liste parcourable sans lire.
         Assez discrete pour ne pas devenir le sujet de la ligne. */
      .piece-icone {
        flex: none; display: inline-flex; align-items: center; justify-content: center;
        width: 2rem; height: 2rem; border-radius: var(--r-petit);
        background: color-mix(in oklab, var(--accent) 12%, var(--surface));
        color: var(--accent);
      }
      /* ⚠️ SEUL LE NOM S ETIRE, et c est ce qui aligne la colonne des metres carres.
         Quand les options prenaient la place restante, le champ de saisie glissait de
         trente pixels selon qu une piece portait deux ou trois pastilles : la colonne
         qu on remonte du regard en mesurant n en etait plus une. */
      .piece-titre {
        flex: 1 1 7rem; min-width: 0; display: flex; align-items: center;
        gap: .4rem; flex-wrap: wrap;
      }
      .piece-titre strong { font-size: .97rem; }

      /* Une piece que l application a deduite du Palier 1, que personne n a encore
         confirmee. Le pointille dit la meme chose que le mot, pour qui parcourt. */
      .piece-proposee { border-style: dashed; }
      .piece-propose {
        flex: none; font-size: .74rem; font-style: italic;
        color: var(--encre-3); border: 1px dashed var(--trait);
        border-radius: 999px; padding: .05rem .45rem;
      }

      /* ⚠️ L UNITE EST A COTE DU CHAMP, JAMAIS DEDANS. Ecrite dedans par un
         padding-right, elle se faisait recouvrir par le nombre : la regle generale des
         input de l application l emporte en specificite sur celle d un bloc. */
      .piece-mesure { flex: none; display: flex; align-items: center; gap: .3rem; }
      /* ⚠️ LA REGLE GENERALE DES CHAMPS L EMPORTE, ET C EST POURQUOI ELLE EST RECOPIEE.
         `input:not(...)` six fois pese plus lourd que `.piece-mesure input[type=number]`
         a la cascade : le champ des metres carres est reste large de 204 px au lieu de
         86, mesure a l ecran. On reprend donc la meme chaine, comme la barre de
         recherche de l espace agent le fait deja plus bas. */
      .piece-mesure input[type=number]:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]) {
        width: 5.4rem; margin: 0; padding: .45rem .55rem; text-align: right;
        font-variant-numeric: tabular-nums;
      }
      .piece-unite { color: var(--encre-3); font-size: .85rem; }

      .piece-options {
        flex: 0 0 15.5rem; display: flex; align-items: center; gap: .3rem; flex-wrap: wrap;
      }
      .piece-note { font-size: .78rem; color: var(--encre-3); }
      .piece-supprimer { flex: none; margin: 0; margin-left: auto; }
      .piece-supprimer button { color: var(--encre-3); padding: .2rem; }
      .piece-supprimer button:hover { color: var(--danger); }

      /* Le commentaire est la deuxieme ligne, et il s efface visuellement tant qu il
         est vide : c est une precision, pas une question posee douze fois. */
      /* ⚠️ LE COMMENTAIRE NE PREND PAS UNE LIGNE PAR PIECE. Affiche en permanence, il
         doublait la hauteur du releve pour une precision qu on ecrit sur une piece sur
         dix. Il apparait des qu on touche la ligne — c est-a-dire des qu on saisit les
         metres carres, le premier geste — et reste visible s il porte deja un texte. */
      .piece-commentaire { display: none; }
      .piece:focus-within .piece-commentaire,
      .piece-commentaire-rempli { display: block; }
      input.piece-commentaire[type=text]:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]) {
        margin: .35rem 0 0; font-size: .88rem; padding: .3rem .45rem;
        border: 1px solid var(--trait); background: none; color: var(--encre);
      }
      input.piece-commentaire[type=text]:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]):focus {
        border-color: var(--accent); background: var(--surface);
      }

      /* Les options d une piece, en pastilles qu on vise du pouce, debout, sans
         regarder : c est toute l etiquette qui coche, pas le petit carre. */
      .case-piece {
        display: inline-flex; gap: .35rem; align-items: center; margin: 0;
        font-weight: 500; font-size: .78rem; cursor: pointer;
        border: 1px solid var(--trait); border-radius: 999px;
        padding: .18rem .5rem; background: var(--papier); color: var(--encre-2);
        -webkit-user-select: none; user-select: none;
      }
      .case-piece input { width: auto; min-height: 0; margin: 0; }
      /* ⚠️ LA CASE NATIVE NE DISPARAIT QUE LA OU :has EXISTE. Sans ce garde-fou, un
         navigateur sans :has aurait affiche une pastille dont rien n indique l etat,
         et sur laquelle on ne peut plus cocher. */
      @supports selector(:has(*)) {
        .case-piece input { position: absolute; opacity: 0; width: 1px; height: 1px; }
        .case-piece:has(input:checked) {
          background: var(--accent-pale); border-color: var(--accent);
          color: var(--accent); font-weight: 650;
        }
        .case-piece:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
      }
      /* Le nom d une piece qu on tape soi-meme. Il tient la place du titre, et se lit
         comme un titre : c est le nom de la piece, pas un champ de plus. */
      input.nom-piece[type=text]:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]) {
        flex: 1 1 auto; min-width: 6rem; width: auto; margin: 0; padding: .25rem .45rem;
        font-size: .97rem; font-weight: 700; font-family: inherit;
        border: 1px dashed var(--trait); border-radius: var(--r-petit);
        background: none; color: var(--encre);
      }
      .nom-piece::placeholder { font-weight: 400; font-size: .85rem; }
      .nom-piece:focus { border-style: solid; border-color: var(--accent); }
      .piece input[type=text] { margin: 0; font-size: .92rem; }
      .ajout-piece { margin: var(--e3) 0 var(--e5); }

      /* Sur telephone, les options passent sous le nom plutot que de comprimer le
         champ des metres carres, qui est ce qu on vient remplir. */
      /* Sur telephone, deux lignes : ce qu on remplit en haut, ce qu on coche en bas.
         ⚠️ LA CROIX PASSE TOUT EN BAS A DROITE. Placee entre le nom et les metres
         carres, elle se trouvait sur le trajet du pouce qui vise le champ de saisie :
         un releve efface d un geste, sans confirmation, debout dans un couloir. */
      @media (max-width: 560px) {
        .piece-icone { order: 0; }
        .piece-titre { order: 1; flex: 1 1 4rem; }
        .piece-mesure { order: 2; margin-left: auto; }
        .piece-options { order: 3; flex: 0 1 auto; }
        .piece-supprimer { order: 4; margin-left: auto; }
      }

      /* Grille d'état : cinq cibles par ligne, assez larges pour être visées sans
         regarder. Le radio natif est masqué, sa pastille prend toute la place. */
      .grille-etat { display: grid; gap: .35rem; margin-bottom: var(--e4); }
      .appreciation {
        display: flex; align-items: center; justify-content: space-between;
        gap: var(--e3); flex-wrap: wrap; padding: .4rem 0;
        border-bottom: 1px solid var(--trait);
      }
      .appreciation:last-child { border-bottom: 0; }
      .appreciation-nom { font-weight: 600; font-size: .95rem; }
      .appreciation-choix { display: flex; align-items: center; gap: .3rem; }
      .appreciation-choix label { margin: 0; }
      .appreciation-choix input { position: absolute; opacity: 0; width: 1px; height: 1px; }
      .appreciation-choix span {
        display: inline-flex; align-items: center; justify-content: center;
        width: 44px; height: 44px; border-radius: 50%;
        border: 1px solid var(--trait); background: var(--surface);
        font-weight: 650; cursor: pointer; user-select: none;
      }
      .appreciation-choix input:checked + span {
        background: var(--accent); border-color: var(--accent); color: #fff;
      }
      .appreciation-choix input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-bord); }
      .appreciation-choix .lien-bouton { font-size: .8rem; margin-left: .2rem; }
      @media (max-width: 560px) {
        .appreciation { flex-direction: column; align-items: stretch; }
        .appreciation-choix { justify-content: space-between; }
        .appreciation-choix span { width: 40px; height: 40px; }
      }

      /* --- Module d'estimation (§10.7) --- */
      /* Les chiffres de synthèse se lisent EN LIGNE, jamais empilés : c'est leur
         comparaison qui travaille, et faire défiler pour comparer revient à ne pas
         comparer du tout. */
      .synthese, .chaine, .choix-surface, .choix-methode, .trio-prix {
        display: grid; gap: var(--e2); margin: 0 0 var(--e3);
      }
      .synthese { grid-template-columns: repeat(3, 1fr); padding: var(--e3);
        background: var(--papier); border: 1px solid var(--trait); border-radius: var(--r); }
      .synthese > div { text-align: center; min-width: 0; }
      .synthese-nom { display: block; font-size: .72rem; text-transform: uppercase;
        letter-spacing: .06em; color: var(--encre-3); font-weight: 700; }
      .synthese strong { font-size: 1.05rem; }
      /* Le résultat final se distingue de la mécanique qui y mène. */
      .synthese-final { background: var(--accent-pale); border-color: var(--accent-bord); }
      .synthese-final strong { font-size: 1.25rem; color: var(--accent-fonce); }

      /* La chaîne de calcul se lit de haut en bas comme une addition posée : chaque
         ligne montre d'où vient le chiffre suivant. */
      .chaine { grid-template-columns: 1fr; gap: 0; margin-bottom: var(--e4); }
      .chaine > div { display: flex; justify-content: space-between; gap: var(--e3);
        padding: .45rem .2rem; border-bottom: 1px solid var(--trait); }
      .chaine > div span { color: var(--encre-2); }
      .chaine-total { border-bottom: 0 !important; border-top: 2px solid var(--encre) !important;
        font-size: 1.05rem; padding-top: .6rem !important; }

      .choix-surface { grid-template-columns: repeat(3, 1fr); }
      .choix-methode { grid-template-columns: repeat(2, 1fr); }
      .choix-surface label, .choix-methode label {
        margin: 0; padding: var(--e3); text-align: center; cursor: pointer;
        border: 1px solid var(--trait); border-radius: var(--r); background: var(--surface);
        font-weight: 400;
      }
      .choix-surface label.actif, .choix-methode label.actif {
        border-color: var(--accent); background: var(--accent-pale);
      }
      .choix-surface label.indisponible { opacity: .45; cursor: not-allowed; }
      .choix-surface input, .choix-methode input {
        position: absolute; opacity: 0; width: 1px; height: 1px;
      }

      .comparable {
        border: 1px solid var(--trait); border-radius: var(--r);
        padding: var(--e3); margin-bottom: var(--e2); background: var(--surface);
      }
      /* Un comparable écarté reste LISIBLE : c'est la trace du raisonnement, pas un
         déchet. Il pâlit, il ne disparaît pas. */
      .comparable-ecarte { opacity: .55; background: var(--papier); }
      .comparable-tete { display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap; }
      .comparable-tete select { width: auto; flex: 1 1 12rem; margin: 0; }
      .comparable-corps {
        display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap; margin: .4rem 0;
      }
      .comparable-corps input[type=text] { flex: 1 1 12rem; margin: 0; }
      .comparable-corps input[type=number] { width: 8rem; margin: 0; }
      .comparable-m2 { font-weight: 650; white-space: nowrap; color: var(--accent-fonce); }
      .comparable input[type=text]:last-child { margin: 0; font-size: .92rem; }

      .ajustement {
        display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap;
        margin-bottom: var(--e2);
      }
      .ajustement input[type=text] { flex: 1 1 12rem; margin: 0; }
      .ajustement input[type=number] { width: 8rem; margin: 0; }

      .bascule-retenu { display: inline-flex; align-items: center; gap: .4rem;
        margin: 0; font-weight: 400; cursor: pointer; white-space: nowrap; }
      .bascule-retenu input { width: auto; min-height: 0; margin: 0; }
      .source-inactive td { opacity: .5; }
      .trio-prix { grid-template-columns: repeat(3, 1fr); }
      .trio-prix input { margin: 0; }

      @media (max-width: 620px) {
        .synthese, .choix-surface, .trio-prix { grid-template-columns: 1fr 1fr; }
        .choix-methode { grid-template-columns: 1fr; }
      }

      /* --- Fiche de synthèse, faite pour être imprimée --- */
      .barre-impression {
        display: flex; justify-content: space-between; gap: var(--e3);
        flex-wrap: wrap; margin-bottom: var(--e4);
      }
      .fiche-estimation h2 { font-size: 1.05rem; margin-top: var(--e5); }
      .fiche-estimation h3 { font-size: .95rem; margin: var(--e3) 0 .2rem; }
      .fiche-estimation table { margin-bottom: var(--e2); }
      .fiche-estimation td, .fiche-estimation th {
        padding: .3rem .5rem; border-bottom: 1px solid var(--trait); text-align: left;
      }
      .fiche-estimation footer {
        margin-top: var(--e6); padding-top: var(--e3); border-top: 1px solid var(--trait);
        font-size: .85rem;
      }
      /* ══════ CE QUI SORT SUR LE PAPIER ══════
         À l'impression, tout ce qui sert à naviguer ou à agir disparaît : l'en-tête, le
         menu, la barre d'onglets, le pied de page, la flèche de retour et les boutons
         n'ont rien à faire sur un document remis en main propre ou à un notaire.

         ⚠️ ET C'EST CE QUE CE BLOC DISAIT SANS LE FAIRE. Il énonçait la règle en
         commentaire, puis listait les cinq sélecteurs dans UNE SEULE règle qui ne pose
         que des marges à zéro : il manquait le `display: none` et l'accolade qui l'aurait
         séparée de `main.contenu`. Aucun des éléments annoncés ne disparaissait donc.
         Constaté le 03/09/2026 en éprouvant l'impression de la fiche de mandat : la
         feuille sortait avec le logo DossFlow, le menu entier, la barre d'onglets du
         téléphone et le pied de page, autour du document.

         ⚠️ LES BOUTONS AUSSI. « Compléter ce qui manque » et les « Déposer » posés à
         côté de chaque pièce absente sont des gestes : sur papier, ce sont des taches
         d'encre qui promettent une action impossible. */
      @media print {
        header.principal, footer.principal, .barre-impression, .onglets-app,
        nav.menu, .bascule-menu, .bouton-menu, .bouton-retour, .barre-navigation,
        .barre-recherche, .rail-lateral, [popover],
        main.contenu form, main.contenu button,
        main.contenu a.bouton, main.contenu a.bouton-2,
        /* ⚠️ ET LE PARAGRAPHE QUI NE PORTAIT QUE LUI. Un bouton retiré laisse sa ligne
           vide derrière lui, avec ses marges : deux trous sur la fiche du bien, un sur
           la fiche de mandat. Vérifié sur dix pages : aucun paragraphe ne mêle du texte
           et un bouton, la règle ne peut donc pas emporter de phrase. */
        main.contenu p:has(> a.bouton), main.contenu p:has(> a.bouton-retour)
          { display: none !important; }

        main.contenu { margin: 0; padding: 0; box-shadow: none; border: 0; }
        /* Le papier porte sa propre marge ; celle de l'écran ferait une seconde bordure. */
        @page { margin: 14mm; }
        body { background: #fff; }

        /* Une carte coupée en deux entre deux feuilles se relit deux fois. */
        .synthese { break-inside: avoid; }
        .fiche-estimation section { break-inside: avoid; }
        main.contenu section.carte { break-inside: avoid; box-shadow: none; }
        tr { break-inside: avoid; }
      }

      /* La ligne qu'on vient de créer se signale une seconde : sur une page longue,
         retrouver la nouvelle parmi six identiques prend plus de temps que de la
         remplir. */
      .ligne-nouvelle { animation: surligner 1.4s ease-out 1; }
      @keyframes surligner {
        from { background: var(--accent-pale); border-color: var(--accent); }
        to   { background: transparent; }
      }

      /* --- Pied de page --- */
      footer.principal {
        max-width: 68rem; margin: 0 auto var(--e7); padding: 0 var(--e5);
        color: var(--encre-3); font-size: .88rem; text-align: center;
      }
      footer.principal nav { display: flex; gap: var(--e4); justify-content: center; flex-wrap: wrap; }
      footer.principal a { color: var(--encre-3); text-decoration: none; }
      footer.principal a:hover { color: var(--encre-2); text-decoration: underline; }
      /* Réseaux du conseiller : présents pour qui les cherche, discrets sinon. */
      footer.principal nav.reseaux { gap: var(--e2); margin-bottom: var(--e3); }
      footer.principal nav.reseaux a {
        display: inline-flex; align-items: center; justify-content: center;
        width: 40px; height: 40px; border-radius: 50%;
        border: 1px solid var(--trait); color: var(--encre-3);
        transition: color .15s ease, border-color .15s ease;
      }
      footer.principal nav.reseaux a:hover {
        color: var(--accent); border-color: var(--accent-bord); text-decoration: none;
      }
      footer.principal .editeur { font-size: .78rem; opacity: .75; margin-top: var(--e2); }

      /* --- Mobile --- */
      @media (max-width: 760px) {
        main.contenu { margin: var(--e3); padding: var(--e5) var(--e4); border-radius: var(--r); }
        h1 { font-size: 1.5rem; }
        .barre { flex-wrap: wrap; padding: var(--e3) var(--e4); }
        .bouton-menu {
          display: inline-flex; align-items: center; gap: var(--e2); cursor: pointer;
          min-height: 44px; padding: .5rem .85rem; font-weight: 600; font-size: .95rem;
          color: var(--encre); background: var(--surface);
          border: 1px solid var(--trait); border-radius: var(--r-petit);
        }
        .bascule-menu:focus-visible + .bouton-menu { outline: none; box-shadow: 0 0 0 3px var(--accent-bord); }
        .bouton-menu .fermer, .bascule-menu:checked + .bouton-menu .ouvrir { display: none; }
        .bascule-menu:checked + .bouton-menu .fermer { display: inline-flex; }
        nav.menu { display: none; width: 100%; }
        .bascule-menu:checked ~ nav.menu {
          display: flex; flex-direction: column; gap: 2px;
          margin-top: var(--e3); padding-top: var(--e3); border-top: 1px solid var(--trait);
        }
        /* Titre et état d'une section ne tiennent pas côte à côte sur un téléphone :
           l'état passe dessous plutôt que d'être rogné par le bord de la carte. */
        details[data-groupe] > summary { flex-wrap: wrap; }
        details[data-groupe] > summary > * { min-width: 0; }
        nav.menu a { padding: .7rem .8rem; font-size: 1rem; }
        /* En colonne, le contour latéral n'a plus de sens : un simple retrait suffit. */
        nav.menu a.a-part { margin: var(--e2) 0 0; text-align: center; }
        .contacts { flex-direction: column; }
        .contacts a { width: 100%; }
        .fiche-conseiller { flex-direction: column; text-align: center; align-items: center; }
      }

      /* ── LA BARRE D'ONGLETS DU TÉLÉPHONE ──────────────────────────────────────
         Sur telephone, le menu de l espace agent etait un bouton « Menu » qui depliait
         six lignes : deux gestes, ouvrir puis choisir, avec la main qui remonte en haut
         de l ecran. En bas, chaque section est a un pouce et rien ne se deplie.

         « sur les applis mobiles le menu c est plus une barre en bas avec des dessins
         sans texte », Rodolphe, 20/08/2026.

         ⚠️ LE MOT RESTE SOUS LE DESSIN, en tres petit. Une maison, un calendrier et une
         bulle se reconnaissent ; « Vendeurs » et « Profil » sont deux silhouettes de
         personne, et rien ne les distingue sans leur nom. Le mot coute dix pixels de
         hauteur et supprime l hesitation.

         ⚠️ CINQ ONGLETS, PAS SIX. Au-dela, chaque cible descend sous les soixante
         pixels de large et le pouce touche la voisine.                            */
      .onglets-app { display: none; }
      /* ══════ LA BARRE DU BAS VAUT AUSSI POUR LA TABLETTE ══════

         « Sur tablette, les bandes en haut c est n importe quoi » — Rodolphe,
         28/08/2026. Mesure a 820 px : l en-tete blanc avec ses huit liens sur DEUX
         lignes (105 px), puis une bande grise, puis la bande verte. Trois strates
         empilees pour arriver au titre.

         La cause tient a un seuil. Le telephone remplace le menu du haut par la barre
         du bas, l ordinateur le remplace par le rail lateral — et entre les deux, de
         761 a 1023 px, il ne restait que le menu, seul et trop long.

         ⚠️ CES REGLES SONT DEPLACEES, PAS RECOPIEES. Elles vivaient dans le bloc du
         telephone ; les dupliquer aurait donne deux barres du bas a tenir a jour, et
         c est exactement le defaut qu on corrige depuis deux jours sur les onglets.
         Le reste du bloc telephone — messagerie, conversations, pied de page — ne
         bouge pas : il ne parle pas de navigation.
         ATTENTION : pas d accent grave dans ce bloc (CONVENTIONS §7). */
      @media (max-width: 1023px) {
        /* 70 pixels de barre plus les 12 qui la separent du bord : mesure a l ecran,
           pas calculee de tete. */
        body.espace-agent, body.espace-client { --h-onglets: 82px; }
        .espace-agent .onglets-app,
        .espace-client .onglets-app {
          display: grid; grid-template-columns: repeat(5, 1fr);
          position: fixed; z-index: 45;
          left: max(12px, env(safe-area-inset-left, 0px));
          right: max(12px, env(safe-area-inset-right, 0px));
          /* ⚠️ DOUZE PIXELS AU-DESSUS DE LA ZONE SÛRE, ET NON DOUZE PIXELS DU BORD.
                Le maximum des deux posait la barre AU NIVEAU du trait de retour a
                l accueil des que celui-ci depassait douze pixels — soit toujours, sur
                un iPhone recent, ou il en mesure trente-quatre. On additionne donc au
                lieu de comparer. Sans encoche, l inset vaut zero et la barre ne bouge
                pas d un pixel. */
          bottom: max(12px, calc(env(safe-area-inset-bottom, 0px) + 10px));
          /* ⚠️ LA MEME COULEUR QUE LE RAIL DE L ORDINATEUR. « Dans la barre de menu en
             bas qui est sur smartphone, est-ce qu on peut la mettre de la meme couleur
             que la barre laterale sur PC ? » — Rodolphe, 27/08/2026. Les deux font le
             meme travail — aller d une section a l autre — et n avaient rien en commun :
             un rail anthracite sur ordinateur, une barre blanche sur telephone.

             Le flou reste, et il compte : la barre flotte au-dessus du contenu, et sans
             lui on verrait le texte defiler derriere un noir opaque. La couleur est donc
             posee a quatre-vingt-huit pour cent, pas en aplat. */
          background: color-mix(in oklab, #101512 88%, transparent);
          -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
          border: 1px solid rgba(255,255,255,.1); border-radius: 999px;
          box-shadow: 0 6px 24px rgba(8, 12, 10, .3);
          padding: .3rem .4rem;
        }
        /* ⚠️ PLUS HAUTE QUE LA MAQUETTE, ET C EST VOULU. Dessinee a 56 pixels elle
           paraissait juste sur un ecran d ordinateur ; sur un vrai telephone, a cote du
           trait de retour a l accueil d iOS, elle se lisait comme une bande secondaire.
           « la barre en bas est trop petite », Rodolphe, 20/08/2026. */
        .onglet-app {
          position: relative; display: flex; flex-direction: column; align-items: center;
          justify-content: center; gap: .18rem; padding: .45rem .1rem; min-height: 58px;
          border-radius: 20px;
          color: rgba(255,255,255,.62); font-size: .64rem; font-weight: 700;
          letter-spacing: .02em; text-decoration: none;
          /* Le doigt appuie pour ouvrir, jamais pour zoomer : sans cette ligne le
             navigateur garde un instant l appui en reserve, au cas ou un second
             viendrait — et l onglet parait ne pas repondre. */
          touch-action: manipulation;
        }
        /* Trois entrees chez le vendeur, cinq chez l agent : la grille se compte
           toute seule plutot que d etre ecrite deux fois. */
        .espace-client .onglets-app { grid-template-columns: repeat(3, 1fr); }
        .onglet-app svg { width: 24px; height: 24px; }
        .onglet-mot { max-width: 100%; overflow: hidden; text-overflow: ellipsis;
                      white-space: nowrap; }
        /* ⚠️ LE SURVOL N EXISTE QUE LA OU IL Y A UN CURSEUR. Sur un ecran tactile, le
           navigateur fait tenir l etat de survol apres l appui : l onglet qu on vient
           de quitter reste eclairci, et sur iOS un premier appui peut ne servir qu a
           poser ce survol. La regle est donc reservee aux appareils qui savent
           survoler. */
        @media (hover: hover) {
          .onglet-app:hover { color: rgba(255,255,255,.85); text-decoration: none; }
        }
        .onglet-dessin { position: relative; display: grid; place-items: center; }
        /* ⚠️ L ONGLET ACTIF SE RECONNAIT SANS LIRE : une pastille pleine derriere
           l icone ET le mot, ET l encre pleine. La seule couleur ne suffit pas, elle
           disparait pour un daltonien — et le trait colle en haut de la barre n a plus
           de bord ou se poser depuis qu elle flotte. */
        /* ⚠️ ET L ONGLET COURANT NE PREND PLUS LA COULEUR D ACCENT DU CONSEILLER, pour
           la meme raison que dans le rail : elle est choisie pour se lire sur du blanc,
           et devient un trou sur ce fond-la. */
        .onglet-app.actif {
          color: #fff; background: rgba(255,255,255,.14);
        }
        .pastille-onglet {
          position: absolute; top: -5px; left: 12px; min-width: 16px; height: 16px;
          padding: 0 .2rem; border-radius: 9px; background: var(--danger); color: #fff;
          font-size: .58rem; font-weight: 800; display: grid; place-items: center;
        }
        /* La barre REMPLACE le menu deroulant : deux navigations vers les memes pages
           feraient hesiter, et le bouton « Menu » reprendrait la place gagnee en haut. */
        .espace-agent .bouton-menu,
        .espace-agent nav.menu,
        .espace-agent .bascule-menu:checked ~ nav.menu { display: none; }
        /* ⚠️ ET L EN-TETE ENTIER AVEC EUX. Vide de son menu, il ne portait plus que le
           logo DossFlow et 74 pixels de blanc en haut de chaque ecran : dans une
           application installee, on ne remet pas le nom du logiciel sur chaque page.
           Le logo ramenait a l accueil, ce que fait l onglet « Aujourd hui ».
           « il y a encore la barre tout en haut avec DossFlow », Rodolphe, 20/08/2026.
           Il reste entier sur ordinateur, ou il n y a pas de barre d onglets. */
        .espace-agent header.principal { display: none; }
      }

      @media (max-width: 760px) {
        /* ⚠️ LES COINS ARRONDIS DE L ECRAN ROGNENT LE PREMIER ET LE DERNIER ONGLET.
           La barre allait d un bord a l autre : sur un telephone dont la dalle est
           arrondie, « Aujourd hui » et « Profil » se retrouvent sous la courbe du
           verre, coupes en biais. Aucune mesure du navigateur ne le signale, la barre
           fait bien 375 pixels de large ; c est l ecran qui n est pas un rectangle.
           Vu par Rodolphe sur son telephone le 20/08/2026.

           ⚠️ UNE BORNE BASSE PLUTOT QU UNE VALEUR FIXE. En paysage, l encoche mange davantage
           que douze pixels d un cote : la marge de securite du systeme l emporte alors,
           et le retrait minimal sert le reste du temps, ou elle vaut zero. */
        /* ⚠️ LA BARRE FLOTTE, ELLE NE SE COLLE PLUS AU BORD. Rodolphe a envoye la
           sienne le 21/08/2026 — « j aime beaucoup la barre du bas si on peut
           l utiliser pour nos cinq onglets » — et c est la reponse a son defaut
           precedent, pas seulement un gout : une barre posee d un bord a l autre
           passe sous la courbe du verre, et le premier comme le dernier onglet s y
           coupent en biais. Retiree des bords, elle ne peut plus etre rognee par une
           dalle dont on ne connait pas la forme.

           LA HAUTEUR OCCUPEE EST PUBLIEE DANS UNE VARIABLE, parce que quatre choses
           se calent dessus : la bulle d aide, son panneau, la zone de reponse d une
           conversation et le bas de page. Ecrite quatre fois a la main, elle finissait
           par ne plus valoir la meme partout. */
        /* ⚠️ QUATRE CHOSES SE DISPUTENT LE BAS DE L ECRAN. La bulle d aide, son panneau
           et la zone de reponse d une conversation s y collent deja : sans ce decalage,
           la barre d onglets leur passe dessus.

           ⚠️ ET POUR LA ZONE DE REPONSE, CE N ETAIT PAS UN DEFAUT D APPARENCE. Collee a
           zero du bas, elle passait entierement derriere la barre : le bouton « Envoyer »
           se trouvait a huit cent quatre pixels d une fenetre qui en fait huit cent
           douze, sous une barre qui commence a sept cent quarante-sept. On pouvait
           ecrire, jamais envoyer. Repondre a un vendeur depuis un telephone etait
           impossible, et rien ne le disait. */
        /* ⚠️ LE BLANC DESCEND JUSQU AU BORD, LA BARRE FLOTTE PAR-DESSUS. Arretee au
           ras des onglets, elle laissait une bande grise entre le champ et la barre :
           du fond de page dans les huit derniers pixels de l ecran, sur la seule page
           ou l on ne fait qu ecrire. Le rembourrage tient le bouton au-dessus des
           onglets — c est lui qui remplace le decalage, et non un simple deplacement
           du bord bas. */
        .espace-agent .zone-reponse,
        .espace-client .zone-reponse {
          bottom: 0;
          padding-bottom: calc(var(--h-onglets) + env(safe-area-inset-bottom, 0px));
        }
        /* ⚠️ PAS DE PIED DE PAGE SOUS UNE CONVERSATION. Ouverte sur son dernier message,
           la page se terminait par la barre d envoi, puis les mentions legales, puis du
           gris : la barre remontait d autant, et l on ecrivait au milieu de l ecran.
           Une messagerie n a pas de pied de page — le sien est atteignable depuis les
           quatre autres ecrans. */
        /* (Le pied de page est masque pour tous les ecrans, voir plus bas.) */
        /* ⚠️ ET LA PAGE NE SE RESERVE PLUS LA HAUTEUR DE LA BULLE D AIDE. Elle la garde
           partout ailleurs pour que le dernier bouton d un ecran ne finisse pas
           derriere ; ici le dernier element est la barre d envoi, qui se colle
           elle-meme au-dessus des onglets. Les quatre-vingt-dix pixels en trop se
           voyaient : du gris entre la barre et les onglets. */
        /* ⚠️ ET PLUS DE RESERVE DU TOUT DEPUIS QUE LA ZONE DE REPONSE PORTE LA SIENNE.
           Les deux la comptaient : la page gardait la hauteur des onglets, la zone
           aussi, et cela faisait quatre-vingt-dix pixels de blanc entre le champ et la
           barre. Mesure a 375 px le 21/08/2026. Un seul des deux reserve, et c est
           celui qui touche le bas. */
        /* (Le fond de page ne se reserve plus rien : regle commune, voir plus haut.) */
        /* ⚠️ ET PAS DE BULLE D AIDE FLOTTANTE SUR UNE CONVERSATION. Elle se posait
           exactement sur le bouton d envoi et sur la phrase qui l accompagne : le
           dernier endroit ou l on veut d un rond qui flotte est celui ou l on ecrit.
           L aide reste a un doigt depuis les quatre autres ecrans. */
        /* Le debordement lateral, lui, reste au telephone : la conversation y occupe
           toute la largeur, alors qu elle vit dans une carte sur ordinateur. */
        /* ⚠️ ET ELLE COMMENCE EN HAUT DE L ECRAN, comme les bandeaux verts des autres
           ecrans. Sans la marge negative du haut, seize pixels de blanc restaient
           au-dessus du vert tant qu on n avait pas fait defiler — la bande n avait l air
           collee qu apres un mouvement du doigt. */
        /* ⚠️ ET PLUS AUCUN BLANC NI AU-DESSUS NI EN DESSOUS. Rodolphe les a entoures
           tous les deux au feutre rouge sur une capture de son telephone, le
           21/08/2026 : seize pixels en haut, faute de marge negative, et douze en bas,
           reste de l espacement qui separait la bande du fil avant qu une barre
           d onglets ne vienne se coller dessous. Le vert commence a l ecran et se
           termine sur les onglets. */
        body:has([data-au-dernier]) .tete-conv {
          margin-top: calc(var(--e4) * -1); margin-bottom: 0;
          margin-left: calc(var(--e4) * -1); margin-right: calc(var(--e4) * -1);
          padding-left: var(--e4); padding-right: var(--e4);
        }
        body.espace-agent:has([data-au-dernier]) .bascule-volet ~ .barre-volets {
          margin-left: calc(var(--e4) * -1); margin-right: calc(var(--e4) * -1);
          padding-left: var(--e4); padding-right: var(--e4);
        }

        /* ── ET SUR TELEPHONE, L EN-TETE DE LA CONVERSATION PASSE AU VERT ─────────────
           « Sur mobile tu peux pas faire quelque chose aussi ? », Rodolphe, 21/08/2026,
           en voyant la bande verte de l ordinateur. Elle n a pas sa place ici — un
           bandeau de cent pixels repousserait la premiere parole — mais la ligne du nom,
           elle, peut porter la meme couleur. Meme identite, zero pixel de plus.

           ⚠️ LA PASTILLE DEVIENT UN ROND DE VERRE, comme dans le bandeau : ses quatre
           teintes pales n existent que sur du blanc. */
        body.espace-agent:has([data-au-dernier]) .tete-conv {
          background: linear-gradient(150deg, #0a3d2e 0%, #0d5c46 52%, #127054 100%);
          border-bottom: 0; color: #fff;
          box-shadow: 0 2px 12px rgba(10, 61, 46, .18);
        }
        body.espace-agent:has([data-au-dernier]) .conv-retour,
        body.espace-agent:has([data-au-dernier]) .chev-conv { color: rgba(255,255,255,.8); }
        body.espace-agent:has([data-au-dernier]) .conv-retour:hover {
          background: rgba(255,255,255,.14); color: #fff;
        }
        body.espace-agent:has([data-au-dernier]) .conv-vers-fiche:hover {
          background: rgba(255,255,255,.1); color: #fff;
        }
        body.espace-agent:has([data-au-dernier]) .conv-qui { font-size: .95rem; color: #fff; }
        body.espace-agent:has([data-au-dernier]) .conv-quoi { color: rgba(255,255,255,.72); }
        body.espace-agent:has([data-au-dernier]) .tete-conv .initiales {
          background: rgba(255,255,255,.16); color: #fff;
          border: 1px solid rgba(255,255,255,.34);
        }
        /* ── LA BANDE, AJUSTEE AU PIXEL ──────────────────────────────────────────────
           Trois defauts mesures a 375 px le 21/08/2026, aucun visible a l oeil nu :
           la pastille faisait trente-six pixels a cote d une fleche de quarante, deux
           ronds cote a cote qui ne se repondaient pas ; le lien du nom debordait de
           trois pixels au-dessus de la bande ; et le bloc du nom pendait vers le bas,
           parce que rien ne le centrait — seulement l alignement de son parent.
           « Centrer bien le nom », Rodolphe. */
        body:has([data-au-dernier]) .tete-conv .initiales {
          width: 40px; height: 40px; font-size: .76rem;
        }
        /* ⚠️ LES TROIS ELEMENTS S ETIRENT SUR TOUTE LA HAUTEUR, ET CENTRENT CHACUN
           LEUR CONTENU. Centres par leur parent, ils prenaient chacun la hauteur de ce
           qu ils contiennent et flottaient : le bloc du nom tenait de sept a
           quarante et un dans une bande de soixante, soit six pixels trop haut. */
        /* ⚠️ ET LE REMBOURRAGE DU BAS DISPARAIT AVEC LE TRAIT QU IL ACCOMPAGNAIT. Douze
           pixels sous une bordure grise avaient un sens ; sous un aplat vert, ils
           reduisaient la boite de contenu a quarante-huit pixels dans une bande de
           soixante, et tout ce qui s y centrait se centrait six pixels trop haut. */
        body:has([data-au-dernier]) .tete-conv {
          align-items: stretch; padding-bottom: 0;
        }
        body:has([data-au-dernier]) .conv-retour { align-self: center; }
        body:has([data-au-dernier]) .conv-vers-fiche {
          padding: 0 .25rem; align-items: center;
        }
        /* ⚠️ ET LE CHEVRON RESTE AU BORD. Sans cette ligne, il se colle a la fin du
           texte : la ligne du bien ayant raccourci, il remontait au milieu de la bande,
           a soixante-dix pixels du bord droit, comme s il pointait le nom. */
        body:has([data-au-dernier]) .conv-titres {
          flex: 1; justify-content: center; gap: .1rem;
        }
        body:has([data-au-dernier]) .conv-qui { line-height: 1.2; }
        body:has([data-au-dernier]) .conv-quoi { line-height: 1.2; }
        /* La barre des deux onglets se cale sous le vert : sur blanc juste dessous, le
           trait du bas de la bande verte manquait et les deux blocs se confondaient. */
        body.espace-agent:has([data-au-dernier]) .bascule-volet ~ .barre-volets {
          box-shadow: 0 1px 0 var(--trait);
        }
        /* ⚠️ ET LES ONGLETS TOUCHENT LA BANDE. Le fil gardait vingt-quatre pixels de
           marge en tete, herites du temps ou il suivait directement l en-tete : ils
           faisaient le second trait blanc de la capture, entre le vert et les onglets.
           Les deux se rejoignent, et c est ce que la barre collante annoncait deja en
           se calant a soixante pixels. */
        body:has([data-au-dernier]) .fil-conv { margin-top: 0; }
        /* ⚠️ LE MEME NOM DEUX FOIS, L UN SOUS L AUTRE. Sur la conversation du vendeur,
           l en-tete de l application annonce « Rodolphe Petyt · Agent commercial » et la
           bande juste dessous « Rodolphe Petyt · Votre conseiller ». Cent seize pixels
           pour dire une fois a qui l on parle. L en-tete cede la place : la bande porte
           deja la fleche de retour, et c est le meme geste que cote agent, ou la barre
           d onglets remplace l en-tete. Sur ordinateur il reste — il y porte la
           navigation, et la place ne manque pas. */
        body.espace-client:has([data-au-dernier]) header.principal { display: none; }
        /* ⚠️ SAUF QUAND IL N Y A PAS D ONGLETS. Une conversation dont l application n a
           jamais rien envoye n a qu un volet, donc pas de barre : la premiere bulle se
           collait alors au bas du vert, sans un pixel entre les deux. Vu sur la
           conversation de Sophie, ou aucun email n est parti. La barre servait
           d espacement sans qu on le sache — ce qui est exactement la raison de ne pas
           compter sur elle. */
        body:has([data-au-dernier]) .fil-conv:not(:has(.barre-volets)) {
          padding-top: var(--e3);
        }

        /* ── LA BARRE D ECRITURE RESTE EN BAS, MEME SANS UN SEUL MESSAGE ──────────────
           Sur une conversation vide, elle se posait juste sous « Aucun message pour
           l instant », au tiers de l ecran, et laissait un grand vide en dessous
           jusqu au clavier. « Mettre l encart de l ecriture juste au-dessus du clavier
           meme s il y a zero message », Rodolphe, 22/08/2026.

           L ecran devient une colonne qui remplit la fenetre : la bande en haut, le fil
           qui prend ce qui reste, la barre en bas. Rien a calculer, rien a coller.

           ⚠️ ET LES BULLES SE POSENT EN BAS DU FIL, pas en haut. Deux messages dans un
           cadre de six cents pixels flottaient sous les onglets ; sur toute messagerie
           ils s empilent depuis le bas. Meme regle que le volet de l ordinateur. */
        /* ⚠️ LA FENETRE ENTIERE, ET NON LA FENETRE MOINS LA BARRE. La reserve de la
              barre d onglets est deja portee par la zone de reponse, en rembourrage :
              la retirer ici aussi la comptait deux fois, et la barre d ecriture montait
              de cent trente pixels au-dessus des onglets. Mesure a 375 px. */
        body:has([data-au-dernier]) main.contenu {
          display: flex; flex-direction: column;
          min-height: 100vh; min-height: 100dvh;
        }
        body:has([data-au-dernier]) .messagerie,
        body:has([data-au-dernier]) .messagerie-panneau {
          display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
        }
        /* ⚠️ LES ONGLETS RESTENT EN HAUT. Pousser TOUT le contenu du fil vers le bas les
           emmenait avec lui : « Conversation » et « Envois » se retrouvaient au ras de
           la barre d ecriture, a huit cents pixels de la bande qu ils suivent.
           « Les onglets tu peux les laisser en haut », Rodolphe, 22/08/2026.
           C est le VOLET qui descend, pas la barre — une marge automatique sur lui
           seul. */
        body:has([data-au-dernier]) .fil-conv {
          flex: 1 1 auto; display: flex; flex-direction: column;
        }
        body:has([data-au-dernier]) .fil-conv > .volets { margin-top: auto; }

        /* (La bulle d aide est masquee pour tous les ecrans, voir plus haut.) */
        /* La page se reserve la hauteur de la barre EN PLUS de celle de la bulle,
           sinon le dernier bouton de chaque ecran finit derriere. */
        body.espace-agent { padding-bottom: calc(9.5rem + env(safe-area-inset-bottom, 0px)); }
        /* ⚠️ ET L AGENDA RECULE D AUTANT. Sa hauteur se mesure sur celle de l ecran, qui
           ignore que les neuf derniers centimetres sont pris par la barre flottante :
           mesure sur telephone, le bas de la grille finissait a sept cent soixante-dix-neuf
           pixels, la barre en occupait sept cents, et dix-huit heures se lisait derriere
           les icones. */
        .cadre-agenda { max-height: calc(100dvh - 13rem - 9.5rem - env(safe-area-inset-bottom, 0px)); }
        /* Le menu des vues se couche au-dessus de la grille et defile lateralement,
           plutot que de manger un tiers de la largeur d un telephone. */
        .agenda-avec-rail { display: block; }
        .rail-agenda {
          flex-direction: row; overflow-x: auto; gap: .3rem;
          margin: 0 0 var(--e3); padding-bottom: .2rem;
          -webkit-overflow-scrolling: touch;
        }
        .rail-agenda a { padding: .4rem .75rem; border: 1px solid var(--trait); }
        /* ⚠️ EN LIGNE ICI, ET NON EN SECONDE LIGNE. Couche en rangee, le rail aligne
           ses sept elements sur le plus haut : la seconde ligne du raccordement les
           faisait TOUS passer de quarante a cinquante-sept pixels — mesure — et
           poussait la grille d autant sur un ecran ou elle manque deja de hauteur.
           La rangee defile lateralement : la largeur, elle, ne coute rien. */
        .rail-agenda .rail-etat { display: inline; margin-left: .35rem; }
        .rail-agenda .rail-trait {
          height: auto; width: 1px; margin: .3rem .2rem; flex: 0 0 1px;
        }
        /* Un mois entier sur trois cent soixante-quinze pixels donne des cases de
           cinquante : le chiffre y tient, la pastille non. On defile. */
        .cadre-mois { overflow-x: auto; }
        .agenda-mois { min-width: 34rem; }
        /* Le vendeur n a pas de bulle flottante : sa page ne reserve que la barre, plus
           un peu d air pour que le dernier bouton ne la touche pas. */
        body.espace-client {
          padding-bottom: calc(var(--h-onglets) + var(--e4) + env(safe-area-inset-bottom, 0px));
        }
        /* ⚠️ ET LE BOUTON DES MESSAGES QUITTE L EN-TETE QUAND LA BARRE EST LA. Les deux
           menaient au meme ecran, a trente centimetres l un de l autre. Il reste sur
           ordinateur, ou la barre n existe pas. */
        .espace-client .vers-messages { display: none; }
        /* ⚠️ ET LE PIED DE PAGE AVEC. « Aide · Mentions legales · Confidentialite ·
           Conditions d utilisation · Application editee par… » s etalait sous chaque
           ecran du vendeur, sous ses biens compris : c est la ligne qui fait qu une
           application ressemble a une page web. Les memes liens vivent sur l ecran du
           conseiller, a deux touches de n importe ou. Sur ordinateur, ou il n y a pas
           de barre d onglets, il reste en bas. */
        body.espace-client:has(.onglets-app) footer.principal { display: none; }
        /* Et le pied remonte : sur l ecran du conseiller, il ferme la page. */
        .pied-mobile {
          display: block;
          margin-top: var(--e6); padding-top: var(--e4);
          border-top: 1px solid var(--trait); text-align: center;
        }
        .pied-mobile nav {
          display: flex; flex-wrap: wrap; justify-content: center;
          gap: var(--e2) var(--e4);
        }
        .pied-mobile a { color: var(--encre-3); font-size: .82rem; }
        .pied-mobile .editeur {
          margin: var(--e3) 0 0; font-size: .76rem; color: var(--encre-4);
        }
      }

      /* ── LE HAUT DU TABLEAU DE BORD, SUR UN TELEPHONE ─────────────────────────
         Mesure avant : 821 pixels a faire defiler avant le premier nom de vendeur,
         plus d un ecran entier. L agent ouvre son telephone entre deux rendez-vous
         pour savoir qui rappeler : il ne doit pas avoir a defiler pour l apprendre.

         ⚠️ RIEN N EST SUPPRIME, TOUT EST RESSERRE. Le titre descend d un cran, les
         trois nombres passent sur une seule rangee, le champ de recherche tient sur
         une ligne. Seule la courbe des sept jours disparait : quarante pixels pour une
         information qu on ne consulte pas en voiture, et qui reste sur ordinateur. */
      @media (max-width: 560px) {
        /* ⚠️ LE CONTENU VA BORD A BORD. Sans en-tete au-dessus, la carte blanche flottait
           au milieu de douze pixels de gris de chaque cote et de ses coins ronds en
           haut : on voyait une page de site posee dans une fenetre, la ou la maquette
           montre un ecran d application. Le fond gris ne se voit plus que derriere les
           listes, ce qui est sa raison d etre.

           ⚠️ SUR TELEPHONE SEULEMENT, PAS SUR TABLETTE. Entre 561 et 760 pixels l en-tete
           disparait aussi, mais la carte garde ses marges : le bandeau y remonte de deux
           centimetres par une marge negative calculee sur l ancien rembourrage, et bord
           a bord il serait sorti du haut de l ecran. */
        .espace-agent main.contenu {
          margin: 0; border-radius: 0; box-shadow: none;
          padding-left: var(--e4); padding-right: var(--e4); padding-top: var(--e4);
          /* ⚠️ ET LA SURFACE BLANCHE DESCEND JUSQU A LA BARRE. Sur un ecran court, le
             contenu s arretait a mi-hauteur et le gris de la page remontait entre lui et
             les onglets : une bande sans role, qui donnait l impression que la page
             s etait arretee en chemin. Releve par Rodolphe le 20/08/2026 : « j aime pas
             trop le fait que la bande grise en dessous monte sur mobile ».

             ⚠️ L UNITE DYNAMIQUE, ET NON L UNITE FIXE. Sur telephone, la barre
             d adresse se retracte au defilement : avec la hauteur d ecran classique, la
             mesure reste celle de l ecran barre comprise, et il manque toujours
             quarante pixels de blanc en bas. La premiere des deux lignes sert de repli
             aux navigateurs qui ignorent l unite dynamique. */
          min-height: calc(100vh - 64px);
          min-height: calc(100dvh - 64px);
        }
        /* Le pied de page passe sous la ligne de flottaison, atteignable au defilement :
           c est sa place sur un telephone, il ne se consulte pas en marchant. */
        .espace-agent footer.principal { padding-top: var(--e5); }

        /* ── L ESPACE VENDEUR PREND LA MEME FORME D APPLICATION ───────────────────────
           « Pour que ça fasse vraiment application mobile », Rodolphe, 22/08/2026, en
           comparant l ecran a son dessin.

           Le contenu vivait dans une carte blanche a coins arrondis, avec une ombre,
           posee sur un fond gris-bleu : c est la forme d une PAGE WEB, et elle se voit
           surtout aux quatre coins et a la bande grise qui court sur les cotes. Bord a
           bord, sans rayon ni ombre, sur un fond blanc, il ne reste que la bande du
           haut, le contenu et la barre du bas — la forme d une application.

           Meme traitement que l espace agent, deux jours plus tot, et pour la meme
           raison. */
        body.espace-client:has(.onglets-app) { background: var(--surface); }
        body.espace-client:has(.onglets-app) main.contenu {
          margin: 0; border-radius: 0; box-shadow: none; border: 0;
          padding-left: var(--e4); padding-right: var(--e4); padding-top: var(--e4);
          /* La surface descend jusqu a la barre : sur un ecran court, le fond de page
             remontait entre le contenu et les onglets. La premiere ligne sert de repli
             aux navigateurs qui ignorent l unite dynamique. */
          /* La reserve du bas de page s ajoute a cette hauteur : sans la retirer ici,
                la page se met a defiler de quatre-vingt-dix pixels sur un ecran qui n a
                rien a montrer de plus. */
          min-height: calc(100vh - 56px - var(--h-onglets) - var(--e4));
          min-height: calc(100dvh - 56px - var(--h-onglets) - var(--e4));
        }

        /* Maquette : padding 1.1rem 1rem 2.2rem, titre a 1.35rem. */
        .espace-agent .tete-bord {
          margin-left: calc(var(--e4) * -1); margin-right: calc(var(--e4) * -1);
          padding: 1.1rem var(--e4) 3.2rem;
          /* Colle au bord haut de l ecran, les coins arrondis laissaient deux triangles
             de gris en haut de la page. */
          border-radius: 0;
        }
        .espace-agent main.contenu > .tete-bord:first-child { margin-top: calc(var(--e4) * -1); }
        .espace-agent .tete-bord-jour { font-size: 1.35rem; line-height: 1.1; }
        .tete-bord-sous { font-size: .82rem; margin-top: .2rem; }
        .tete-bord-cta { font-size: .85rem; padding: .5rem .85rem; }
        .tete-bord-courbe { display: none; }

        /* ⚠️ UNE SEULE RANGEE, ET LES CARTES SE TOUCHENT. Ce sont des nombres a un ou
           deux chiffres : ils n ont jamais eu besoin d une carte chacun. Empilees, elles
           coutaient 307 pixels ; cote a cote, elles en coutent 80. Le trait d un pixel
           entre elles remplace l ombre, qui ne se voit plus a cette taille.
           Maquette : marge -1.5rem 1rem 1rem, rayon 14px, case a .7rem .5rem. */
        .espace-agent .chiffres-bord {
          grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
          gap: 1px; padding: 0; background: var(--trait);
          margin: -3.7rem var(--e4) var(--e4);
          border-radius: 14px; overflow: hidden; box-shadow: var(--ombre-relief);
        }
        .espace-agent .chiffres-bord .carte-chiffre {
          border-radius: 0; box-shadow: none; align-items: center; text-align: center;
          padding: .7rem .5rem; gap: .25rem;
        }
        .espace-agent .chiffres-bord .carte-chiffre:hover { box-shadow: none; }
        .espace-agent .chiffres-bord .carte-chiffre .chiffre { font-size: 1.7rem; }
        /* Mesure : « REMPLIES SEULES » reclame 92 pixels dans une case utile de 84 et
           passait sur deux lignes, seule des trois. La chasse se resserre plutot que le
           corps, pour que les trois libelles gardent la meme taille de lettre. */
        .espace-agent .chiffres-bord .carte-chiffre .quoi {
          font-size: .54rem; letter-spacing: .01em; line-height: 1.25;
          white-space: nowrap;
        }
        /* ⚠️ LES TROIS CASES DOIVENT SE RESSEMBLER, SINON ON LES COMPARE MAL. La
           troisieme portait une quatrieme ligne, « cette semaine », qui la rendait plus
           lourde que ses voisines a nombre egal. La maquette ne la montre pas : le fond
           vert de la case dit deja que ce chiffre-la est d une autre nature, et la
           mention reste ecrite sur l ordinateur ou la place existe.
           « les trois en haut ont pas la meme taille », Rodolphe, 20/08/2026. */
        .espace-agent .chiffres-bord .note-chiffre { display: none; }
        /* ⚠️ ET LE FOND VERT REPREND SA PLACE. La regle qui blanchit les cartes posees
           sur le bandeau l emportait sur celle de la carte gagnante, plus courte : le
           chiffre etait vert sur blanc au lieu d etre vert sur vert pale. C est ce fond
           qui remplace la mention « cette semaine » masquee juste au-dessus. */
        .espace-agent .chiffres-bord .carte-chiffre.carte-gagne {
          background: linear-gradient(160deg, #e7f5ee, #f7fcfa);
        }

        /* ⚠️ LE CHAMP ET LA LOUPE NE FONT PLUS QU UNE SEULE PIECE, comme sur la
           maquette : un rectangle blanc arrondi de douze pixels, la loupe a gauche, le
           texte a sa suite. Le champ portait son propre cadre et le bouton le sien : on
           lisait deux objets colles, et « Chercher » prenait 85 des 319 pixels.

           ⚠️ L ORDRE EST INVERSE PAR LA FEUILLE DE STYLE, PAS DANS LE HTML. Le bouton
           d envoi doit rester APRES le champ dans le document : c est lui qui donne son
           role au formulaire pour un lecteur d ecran, et le deplacer avant le champ
           ferait annoncer l action avant son objet. */
        .espace-agent .barre-recherche {
          flex-wrap: nowrap; flex-direction: row-reverse; align-items: center;
          gap: .5rem; padding: .55rem .7rem; border-radius: 12px;
          background: var(--surface); box-shadow: var(--ombre);
        }
        /* ⚠️ LES QUATRE NEGATIONS NE SONT PAS DECORATIVES : SANS ELLES LA REGLE PERD.
           La regle generale des champs, plus haut, designe un input suivi de SIX
           negations portant chacune un attribut : elle pese donc 0-6-1, quand deux
           classes et un attribut ne pesent que 0-3-1. Elle gagnait en silence, et le
           champ gardait son cadre et ses seize pixels au milieu du rectangle blanc.
           Quatre negations de plus suffisent a repasser devant, sans toucher a la regle
           generale dont depend tout le reste de l application. */
        .espace-agent .barre-recherche input[type="search"]:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]) {
          min-width: 0; border: 0; background: none; box-shadow: none;
          padding: 0; font-size: .88rem; min-height: 0; height: auto;
        }
        .espace-agent .barre-recherche input[type="search"]:focus { box-shadow: none; }
        .espace-agent .barre-recherche .bouton {
          background: none; border: 0; box-shadow: none; color: var(--encre-3);
          width: 34px; height: 34px; min-height: 34px;
        }
        .espace-agent .barre-recherche .bouton:hover { background: none; color: var(--accent); }
        .espace-agent .barre-recherche .mot-chercher {
          position: absolute; width: 1px; height: 1px; overflow: hidden;
          clip-path: inset(50%); white-space: nowrap;
        }
        .espace-agent .barre-recherche .bouton { padding: 0; display: grid; place-items: center; }
        .espace-agent .barre-recherche .loupe-chercher { display: grid; place-items: center; }

        /* Maquette : segments a .76rem, compte a .62rem, gouttiere .25rem. */

        /* Maquette : titre de section a 1.1rem, compte a .62rem, raison a .82rem. */
        .espace-agent .tete-section { flex-wrap: nowrap; margin-top: var(--e4); }
        .espace-agent .tete-section h2 { font-size: 1.1rem; min-width: 0; }
        .compteur-section { font-size: .62rem; padding: .15rem .45rem; }
        .pourquoi-section { font-size: .82rem; margin-bottom: .6rem; }

        /* ⚠️ CINQ REGLES ONT ETE RETIREES D ICI, ET C EST LE SIXIEME DOUBLON DE CE
              FICHIER. Ecrites lors d une passe precedente, elles redisaient — mal — ce
              que le bloc d identite dit maintenant pour toutes les largeurs : la
              pastille y revenait a 34 pixels au lieu de 36, le rembourrage a .8rem au
              lieu de .75, et le bouton d appel gardait son rayon de douze la ou il doit
              etre rond. Venant apres, elles gagnaient. Seule survit la jauge, qui n a
              pas d equivalent ailleurs. */
        .espace-agent .jauge-attente { width: 34px; }
        .espace-agent .ligne-vendeur { gap: .6rem; }

        /* ⚠️ LA BULLE D AIDE PERD SON MOT ET DEVIENT UN ROND. Elle flotte au-dessus du
           contenu : large de cent trente pixels, elle couvrait la fin de deux lignes de
           texte a chaque ecran. Le libelle reste lu par les lecteurs d ecran, il est
           porte par l attribut du bouton, pas par ce mot.

           ⚠️ COTE AGENT SEULEMENT. Chez le vendeur, ce meme mot porte le compte de
           messages non lus : le masquer ferait disparaitre l information, et le vendeur
           n a de toute facon pas de barre d onglets qui lui dispute le bas de l ecran. */

        /* Le detail des valeurs de maquette est monte hors de ce bloc : il decrit un
           dessin, pas une contrainte de largeur. Voir « L IDENTITE DE L ESPACE AGENT ». */

        /* ── LA FRISE DES ONZE ETAPES DEVIENT UN RUBAN ────────────────────────────
           Onze ronds legendes reclamaient 4005 pixels de large dans 375 : on en
           voyait trois, dont un coupe en deux par le bord de l ecran, et les huit
           autres se cherchaient au doigt sans qu aucune fleche ne le dise. La frise
           debordait de son propre cadre de 36 pixels.

           ⚠️ ONZE SEGMENTS DISENT LA MEME CHOSE. Ou l on en est, combien il reste, ce
           qui est franchi : c est tout ce qu on lit d une frise en marchant. Le nom de
           l etape est ecrit juste dessous, en toutes lettres, par la carte.

           ⚠️ CHAQUE SEGMENT RESTE UN LIEN. C est ce qui remplace le glissement : on
           touche un segment, la page s ouvre sur cette etape. Rien ne devient
           inatteignable. */
        .espace-agent .frise-etapes { padding: var(--e2) 0 0; margin-bottom: var(--e3); }
        .espace-agent .frise-piste {
          width: 100%; gap: 3px; margin: 0; transform: none;
        }
        /* ⚠️ LE SEGMENT FAIT QUATRE PIXELS DE HAUT, MAIS SE TOUCHE SUR QUARANTE-QUATRE.
           C est le minimum sous lequel un pouce attrape le voisin. Le trait reste fin,
           la zone sensible l entoure. */
        .espace-agent .etape-frise {
          flex: 1; min-width: 0; padding: 0; gap: 0; min-height: 44px;
          justify-content: center; transform: none; opacity: 1; border-radius: 3px;
        }
        .espace-agent .etape-frise .nom-frise { display: none; }
        .espace-agent .etape-frise .rond-frise {
          width: 100%; height: 4px; border-radius: 2px; border: 0;
          font-size: 0; background: var(--trait); color: transparent;
        }
        /* Meme piege ici : le dessin ne se laisse pas effacer par la taille du texte. */
        .espace-agent .etape-frise .rond-frise svg { display: none; }
        .espace-agent .etape-frise.faite .rond-frise { background: var(--accent); }
        .espace-agent .etape-frise.encours .rond-frise {
          background: var(--accent-fonce); box-shadow: none;
        }
        /* Celle qu on REGARDE sans y etre : plus sombre que le vide, plus claire que
           l accent, sinon on croit avoir change d etape. */
        .espace-agent .etape-frise.regarde .rond-frise { background: var(--encre-3); }
        .espace-agent .etape-frise:hover { background: none; }

        /* ── UNE SEULE CARTE D ETAPE, CELLE QU ON REGARDE ─────────────────────────
           Les onze cartes existaient toutes dans la page, cote a cote, et la bonne se
           voyait parce que le rail etait decale jusqu a elle : 4005 pixels de large a
           faire defiler lateralement. Chacune prenait en plus la hauteur de la plus
           chargee, ce qui reservait 370 pixels de blanc sous celle en cours.

           ⚠️ LA HAUTEUR EGALE AVAIT UNE RAISON, ET ELLE TOMBE ICI. Elle empechait la
           page de sauter d un glissement a l autre. Sans glissement, plus de saut : la
           carte reprend sa taille.

           ⚠️ ET LE GLISSEMENT N EST PAS PERDU, IL DEVIENT UN TOUCHER. Les segments du
           ruban sont des liens vers chaque etape. Sur ordinateur, le carrousel et ses
           onze cartes restent entiers : la place y est. */
        /* ⚠️ « AVANCEMENT DE CE DOSSIER » NE S ECRIT PLUS AU-DESSUS DU RUBAN. La carte
           juste dessous annonce « etape 4 sur 11 · en cours » et le nom de l etape en
           gras : le libelle redisait, en plus petit et en majuscules, ce que la carte
           dit mieux deux centimetres plus bas. La maquette ne le montre pas. */
        .espace-agent .module-avancement > .surtitre { display: none; }
        /* ── LE RUBAN VIT DANS LE BANDEAU ─────────────────────────────────────────
           Blanc sur le vert, et non gris sur blanc : c est ce que montre la maquette, et
           c est ce qui fait du bandeau un en-tete complet plutot qu un titre suivi d une
           barre. Le nom de l etape et son rang se posent dessous, comme dessine. */
        .espace-agent .tete-ecran-dessous { margin-top: 0; }
        .espace-agent .tete-ecran-dessous .frise-etapes {
          position: relative; padding: .7rem 0 0; margin: 0;
        }
        .espace-agent .tete-ecran-dessous .etape-frise .rond-frise {
          background: rgba(255,255,255,.24); border-color: transparent;
        }
        .espace-agent .tete-ecran-dessous .etape-frise.faite .rond-frise {
          background: rgba(255,255,255,.85); border-color: transparent;
        }
        .espace-agent .tete-ecran-dessous .etape-frise.encours .rond-frise {
          background: #fff; border-color: transparent;
        }
        .espace-agent .tete-ecran-dessous .etape-frise.regarde .rond-frise { background: rgba(255,255,255,.6); }
        .espace-agent .etape-bandeau {
          position: relative; display: flex; justify-content: space-between;
          align-items: baseline; gap: var(--e2);
          margin: 0; font-size: .74rem; color: rgba(255,255,255,.85);
        }
        .espace-agent .etape-bandeau b { font-weight: 600; color: #fff; }

        .espace-agent .rail-etapes {
          display: block; overflow: visible; padding: 0; margin: 0;
          scroll-snap-type: none;
        }
        /* ── CE QUI AIDE CESSE DE RESSEMBLER A CE QUI AGIT ───────────────────────
           Sur la carte d une etape, les depliants d aide — « Preparer ce rendez-vous »,
           « Deplacer ou annuler » — portaient le meme cadre blanc que les cartes de la
           page, sur toute la largeur : 317 pixels chacun, contre 242 pour l action du
           moment. Les deux choses les plus lourdes de l ecran etaient donc des aides.

           ⚠️ AUCUN CLASSEMENT N EST INVENTE ICI. La hierarchie existe deja dans le
           code : un depliant est un details porteur de data-groupe, l action qui fait
           avancer le dossier est le seul bouton sans bouton-2 de la carte, et les
           outils portent les deux classes. On ne fait que la rendre visible.

           ⚠️ ET SUR ORDINATEUR RIEN NE CHANGE : la place y est, les cadres n y ecrasent
           personne, et ces memes depliants servent ailleurs dans l application. */
        .espace-agent .carte-etape details[data-groupe] {
          border: 0; border-radius: 0; background: none; margin-bottom: var(--e2);
          border-top: 1px solid var(--trait);
        }
        .espace-agent .carte-etape details[data-groupe] > summary {
          padding: .7rem 0; font-weight: 500; font-size: .9rem; color: var(--encre-2);
        }
        .espace-agent .carte-etape details[data-groupe] > summary:hover {
          background: none; color: var(--encre);
        }
        .espace-agent .carte-etape details[data-groupe][open] > summary {
          color: var(--encre); font-weight: 650;
        }

        /* ⚠️ L ACTION QUI FAIT AVANCER LE DOSSIER PREND TOUTE LA LARGEUR ET LA COULEUR.
           Une seule par carte, et c est la seule qui change quelque chose : les autres
           ouvrent un outil ou une aide. Elle mesurait 202 pixels au milieu de six blocs
           qui se ressemblaient. */
        .espace-agent .carte-etape .pied-carte { padding-top: var(--e4); }
        .espace-agent .carte-etape .pied-carte form { width: 100%; }
        .espace-agent .carte-etape .pied-carte .bouton:not(.bouton-2),
        .espace-agent .carte-etape .pied-carte button.bouton:not(.bouton-2) {
          width: 100%; justify-content: center;
        }

        .espace-agent .rail-etapes > .carte-etape { display: none; margin: 0; }
        .espace-agent .rail-etapes > .carte-etape[data-ouverte] { display: flex; }
        .espace-agent .carte-etape.avenir { opacity: 1; }

        /* ── LE BANDEAU DE L ACCUEIL, SUR LES AUTRES ECRANS ───────────────────────
           Trois pages qui commencent par un titre noir sur blanc et une quatrieme qui
           commence par le vert de la marque, ce n est pas la meme application.
           « ce serait bien de mettre bandeau ouvert un peu comme on a fait sur
           l accueil », Rodolphe, 20/08/2026.

           ⚠️ ET LE LIEN DE RETOUR DISPARAIT. L onglet « Aujourd hui » fait exactement
           cela, en bas, sous le pouce. Deux chemins vers la meme page font hesiter sur
           les deux. Il reste sur ordinateur, ou il n y a pas de barre d onglets. */
        /* Bord a bord, sans rayon, et resserre : seule la geometrie change ici, le
           bandeau lui-meme est defini pour toutes les largeurs plus haut.
           La marge basse laisse respirer ce qui suit quand aucun onglet ne vient se
           poser dessus ; les onglets, eux, la remontent par leur marge negative. */
        .espace-agent .tete-ecran {
          margin: calc(var(--e4) * -1) calc(var(--e4) * -1) var(--e4);
          padding: 1.1rem var(--e4) 2.2rem;
          border-radius: 0;
        }
        /* Le meme seize pixels de blanc qu on vient de retirer sur ordinateur : la
           regle « premier enfant, marge du haut a zero » reprenait au bandeau la marge
           negative qui le fait deborder. Le vert commence donc vraiment en haut de
           l ecran, comme sur les maquettes. */
        main.contenu > .tete-ecran:first-child,
        /* La bande d une conversation est un bandeau comme un autre : chez le vendeur
              elle est le premier enfant du conteneur, et la regle « premier enfant,
              marge du haut a zero » lui reprenait sa marge negative — vingt pixels de
              blanc entre l en-tete et le bandeau. Chez l agent elle est imbriquee dans
              la messagerie et n a jamais ete concernee. */
        main.contenu > .tete-conv:first-child { margin-top: calc(var(--e4) * -1); }
        .espace-agent .tete-ecran-haut {
          position: relative; margin-bottom: 0; flex-wrap: nowrap; gap: var(--e3);
        }
        /* 1.2rem sur la fiche d un dossier comme sur sa maquette ; le tableau de bord,
           qui n a pas de fil au-dessus, garde son 1.35rem. */
        .espace-agent .tete-ecran h1 { font-size: 1.2rem; line-height: 1.15; }
        .espace-agent .fil-ecran { font-size: .76rem; margin-bottom: var(--e2); }
        .espace-agent .tete-ecran-sous {
          font-size: .8rem; color: rgba(255,255,255,.72); margin-top: .2rem;
        }
        /* ⚠️ LE BOUTON DEVIENT UN SIGNE. « Inviter un vendeur » prenait une ligne
           entiere pour un geste qu on fait une fois par semaine. Le mot reste lu par
           les lecteurs d ecran, il ne quitte que l oeil. */
        /* ⚠️ SUR TELEPHONE SEULEMENT, L ACTION SE REDUIT A UN ROND VERT PALE. Sur
           ordinateur elle garde son mot : la place existe, et un rond sans legende s y
           devine mal. Le vert pale plutot qu un blanc transparent : sur le vert du
           bandeau, un fond blanc a seize pour cent se lit comme un trou. */
        .espace-agent .tete-ecran-action {
          width: 34px; height: 34px; min-height: 34px; padding: 0;
          border-radius: 50%; display: grid; place-items: center;
          background: var(--accent-pale); color: var(--accent-fonce); box-shadow: none;
        }
        .espace-agent .tete-ecran-action:hover { background: #fff; }
        /* ⚠️ ET LE BOUTON DU TABLEAU DE BORD SUIT LA MEME REGLE. « Inviter un vendeur »
           ne tenait pas a cote du resume du jour : il passait a la ligne, et la bande
           d Aujourd hui mesurait 183 px quand les quatre autres en font 134. Il mene au
           meme endroit que le « + » de la liste des vendeurs, il en prend donc la
           forme. Mesure du 02/09/2026. */
        .espace-agent .tete-bord-cta {
          width: 34px; height: 34px; min-height: 34px; padding: 0;
          border-radius: 50%; display: grid; place-items: center;
          background: var(--accent-pale); color: var(--accent-fonce); box-shadow: none;
        }
        .espace-agent .tete-bord-cta:hover { background: #fff; transform: none; }
        /* Le rond se pose en haut, a hauteur du titre, et non au bas du resume. */
        .espace-agent .tete-bord-haut { align-items: flex-start; flex-wrap: nowrap; }
        .espace-agent .signe-action { display: block; font-size: 1.25rem; font-weight: 500; line-height: 1; }
        .espace-agent .tete-ecran-action .mot-action,
        .espace-agent .tete-bord-cta .mot-action {
          position: absolute; width: 1px; height: 1px; overflow: hidden;
          clip-path: inset(50%); white-space: nowrap;
        }

        /* ⚠️ CE QUI SUIT LE BANDEAU VIENT SE POSER DESSUS. C est le recouvrement qui
           fait la profondeur, et il economise la marge qui aurait separe les deux. Sur
           ordinateur il n y a pas de bandeau : les onglets y restent poses a plat. */
        /* ⚠️ LA MARGE NEGATIVE NE VAUT QUE S IL Y A UN BANDEAU AU-DESSUS. Sans lui,
           les onglets remontaient sur ce qui les precedait : sur la fiche d un dossier,
           ils passaient par-dessus le bouton « Fiche du bien ». Le selecteur exige donc
           un bandeau parmi leurs aines. */
        .espace-agent .bascule-volet ~ .barre-volets {
          max-width: none; background: var(--surface); box-shadow: var(--ombre-relief);
        }
        /* ⚠️ LE CHEVAUCHEMENT A DISPARU AVEC LA BARRE FLOTTANTE. Les onglets se
           posaient a mi-hauteur du bandeau tant qu ils defilaient avec lui ; colles en
           haut de l ecran, ils doivent au contraire s en detacher franchement, sinon la
           barre semble arrachee au bandeau des le premier mouvement du doigt. Le
           bandeau se termine, la barre commence. */
        /* ⚠️ ET « tete-bord » AUTANT QUE « tete-ecran ». Le tableau de bord porte le
              second nom : quand sa barre a rejoint le dessin commun, elle a cesse de
              toucher les deux bords de l ecran — seize pixels de blanc de chaque cote,
              la ou le trait du bas traversait avant. Mesure : 343 pixels de large sur
              un ecran de 375, contre 375 pour celle d un dossier. */
        /* ⚠️ SAUF LA BARRE VERTE, QUI MORD DESORMAIS SUR LE BANDEAU. Cette regle
           colle les onglets au bas du bandeau, ce qui valait tant qu ils flottaient ;
           la barre du bandeau, elle, remonte a mi-hauteur comme les cases de la liste,
           et sa marge negative se faisait effacer ici — quatre classes contre trois,
           mille lignes plus bas. Le `:not` la laisse passer sans toucher aux autres. */
        .espace-agent .tete-ecran ~ .bascule-volet ~ .barre-volets:not(.barre-volets-vert),
        .espace-agent .tete-bord ~ .bascule-volet ~ .barre-volets:not(.barre-volets-vert) {
          margin-top: 0; margin-left: calc(var(--e4) * -1); margin-right: calc(var(--e4) * -1);
        }
        /* La liste des vendeurs porte DEUX choses au-dessus de ses cartes, un champ et
           des onglets : c est leur bloc qui monte sur le bandeau, pas chacun d eux.

           ⚠️ ET IL PORTE LE VERT ICI AUSSI. Cette reprise-la est ecrite plus bas dans la
           feuille que la regle generale : a poids egal elle gagnait, et repeignait le
           bloc en blanc — champ blanc sur blanc, onglets blancs sur blanc, on ne lisait
           plus qu un « Tous ». Seules les mesures changent entre les deux, pas
           l habillage. */
        /* La reprise telephone de `.monte-bandeau` part avec lui. */


        /* ⚠️ CINQ SECTIONS EMPILEES FONT QUATRE MILLE PIXELS, dont quatre listes qu on
           ne voit jamais. En onglets, chacune tient dans un ecran et le compte reste
           inscrit sur l onglet : rien ne se cache, on sait qu il y a trois visites sans
           suite sans avoir a y aller. */
        /* ⚠️ LE MEME DESSIN QUE LES ONGLETS DES AUTRES ECRANS, ET POUR LA MEME RAISON.
           Le tableau de bord gardait les pastilles grises pendant que la fiche, les
           visites et les messages passaient au soulignement colle en haut : deux
           dessins d onglets dans la meme application, sur les cinq ecrans qu on ouvre
           tous les jours. Les deux mecaniques restent differentes — ici les panneaux
           vivent dans deux colonnes — mais rien ne justifie deux apparences. */
        /* ⚠️ QUARANTE-CINQ LIGNES D HABILLAGE ONT DISPARU D ICI LE 22/08/2026. La
              barre du tableau de bord portait ses propres classes et ses propres
              declarations, qui redisaient a deux centiemes de rem pres celles des
              onglets — et ce bloc a lui seul avait produit trois collisions
              silencieuses, consignees dans les commentaires qu il emportait avec lui.
              Elle emprunte desormais les classes de `ongletsPage`, dont les regles
              fonctionnent au rang : le bouton radio numero N eclaire l etiquette
              numero N, sans une ligne ici.

              Ne reste que ce qui ne peut PAS fusionner : le commutateur des panneaux,
              juste en dessous. */
        .espace-agent .panneau-bord { display: none; }
        .espace-agent .panneau-bord > *:first-child { margin-top: 0; }
        #segment-agir:checked ~ .grille-bord [data-segment="agir"],
        #segment-visites:checked ~ .grille-bord [data-segment="visites"],
        #segment-attente:checked ~ .grille-bord [data-segment="attente"],
        #segment-messages:checked ~ .grille-bord [data-segment="messages"],
        #segment-activite:checked ~ .grille-bord [data-segment="activite"] { display: block; }
        /* Et les quatre groupes de selecteurs qui eclairaient l etiquette ouverte
              — encre pleine, trait dessous, pastille en accent, anneau de focus — sont
              partis avec l habillage : les regles generales des onglets les portent
              toutes les quatre, au rang. */

        /* ⚠️ LES DEUX BANDEAUX DE L AGENT TOUCHENT LE HAUT DE L ECRAN A CETTE
              LARGEUR, et eux aussi doivent laisser passer l horloge. Meme regle que
              l en-tete, plus haut dans ce fichier : le vert monte jusqu au bord, le
              texte reste dessous.

              ⚠️ ET C EST ECRIT ICI, APRES le rembourrage de ces deux regles, parce que
              c est un raccourci « padding » qu elles posent : place avant, il serait
              efface. */
        .espace-agent .tete-bord,
        .espace-agent .tete-ecran {
          padding-top: calc(1.1rem + env(safe-area-inset-top, 0px));
        }

        /* ⚠️ ET LES ECRANS QUI N ONT PAS DE BANDEAU DU TOUT. La fiche de visite, par
              exemple, commence par un simple lien de retour : rien ne porte alors la
              marge de securite, et sa premiere ligne passait sous l horloge. On la
              pose donc sur la zone de contenu — SAUF quand un bandeau l ouvre, puisque
              celui-ci s en charge deja et monte volontairement sous l horloge, c est
              tout l interet. */
        .espace-agent main.contenu {
          padding-top: calc(var(--e4) + env(safe-area-inset-top, 0px));
        }
        .espace-agent main.contenu:has(> .tete-bord:first-child),
        .espace-agent main.contenu:has(> .tete-ecran:first-child),
        .espace-agent main.contenu:has(> .tete-conv:first-child) {
          padding-top: var(--e4);
        }

      }

      /* LA VISIONNEUSE DE DOCUMENTS.
         Consulter une pièce faisait quitter l'application : dans le même onglet elle
         remplaçait la page et l'on revenait à la première étape du formulaire, dans un
         nouvel onglet on sortait du produit. Elle s'ouvre donc par-dessus. */
      dialog.visionneuse {
        width: min(96vw, 1100px); height: min(92vh, 900px);
        padding: 0; border: 0; border-radius: var(--r-grand);
        background: var(--surface); box-shadow: var(--ombre-relief);
      }
      dialog.visionneuse::backdrop { background: rgba(15, 23, 42, .55); }
      dialog.visionneuse .visionneuse-tete {
        display: flex; gap: var(--e3); align-items: center; justify-content: space-between;
        padding: var(--e3) var(--e4); border-bottom: 1px solid var(--trait);
      }
      dialog.visionneuse .visionneuse-nom {
        font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      }
      dialog.visionneuse iframe {
        display: block; width: 100%; height: calc(100% - 3.9rem); border: 0;
      }
      dialog.visionneuse .visionneuse-actions { display: flex; gap: var(--e2); flex-shrink: 0; }

      @media (prefers-reduced-motion: reduce) {
        * { animation: none !important; transition: none !important; }
      }
