
/* ═══ 1 · LA BASE, ET L'ÉCHELLE ════════════════════════════════════════════
   15 px au lieu de 14 : ces écrans se lisent huit heures par jour.

   ── SIX CRANS, ET PAS UN DE PLUS ──────────────────────────────────────────
   Il y avait plus de trente tailles écrites en dur dans les feuilles. Deux
   objets de même importance finissaient à deux tailles différentes, sans que
   personne l'ait décidé, et l'écran ne disait plus ce qui comptait.

     32  le titre de l'écran, un par page
     22  le titre d'une section
     17  le titre d'un objet : une carte, un dossier
     15  le texte courant, et la ligne d'une liste
     13  la précision sous une ligne, la méta
     11  l'étiquette en capitales

   ── L'INTERLETTRAGE VIENT DE LA TAILLE, PAS DU GOÛT ───────────────────────
   Inter est dessinée pour le texte : au-dessus de 28 px, ses approches
   paraissent larges. On les resserre par paliers, et c'est ce resserrement,
   pas le choix de la famille, qui fait la tenue d'un grand titre.

     ≥ 28 px  -.03em      18 à 28 px  -.02em      < 18 px  0

   ── TROIS GRAISSES ────────────────────────────────────────────────────────
   400 le texte · 500 ce qui se compte et ce qui s'étiquette · 600 les titres.
   Le 700 et le 800 sont partis avec Bricolage : à ces tailles-là, ils
   n'ajoutaient pas de la hiérarchie, ils ajoutaient du poids. */
body{background:var(--craie);color:var(--encre);font-family:var(--sans);
  font-size:15px;line-height:1.55}
body h1{font-family:var(--titre);font-size:32px;font-weight:600;letter-spacing:-.03em;
  line-height:1.1;margin:0 0 .4rem}
body h2{font-family:var(--titre);font-size:22px;font-weight:600;letter-spacing:-.02em;
  line-height:1.2;margin:0 0 .5rem}
body h3{font-family:var(--titre);font-size:17px;font-weight:600;letter-spacing:-.01em;
  margin:0 0 .3rem}
body .souffle{color:var(--ardoise);font-size:15px;max-width:66ch}
/* LES NOMBRES S'ALIGNENT SANS CHANGER DE FAMILLE.
   La propriété tabular-nums donne à chaque chiffre la même chasse : une colonne de
   montants s'aligne au pixel, et le 1 ne creuse plus un trou. C'est ce qui a
   permis de renvoyer DM Mono : elle ne servait vraiment qu'ici, et elle
   changeait de dessin au milieu d'une phrase pour le faire. */
body .tnum,body .chiffre,body kbd,body .count,body .compteur,body time{
  font-variant-numeric:tabular-nums}
/* L'étiquette en capitales : elle nomme une nature, jamais un état.
   600 et non 500 : en capitales de 11 px, le 500 d'Inter se délave sur la
   craie, et c'était la seule graisse que la chasse fixe tenait toute seule.
   Le fil d'Ariane s'appelle .fil, et la conversation de Paul aussi (elle
   porte data-fil) : sans l'exception, toute la conversation passait en
   petites capitales grasses, illisible, depuis la refonte généralisée. */
body .eyebrow,body .fil:not([data-fil]),body .navgroup,body table.liste th,body .lst-tete{
  font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  color:var(--estompe-clair)}
body a{color:var(--lien)}
body :focus-visible{outline:2px solid var(--cobalt);outline-offset:2px;border-radius:var(--r-1)}
@media (prefers-reduced-motion:reduce){body *{transition:none!important;animation:none!important}}

/* ═══ 2 · LA COQUILLE ══════════════════════════════════════════════════════
   Le rail passe à l'encre. C'est le seul changement de fond qui déplace
   vraiment le repérage : le sombre à gauche dit « vous êtes ici, et le reste
   est la page », et ça se lit avant toute couleur. */
body .rail{border-right:none}
body .brand b{color:var(--sur-plein)}
body .brand-txt span{color:var(--estompe)}
/* Le sceau était un dégradé radial : le seul de la maison, et il ne disait
   rien. Un aplat de cobalt, et l'initiale dans la police d'affichage. */
body .seal-mark{background:var(--cobalt);box-shadow:none;font-family:var(--titre);border-radius:var(--r-1)}
body .navgroup{color:var(--estompe)}
body .navlink,body .navsub{color:var(--rail-texte);font-size:13px}
body .navlink:hover,body .navsub:hover{background:var(--rail-survol);color:var(--sur-plein)}
body .navlink.active{background:var(--cobalt);color:var(--sur-plein);box-shadow:none;font-weight:600}
body .navlink.active svg{color:var(--sur-plein)}
body .navsub.actif{color:var(--sur-plein)}
body .navsub.actif::before{background:var(--cobalt)}
body .navlink .tag{background:var(--prune-plein);font-weight:500}
body .navlink .count,body .navsub .count,body .navlink .apreparer{color:var(--estompe)}
body .navlink .okmark{color:var(--menthe)}
/* LA BARRE DU HAUT ET LE RAIL NE SONT PLUS REPEINTS D'ICI, et c'est la
   correction du 23/09/2026. Cette feuille posait leur chrome entier en
   sélecteurs préfixés par body, donc plus spécifiques que les feuilles des
   composants eux-memes : le jour où la barre a voulu changer, ses propres
   régles ont perdu contre celles-ci. Le champ de recherche prenait 42 px de
   haut dans une pilule de 32, et les deux fléches gardaient un fond gris que
   plus rien ne demandait.

   C'est exactement la stratification qu'on retire partout ailleurs : une
   couche de repeinture au-dessus d'un composant finit par le commander. Le
   chrome de la barre vit dans shell-style.ts, celui du rail dans rail.ts, et
   les deux sont libres de bouger. */
body .rail-bulle{background:var(--inverse);color:var(--sur-plein)}
body .rail-bulle::before{background:var(--inverse)}
/* La barre du bas reste ici : elle n'a pas de feuille à elle. Opaque, le flou
   coûtait une couche de composition à chaque défilement pour un effet que
   personne n'a jamais nommé. */
body .os-barre{background:var(--blanc);backdrop-filter:none;border-top:1px solid var(--brume)}
body .os-barre kbd{background:var(--brume);border:none;color:var(--ardoise)}
/* Les deux seuls endroits où l'ancien --cobalt voulait dire « c'est fait »
   et non « appuyez ici » : ils reprennent la menthe. */
body .os-barre .pt.ok{background:var(--menthe)}
body .chip.ok{background:var(--menthe-voile);color:var(--menthe-fonce)}
body .icon-btn,body .agent-close{border:none;background:var(--brume);color:var(--ardoise)}
body .icon-btn:hover{background:var(--filet);color:var(--encre)}

/* ═══ 3 · LES OBJETS POSÉS ═════════════════════════════════════════════════
   Aucun objet n'est cerné d'un trait : un aplat blanc que deux ombres
   détachent de la craie. Une bordure qui entoure disparaît ; un filet qui
   SÉPARE deux zones reste : c'est toute la distinction.

   ⚠️ CES SIX SÉLECTEURS ONT ÉTÉ MUETS DU 21 AU 22/09/2026. Ils étaient écrits
   sous body.v4, du temps où la feuille se portait écran par écran. Quand le
   drapeau extra.v4 a disparu, plus rien n'a posé cette classe sur le body : la
   règle est restée, sans jamais s'appliquer, et toutes les cartes de la
   plateforme ont gardé le contour de la V3, le contraire exact de ce que la
   section annonce. Rien ne l'a vu parce que le drapeau continuait d'être passé
   à page() sans que le type Extra le déclare, et qu'aucun typage n'était
   vérifié. C'est ce trou-là que outils/types.sh ferme. */
body .carte,body .card,body .tuile,body .tbord,body table.liste,body .dep{
  border:none;box-shadow:var(--ombre-1)}
body .carte.plate{background:var(--creux);box-shadow:none}
body .tuile{transition:transform .14s var(--sortie),box-shadow .14s var(--sortie)}
body .tuile:hover{transform:translateY(-3px);box-shadow:var(--ombre-2);border:none}
body .tuile .chiffre{font-weight:500;font-size:34px;font-variant-numeric:tabular-nums;
  letter-spacing:-.03em;color:var(--encre)}
body .tuile .lib{color:var(--ardoise)}
body table.liste th{background:var(--creux);border-bottom:1px solid var(--brume)}
body table.liste td{border-bottom:1px solid var(--brume)}
body table.liste tr:hover td{background:var(--creux)}

/* ── TROIS NIVEAUX DE SURFACE, ET PAS UN DE PLUS ─────────────────────────
   Le défaut que la craie et les aplats ont fabriqué : tout est une carte
   blanche au même relief. Six blocs identiques sur un écran, c'est six fois
   « regardez-moi », donc aucune hiérarchie, donc un écran fade où l'on ne sait
   pas par où commencer. Le blanc n'est pas une décoration, c'est un RANG.

     .majeure   ce qu'il faut voir en premier, et il y en a UN par écran.
                Ombre plus profonde, et un aplat de gravité quand quelque chose
                bloque : c'est le seul endroit de la plateforme où la couleur
                occupe une surface, et c'est pour ça qu'elle se voit.
     .carte     ce qui se lit ensuite. Blanc, ombre légère. Le cas courant.
     .contexte  ce qui s'est passé, ce qui explique. Posé à même la craie,
                sans carte : un fond qui ne se détache pas ne réclame rien.

   Un écran qui met tout en .carte n'a pas fini d'être dessiné. */
body .majeure{background:var(--blanc);border-radius:var(--radius);box-shadow:var(--ombre-2);
  padding:20px 24px}
body .majeure.bloque{background:var(--grenat-voile);box-shadow:none}
body .majeure.bloque a{color:var(--grenat-fonce)}
body .majeure.attention{background:var(--ambre-voile);box-shadow:none}
body .majeure.attention a{color:var(--ambre-fonce)}
body .contexte{background:none;box-shadow:none;border:none;padding:0}

/* ── Ce qui se manipule ──────────────────────────────────────────────────
   Le secondaire est un aplat tonal, pas un contour. Le plein reste rare :
   un par écran. */
body .btn,body .mini{border:none;background:var(--brume);color:var(--encre);
  border-radius:var(--radius-sm);font-family:var(--sans);font-weight:500;
  transition:background .12s var(--sortie),color .12s}
body .btn{padding:11px 16px;font-size:13px}
body .btn:hover,body .mini:hover{background:var(--filet)}
body .btn.plein,body .mini.solid{background:var(--cobalt);color:var(--sur-plein);font-weight:600}
body .btn.plein:hover,body .mini.solid:hover{background:var(--cobalt-survol)}
body .btn.plein:disabled,body .btn:disabled,body .mini:disabled{
  background:var(--brume);color:var(--estompe);cursor:not-allowed;opacity:1}
body .btn.danger{background:var(--grenat-voile);color:var(--grenat-fonce)}
body .btn.danger:hover{background:var(--grenat-voile)}
body .btn.discret,body .btn.ghost{background:transparent;color:var(--ardoise)}
body .btn.discret:hover,body .btn.ghost:hover{background:var(--brume);color:var(--encre)}
body .btn.on,body .mini.on{background:var(--cobalt-voile);color:var(--cobalt-fonce)}
body .amorce{border:none;background:var(--brume);color:var(--encre)}
body .amorce:hover{background:var(--prune-voile);color:var(--prune-fonce)}

/* ── Ce qui se saisit ────────────────────────────────────────────────────
   Un creux plein, et un seul anneau au focus. Jamais deux cercles emboîtés :
   c'était le défaut de la version précédente. */
body input[type=text],body input[type=email],body input[type=tel],
body input[type=date],body input[type=number],body input[type=password],
body input[type=search],body select,body textarea{
  border:none;background:var(--brume);color:var(--encre);border-radius:var(--radius-sm);
  padding:11px 13px;font-family:var(--sans);font-size:15px;
  transition:background .14s var(--sortie),box-shadow .14s var(--sortie)}
body input:focus,body select:focus,body textarea:focus{
  outline:none;background:var(--blanc);box-shadow:0 0 0 2px var(--cobalt)}
body .champ>span{font-size:11px;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ardoise)}
body .champ>span b.req{color:var(--grenat)}
body .champ small{color:var(--estompe-clair)}
body input[type=checkbox],body input[type=radio]{accent-color:var(--cobalt);width:18px;height:18px}

/* ── Ce qui dit un état ──────────────────────────────────────────────────
   La pastille porte un point ET un mot. Un état ne se code jamais par la
   seule couleur : vue en noir et blanc, elle doit encore dire ce qu'elle dit. */
body .chip,body .etat{display:inline-flex;align-items:center;gap:6px;
  border-radius:999px;padding:4px 10px;font-size:11px;font-weight:600;
  background:var(--prune-voile);color:var(--prune-fonce);width:fit-content}
body .etat.bon{background:var(--menthe-voile);color:var(--menthe-fonce)}
body .etat.attend,body .chip.warn{background:var(--ambre-voile);color:var(--ambre-fonce)}
body .etat.perd,body .chip.crit,body .chip.bad{background:var(--grenat-voile);color:var(--grenat-fonce)}
body .etat.neutre,body .chip.neutral{background:var(--brume);color:var(--ardoise)}
body .etat>i,body .chip>i{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
/* Les bandeaux : un aplat, un rayon de 8, et le texte qui dit quoi réparer. */
body .erreur{background:var(--grenat-voile);color:var(--grenat-fonce);border-radius:var(--radius-sm)}
body .ok{background:var(--menthe-voile);color:var(--menthe-fonce);border-radius:var(--radius-sm)}

/* ── La conversation ─────────────────────────────────────────────────────
   Elle garde sa forme ; seules les couleurs changent. Vos mots en cobalt,
   les siens sur le creux, et l'attente respire comme avant. */
body .agentcol{background:var(--creux);border-right:1px solid var(--brume)}
body .agent-head{border-bottom:1px solid var(--brume)}
body .agent-id b{font-family:var(--titre)}
body .agent-face,body .agent-poignee .mini-face{background:var(--prune-voile)}
body .bulle.elle{background:var(--creux);border:none;box-shadow:none}
body .bulle.vous{background:var(--cobalt)}
/* Le fil d'avant (30/09/2026) : un ton en retrait, puis la ligne « Sur cet écran ». */
body .bulle.passe{opacity:.72}
.fil-ici{align-self:center;font-size:11px;color:var(--estompe-clair);margin:6px 0;letter-spacing:.02em}
.agent-memoire{display:block;font-size:11px;color:var(--estompe-clair);text-align:center;margin:8px 0 0;text-decoration:none}
.agent-memoire:hover{color:var(--cobalt);text-decoration:underline}
body .agent-say{border-top:1px solid var(--brume);background:var(--blanc)}
body .agent-say button{background:var(--cobalt);border-radius:var(--radius-sm)}
body .agent-pastille{background:var(--grenat)}
body .agent-etat .pt{background:var(--menthe)}
body .agent-etat.attente .pt{background:var(--ambre)}

/* ═══ 4 · LE RELIEF, AU DOIGT ══════════════════════════════════════════════
   Trois pixels vers le haut et l'ombre qui s'allonge, en 140 ms. Une LIGNE de
   liste ne se soulève pas, elle s'éclaircit, sinon la liste ondule sous le
   curseur. */
body .leve{transition:transform .14s var(--sortie),box-shadow .14s var(--sortie)}
body .leve:hover{transform:translateY(-3px);box-shadow:var(--ombre-2)}
body .ligne{transition:background .12s var(--sortie)}
body .ligne:hover{background:var(--creux)}
body .toast{background:var(--inverse);color:var(--sur-plein);box-shadow:var(--ombre-2)}
body .toast svg{color:var(--cobalt-vif)}

/* ══ LE VERRE DANS L'APPLICATION (26/09/2026) ═════════════════════════════
   La matière de la page d'accueil entre dans l'espace client, à la demande de
   Karim : le fond de page porte les deux nappes, et les surfaces posées dessus
   deviennent du verre (translucide, flouté, une arête claire). Tout passe par
   les jetons du relief, qui ont leur jeu de nuit : rien à reprendre écran par
   écran. Un verre sans rien derrière n'est qu'un blanc terne, d'où les nappes,
   fixes pour qu'elles ne défilent pas avec la page.

   « body :is(...) » pèse une balise et une classe : il passe devant la feuille
   propre de chaque écran, chargée après celle-ci. */
body{background:var(--nappes-app),var(--craie);background-attachment:fixed}
/* Un écran qui repeint sa zone principale cacherait les nappes. */
body .main{background:transparent}
body :is(.topbar,.rail,.carte,.card,.tuile,.tbord,.bx-piece,.tdb-carte,.tdb-kpi,.ops-k,.ops-semaine,.majeure,.s-carte,.s-poser,.tbord,.ctl,.qt-tuile,.action-suivante,.passerelle){
  background:var(--verre);-webkit-backdrop-filter:var(--verre-flou);backdrop-filter:var(--verre-flou);
  border:1px solid var(--verre-bord);box-shadow:var(--verre-haut)}
/* La barre du haut et le rail tiennent toute la hauteur ou toute la largeur :
   ils gardent un seul filet, du côté du contenu. */
body .topbar{border-width:0 0 1px}
body .rail{border-width:0 1px 0 0}
/* ══ L'AGENT FLOTTANT (26/09/2026) ══════════════════════════════════════
   La colonne de l'agent prenait un tiers de l'écran pour trois phrases : Karim
   l'a refusée. L'agent devient une pastille ronde en bas à droite, qui ouvre
   la MÊME conversation (fil, amorces, champ) dans un panneau de verre posé sur
   la page. La page garde toute sa largeur ; elle reste lisible et cliquable
   pendant qu'on parle, donc pas de voile. Échap et la croix referment. */
/* Au-dessus du téléphone seulement : en dessous de 820 px, la coquille passe
   en une colonne, et cette règle, plus lourde, l'écrasait. Le contenu gardait
   une piste de rail à sa gauche et débordait à droite (30/09/2026). */
@media (min-width:821px){
  body .app,body .app.sans-agent,body .app.agent-mince{grid-template-columns:var(--w-rail) 1fr}
  body .app.rail-mince{grid-template-columns:var(--w-rail) 1fr}
}
body .agentcol{position:fixed;z-index:40;top:auto;left:auto;right:24px;bottom:122px;
  width:min(400px,calc(100vw - 32px));height:min(620px,calc(100dvh - 140px));
  border:1px solid var(--verre-bord);border-radius:var(--r-4);overflow:hidden;
  background:var(--verre);-webkit-backdrop-filter:var(--verre-flou);backdrop-filter:var(--verre-flou);
  box-shadow:var(--verre-ombre);
  opacity:0;transform:translateY(12px) scale(.98);transform-origin:bottom right;pointer-events:none;
  transition:opacity .18s var(--sortie),transform .18s var(--sortie)}
body .app.agent-ouvert .agentcol{opacity:1;transform:none;pointer-events:auto}
body .agent-in{min-width:0;width:100%;visibility:visible}
body .agent-say,body .agent-etat{background:transparent}
body .agent-voile,body .app.agent-ouvert ~ .agent-voile{display:none}
/* La pastille : le visage dans un anneau cobalt → prune, la signature de
   l'agent. Tant qu'il a quelque chose à dire, un halo respire autour et un
   point le signale ; l'aperçu de sa première phrase se tient à côté. */
body .app:not(.sans-agent) ~ .agent-poignee{display:grid}
body .agent-poignee{position:fixed;z-index:41;left:auto;right:24px;bottom:44px;
  width:64px;height:64px;padding:4px;place-items:center;border-radius:50%;
  border:2px solid transparent;
  background:linear-gradient(var(--verre-plein),var(--verre-plein)) padding-box,
    linear-gradient(135deg,var(--cobalt-vif),var(--prune)) border-box;
  box-shadow:var(--ombre-cobalt-haut);transition:transform .16s var(--sortie)}
body .agent-poignee:hover{transform:translateY(-2px) scale(1.04)}
body .agent-poignee .mini-face{width:52px;height:52px}
body .agent-poignee-nom{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
body .agent-poignee.a-dire::before{content:"";position:absolute;inset:-8px;border-radius:50%;
  border:2px solid var(--cobalt-vif);opacity:0;animation:agent-respire 2.4s var(--sortie) infinite}
body .agent-poignee.a-dire::after{content:"";position:absolute;top:2px;right:2px;width:14px;height:14px;
  border-radius:50%;background:var(--grenat);border:2px solid var(--blanc)}
@keyframes agent-respire{0%{transform:scale(.9);opacity:.7}70%{transform:scale(1.25);opacity:0}100%{opacity:0}}
@media (prefers-reduced-motion:reduce){body .agent-poignee.a-dire::before{animation:none;opacity:.35}}
body .app.agent-ouvert ~ .agent-poignee{box-shadow:var(--halo),var(--ombre-cobalt-haut)}
body .agent-apercu{position:fixed;z-index:41;right:104px;bottom:52px;max-width:320px;
  display:flex;align-items:flex-start;gap:4px;padding:12px 10px 12px 16px;border-radius:var(--r-4) var(--r-4) var(--r-1) var(--r-4);
  background:var(--verre);-webkit-backdrop-filter:var(--verre-flou);backdrop-filter:var(--verre-flou);
  border:1px solid var(--verre-bord);box-shadow:var(--verre-ombre);animation:agent-entre .35s var(--sortie) both .4s}
body .agent-apercu[hidden],body .app.agent-ouvert ~ .agent-apercu{display:none}
body .agent-apercu-t{border:none;background:none;padding:0;text-align:left;cursor:pointer;
  font:inherit;font-size:13px;line-height:1.45;color:var(--encre)}
body .agent-apercu-t b{display:block;font-size:11px;font-weight:650;color:var(--lien);margin-bottom:2px}
body .agent-apercu-x{border:none;background:none;cursor:pointer;color:var(--estompe-clair);font-size:17px;
  line-height:1;padding:0 4px;border-radius:var(--r-1)}
body .agent-apercu-x:hover{color:var(--encre);background:var(--brume)}
@keyframes agent-entre{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* LE TÉLÉPHONE (30/09/2026). La bulle d'aperçu couvrait un tiers de l'écran
   par-dessus le contenu : elle se tait, le point rouge suffit à dire qu'il y a
   du nouveau. La pastille rétrécit, et la conversation s'ouvre en panneau
   pleine largeur, collé en bas, au-dessus du pouce. */
@media (max-width:640px){
  body .agent-apercu{display:none}
  body .agent-poignee{right:14px;bottom:16px;width:52px;height:52px;padding:3px}
  body .agent-poignee .mini-face{width:42px;height:42px}
  body .agentcol{left:8px;right:8px;width:auto;bottom:78px;height:min(72dvh,560px);
    border-radius:var(--r-4)}
  /* La pastille flotte au-dessus du bas de page : rien ne doit finir dessous. */
  body .app:not(.sans-agent) .content{padding-bottom:88px}
}
/* Les raccourcis clavier n'ont rien à faire sous un doigt. */
@media (hover:none) and (pointer:coarse){
  body .os-barre .cle{display:none}
}
/* La barre des raccourcis, collée en bas : du verre, avec l'ombre qui monte. */
body .os-barre{background:var(--verre);-webkit-backdrop-filter:var(--verre-flou);backdrop-filter:var(--verre-flou);
  border-top:1px solid var(--verre-bord);box-shadow:var(--verre-bas)}
/* La tête et le pied du rail ne masquent rien : c'est la liste qui défile
   (rail.ts). Ils laissent voir le verre de la colonne. */
body .rl-tete,body .rl-pied{background:transparent}
/* Une pièce manquante garde son cadre en tirets, un état l'emporte sur la matière. */
body .bx-piece.manque,body .nda .bx-piece.manque{border-style:dashed;border-color:var(--filet)}
body .carte.plate{background:var(--verre-plein);box-shadow:none}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  body :is(.topbar,.rail,.carte,.card,.tuile,.tbord,.bx-piece,.tdb-carte,.tdb-kpi,.ops-k,.ops-semaine,.majeure,.s-carte,.s-poser,.tbord,.ctl,.qt-tuile,.action-suivante,.passerelle){
    background:var(--verre-plein)}
}

/* ══ LE BOUTON QUI OUVRE LE RAIL ═══════════════════════════════════════════
   Il vit dans la barre du haut de tous les écrans, et il ne se montre que
   dans le tiroir. Rendu partout plutôt que conditionnellement : un bouton
   qui n'existe dans le HTML qu'en dessous d'une largeur devrait être rendu
   par le serveur, qui ne connaît pas la largeur de l'écran. */
.tb-rail{display:none;width:34px;height:34px;flex:none;place-items:center;
  border:none;background:none;cursor:pointer;color:var(--ardoise);
  border-radius:var(--r-1);margin-right:2px}
.tb-rail:hover{background:var(--craie);color:var(--encre)}
.tb-rail svg{width:19px;height:19px}

/* Le voile du tiroir. Il existe toujours dans la page et ne coûte rien tant
   qu'il est transparent : le fabriquer à l'ouverture ferait apparaitre un
   élément sans transition, donc un clignotement. */
.rail-voile{position:fixed;inset:0;z-index:50;background:var(--encre);
  opacity:0;pointer-events:none;transition:opacity .22s ease}

@media (max-width:820px){

  /* ── 1 · LA GRILLE S'ÉCROULE ─────────────────────────────────────────────
     Les cinq sélecteurs sont écrits en entier, avec le préfixe body, parce
     que c'est ce qu'il faut pour battre v4-style : deux classes et un
     élément. Les raccourcir, c'est rouvrir le défaut du 09/09. */
  body .app,
  body .app.sans-agent,
  body .app.agent-mince,
  body .app.rail-mince,
  body .app.rail-mince.sans-agent{
    --w-rail:0px;--w-agent:0px;grid-template-columns:1fr}

  /* ── 2 · LE RAIL DEVIENT UN TIROIR ───────────────────────────────────────
     100dvh et non 100vh : sur un téléphone, la barre d'adresse mange la
     différence, et le pied du rail (le compte, la déconnexion) tombait
     dessous sans qu'aucune mesure ne le montre. */
  body .app .rail,
  body .app.rail-mince .rail{
    position:fixed;z-index:55;top:0;left:0;bottom:0;
    width:min(300px,86vw);height:100dvh;max-height:none;
    padding:0 14px;align-items:stretch;
    background:var(--blanc);box-shadow:var(--ombre-2);
    transform:translateX(-101%);transition:transform .24s var(--sortie,ease);
    overflow:hidden}
  body .app.rail-ouvert .rail{transform:none}
  /* LE VOILE EST LE VOISIN DE .app, PAS SON ENFANT : un tiroir posé sur la
     page ne peut pas vivre dans une grille qui défile. Écrit en descendant,
     la règle ne s'appliquait jamais, le voile restait transparent ET sans
     prise, et le doigt qui tapait à côté du tiroir ne le fermait pas. Le
     clic synthétique d'un test, lui, passait : il ne lit pas pointer-events. */
  body .app.rail-ouvert ~ .rail-voile{opacity:.42;pointer-events:auto}

  /* La tête et le pied du rail reprennent un fond : dans un tiroir posé sur
     la page, la liste défile SOUS eux, et v4-style les avait rendus
     transparents pour le verre de la colonne (26/09). */
  body .rl-tete,body .rl-pied{background:var(--blanc)}

  /* La bulle qui nomme une icône de rail replié n'a plus d'objet : le tiroir
     montre les libellés, et elle se déclenchait au toucher. */
  body .rail-bulle,body .rail-bulle.on{display:none}

  /* ── 3 · LA BARRE DU HAUT ────────────────────────────────────────────────
     Elle portait sept choses pour 390 px de large. Ce qui reste est ce qui
     sert au doigt : ouvrir le rail, savoir où l'on est, les deux gestes, la
     lumière, la recherche. */
  body .tb-rail{display:grid}
  /* Les deux flèches et le fil d'Ariane : le navigateur a déjà un retour, et
     le fil répétait le titre juste en dessous. */
  body .topbar .tb-nav{display:none}
  body .topbar{padding:0 12px;gap:8px}
  body .hi{flex:1 1 auto}
  body .hi h2{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* Le nom du centre est déjà en tête du rail, à deux doigts d'ici. */
  body .topbar #tb-sub{display:none}
  body .tb-etat{display:none}
  /* Les gestes gardent leur dessin, perdent leur mot : « Nouveau » et
     « Déposer » font 150 px à eux deux, soit la moitié du titre. */
  body .tb-gestes{gap:4px}
  body .tb-gestes .geste-b{width:34px;height:34px;padding:0;justify-content:center}
  body .tb-gestes .geste-b span{display:none}
  /* LES CIBLES AU DOIGT. Le bouton jour/nuit faisait 28 px, la marque du rail
     22 : des tailles de souris, où le pointeur est précis au pixel. Au doigt,
     en dessous de 34 px on rate une fois sur trois, et on ne sait pas qu'on a
     raté : rien ne bouge. La marque ne grandit pas, elle prend la hauteur de
     la tête du rail, qui en fait 64 et ne servait à rien. */
  body .topbar .tb-fl{width:34px;height:34px}
  body .rl-marque{align-self:stretch}

  /* LA RECHERCHE SE REPLIE SUR SA LOUPE, et s'ouvre en grand au toucher.
     La masquer aurait retiré la seule recherche de la plateforme sur
     téléphone ; la laisser à 280 px poussait le titre hors de l'écran. */
  body .topbar .search{flex:0 0 34px;width:34px;padding:0;justify-content:center;
    transition:none}
  body .topbar .search kbd{display:none}
  body .topbar .search input{width:0;flex:0 0 0;padding:0}
  body .topbar .search:focus-within{position:absolute;z-index:6;
    left:10px;right:10px;top:7px;width:auto;flex:1 1 auto;
    padding:0 10px;justify-content:flex-start}
  body .topbar .search:focus-within input{width:100%;flex:1 1 auto;padding:0}
  body .gsearch{left:0;right:0;width:auto}

  /* ── 4 · LE RESTE DE LA COQUILLE ─────────────────────────────────────────
     La barre des raccourcis clavier dit « ⌫ revenir », « / rechercher »,
     « Échap désélectionner » : trois touches qu'un téléphone n'a pas, pour
     42 px de hauteur pris à l'écran. */
  body .os-barre{display:none}
  body .content{padding:18px 16px 30px}
  /* Le pied de la zone de travail se cale sur le bord, pas sur une colonne
     de rail qui n'existe plus. */
  body .zt-barre{left:0;right:0;bottom:16px}
}

/* ══ L'ÉTROIT, sous 400 px ═════════════════════════════════════════════════
   Le seuil n'est pas un goût : c'est la largeur des téléphones que l'on
   croise (360, 375, 390). En dessous, le titre et les deux gestes ne tiennent
   plus ensemble, et c'est le titre qui doit rester. */
@media (max-width:400px){
  body .tb-gestes #tb-nouveau{display:none}
}
