/* ══════════════════════════════════════════════════════════════════════
   AGENDA
   ══════════════════════════════════════════════════════════════════════ */
.fof-ag-head{display:flex;flex-direction:column;gap:calc(12 * var(--fof-px));margin-bottom:calc(16 * var(--fof-px));}
/* Les trois titres de l'Agenda passent à --police-titre (maquette « Menu
   AGENDA » du 2026-08-26). Trois choses vont ensemble à chaque fois :
     • `font-weight:400` — Bebas Neue n'a QU'ELLE ; le 600 d'avant ne
       donnait rien de plus, ou un faux gras selon le navigateur ;
     • `letter-spacing:normal` — le resserrement négatif était réglé pour
       Instrument Sans ; sur une condensée il colle les lettres ;
     • la taille, elle, ne bouge pas encore : l'échelle de titres se règle
       en une fois quand les autres écrans seront arrivés. */
.fof-ag-h1{margin:0;font-family:var(--police-titre);font-size:var(--fof-t-titre-ecran);
  font-weight:400;letter-spacing:normal;color:var(--fof-ink);}
.fof-ag-head-actions{display:flex;gap:calc(8 * var(--fof-px));}
.fof-ag-head-actions > *{flex:1 1 0;}

/* ── En-tête d'écran, TÉLÉPHONE (maquette 1a) ─────────────────────────────
   Le titre SEUL à gauche, les boutons CARRÉS à droite, sur la même ligne dès
   le téléphone : ajouter, rechercher, compte.

   Plus de sous-titre depuis le 2026-08-21 (demande d'Etienne, tous modules) :
   il redisait ce que la liste montre juste dessous. La rangée ne fait donc
   plus qu'UNE ligne de texte — les deux valeurs qui en dépendaient suivent :
   les titres se centrent sur les boutons (`center` et non `flex-start`, qui
   n'avait de sens que pour aligner le haut de deux blocs inégaux), et les
   carrés passent de 52 à 44 px. 44 px n'est pas un nombre choisi ici : c'est
   déjà celui des carrés de la barre du haut (`.fof-hd-new`, `.fof-hd-ghost`,
   `.fof-hd-me`) et le plancher de la cible tactile. Les mêmes boutons font
   donc la même taille aux deux largeurs. */
.fof-ag-top{display:flex;align-items:center;justify-content:space-between;
  gap:calc(12 * var(--fof-px));margin-bottom:calc(14 * var(--fof-px));}
.fof-ag-titles{min-width:0;}
.fof-ag-acts{display:flex;align-items:center;gap:calc(8 * var(--fof-px));flex-shrink:0;}
.fof-ag-sq{width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));flex:0 0 calc(44 * var(--fof-px));padding:0;
  border-radius:var(--fof-r-md);display:inline-flex;align-items:center;
  justify-content:center;cursor:pointer;font-family:inherit;
  transition:background .12s,border-color .12s,color .12s;}
.fof-ag-sq-primary{background:var(--fof-primary-degrade);color:var(--fof-on-primary);border:none;}
.fof-ag-sq-primary:hover{background:var(--fof-primary-hover);}
/* Le même carré, en BLEU : la fiche d'une répétition, où rien n'est bordeaux.
   Un seul modificateur, le même mot que partout ailleurs — `.fof-btn-primary`
   (feuille 3) et `.fof-rf-icon` le portent déjà.
   Le survol prend --fof-info à plat : il n'existe pas de --fof-info-hover, et
   c'est justement le bas du dégradé — le carré s'assombrit d'un bloc, comme
   le bordeaux le fait avec --fof-primary-hover. */
.fof-ag-sq-primary.is-info{background:var(--fof-info-degrade);color:var(--fof-on-primary);}
.fof-ag-sq-primary.is-info:hover{background:var(--fof-info);}
/* Action secondaire de l'en-tête d'écran : même carré, mais discret — une
   seule action dominante par écran. Elle reprend l'habillage de
   `.fof-btn-secondary`, pas une couleur inventée pour l'occasion. */
.fof-ag-sq-ghost{background:var(--fof-surface);color:var(--fof-ink);
  border:1px solid var(--fof-border);}
.fof-ag-sq-ghost:hover{background:var(--fof-surface-2);}
.fof-ag-sq-avatar{background:var(--fof-surface-2);color:var(--fof-ink);
  border:1px solid var(--fof-border);overflow:hidden;
  font-size:var(--fof-t-libelle);font-weight:700;letter-spacing:calc(.2 * var(--fof-px));}
.fof-ag-sq-avatar:hover{background:var(--fof-bg);}
.fof-ag-sq-avatar img{width:100%;height:100%;object-fit:cover;display:block;}
/* Petit menu du bouton « + » : deux créations possibles, une seule icône.
   `top` = hauteur du bouton (44) + 8 : le menu se pose juste dessous. Cette
   valeur vaut aussi pour le menu de la barre du haut (`.fof-hd-addmenu`),
   dont le carré mesure 44 px lui aussi — un seul ancrage pour les deux. */
.fof-ag-addwrap{position:relative;}
.fof-ag-addmenu{position:absolute;right:0;top:calc(52 * var(--fof-px));z-index:41;width:calc(216 * var(--fof-px));
  background:var(--fof-surface);border:1px solid var(--fof-border-soft);
  border-radius:calc(11 * var(--fof-px));box-shadow:var(--fof-shadow);overflow:hidden;
  animation:popIn .14s ease;}
.fof-ag-addmenu button{display:block;width:100%;min-height:calc(48 * var(--fof-px));padding:0 calc(15 * var(--fof-px));
  border:none;background:none;text-align:left;cursor:pointer;
  font-family:inherit;font-size:var(--fof-t-libelle);font-weight:500;color:var(--fof-ink);}
.fof-ag-addmenu button + button{border-top:1px solid var(--fof-border-soft);}
.fof-ag-addmenu button:hover{background:var(--fof-bg);}

/* ── Segmenté : UN SEUL composant pour toute l'application ───────────────
   Trois emplois aujourd'hui : les onglets de l'Agenda (3 états sur
   ordinateur, 2 au téléphone), ceux de la Boîte mail (2 états) et la bascule
   Clair / Sombre (2 états, dans le menu du compte et sur l'écran « Plus »).
   Toute nouvelle bascule de ce type réutilise ces trois classes.

   Fond du conteneur = --fof-bg, la couleur posée derrière les boutons du
   rail (demande d'Etienne : --fof-border était trop sombre). Comme --fof-bg
   est AUSSI le fond de page, un filet --fof-border dessine le contour :
   sans lui le contrôle disparaîtrait sur l'Agenda au téléphone, où il n'est
   pas posé sur la barre blanche. L'onglet actif prend --fof-surface, donc il
   se détache dans les deux situations. */
.fof-seg{display:flex;gap:calc(4 * var(--fof-px));background:var(--fof-bg);
  border:1px solid var(--fof-border);border-radius:var(--fof-r-md);
  padding:calc(4 * var(--fof-px));overflow-x:auto;}
.fof-seg-btn{flex:1 1 0;min-height:calc(44 * var(--fof-px));padding:0 calc(22 * var(--fof-px));border:none;border-radius:calc(9 * var(--fof-px));
  display:inline-flex;align-items:center;justify-content:center;gap:calc(6 * var(--fof-px));
  background:transparent;color:var(--fof-muted);cursor:pointer;
  font-family:inherit;font-size:var(--fof-t-badge);font-weight:600;white-space:nowrap;
  transition:background .12s,color .12s;}
.fof-seg-btn.is-selected{background:var(--fof-surface);color:var(--fof-ink);
  box-shadow:0 1px calc(3 * var(--fof-px)) rgba(0,0,0,.10);}
/* Le compte accompagne le libellé sans le concurrencer (chiffres alignés).
   Il reste en --fof-muted et non --fof-faint : sur le fond du conteneur,
   --fof-faint ne donnait que 3,8:1, insuffisant pour un chiffre utile. */
.fof-seg-n{font-family:var(--police-mono);font-weight:600;
  font-variant-numeric:tabular-nums;color:var(--fof-muted);}
/* ── Boutons de contexte : le segmenté n'est plus un segmenté ────────────
   Les onglets de l'Agenda et de la Boîte mail, et les filtres de Clients,
   se présentent comme des boutons SÉPARÉS : plus de cadre gris qui les
   réunit, chacun porte son filet, et celui qui est actif est en bordeaux
   plein. Demande d'Etienne du 2026-07-28, sur capture — d'abord au
   téléphone, puis reportée sur l'ordinateur.

   Deux emplacements, une seule apparence :
     • `.fof-seg-page` — dans la page, au téléphone ;
     • `.fof-hd-seg`   — dans la barre du haut, sur ordinateur.

   La bascule reste le MÊME composant : mêmes classes, mêmes liaisons,
   `_segCls` inchangé — seule l'apparence de ces deux variantes est
   redéfinie. Le cadre gris subsiste pour la bascule Clair / Sombre, qui est
   un vrai interrupteur à deux états et non une rangée de boutons.

   Onglets ou filtres, l'apparence est la même mais le sens diffère : les
   onglets sont un choix UNIQUE (un seul bouton coloré à la fois), les
   filtres de Clients se CUMULENT. */
.fof-seg.fof-seg-page,
.fof-seg.fof-hd-seg{background:none;border:none;padding:0;gap:calc(8 * var(--fof-px));
  overflow:visible;}
.fof-seg.fof-seg-page{margin-bottom:var(--fof-gap-e);}
.fof-seg-page .fof-seg-btn,
.fof-hd-seg .fof-seg-btn{min-height:calc(44 * var(--fof-px));border-radius:calc(10 * var(--fof-px));font-size:var(--fof-t-second);
  border:1px solid var(--fof-border);background:var(--fof-surface);
  color:var(--fof-muted);}
.fof-seg-page .fof-seg-btn.is-selected,
.fof-hd-seg .fof-seg-btn.is-selected{border-color:transparent;
  background:var(--fof-primary-degrade);color:var(--fof-on-primary);box-shadow:none;}
/* Le compte (« À venir 15 ») suit la couleur du bouton : sur le bordeaux,
   le gris d'origine tombait à 2,4:1. */
.fof-seg-page .fof-seg-btn.is-selected .fof-seg-n,
.fof-hd-seg .fof-seg-btn.is-selected .fof-seg-n{color:inherit;opacity:.8;}
/* Le badge de non-lus de la Boîte mail est posé sur l'onglet : sur fond
   bordeaux il doit se détacher, comme il le fait sur le fond clair. */
.fof-hd-seg .fof-seg-btn.is-selected .fof-nav-badge,
.fof-seg-page .fof-seg-btn.is-selected .fof-nav-badge{
  background:var(--fof-on-primary);color:var(--fof-primary);}
/* 22 px de retrait latéral, c'était la mesure d'un segmenté — des cases
   collées dans un cadre commun. Séparés et bordés, 14 px suffisent, et les
   ~50 px ainsi rendus vont au champ de recherche, qui est le seul élément
   rétractable de la barre. */
.fof-hd-seg .fof-seg-btn{padding:0 calc(14 * var(--fof-px));flex:0 0 auto;}
/* Dans une page, le segmenté doit tenir sur la largeur d'un téléphone à
   TROIS onglets (« À venir 8 / Passés / Répétitions »). Les 22 px de retrait
   latéral débordaient sur un écran de 360 px et déclenchaient l'ascenseur
   horizontal du conteneur. Les boutons étant en `flex:1 1 0`, ce retrait ne
   fixe que leur largeur MINIMALE : le rendu à deux onglets est inchangé,
   ils se partagent la largeur comme avant. */
.fof-seg-page .fof-seg-btn{padding:0 calc(10 * var(--fof-px));}

/* ── Bloc « Prochain » (maquette 1a) ──────────────────────────────────────
   Fond bordeaux, seule zone pleine couleur de l'écran. Trois éléments s'en
   détachent en AMBRE : le compteur J-xx (pastille pleine), la date, et
   l'horloge du Get-in. Le statut porte sa propre couleur. */
/* Le bloc entier est cliquable : il ouvre la fiche de la date. Il remplace
   le bouton « Voir la fiche », supprimé le 2026-07-28. */
/* ── Le carrousel des prochaines dates ────────────────────────────────────
   Une FENÊTRE qui ne laisse voir qu'une fiche, et une PISTE qui les porte
   toutes côte à côte. C'est la PISTE que le doigt déplace : les fiches ne
   bougent pas les unes par rapport aux autres, et en tirant on voit arriver la
   voisine — demande d'Etienne du 2026-08-21.
   Le doigt fait glisser la piste horizontalement ; la page, elle, garde le
   défilement vertical. C'est ce que dit `pan-y` — et c'est ce qui permet aux
   écouteurs de rester PASSIFS, sans jamais bloquer le défilement.
   La transition ne sert qu'au relâché : pendant le geste, la logique la coupe
   pour que la piste colle au doigt, au pixel près. */
.fof-ag-carousel{overflow:hidden;margin-bottom:calc(22 * var(--fof-px));touch-action:pan-y;}
/* UNE seule formule de position : le rang vient de la classe, le décalage du
   doigt de --fof-ag-dx. Le pas, c'est la largeur de la fenêtre plus la
   gouttière — et 100 % se lit sur la PISTE, qui fait la largeur de la fenêtre
   (les fiches, elles, débordent). */
.fof-ag-track{display:flex;gap:var(--fof-sp-3);
  transform:translateX(calc(var(--fof-ag-i,0) * -1 * (100% + var(--fof-sp-3))
                            + var(--fof-ag-dx,0px)));
  transition:transform .2s ease-out;}
.fof-ag-track.is-at-1{--fof-ag-i:1;}
.fof-ag-track.is-at-2{--fof-ag-i:2;}
.fof-ag-track.is-at-3{--fof-ag-i:3;}
.fof-ag-track.is-at-4{--fof-ag-i:4;}
.fof-ag-track.is-at-5{--fof-ag-i:5;}
/* Chaque fiche occupe toute la fenêtre. Elles s'étirent à la hauteur de la
   plus haute : le bloc ne saute pas d'une date à l'autre. */
.fof-ag-track > .fof-ag-next{flex:0 0 100%;}
.fof-ag-next{background:var(--fof-primary-degrade);color:var(--fof-on-primary);
  border-radius:var(--fof-r-xl);padding:calc(20 * var(--fof-px));
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:background .12s;}
/* ── Aucun survol sur un écran tactile ────────────────────────────────────
   Sur un téléphone, :hover se COLLE : il se déclenche au toucher et y reste
   jusqu'au toucher suivant ailleurs. Toucher l'icône GPS laissait donc le bloc
   entier dans sa teinte de survol, sans en ressortir — la couleur du bloc
   « changeait » sans raison visible. Ces règles ne valent maintenant que là où
   il existe un VRAI pointeur.
   L'icône GPS, elle, n'a plus aucun survol : demande d'Etienne du 2026-08-21,
   sa couleur ne doit changer en aucun cas.
   Le survol reste un APLAT (--fof-primary-hover) alors que le repos est un
   dégradé : le dégradé disparaît donc le temps du survol. C'est assumé,
   décision d'Etienne du 2026-08-26 — « garde l'aplat existant pour le
   moment ». Le jour où une paire de survol sera donnée, elle s'écrira dans
   le socle, à côté de --fof-primary-degrade, et cette règle ne bougera pas. */
@media (hover:hover){
  .fof-ag-next:hover{background:var(--fof-primary-hover);}
}
/* La RÉFÉRENCE de cette ligne est la pastille du compte à rebours : la date se
   centre VERTICALEMENT dessus (demande d'Etienne du 2026-08-26). D'où le
   centrage — l'alignement sur la ligne de base, essayé d'abord, posait les deux
   textes sur le même trait du BAS ; c'est bien leur MILIEU qui doit coïncider.
   Ce que le centrage doit attraper, c'est le texte VU et non sa boîte : voir le
   rognage `text-box` de la date, juste en dessous. */
.fof-ag-next-top{display:flex;align-items:center;justify-content:space-between;gap:calc(12 * var(--fof-px));}
.fof-ag-next .fof-ag-eyebrow{color:var(--fof-on-primary);opacity:.72;}
.fof-ag-countdown{display:inline-flex;align-items:center;padding:calc(5 * var(--fof-px)) calc(11 * var(--fof-px));
  border-radius:var(--fof-r-sm);background:var(--fof-amber);color:var(--fof-amber-ink);
  font-family:var(--police-mono);font-size:var(--fof-t-second);font-weight:600;
  font-variant-numeric:tabular-nums;}
/* La date vit dans la PREMIÈRE ligne du bloc, face au compte à rebours
   (2026-08-21) : elle n'a plus d'écart à prendre au-dessus d'elle, et c'est le
   nom qui reprend celui qu'elle laisse. */
/* Deux crans au-dessus de --fof-t-libelle (14,5) où elle était : la date prend
   --fof-t-section (19), soit 17,9 px au téléphone. Elle a été trouvée trop
   petite deux fois de suite (constats d'Etienne du 2026-08-26). La maquette
   « Menu AGENDA » la donne à 13,5 px : l'écart avec elle est VOULU.

   `text-box` rogne la boîte du texte sur ses CAPITALES — du haut de capitale à
   la ligne de base. Sans ce rognage, le centrage porte sur la boîte de LIGNE,
   qui réserve au-dessus et en dessous une place d'accents et de jambages que
   « Jeudi 8 octobre 2026 » n'occupe pas : les lettres tombaient 1,7 px plus
   haut que le milieu de la pastille d'en face, alors que les deux BOÎTES,
   elles, étaient bien centrées. Rogné, c'est le texte VU qui se centre.
   Un navigateur qui ne connaît pas `text-box` l'ignore et retombe sur le
   centrage de boîte : l'écart d'avant revient, rien ne casse. */
.fof-ag-next-date{font-size:var(--fof-t-section);font-weight:600;color:var(--fof-amber);
  text-box:trim-both cap alphabetic;}
.fof-ag-next-name{margin:var(--fof-sp-2) 0 0;font-family:var(--police-titre);
  font-size:var(--fof-t-titre-carte);font-weight:400;letter-spacing:normal;line-height:1.25;}
.fof-ag-next-where{margin-top:calc(4 * var(--fof-px));font-size:var(--fof-t-second);opacity:.86;}
/* Ligne setlist : texte simple. Ce n'était un lien que dans le texte du
   brief ; la maquette la montre en clair, et un lien de 20 px de haut
   violait la règle des cibles de 44 px. La setlist reste ouvrable depuis la
   fiche de la date et depuis l'écran Setlists. */
.fof-ag-next-setlist{margin-top:calc(3 * var(--fof-px));font-size:var(--fof-t-second);opacity:.86;}
/* Les puces et le lien d'itinéraire partagent la même ligne : le statut à
   gauche, puis get-in et itinéraire collés au bord droit (voir plus bas, qui
   des deux porte le `margin-left:auto`). `align-items:center` : le bouton
   d'itinéraire est plus haut que les puces, elles se centrent entre elles. */
.fof-ag-next-chips{display:flex;flex-wrap:wrap;align-items:center;
  gap:calc(8 * var(--fof-px));margin-top:calc(14 * var(--fof-px));}
.fof-ag-chip{display:inline-flex;align-items:center;gap:calc(7 * var(--fof-px));padding:calc(7 * var(--fof-px)) calc(11 * var(--fof-px));
  border-radius:var(--fof-r-sm);font-size:var(--fof-t-badge);font-weight:600;white-space:nowrap;
  background:rgba(255,255,255,.16);color:var(--fof-on-primary);}
[data-theme="dark"] .fof-ag-chip{background:rgba(255,255,255,.34);}
/* Get-in : PAS une puce — une simple mention (maquette « Menu AGENDA »,
   2026-08-26). Ni cadre, ni aplat, ni horloge : du texte blanc, et c'est
   tout. La maquette ne dessine aucun rectangle autour d'elle, là où elle en
   dessine un autour du bouton d'itinéraire. Elle a donc perdu la classe
   `.fof-ag-chip` dans le gabarit : son aplat et son retrait n'avaient plus
   lieu d'être, et les garder pour les annuler ici aurait été un combat de
   priorités avec la règle sombre de `.fof-ag-chip`.
   Elle passe en --police-titre, comme le nom de la date juste au-dessus, et
   déclare son `font-weight:400` : Bebas Neue n'a qu'une graisse, un 600
   hérité de l'ancienne puce n'aurait donné qu'un faux gras.
   Elle prend le MÊME jeton que le nom de la date, --fof-t-titre-carte : la
   maquette leur donne la même taille, et c'est un relevé, pas un choix. Les
   tracés du texte y sont vectorisés ; « GET-IN 15:00 » y couvre 381,7 unités
   pour 72 de hauteur de capitale, soit 131,2 × 24,7 px à l'échelle du
   téléphone de 378 px. Le jeton, à cette largeur d'écran (échelle .94, donc
   33,84 px), rend 130,8 × 24,0 px — 0,3 % d'écart en largeur. La méthode a
   été contrôlée sur le titre de la carte, dont la valeur était déjà connue :
   elle le retrouve à 34,07 px pour 33,84 attendus.
   La mention se pousse à DROITE (`margin-left:auto`) pour venir se coller au
   bouton d'itinéraire, le statut restant seul à gauche. Quand elle est là,
   c'est ELLE qui absorbe l'espace libre : le bouton d'itinéraire rend son
   propre `margin-left:auto`, sinon les deux se partageraient le vide et la
   mention flotterait au milieu.
   Le `margin-right` complète les 8 px de gouttière de la rangée : la maquette
   laisse 21,1 px entre la fin du texte et le bouton, pas 8.

   Elle se centre VERTICALEMENT sur le bouton d'itinéraire, référence de la
   rangée, comme la pastille de statut (demande d'Etienne du 2026-08-26).
   `text-box` rogne sa boîte sur ses capitales : Bebas Neue réserve sous sa
   ligne de base une place de jambages que « GET-IN 15:00 » n'occupe jamais, et
   sans ce rognage le texte VU montait de 1,7 px pendant que sa boîte, elle,
   était bien centrée. Même raison que pour la date du haut. */
.fof-ag-chip-getin{margin-left:auto;margin-right:var(--fof-sp-3);white-space:nowrap;
  font-family:var(--police-titre);font-size:var(--fof-t-titre-carte);font-weight:400;
  letter-spacing:normal;color:var(--fof-on-primary);
  text-box:trim-both cap alphabetic;}
/* Statut : la couleur du statut, tenue lisible sur le bordeaux (clair) puis
   sur l'orange (sombre). Toutes ces paires dépassent 6:1. */
.fof-ag-chip-ok{background:rgba(20,102,56,.62);color:#A8E9C1;}
.fof-ag-chip-wait{background:rgba(122,90,12,.62);color:#F6DEA0;}
.fof-ag-chip-warn{background:rgba(184,64,26,.62);color:#FFD6C2;}
.fof-ag-chip-bad{background:rgba(179,36,28,.62);color:#FFD2CD;}
[data-theme="dark"] .fof-ag-chip-ok{background:rgba(255,255,255,.48);color:#0C3D1F;}
[data-theme="dark"] .fof-ag-chip-wait{background:rgba(255,255,255,.48);color:#4A3505;}
[data-theme="dark"] .fof-ag-chip-warn{background:rgba(255,255,255,.48);color:#6B2A0C;}
[data-theme="dark"] .fof-ag-chip-bad{background:rgba(255,255,255,.48);color:#6B120D;}
/* Itinéraire : carré à filet blanc, ancré à DROITE de la ligne des puces.
   `margin-left:auto` pousse le lien au bout, quel que soit le nombre de
   puces à sa gauche — sauf quand la mention get-in est là, car c'est alors
   ELLE qui prend le vide (voir plus haut).
   56 px, et non plus 44 : la maquette « Menu AGENDA » le dessine à 162 de
   ses unités, et son échelle est celle déjà calée dans 1-socle.css pour les
   titres Bebas — un téléphone de 378 px, soit 55,7 px. Les 44 px d'avant
   étaient le minimum d'une cible tactile, pas une mesure. Contrôle de
   l'échelle sur la même maquette : le pas entre deux points de carrousel y
   fait 24,05 px (--fof-sp-6) et leur rond 8,9 px (--fof-sp-2).
   Le filet est PLEIN, et de la même encre que l'icône qu'il encadre :
   --fof-on-primary, donc blanc franc sur le bordeaux (demande d'Etienne du
   2026-08-26 ; la maquette écrit bien `stroke="white"`, sans transparence).
   Il était à 40 % de blanc, ce qui le tirait vers le gris rosé du fond.
   Ce jeton retourne l'encre foncée en thème sombre, où le bloc est clair :
   le filet suit donc son icône tout seul, et la règle sombre qui le rattrapait
   à la main a disparu. */
.fof-ag-next-gps{flex:0 0 calc(56 * var(--fof-px));height:calc(56 * var(--fof-px));margin-left:auto;
  border-radius:var(--fof-r-md);
  display:inline-flex;align-items:center;justify-content:center;
  background:none;border:1px solid var(--fof-on-primary);
  color:var(--fof-on-primary);text-decoration:none;}
.fof-ag-chip-getin ~ .fof-ag-next-gps{margin-left:0;}
/* La pastille de statut ne se décale plus : la RÉFÉRENCE de la rangée est le
   bouton d'itinéraire, et le centrage de la rangée pose déjà son milieu sur
   celui du bouton (demande d'Etienne du 2026-08-26). Elle a un temps été
   remontée de 4 px pour se caler sur le get-in ; c'est le get-in qui se
   recentre, pas elle. */

/* ── Points de pagination du bloc « Prochain » ────────────────────────────
   Le bloc est un carrousel : un point par concert à venir, six au plus. Les
   points sont HORS du bloc, juste en dessous (2026-08-21) : ils ne se lisent
   plus sur le bordeaux mais sur le fond de l'écran, et prennent donc d'autres
   jetons — aucune couleur nouvelle pour autant.
   Les points sont BORDEAUX : --fof-primary, la couleur d'action de
   l'application (demande d'Etienne du 2026-08-26). Un APLAT, et non le
   dégradé qui remplit désormais boutons et cartes : sur un rond de 8 px, un
   dégradé vertical ne se voit pas — il n'ajouterait qu'une règle à tenir.
   Même raison pour la pastille « non lu » du mail et le filet de dépôt des
   setlists. Ils étaient orange
   (--fof-accent). Ce n'est PAS --fof-amber : cet ambre-là ne vaut que sur le
   bordeaux (son propre commentaire dans 1-socle.css le dit), et il vire au
   brun foncé en thème sombre — invisible sur le fond d'écran.
   UN seul jeton pour les deux états : c'est l'OPACITÉ qui dit lequel est le
   point courant — .42 pour les autres, 1 et un rond plus gros pour lui.
   La CIBLE fait 44 px de haut, comme partout dans l'application ; le rond
   visible n'en fait que 8. C'est le bouton qui est grand, pas le décor —
   d'où les 18 px d'air que le bouton pose lui-même entre le bloc et le point.
   Quand les points suivent le carrousel, c'est LEUR rangée qui porte l'écart
   avec la liste : la fenêtre rend les 22 px qu'elle réservait. */
.fof-ag-carousel:has(+ .fof-ag-dots){margin-bottom:0;}
/* Les boutons se touchent (aucun écart) et mesurent 24 px de large : c'est le
   minimum d'une cible répétée, et c'est ce qui rapproche les ronds. Avec 32 px
   et 4 px d'écart, il y avait 28 px entre deux ronds de 8 px ; il en reste 16. */
.fof-ag-dots{display:flex;align-items:center;justify-content:center;
  margin:0 0 var(--fof-sp-1);}
.fof-ag-dot{flex:0 0 var(--fof-sp-6);height:calc(44 * var(--fof-px));padding:0;
  border:none;background:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent;}
/* Le rond lui-même : pas d'icône, une forme. */
.fof-ag-dot::before{content:'';display:block;
  width:var(--fof-sp-2);height:var(--fof-sp-2);border-radius:50%;
  background:var(--fof-primary);opacity:.42;
  transition:opacity .12s,background .12s,transform .12s;}
.fof-ag-dot.is-on::before{background:var(--fof-primary);opacity:1;transform:scale(1.25);}
@media (hover:hover){ .fof-ag-dot:hover::before{opacity:.66;} }

/* ── Découpage par mois ───────────────────────────────────────────────────
   Un intertitre discret (« SEPTEMBRE 2026 · 2 dates ») puis UNE carte blanche
   à coins arrondis contenant les dates de ce mois. Un mois = un bloc. */
.fof-ag-month{display:flex;align-items:baseline;gap:calc(10 * var(--fof-px));padding:calc(20 * var(--fof-px)) calc(2 * var(--fof-px)) calc(9 * var(--fof-px));}
.fof-ag-month:first-child{padding-top:calc(2 * var(--fof-px));}
.fof-ag-month-count{font-size:var(--fof-t-badge);color:var(--fof-faint);}
.fof-ag-card{background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-lg);overflow:hidden;}

/* Ligne « date » : la pastille de date à gauche, puis UNE colonne qui porte
   l'en-tête (type / statut) et, dessous, l'information sur toute la largeur. */
.fof-ag-row{display:flex;align-items:center;gap:calc(14 * var(--fof-px));width:100%;
  min-height:calc(64 * var(--fof-px));padding:calc(12 * var(--fof-px));text-align:left;cursor:pointer;
  background:var(--fof-surface);color:inherit;font-family:inherit;
  border:none;border-bottom:1px solid var(--fof-border-soft);
  transition:background .12s;}
.fof-ag-card .fof-ag-row:last-child{border-bottom:none;}
.fof-ag-row:hover{background:var(--fof-surface-2);}
.fof-ag-row.is-past{opacity:.7;}
/* ── Sélection (maquette 2a) ──────────────────────────────────────────────
   La ligne choisie — celle dont le panneau de droite montre le détail — est
   ENCADRÉE, et rien d'autre. La pastille de date ne bouge plus : elle dit le
   TYPE de la date, pas la sélection. Deux signaux pour une seule chose, et on
   ne savait plus lequel lire (demande d'Etienne du 2026-08-24).
   Le fond reste blanc : c'est le cadre qui parle, pas un aplat.
   La bordure basse devient transparente au lieu de disparaître, pour que la
   ligne garde exactement la même hauteur, sélectionnée ou non. */
.fof-ag-row.is-selected{box-shadow:inset 0 0 0 calc(2 * var(--fof-px)) var(--fof-primary);
  border-radius:var(--fof-r-lg);border-bottom-color:transparent;}
/* Le séparateur de la ligne du dessus s'efface aussi : sinon un filet vient
   buter contre le haut du cadre. */
.fof-ag-row:has(+ .fof-ag-row.is-selected){border-bottom-color:transparent;}
/* ── Pastille de date ─────────────────────────────────────────────────────
   Concert et showcase : pleine, de la COULEUR D'ACTION — bordeaux en clair,
   orange en sombre — avec l'encre prévue pour elle. C'est la paire
   --fof-primary / --fof-on-primary, celle que porte déjà tout aplat plein de
   l'application ; son contraste est acquis dans les deux thèmes, il n'y a pas
   à le régler ici. Le fond est le DÉGRADÉ d'action depuis le 2026-08-26 ; son
   filet passe transparent — plat, il serait resté bordeaux là où le fond vire
   au brun, et se serait vu tout le long du bas. Il garde son pixel de large
   pour que la pastille ne change pas de taille. */
.fof-ag-pill{flex:0 0 calc(48 * var(--fof-px));width:calc(48 * var(--fof-px));padding:calc(6 * var(--fof-px)) 0;border-radius:var(--fof-r-md);
  background:var(--fof-primary-degrade);border:1px solid transparent;
  display:flex;flex-direction:column;align-items:center;line-height:1.15;}
/* Répétition : pastille bleutée, du bleu que porte aussi son type écrit en
   tête de ligne. Elle ne suit PAS le plein ci-dessus — c'est ce bleu qui
   distingue une répétition d'une date de scène au premier coup d'œil. */
.fof-ag-pill.is-reh{background:var(--fof-info-soft);border-color:transparent;}
.fof-ag-pill.is-reh .fof-ag-pill-day,
.fof-ag-pill.is-reh .fof-ag-pill-wd,
.fof-ag-pill.is-reh .fof-ag-pill-mon{color:var(--fof-info);}
.fof-ag-pill-wd{font-size:calc(11px * var(--fof-echelle-texte));font-weight:600;color:var(--fof-on-primary);text-transform:uppercase;}
.fof-ag-pill-day{font-size:var(--fof-t-section);font-weight:700;color:var(--fof-on-primary);}
.fof-ag-pill-mon{font-size:calc(11px * var(--fof-echelle-texte));font-weight:600;color:var(--fof-on-primary);text-transform:uppercase;}
/* ── Colonne de droite : en-tête (type + statut) puis information ─────────
   Le statut était une pastille centrée EN HAUTEUR au bout de la ligne : elle
   retirait sa largeur à l'information sur toute la hauteur de la ligne, d'où
   un retour à la ligne forcé. Elle remonte face au type, et l'information
   hérite de la largeur ainsi libérée. Demande d'Etienne du 2026-08-21. */
.fof-ag-row-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(4 * var(--fof-px));}
.fof-ag-row-head{display:flex;align-items:center;justify-content:space-between;gap:calc(10 * var(--fof-px));}
/* Le type, à gauche : petites capitales de SA couleur (l'encre vient du rendu,
   accent pour un concert, bleu pour un showcase ou une répétition), sans fond.
   Le fond plein reste au statut : deux badges côte à côte et on ne saurait
   plus lequel des deux lire.
   C'est une LIGNE : le texte, puis le point de note s'il y en a un. Son
   alignement se règle sur le point lui-meme (`align-self`), pas ici. */
.fof-ag-row-type{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  display:inline-flex;align-items:center;gap:var(--fof-sp-1);
  font-size:calc(11px * var(--fof-echelle-texte));font-weight:700;letter-spacing:calc(.5 * var(--fof-px));text-transform:uppercase;}
/* Aucun écart entre le titre et l'information : l'interligne de la ligne
   d'information (1,35) réserve déjà ~2,8 px au-dessus de son texte, et les
   2 px d'écart qui s'y ajoutaient l'éloignaient du titre plus que le titre ne
   l'est du type au-dessus (11,7 px contre 9,3). L'écart retiré, les deux
   respirations se valent (demande d'Etienne du 2026-08-26). */
.fof-ag-row-text{min-width:0;display:flex;flex-direction:column;}
/* Un titre a le droit de passer sur deux lignes plutôt que d'être coupé. */
.fof-ag-row-title{display:flex;align-items:center;flex-wrap:wrap;gap:calc(9 * var(--fof-px));
  font-family:var(--police-titre);font-size:var(--fof-t-titre-ligne);font-weight:400;
  line-height:1.3;color:var(--fof-ink);}
.fof-ag-row-second{font-size:var(--fof-t-second);color:var(--fof-muted);line-height:1.35;}
/* J-xx à côté du titre de la prochaine date (ordinateur, maquette 2a). */
.fof-ag-row-jx{padding:calc(2 * var(--fof-px)) calc(8 * var(--fof-px));border-radius:var(--fof-r-sm);
  background:var(--fof-amber);color:var(--fof-amber-ink);
  font-family:var(--police-mono);font-size:calc(12px * var(--fof-echelle-texte));font-weight:600;
  font-variant-numeric:tabular-nums;}
/* Une note existe : un POINT accolé au type, pas une icône (demande d'Etienne,
   2026-08-24). C'est le même rond que les points de navigation du carrousel —
   8 px, parfaitement rond — et il prend la couleur du texte qui le porte, donc
   celle du type : bleu pour une répétition, accent pour une date de scène.
   `align-self:baseline` : le point POSE son bas sur la ligne de base du texte.
   Centré (`align-items:center`), il tombait 1 px trop bas — mesuré : le centre
   d'une ligne de texte n'est pas le centre de ses CAPITALES, la place réservée
   sous la ligne de base aux jambages tire le milieu vers le bas, et le type
   n'a que des capitales. Sur la ligne de base, les 8 px du rond couvrent tout
   juste la hauteur de capitale de League Spartan à cette taille : haut du rond
   au haut du C, bas du rond sur la ligne de base (demande d'Etienne,
   2026-08-26). */
.fof-ag-row-note{flex:0 0 var(--fof-sp-2);height:var(--fof-sp-2);align-self:baseline;
  border-radius:50%;background:currentColor;}
.fof-ag-row-badge{flex-shrink:0;white-space:nowrap;}
.fof-ag-row-chevron{flex-shrink:0;display:flex;color:var(--fof-faint);}

/* État vide */
.fof-ag-empty{border:calc(1.5 * var(--fof-px)) dashed var(--fof-border);border-radius:var(--fof-r-lg);
  padding:calc(28 * var(--fof-px)) calc(20 * var(--fof-px));text-align:center;}
.fof-ag-empty-title{font-size:var(--fof-t-corps);font-weight:600;color:var(--fof-ink);}
.fof-ag-empty-text{margin:calc(6 * var(--fof-px)) 0 calc(16 * var(--fof-px));font-size:var(--fof-t-libelle);color:var(--fof-muted);}

/* Recherche de l'Agenda au téléphone : le champ vit dans la page, faute de
   barre du haut. Au-delà de 1101 px c'est celui de la barre qui sert. */
/* Recherche → contenu : le MÊME espace E qu'entre les boutons et elle.
   Sert à l'Agenda ET à la Boîte mail — c'est le même élément. */
.fof-ag-search{margin-bottom:var(--fof-gap-e);}

/* Une seule colonne par défaut ; le panneau apparaît au-delà de 1100 px. */
.fof-agenda{display:block;}
.fof-agenda-list{min-width:0;}
.fof-agenda-panel{display:none;}
/* ── Le panneau en fenêtre, sur téléphone ────────────────────────────────
   Toucher une date ouvrait directement l'éditeur : on passait de la liste à
   un formulaire sans jamais pouvoir simplement LIRE la date. La fiche
   s'ouvre maintenant en lecture, comme la colonne de droite sur ordinateur,
   et « Modifier » reste la porte vers le formulaire. */
/* Plein écran PAR-DESSUS la barre de navigation basse (z-index 35), comme la
   lecture d'un mail — demande d'Etienne du 2026-07-28. Auparavant elle
   passait volontairement DESSOUS (z-index 34) pour qu'on puisse changer de
   menu sans revenir en arrière ; le choix est inversé, les deux écrans de
   lecture se comportent maintenant pareil. On en sort par la flèche de
   retour de la fiche, ou par le geste de retour du téléphone.
   Le retrait bas n'a plus à réserver la place de la barre : 110 px → 24.

   ⚠ ELLE N'A PLUS DE RETRAIT DU TOUT depuis le 2026-09-04, ni de fond gris :
   « BLOC_ReadEvent=M_Event Clair » pose la fiche À MÊME L'ÉCRAN, d'un bord à
   l'autre et sur un aplat de panneau — c'est le bloc lui-même qui porte ses 40
   et ses 80, puisqu'il n'a plus de `RoundedPanel` pour les porter. Ne restent
   ici que les réserves d'écran, en haut comme en bas. */
.fof-agenda-panel.is-sheet{display:block;position:fixed;inset:0;z-index:36;
  overflow-y:auto;overscroll-behavior:contain;background:var(--panel-color);
  padding:env(safe-area-inset-top) 0 env(safe-area-inset-bottom);}
/* Ce qu'elle recouvre est aussi retiré : recouvert, cela resterait
   atteignable au clavier et annoncé par un lecteur d'écran.
   `visibility:hidden` — et surtout PAS `display:none`, qui détruirait les
   boîtes de mise en page : la page perdrait sa hauteur, le navigateur
   ramènerait le défilement à zéro, et on reviendrait de la fiche EN HAUT de
   l'agenda au lieu de l'endroit d'où on l'avait ouverte (constat d'Etienne du
   2026-08-21). Masquée ainsi, la liste n'est ni cliquable, ni atteignable au
   clavier, ni annoncée par un lecteur d'écran : la raison d'origine tient
   toujours. C'est mot pour mot le parti pris de la fiche client recouverte
   (`.fof-drawer-overlay.is-behind`, feuille 2).
   Le pendant de ce choix : la liste étant toujours là, le défilement de la
   fiche pourrait se REPORTER sur elle en butée — d'où l'`overscroll-behavior`
   ci-dessus, sans quoi on perdrait la place qu'on vient de garder. */
.fof-main.is-agsheet .fof-ag4-top,
.fof-main.is-agsheet .fof-ag4-seg,
.fof-main.is-agsheet .fof-ag4-search,
.fof-main.is-agsheet .fof-agenda-list{visibility:hidden;}
/* La fiche en lecture n'est plus UNE carte mais une SUITE de cartes
   (maquettes EVENEMENT_Read et REPETITION_Read du 2026-08-28) : identité,
   setlist, itinéraire, road map, textes, line up, client. Chacune ne dit
   qu'une chose, et le gabarit la retire entièrement quand elle n'a rien à
   dire — d'où l'écart porté par la carte SUIVANTE et non par la précédente :
   une carte absente n'y laisse aucun blanc. */
.fof-ag-panel-card{background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-lg);padding:calc(20 * var(--fof-px));}
.fof-ag-panel-card + .fof-ag-panel-card{margin-top:var(--fof-sp-5);}
/* Le nom de la date, en tête de la fiche — dans la colonne de droite sur
   ordinateur, en vue plein écran au téléphone : c'est la MÊME balise. Il lit
   --fof-t-titre-carte et non un rôle à lui : la carte « prochaine date » de
   l'Agenda porte exactement le même contenu, le nom d'une date. Deux tailles
   pour une même chose, c'est deux occasions de diverger.
   `line-height:1.25` était déjà là et reste juste : Bebas a des métriques
   verticales hautes, sans hauteur de ligne écrite le titre se réserverait
   une bande bien plus large que ses lettres.
   Le titre est CENTRÉ depuis le 2026-08-28 : il est le sujet de la carte, et
   la mention « Suivi par » se range dessous, centrée elle aussi. La ligne du
   client, qui vivait là (`.fof-ag-panel-where`), est descendue dans sa propre
   carte au bas de l'écran — la classe a disparu avec elle. */
.fof-ag-panel-name{margin:0;font-family:var(--police-titre);font-size:var(--fof-t-titre-carte);
  font-weight:400;letter-spacing:normal;line-height:1.25;color:var(--fof-ink);
  text-align:center;}
/* Type et statut en tête de panneau, au-dessus du nom (maquette 2a) ; le
   carré d'action ferme la ligne, poussé au bout par la marge automatique —
   c'est la seule chose qui le tient à droite quel que soit le nombre de
   badges, y compris sur une répétition qui n'en porte qu'un. */
.fof-ag-panel-top{display:flex;align-items:center;flex-wrap:wrap;gap:calc(8 * var(--fof-px));
  margin-bottom:calc(12 * var(--fof-px));}
.fof-ag-panel-top .fof-ag-sq{margin-left:auto;}
.fof-ag-panel-badge{display:inline-block;}
/* Un badge posé dans une ligne de contact (la réponse d'un musicien) ne se
   laisse pas comprimer par le nom : le nom se tronque, pas le statut. */
.fof-ag-contact .fof-ag-panel-badge{flex-shrink:0;}
.fof-ag-panel-follow{margin-top:var(--fof-sp-1);text-align:center;
  font-size:var(--fof-t-badge);color:var(--fof-muted);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* Contact sur place : vignette, nom, rôle et téléphone, bouton d'appel rond. */
.fof-ag-contact{display:flex;align-items:center;gap:calc(12 * var(--fof-px));
  padding:calc(10 * var(--fof-px)) calc(12 * var(--fof-px));border-radius:var(--fof-r-md);background:var(--fof-surface-2);}
.fof-ag-contact + .fof-ag-contact{margin-top:calc(8 * var(--fof-px));}
.fof-ag-contact-av{flex-shrink:0;}
.fof-ag-contact-text{flex:1;min-width:0;display:flex;flex-direction:column;}
.fof-ag-contact-name{font-size:var(--fof-t-libelle);font-weight:600;color:var(--fof-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fof-ag-contact-sub{font-size:var(--fof-t-badge);color:var(--fof-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fof-ag-contact-call{flex:0 0 calc(44 * var(--fof-px));width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--fof-surface);border:1px solid var(--fof-border);
  color:var(--fof-primary);text-decoration:none;}
.fof-ag-contact-call:hover{background:var(--fof-bg);}

/* Cartes « ressource » du panneau : setlist, conversation archivée. */
.fof-ag-rescard{display:flex;align-items:center;gap:calc(12 * var(--fof-px));width:100%;
  margin-top:calc(14 * var(--fof-px));padding:calc(12 * var(--fof-px));border-radius:var(--fof-r-md);
  background:var(--fof-surface-2);border:1px solid var(--fof-border-soft);
  text-align:left;font-family:inherit;}
.fof-ag-rescard.is-button{cursor:pointer;transition:background .12s;}
.fof-ag-rescard.is-button:hover{background:var(--fof-bg);}
.fof-ag-rescard-icon{flex-shrink:0;display:flex;color:var(--fof-faint);}
.fof-ag-rescard-text{flex:1;min-width:0;display:flex;flex-direction:column;}
.fof-ag-rescard-title{font-size:var(--fof-t-libelle);font-weight:600;color:var(--fof-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fof-ag-rescard-sub{font-size:var(--fof-t-badge);color:var(--fof-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fof-ag-rescard-open{flex-shrink:0;font-size:var(--fof-t-second);font-weight:600;color:var(--fof-primary);}
.fof-ag-rescard-btn{flex:0 0 calc(44 * var(--fof-px));width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--fof-r-sm);border:1px solid var(--fof-border);
  background:var(--fof-surface);color:var(--fof-ink-2);cursor:pointer;
  transition:background .12s,color .12s;}
.fof-ag-rescard-btn:hover{background:var(--fof-bg);color:var(--fof-primary);}

.fof-ag-kv{margin:calc(16 * var(--fof-px)) 0 0;padding:0;}
.fof-ag-kv-row{display:flex;align-items:baseline;justify-content:space-between;
  gap:calc(16 * var(--fof-px));padding:calc(9 * var(--fof-px)) 0;border-bottom:1px solid var(--fof-border-soft);}
.fof-ag-kv-label{margin:0;font-size:var(--fof-t-second);color:var(--fof-muted);flex-shrink:0;}
.fof-ag-kv-value{margin:0;font-size:var(--fof-t-second);font-weight:600;color:var(--fof-ink);text-align:right;}
/* Le CADRE de la note ne contient plus que le texte : son sur-titre est passé
   au-dessus, en `.fof-section-title`, comme celui de « CONTACT SUR PLACE »
   (demande d'Etienne, 2026-08-24). D'où la marge du haut retirée ici — c'est
   le sur-titre qui porte l'écart — et le texte qui commence au bord du cadre. */
.fof-ag-note{background:var(--fof-surface-2);
  border-radius:var(--fof-r-md);padding:calc(14 * var(--fof-px));}
.fof-ag-note-text{margin:0;font-size:var(--fof-t-libelle);line-height:1.55;
  color:var(--fof-ink-2);white-space:pre-wrap;}
/* La rangée « Modifier » pleine largeur a disparu le 2026-08-28 : l'action
   est remontée en carré, au bout de la ligne des badges. `.fof-ag-panel-actions`
   n'avait plus qu'elle — la règle est partie avec, pas de style orphelin.

   ── ROAD MAP, en lecture ───────────────────────────────────────────────
   L'heure d'abord, en bordeaux et en gras ; l'action ensuite, dans un cadre
   gris. C'est l'inverse d'une ligne `.fof-ag-kv`, et c'est voulu : on ne
   cherche pas « à quelle heure est le catering », on descend la journée
   heure par heure. La colonne des heures est FIXE (48 px, relevé sur la
   maquette) pour que les cadres s'alignent, quelle que soit l'heure.
   Le cadre lit `--fof-r-sm` : ce sont de petites boîtes empilées, pas des
   blocs de contenu — la note et le contact gardent `--fof-r-md`.
   Le retrait vertical est --fof-sp-2 et non un 6 px écrit sur place : mesure
   faite, il rend une ligne de 31 px là où la maquette en donne 33, quand 6 px
   n'en rendait que 27. Le plus proche des deux EST sur l'échelle. */
.fof-ag-rm{display:flex;flex-direction:column;gap:var(--fof-sp-2);}
.fof-ag-rm-row{display:flex;align-items:center;gap:var(--fof-sp-2);}
.fof-ag-rm-time{flex:0 0 calc(48 * var(--fof-px));font-weight:700;color:var(--fof-primary);}
.fof-ag-rm-act{flex:1;min-width:0;background:var(--fof-surface-2);
  border-radius:var(--fof-r-sm);color:var(--fof-ink-2);
  padding:var(--fof-sp-2) var(--fof-sp-3);}

/* ── LINE UP : combien ont répondu ──────────────────────────────────────
   Une barre et un compte, dans le même cadre gris que le reste des blocs de
   la fiche. La barre est la seule de l'application ; elle est faite de deux
   boîtes, la piste et son remplissage, et c'est le GABARIT qui donne la
   largeur du second — un pourcentage n'est pas une valeur de feuille de
   style, il se calcule.
   6 px d'épaisseur : la maquette en donne 5,2 ; six se divise en deux pour
   le rayon et reste visible sur un écran de téléphone. */
.fof-ag-lineup-head{display:flex;align-items:center;gap:var(--fof-sp-3);
  background:var(--fof-surface-2);border-radius:var(--fof-r-md);
  padding:var(--fof-sp-3);margin-bottom:var(--fof-sp-2);}
.fof-ag-lineup-bar{flex:1;min-width:0;height:calc(6 * var(--fof-px));
  border-radius:calc(3 * var(--fof-px));background:var(--fof-border);overflow:hidden;}
.fof-ag-lineup-bar > span{display:block;height:100%;border-radius:inherit;
  background:var(--fof-primary);}

/* ── Itinéraire, dans la fiche en LECTURE ───────────────────────────────
   Le carré est REMPLI depuis le 2026-08-28 (maquettes de lecture) : c'est le
   geste qu'on vient chercher quand on ouvre la fiche le jour même, et un
   carré blanc bordé se perdait sur une carte blanche. Il prend donc le
   dégradé d'action, comme tout ce qui se remplit dans l'application — et le
   bleu par `is-info` sur une répétition.
   Il n'est plus retiré au-delà de 1101 px : ces écrans servent les deux
   largeurs, la colonne de droite de l'ordinateur comprise (décision
   d'Etienne, 2026-08-28). Il n'a plus de marge non plus — c'est son
   conteneur qui le centre.
   Sa taille ne bouge pas : 56 px, la mesure de la maquette, bien au-delà des
   44 px de cible minimale. */
.fof-ag-panel-gps{display:flex;width:calc(56 * var(--fof-px));height:calc(56 * var(--fof-px));
  flex:0 0 calc(56 * var(--fof-px));align-items:center;justify-content:center;
  border:none;border-radius:var(--fof-r-md);
  background:var(--fof-primary-degrade);color:var(--fof-on-primary);text-decoration:none;
  transition:background .12s;}
.fof-ag-panel-gps:hover{background:var(--fof-primary-hover);}
.fof-ag-panel-gps.is-info{background:var(--fof-info-degrade);}
.fof-ag-panel-gps.is-info:hover{background:var(--fof-info);}
/* Ce qui l'entoure. Sur une répétition : rien, le carré est seul et centré.
   Sur une DATE : une pilule bordée qui annonce l'heure du get-in à sa gauche
   — « GET-IN 15:00 », en Bebas, à la taille du titre de carte. C'est le titre
   de SA carte, pas le libellé d'un bouton parmi d'autres.
   Une seule balise dans le gabarit pour les deux cas : `is-pill` porte le
   cadre, et l'icône n'est écrite qu'une fois. */
.fof-ag-getin{display:flex;align-items:center;justify-content:center;gap:var(--fof-sp-5);}
.fof-ag-getin.is-pill{border:1px solid var(--fof-primary);border-radius:var(--fof-r-md);
  padding:calc(6 * var(--fof-px)) var(--fof-sp-5);}
.fof-ag-getin-label{font-family:var(--police-titre);font-size:var(--fof-t-titre-carte);
  font-weight:400;line-height:1;color:var(--fof-primary);}

/* ── Le pied de la fiche : qui l'a créée, qui l'a modifiée ──────────────
   Hors carte, sur le fond de l'écran, sous un filet. C'est un repère, pas
   une information de travail : il se lit en dernier, et il ne mérite ni
   cadre ni surface à lui. Les deux lignes sont des `.fof-t-hint`, la mention
   grise déjà employée par l'écran de modification d'une répétition. */
.fof-ag-stamp{margin-top:var(--fof-sp-5);padding-top:var(--fof-sp-4);
  border-top:1px solid var(--fof-border-soft);
  display:flex;flex-direction:column;gap:var(--fof-sp-2);}

/* ══════════════════════════════════════════════════════════════════════
   CRÉER / MODIFIER UNE RÉPÉTITION (maquettes REPETITION_Create du 2026-08-27)
   ----------------------------------------------------------------------
   Ce n'est plus une fenêtre posée sur l'écran : c'est un ÉCRAN. Au téléphone
   il prend toute la surface, sur ordinateur toute la zone de contenu — la
   barre du haut et le menu de gauche restent en place, comme sur la capture.
   La bascule elle-même n'est pas ici : elle est portée par `.is-fullpage`
   (feuille 3 pour le téléphone, feuille 6 pour l'ordinateur), commune aux
   trois formulaires pleine page de l'application.

   Trois blocs, et le MÊME gabarit sert les deux largeurs — seule leur mise
   en place change :
     • `.fof-rf-head`  l'identité : le carré d'icône et le titre ;
     • `.fof-rf-body`  le formulaire, la seule partie qui défile ;
     • `.fof-rf-acts`  Annuler et Enregistrer.
   Au téléphone les trois s'empilent et les actions tombent en bas de l'écran
   (le corps prend la place, elles suivent). Sur ordinateur l'en-tête et les
   actions partagent la première ligne, le formulaire tient la seconde : deux
   dispositions, une seule suite de balises, aucun bouton écrit deux fois.
   ══════════════════════════════════════════════════════════════════════ */
.fof-rf-head{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;
  gap:var(--fof-sp-3);padding:var(--fof-sp-5) var(--fof-sp-5) 0;}
.fof-rf-ident{display:flex;align-items:center;gap:var(--fof-sp-3);min-width:0;}
/* `line-height:1` sur le titre, pour la même raison qu'en haut de la barre
   (`.fof-hd-h1`, feuille 2) : Bebas a des métriques verticales bien plus
   hautes que sa taille de police. Sans cette ligne, un titre de 33,8 px se
   réserve une bande de 53, l'en-tête gagne vingt pixels de vide que la
   maquette ne montre pas, et tout le formulaire descend d'autant. */
.fof-rf-ident .fof-ag-h1{line-height:1;}
/* Le carré d'icône du titre. Il portait jusqu'ici un fond --fof-info-soft et
   une icône --fof-info, écrits en clair dans le gabarit ; les maquettes le
   veulent REMPLI. C'est la seule surface pleine de l'en-tête, et elle ne porte
   pas de texte — le trait blanc de l'icône y suffit.
   Par défaut il prend les couleurs de l'APPLICATION : c'est ce que demande la
   maquette de l'évènement, et c'est le bon défaut — le bleu est la couleur
   d'UNE famille d'écrans, pas celle du gabarit. La répétition le réclame donc
   par `is-info`, exactement comme ses deux boutons (`.fof-btn-primary.is-info`,
   feuille 3) : un seul modificateur, la même habitude partout. */
.fof-rf-icon{flex:0 0 auto;width:calc(32 * var(--fof-px));height:calc(32 * var(--fof-px));
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--fof-r-sm);
  background:var(--fof-primary-degrade);color:var(--fof-on-primary);}
.fof-rf-icon.is-info{background:var(--fof-info-degrade);}
/* L'air sous le titre est --fof-sp-8, et lui seul : Etienne a descendu le
   formulaire de 41 px sur la maquette du téléphone (2026-08-27) pour dégager
   le titre. Le même cran sert sur ordinateur, où il tombe sous le filet. */
.fof-rf-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:var(--fof-sp-8) var(--fof-sp-5) var(--fof-sp-5);}
/* La colonne de saisie garde EXACTEMENT la largeur qu'elle avait dans la
   fenêtre : 440 px moins ses deux retraits. Rien ne s'étire parce que la
   fenêtre s'est agrandie — un champ « Titre » large de 1 400 px ne se
   remplirait pas mieux. Sur ordinateur elle se centre dans la carte. */
.fof-rf-form{display:flex;flex-direction:column;gap:var(--fof-sp-5);
  width:100%;max-width:calc(440 * var(--fof-px));margin:0 auto;}
/* La note est plus HAUTE que le champ qui grandit ailleurs dans
   l'application : les deux maquettes lui donnent 384 unités, soit 130 px au
   téléphone et 169 sur ordinateur, contre 64 px de départ partout ailleurs.
   132 × --fof-px rend 132 et 165 — les deux largeurs d'un seul nombre.
   Elle continue de grandir avec son texte à partir de là ; c'est le point de
   DÉPART qui change, pas la mécanique. */
.fof-rf-form .fof-grow > textarea,
.fof-rf-form .fof-grow::after{min-height:calc(132 * var(--fof-px));}
/* Date et Heure : deux parts ÉGALES, comme sur les deux maquettes. */
.fof-rf-duo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--fof-sp-6);}
/* Le bleu jusque dans le focus : sur ces écrans-là, rien n'est bordeaux.
   Une seule règle remplace les cinq anneaux qui étaient écrits en clair sur
   les champs, chacun avec son propre `rgba(31,95,166,.12)`. */
.fof-rf-form .fof-input:focus,
.fof-rf-form .fof-tp-field:focus-visible,
.fof-rf-form textarea:focus{border-color:var(--fof-info);
  box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-info-soft);}
.fof-rf-form .fof-tp-field:hover{border-color:var(--fof-info);}
/* Les deux actions. Au téléphone elles se partagent la largeur à parts
   égales (maquette mobile) ; sur ordinateur elles reprennent leur largeur
   naturelle et se calent à droite — c'est dans `6-adaptatif.css`. */
.fof-rf-acts{flex:0 0 auto;display:flex;gap:var(--fof-sp-7);
  padding:var(--fof-sp-5);}
.fof-rf-acts > *{flex:1 1 0;}

/* ══════════════════════════════════════════════════════════════════════
   CRÉER / MODIFIER UN ÉVÈNEMENT (maquette EVENEMENT_Create_Desktop, 2026-08-27)
   ----------------------------------------------------------------------
   L'écran emprunte à la répétition tout ce qui l'entoure — `.fof-rf-sheet`,
   son en-tête, son corps qui défile, sa rangée d'actions. Il n'ajoute que ce
   que la répétition n'a pas : TROIS colonnes au lieu d'une, et deux blocs qui
   se répètent, la road map et le line up.

   Ce qui n'est PAS ici, et c'est voulu : la couleur. `.fof-rf-form` porte le
   bleu du focus, `.fof-ef-form` ne porte rien — les champs retrouvent donc le
   bordeaux de `.fof-input:focus` (feuille 3), qui est la couleur de
   l'application. Pas une règle de plus pour dire la même chose.

   Une seule colonne par défaut : c'est la largeur du téléphone, dont la
   maquette reste à faire. Les trois colonnes sont dans `6-adaptatif.css`,
   avec le reste de l'ordinateur.
   ══════════════════════════════════════════════════════════════════════ */
.fof-ef-form{display:grid;grid-template-columns:minmax(0,1fr);
  gap:var(--fof-sp-8);align-items:start;}
/* Une colonne : les mêmes champs, le même air entre eux que sur l'écran de
   répétition (--fof-sp-5). Aucune n'est plus large qu'un champ ne se remplit —
   c'est le plafond de `.fof-rf-form`, repris tel quel. */
.fof-ef-col{display:flex;flex-direction:column;gap:var(--fof-sp-5);
  min-width:0;max-width:calc(440 * var(--fof-px));}
/* Le message d'erreur reste sous les colonnes, sur la largeur d'une seule :
   plus long, il se lirait d'un bord à l'autre de l'écran. */
.fof-ef-alert{max-width:calc(440 * var(--fof-px));margin-top:var(--fof-sp-5);}

/* ── Le ruban 1-2-3-4 ──────────────────────────────────────────────────
   L'ALLURE du ruban est ici ; le parcours lui-même — quelle étape se voit,
   dans quel ordre — est dans `6-adaptatif.css`, avec le téléphone, parce
   qu'il n'existe QUE là. Au-delà de 1101 px le ruban est masqué et les
   quinze champs sont affichés d'un bloc, en trois colonnes.

   Quatre carrés reliés par un filet, entre le formulaire et les boutons —
   dans la zone FIXE du bas, pas à la fin du défilement : sur les quatre
   maquettes il reste au même endroit quelle que soit la longueur de l'étape.

   Il prend la gouttière des boutons (--fof-sp-5) et non celle, plus étroite
   de 10 px, de la maquette : 10 n'est pas sur l'échelle base 4, et le ruban
   se cale mieux sur les boutons avec lesquels il partage la barre.

   Le filet est tiré d'un CENTRE de carré à l'autre et passe DERRIÈRE eux —
   les carrés sont opaques, ils le mangent là où il ne doit pas se voir.
   C'est un seul trait pour trois intervalles, au lieu de trois traits à
   placer un par un. */
.fof-ef-steps{flex:0 0 auto;position:relative;display:flex;align-items:center;
  justify-content:space-between;padding:0 var(--fof-sp-5);}
.fof-ef-steps::before{content:"";position:absolute;top:50%;
  left:calc(var(--fof-sp-5) + 28 * var(--fof-px));
  right:calc(var(--fof-sp-5) + 28 * var(--fof-px));
  height:calc(2 * var(--fof-px));margin-top:calc(-1 * var(--fof-px));
  background:var(--fof-border);}
/* 56 px : la maquette en donne 166 unités, et son échelle est de 3 unités
   par pixel (le carré d'icône du titre et la hauteur d'un champ le disent
   tous les deux). C'est aussi, au passage, bien au-dessus du plancher
   tactile de 44 px — un carré de ruban se vise au pouce. */
.fof-ef-step{position:relative;flex:0 0 calc(56 * var(--fof-px));
  width:calc(56 * var(--fof-px));height:calc(56 * var(--fof-px));padding:0;
  display:flex;align-items:center;justify-content:center;
  border:none;border-radius:var(--fof-r-md);
  background:var(--fof-etape);color:var(--fof-etape-ink);
  font-family:var(--police-titre);font-size:var(--fof-t-titre-etape);
  font-weight:400;letter-spacing:normal;line-height:1;cursor:pointer;
  transition:background .12s,color .12s;}
.fof-ef-step.is-current{background:var(--fof-primary-degrade);color:var(--fof-on-primary);}
/* La corbeille du pied, en modification. `.fof-rf-acts > *` étire tout ce
   qu'il contient à parts égales : le carré à icône, lui, garde sa largeur —
   c'est ce que montre la maquette, deux boutons plus étroits À CÔTÉ d'elle
   et non trois tiers. */
.fof-rf-acts > .fof-icon-btn{flex:0 0 auto;}

/* ── Road Map ──────────────────────────────────────────────────────────
   Une ligne = une heure, une action, et le geste qui va avec. Les deux
   champs gardent les proportions de la maquette (295 et 561 unités, soit
   1 pour 1,9) ; le geste prend ce qu'il lui faut, jamais plus. */
.fof-ef-rm{display:flex;flex-direction:column;gap:var(--fof-sp-3);}
.fof-ef-rm-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.9fr) auto;
  gap:var(--fof-sp-3);align-items:center;}

/* ── Line Up ───────────────────────────────────────────────────────────
   Le poste à gauche, calé à DROITE contre son champ, comme sur la maquette :
   les dix noms s'alignent alors sur une seule verticale, et l'œil descend la
   liste sans repartir de la marge à chaque ligne.
   Le poste n'est pas un `.fof-field-label` : ce n'est pas le libellé du bloc
   (c'est « Line Up » qui l'est), c'est une valeur en regard d'un champ. Il en
   prend donc la taille, dans le gris des mentions.
   Une TROISIÈME colonne est arrivée le 2026-08-28 : la réponse du musicien
   (« Confirmé », « En attente », « Pas dispo »). Elle se règle ici et nulle
   part ailleurs — la fiche en lecture l'affiche sans jamais y toucher. Elle
   prend la largeur du poste, pas celle du nom : c'est un choix entre trois
   mots, pas une liste de dix personnes. Un poste vide n'affiche pas la
   troisième cellule ; la grille laisse alors sa colonne libre, ce qui est
   exactement ce qu'on veut voir — une ligne pas encore pourvue. */
.fof-ef-lu{display:flex;flex-direction:column;gap:var(--fof-sp-3);}
.fof-ef-lu-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.45fr) minmax(0,1.1fr);
  gap:var(--fof-sp-3);align-items:center;}
.fof-ef-lu-role{text-align:right;min-width:0;
  font-size:var(--fof-field-size);color:var(--fof-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ══════════════════════════════════════════════════════════════════════
   BOÎTE MAIL
   ══════════════════════════════════════════════════════════════════════ */
/* Hauteur de la page Mail : la liste défile pour elle-même, sans emmener la
   page. Sur téléphone l'en-tête d'écran et le segmenté prennent la place que
   libère la barre du haut, masquée sur cet écran comme sur l'Agenda — d'où le
   même retrait aux deux largeurs. */
.fof-mail-page{display:flex;flex-direction:column;
  height:calc(100vh - 118 * var(--fof-px));min-height:calc(460 * var(--fof-px));}
/* ⚠️ `.fof-search` porte `flex:1 1 100%` (et `flex:0 0 280px` au-delà de
   760 px) : utile dans la rangée de « Clients », désastreux ici, où
   le PARENT est une colonne flex — le champ s'étirait sur toute la hauteur et
   poussait la liste des messages hors de l'écran. À l'Agenda le problème
   n'existe pas : son parent est un bloc, le `flex` y est ignoré.
   Ne pas retirer cette règle. Les deux autres blocs du haut sont figés pour
   la même raison : dans une colonne flex ils pourraient se comprimer.
   Seul `.fof-mail-body` a le droit de prendre la place restante. */
.fof-mail-page > .fof-ag-top,
.fof-mail-page > .fof-seg,
.fof-mail-page > .fof-search{flex:0 0 auto;}
/* Message ouvert au téléphone : les trois blocs du haut sont RETIRÉS, pas
   seulement recouverts. Recouverts, ils resteraient atteignables au clavier
   et annoncés par un lecteur d'écran. Au-delà de 1101 px ils sont déjà
   masqués par ailleurs (leur contenu vit dans la barre du haut). */
.fof-mail-page.is-reading > .fof-ag-top,
.fof-mail-page.is-reading > .fof-seg,
.fof-mail-page.is-reading > .fof-search{display:none;}
.fof-mail-body{display:flex;flex-direction:column;gap:calc(10 * var(--fof-px));flex:1;min-height:0;}
.fof-mail-main{flex:1;min-width:0;display:flex;flex-direction:column;
  background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-lg);overflow:hidden;}

/* ── Le titre d'écran EST le sélecteur de dossier (2026-08-23) ────────
   Le nom du dossier consulté a pris la place du titre « Boîte mail », et un
   chevron dit qu'il s'ouvre. Aucun habillage propre : c'est le titre de
   l'écran (`.fof-ag-h1`) ou celui de la barre du haut (`.fof-hd-h1`), tels
   quels. Seul le curseur manquait — le titre ne se distinguait en rien d'un
   titre ordinaire à la souris. La règle porte sur le `role="button"` posé
   DANS le titre : le `<h1>` reste un `<h1>` pour un lecteur d'écran, et
   n'importe quel autre écran qui rendrait son titre cliquable en hérite.
   L'ancien bouton « Réception ▾ » (`.fof-mail-folder-select`), en bordeaux
   plein en tête de la liste, a été retiré : le titre le remplace. */
.fof-hd-h1 [role="button"],
.fof-ag-h1 [role="button"]{cursor:pointer;}
.fof-sheet-overlay{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:60;}

/* ── Choix du client (devis / facture) ────────────────────────────────────
   Fermé, `.fof-cli-field` copie AU PIXEL le `<select>` des champs voisins :
   même hauteur, même bordure, même rayon — on ne doit pas voir que ce n'en
   est plus un. Ouvert, le même élément devient un champ de saisie et la
   liste se pose dessous.
   `.fof-cli-catch` est la surface qui rattrape le clic à côté : sans elle on
   ne pourrait refermer qu'en choisissant, ou avec Échap. */
/* Remise des deux dates à aujourd'hui : posé sur la ligne du libellé, donc
   petit, mais la cible tactile reste à 32 px. */
.fof-date-today{flex:0 0 auto;display:inline-flex;align-items:center;
  justify-content:center;width:calc(32 * var(--fof-px));height:calc(32 * var(--fof-px));margin:calc(-6 * var(--fof-px)) 0;
  border:1px solid var(--fof-border);border-radius:calc(8 * var(--fof-px));
  background:var(--fof-surface);color:var(--fof-faint);cursor:pointer;}
.fof-date-today:hover{background:var(--fof-bg);color:var(--fof-ink-2);}
.fof-date-today:focus-visible{border-color:var(--fof-primary);
  box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);outline:none;}

.fof-cli-wrap{position:relative;}
.fof-cli-field{display:flex;align-items:center;gap:calc(8 * var(--fof-px));width:100%;
  height:var(--fof-field-h);padding:0 var(--fof-field-px);
  box-sizing:border-box;text-align:left;
  font-family:inherit;font-size:var(--fof-field-size);color:var(--fof-ink);
  background:var(--fof-field-bg);border:1px solid var(--fof-border);
  border-radius:var(--fof-field-radius);outline:none;cursor:pointer;}
.fof-cli-field > span:first-child{flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.fof-cli-field > svg{flex:0 0 auto;color:var(--fof-faint);}
.fof-cli-field > span.is-empty{color:var(--fof-faint);}
.fof-cli-input{position:relative;z-index:81;cursor:text;}
.fof-cli-field:focus{border-color:var(--fof-primary);box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);}
.fof-cli-list{position:absolute;left:0;right:0;top:calc(52 * var(--fof-px));z-index:81;
  max-height:calc(264 * var(--fof-px));overflow-y:auto;overscroll-behavior:contain;
  background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);box-shadow:var(--fof-shadow);padding:calc(6 * var(--fof-px));}
.fof-cli-opt{display:block;width:100%;min-height:calc(44 * var(--fof-px));padding:calc(11 * var(--fof-px)) calc(10 * var(--fof-px));
  border:none;border-radius:var(--fof-r-sm);background:none;
  color:var(--fof-ink);font-family:inherit;font-size:var(--fof-t-second);line-height:1.3;
  text-align:left;cursor:pointer;}
.fof-cli-opt:hover{background:var(--fof-surface-2);}
.fof-cli-opt.is-selected{background:var(--fof-accent-soft);color:var(--fof-accent-ink);font-weight:600;}
.fof-cli-empty{padding:calc(12 * var(--fof-px)) calc(10 * var(--fof-px));font-size:var(--fof-t-badge);color:var(--fof-faint);}
.fof-cli-catch{position:fixed;inset:0;z-index:80;}
.fof-tel-opt-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fof-tel-opt-dial{flex:0 0 auto;color:var(--fof-faint);font-size:var(--fof-t-badge);}
.fof-tel-opt.is-selected .fof-tel-opt-dial{color:inherit;}

/* Feuille montante : poignée, coins arrondis en haut, action en pied. */
.fof-mail-folders{display:none;flex-direction:column;gap:calc(4 * var(--fof-px));}
.fof-mail-folders.is-open{display:flex;position:fixed;left:0;right:0;bottom:0;
  z-index:61;max-height:70vh;overflow-y:auto;
  background:var(--fof-surface);border-top:1px solid var(--fof-border);
  border-radius:var(--fof-r-xl) var(--fof-r-xl) 0 0;
  padding:calc(20 * var(--fof-px)) calc(16 * var(--fof-px)) calc(20 * var(--fof-px) + env(safe-area-inset-bottom));
  box-shadow:var(--fof-shadow);}
.fof-mail-folders.is-open::before{content:"";display:block;width:calc(38 * var(--fof-px));height:calc(4 * var(--fof-px));
  border-radius:calc(2 * var(--fof-px));background:var(--fof-border);margin:0 auto calc(14 * var(--fof-px));}

/* ── Le bouton ⋮ des filtres, au bout de la bascule de boîte ───────────
   Il vivait en tête de la liste, sur une ligne à lui avec « Réception ▾ ».
   Cette ligne a disparu le 2026-08-23 : le dossier se choisit dans le titre,
   et le ⋮ est passé AU BOUT de la ligne « Boîte commune / Ma boîte » — même
   ligne, mais poussé à droite, parce que filtrer les messages n'est pas
   choisir sa boîte. La liste des messages gagne la hauteur de l'ancienne
   ligne. Sur ordinateur ce bouton s'efface (voir 6-adaptatif.css) : les trois
   filtres y sont des boutons à part entière, dans la barre du haut. */
.fof-mail-more{position:relative;margin-left:auto;flex:0 0 auto;}

/* ── Ligne de message : deux niveaux, extrait sur une seule ligne ─────── */
.fof-ml-row{display:flex;align-items:flex-start;gap:calc(12 * var(--fof-px));
  padding:calc(12 * var(--fof-px)) calc(14 * var(--fof-px));cursor:pointer;background:var(--fof-surface);
  border-bottom:1px solid var(--fof-border-soft);
  -webkit-user-select:none;user-select:none;transition:background .12s;}
.fof-ml-row:hover{background:var(--fof-surface-2);}
.fof-ml-row.is-checked{background:var(--fof-accent-soft);
  box-shadow:inset calc(3 * var(--fof-px)) 0 0 var(--fof-primary);}
.fof-ml-dot{flex:0 0 calc(8 * var(--fof-px));width:calc(8 * var(--fof-px));height:calc(8 * var(--fof-px));margin-top:calc(7 * var(--fof-px));border-radius:50%;
  background:transparent;}
.fof-ml-row.is-unread .fof-ml-dot{background:var(--fof-primary);}
.fof-ml-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(2 * var(--fof-px));}
.fof-ml-line1{display:flex;align-items:baseline;gap:calc(10 * var(--fof-px));}
.fof-ml-from{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-ml-date{flex-shrink:0;}
.fof-ml-subject{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Extrait : une seule ligne, jamais deux — mais une ligne entière, du point
   de non-lu jusqu'au bord droit, depuis que la colonne de droite a
   disparu. */
.fof-ml-snippet{font-size:var(--fof-t-second);color:var(--fof-muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-ml-chips{display:flex;flex-wrap:wrap;gap:calc(6 * var(--fof-px));margin-top:calc(6 * var(--fof-px));}
.fof-ml-chip{display:inline-flex;align-items:center;padding:calc(3 * var(--fof-px)) calc(9 * var(--fof-px));
  border-radius:var(--fof-r-sm);font-size:var(--fof-t-badge);font-weight:600;
  background:var(--fof-surface-2);color:var(--fof-muted);white-space:nowrap;}
.fof-ml-chip.is-crm{background:var(--fof-info-soft);color:var(--fof-info);cursor:pointer;}
.fof-ml-chip.is-important{background:var(--fof-warning-soft);color:var(--fof-warning);}
/* La corbeille des brouillons ferme la ligne de la date, au lieu de tenir une
   colonne à part sur toute la hauteur de la ligne de message (2026-08-24).
   Elle garde ses 44 px de large : sa place à droite ne bouge pas d'un pixel.
   Seule la hauteur tombe à 24 px, celle de la ligne qu'elle partage
   maintenant — restée à 44 px, elle aurait haussé d'autant chaque ligne de la
   liste.
   L'étoile portait cette même classe et occupait cette même place. Elle a
   quitté la liste le 2026-08-24 (demande d'Etienne) : elle est sous la main
   dans la barre du haut dès que le message est ouvert. Le nom de la classe et
   son `align-self:baseline` restent tels quels — c'est le réglage d'un
   contenu TEXTE, qui se pose sur la ligne de base comme l'expéditeur et la
   date ; centré dans la ligne, un glyphe descendait 1,5 px plus bas que les
   chiffres. Plus rien ne l'emprunte aujourd'hui (la corbeille est un dessin,
   voir la règle suivante), mais il attend là si l'étoile revient. */
.fof-ml-star{flex:0 0 calc(44 * var(--fof-px));height:calc(24 * var(--fof-px));align-self:baseline;display:flex;align-items:center;
  justify-content:center;font-size:calc(18px * var(--fof-echelle-texte));cursor:pointer;border-radius:var(--fof-r-md);}
/* Le contenu de la corbeille est un DESSIN, pas un texte : il n'a pas de ligne
   de base, et le navigateur en invente une — le bas de la boîte. Posée dessus,
   l'icône flottait 6 px au-dessus de l'étoile et haussait la ligne des seuls
   brouillons. Un dessin se centre, un texte s'aligne : les deux tombaient
   alors au même endroit à 1 px près. */
.fof-ml-star:has(svg){align-self:center;}

/* ── Vue message ─────────────────────────────────────────────────────────
   Au téléphone, la lecture d'un message occupe TOUT l'écran et passe
   par-dessus la barre de navigation basse (z-index 35) : le titre de la
   page, la bascule de boîte, la recherche et les onglets du bas n'ont
   aucune utilité pendant qu'on lit. On en sort par le chevron de retour —
   ou par le geste de retour du téléphone.
   Au-delà de 1101 px la classe est neutralisée : le message reprend sa
   place dans le bloc, à droite de la colonne des dossiers. */
.fof-mv{display:flex;flex-direction:column;flex:1;min-height:0;
  position:fixed;inset:0;z-index:36;background:var(--fof-surface);
  padding-top:env(safe-area-inset-top);}

/* Barre du haut réduite à quatre cibles : retour, étoile, dossier, menu.
   Le libellé « Retour » disparaît — un chevron seul suffit.
   Elle porte AUSSI l'objet du message. Au téléphone elle se replie : la
   rangée d'icônes reste sur sa ligne, l'objet passe en dessous et retrouve
   au pixel près la place qu'il occupait dans `.fof-mv-head` (le filet qui
   les séparait est simplement porté par l'objet, d'où le `border-bottom`
   retiré ici). Sur ordinateur, tout tient sur une seule ligne. */
.fof-mv-topbar{display:flex;align-items:center;flex-wrap:wrap;gap:calc(4 * var(--fof-px));
  padding:calc(8 * var(--fof-px)) calc(10 * var(--fof-px)) 0;}
.fof-mv-tb-actions{display:flex;align-items:center;gap:calc(4 * var(--fof-px));
  flex:0 0 auto;margin-left:auto;}
.fof-mv-icon{width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));display:inline-flex;align-items:center;
  justify-content:center;border:none;border-radius:var(--fof-r-md);
  background:none;color:var(--fof-muted);font-family:inherit;font-size:calc(20px * var(--fof-echelle-texte));cursor:pointer;}
.fof-mv-icon:hover{background:var(--fof-surface-2);}
.fof-mv-menu{position:absolute;right:0;top:calc(48 * var(--fof-px));z-index:40;min-width:calc(250 * var(--fof-px));
  background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);box-shadow:var(--fof-shadow);padding:calc(6 * var(--fof-px));}
.fof-mv-menu-item{display:flex;align-items:center;width:100%;min-height:calc(44 * var(--fof-px));
  padding:0 calc(12 * var(--fof-px));border:none;border-radius:var(--fof-r-sm);background:none;
  color:var(--fof-ink);font-family:inherit;font-size:var(--fof-t-libelle);font-weight:500;
  text-align:left;text-decoration:none;cursor:pointer;}
.fof-mv-menu-item:hover{background:var(--fof-surface-2);}
.fof-mv-menu-item.is-sub{padding-left:calc(26 * var(--fof-px));font-size:var(--fof-t-second);color:var(--fof-muted);}
.fof-mv-menu-item.is-danger{color:var(--fof-danger);}

/* En-tête : la ligne expéditeur, puis la carte CRM. L'objet est remonté
   dans la barre du haut ; le retrait supérieur passe donc avec lui, sinon
   l'expéditeur se retrouverait décalé de 14 px de trop. */
.fof-mv-head{padding:0 calc(18 * var(--fof-px)) calc(14 * var(--fof-px));border-bottom:1px solid var(--fof-border-soft);}
/* Objet — troisième et dernier élément de la barre du haut au téléphone :
   il prend toute la largeur, sous la rangée d'icônes. Les marges négatives
   lui rendent les bords de l'écran, pour que son filet supérieur remplace
   à l'identique celui que portait la barre. */
.fof-mv-subject{order:3;flex:1 1 100%;margin:calc(8 * var(--fof-px)) calc(-10 * var(--fof-px)) 0;padding:calc(14 * var(--fof-px)) calc(18 * var(--fof-px)) 0;
  border-top:1px solid var(--fof-border-soft);
  font-size:var(--fof-t-fiche);font-weight:700;letter-spacing:calc(-.3 * var(--fof-px));
  line-height:1.25;color:var(--fof-ink);word-break:break-word;}
/* Pastille d'initiales, unique modèle pour l'expéditeur et pour la fiche
   liée : fond posé, encre bordeaux — pas l'avatar à fond plein du CRM,
   la capture montre des pastilles claires. */
.fof-mv-av{flex:0 0 calc(44 * var(--fof-px));width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));border-radius:var(--fof-r-md);
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--fof-surface-2);color:var(--fof-primary);
  font-size:var(--fof-t-second);font-weight:700;letter-spacing:calc(.3 * var(--fof-px));}
.fof-mv-from{display:flex;align-items:center;gap:calc(12 * var(--fof-px));margin-top:calc(14 * var(--fof-px));}
.fof-mv-from-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(2 * var(--fof-px));}
.fof-mv-from-name{font-size:var(--fof-t-corps);font-weight:700;color:var(--fof-ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-mv-from-meta{font-size:var(--fof-t-second);color:var(--fof-muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

/* Le lien vers la fiche CRM est une carte : pastille, nom, ligne
   secondaire, et « Ouvrir » en action à droite. */
.fof-mv-crm{display:flex;align-items:center;gap:calc(12 * var(--fof-px));width:100%;margin-top:calc(12 * var(--fof-px));
  min-height:calc(64 * var(--fof-px));padding:calc(10 * var(--fof-px)) calc(14 * var(--fof-px));border-radius:var(--fof-r-md);
  background:var(--fof-surface-2);border:1px solid transparent;
  color:var(--fof-ink);font-family:inherit;text-align:left;cursor:pointer;}
.fof-mv-crm:hover{background:var(--fof-bg);}
.fof-mv-crm .fof-mv-av{background:var(--fof-surface);}
.fof-mv-crm-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(2 * var(--fof-px));}
.fof-mv-crm-name{font-size:var(--fof-t-corps);font-weight:700;color:var(--fof-ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-mv-crm-second{font-size:var(--fof-t-second);color:var(--fof-muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-mv-crm-open{flex:0 0 auto;font-size:calc(15px * var(--fof-echelle-texte));font-weight:700;color:var(--fof-primary);}

/* Pièces jointes : cartes posées dans le corps du message, sans bandeau
   gris ni icône de téléchargement — la carte entière est le lien. */
.fof-mv-atts{display:flex;flex-direction:column;gap:calc(8 * var(--fof-px));
  flex-shrink:0;padding:calc(4 * var(--fof-px)) calc(18 * var(--fof-px)) calc(16 * var(--fof-px));background:var(--fof-surface);}
.fof-mv-att{display:flex;align-items:center;gap:calc(12 * var(--fof-px));min-height:calc(64 * var(--fof-px));
  padding:calc(10 * var(--fof-px)) calc(14 * var(--fof-px));border-radius:var(--fof-r-md);
  background:var(--fof-surface);border:1px solid var(--fof-border);
  color:var(--fof-muted);text-decoration:none;}
.fof-mv-att:hover{background:var(--fof-surface-2);}
.fof-mv-att-badge{flex:0 0 auto;width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));border-radius:var(--fof-r-md);
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--police-mono);font-size:calc(12px * var(--fof-echelle-texte));font-weight:700;}
.fof-mv-att-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(2 * var(--fof-px));}
.fof-mv-att-name{font-size:calc(15px * var(--fof-echelle-texte));font-weight:700;color:var(--fof-ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-mv-att-size{font-size:var(--fof-t-second);color:var(--fof-faint);}

/* Pied : « Répondre » en action dominante, puis deux carrés d'icône.
   Trois cibles de 52 px, comme l'annonce la capture. */
.fof-mv-footer{display:flex;gap:calc(8 * var(--fof-px));flex-shrink:0;
  padding:calc(10 * var(--fof-px)) calc(12 * var(--fof-px)) calc(10 * var(--fof-px) + env(safe-area-inset-bottom));
  border-top:1px solid var(--fof-border);background:var(--fof-surface);}
.fof-mv-action{flex:1 1 auto;min-height:calc(52 * var(--fof-px));display:inline-flex;
  align-items:center;justify-content:center;gap:calc(8 * var(--fof-px));
  border:none;border-radius:var(--fof-r-md);
  background:var(--fof-primary-degrade);color:var(--fof-on-primary);
  font-family:inherit;font-size:calc(15px * var(--fof-echelle-texte));font-weight:700;cursor:pointer;}
.fof-mv-action:hover{background:var(--fof-primary-hover);}
.fof-mv-sq{flex:0 0 calc(52 * var(--fof-px));width:calc(52 * var(--fof-px));min-height:calc(52 * var(--fof-px));display:inline-flex;
  align-items:center;justify-content:center;
  border:1px solid var(--fof-border);border-radius:var(--fof-r-md);
  background:var(--fof-surface);color:var(--fof-ink);
  font-family:inherit;cursor:pointer;}
.fof-mv-sq:hover{background:var(--fof-surface-2);}
.fof-mv-sq.is-danger{color:var(--fof-danger);}

/* ══════════════════════════════════════════════════════════════════════
   CLIENTS
   ══════════════════════════════════════════════════════════════════════ */
/* En-tête : exactement le partage de l'Agenda et de la Boîte mail. Sous
   1101 px, l'écran porte le sien (`.fof-ag-top`, retiré au-delà) ; à partir
   de 1101 px, le titre, le sous-titre et le « + » vivent dans la barre du
   haut. Il n'y a donc plus d'en-tête de page ici — celui qui existait a été
   supprimé, il aurait fait doublon avec la barre.

   Les trois filtres tiennent sur UNE ligne, à parts égales — la place et le
   rythme des onglets de l'Agenda. `min-width:0` sur les enveloppes : sans
   lui, un libellé long (« Statut · Client ») pousserait la ligne au lieu de
   se laisser tronquer, et le troisième filtre passerait dessous. */
.fof-lx-filters{display:flex;align-items:center;gap:calc(8 * var(--fof-px));margin-bottom:var(--fof-gap-e);}
.fof-lx-filters > *{flex:1 1 0;min-width:0;}
.fof-lx-search{display:flex;align-items:center;gap:calc(8 * var(--fof-px));margin-bottom:var(--fof-gap-e);}
.fof-lx-search > *{flex:1 1 auto;min-width:0;}
.fof-lx-chip{display:inline-flex;align-items:center;width:100%;
  justify-content:center;overflow:hidden;white-space:nowrap;}
/* Le libellé est enveloppé pour pouvoir se tronquer proprement : sur un tiers
   d'écran, « Statut · Client » ne tient pas. Le chevron, lui, reste visible —
   c'est le seul indice qu'il s'agit d'un menu. */
.fof-lx-chip-t{min-width:0;overflow:hidden;text-overflow:ellipsis;}
/* Menu déroulant d'un filtre. Écrit UNE fois pour les deux exemplaires — la
   page (téléphone) et la barre du haut (ordinateur) — au lieu des quatre
   styles en ligne identiques qu'il y avait avant. `top:calc(100% + 6px)` et
   non 44 px : le bouton mesure 44 px dans la page mais 52 avec le
   remplissage du segmenté, dans la barre.
   Passé de 240 à 280 px le 2026-08-23 : les statuts ont gagné une case à
   cocher de 24 px à gauche, et « Contacté - En attente de réponse » n'avait
   déjà plus beaucoup de place. Les deux menus « Types » y gagnent de l'air. */
.fof-lx-menu{width:calc(280 * var(--fof-px));position:absolute;left:0;top:calc(100% + 6 * var(--fof-px));z-index:41;
  background:var(--fof-surface);border:1px solid var(--fof-border-soft);
  border-radius:calc(11 * var(--fof-px));overflow:hidden;box-shadow:var(--fof-shadow);
  animation:popIn .14s ease;}
/* Chaque filtre de la barre est une case du segmenté ; celles qui portent un
   menu ont besoin d'être le repère de position de ce menu. */
/* Dans la BARRE DU HAUT, chaque filtre prend la largeur de SON texte.
   Il portait `flex:1 1 0` — base zéro, largeurs égales — hérité du segmenté
   où trois cases se partagent un cadre. Deux défauts en découlaient :
   le libellé se tronquait alors qu'il change de longueur (« Statut » devient
   « Statut · Client »), et l'écart de 8 px entre les boutons ne se voyait
   qu'une fois l'un d'eux actif, la base zéro faussant le calcul de largeur
   du conteneur. Les deux disparaissent avec un dimensionnement au contenu. */
.fof-crm-f{position:relative;display:flex;flex:0 0 auto;}
.fof-crm-hdf .fof-seg-btn{padding:0 calc(14 * var(--fof-px));}
/* … et le libellé ne se tronque plus : il n'y a plus de largeur imposée à
   laquelle il faudrait le plier. Il garde sa troncature au téléphone, où
   les trois filtres SE PARTAGENT bien la largeur de l'écran. */
.fof-crm-hdf .fof-lx-chip-t{overflow:visible;text-overflow:clip;}
.fof-lx-wrap{display:flex;align-items:flex-start;gap:calc(6 * var(--fof-px));}
.fof-lx-list{flex:1;min-width:0;}

/* Intertitre alphabétique dans le flux */
.fof-lx-letter{padding:calc(16 * var(--fof-px)) calc(2 * var(--fof-px)) calc(6 * var(--fof-px));scroll-margin-top:calc(80 * var(--fof-px));}

/* Ligne « entité » : avatar initiales 42 rayon 12 + titre + ligne
   secondaire + un badge. Hauteur minimale 64. */
.fof-lx-row{display:flex;align-items:center;gap:calc(14 * var(--fof-px));width:100%;
  min-height:calc(64 * var(--fof-px));padding:calc(10 * var(--fof-px)) calc(12 * var(--fof-px));text-align:left;cursor:pointer;
  background:var(--fof-surface);color:inherit;font-family:inherit;
  border:none;border-bottom:1px solid var(--fof-border-soft);
  scroll-margin-top:calc(80 * var(--fof-px));transition:background .12s;}
.fof-lx-row:hover{background:var(--fof-surface-2);}
.fof-lx-avatar{flex:0 0 calc(42 * var(--fof-px));width:calc(42 * var(--fof-px));height:calc(42 * var(--fof-px));border-radius:var(--fof-r-md);
  display:flex;align-items:center;justify-content:center;}
.fof-lx-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(2 * var(--fof-px));}
.fof-lx-name{font-size:var(--fof-t-ligne);font-weight:600;line-height:1.3;color:var(--fof-ink);}
.fof-lx-second{font-size:var(--fof-t-second);color:var(--fof-muted);line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fof-lx-badge{flex-shrink:0;white-space:nowrap;}
.fof-lx-chevron{flex-shrink:0;display:flex;color:var(--fof-faint);}

/* ── Rail A→Z ────────────────────────────────────────────────────────────
   MASQUÉ aux deux largeurs depuis le 2026-07-28 : il mangeait de la largeur
   sur la liste. Demande d'Etienne — il veut reprendre son usage, donc RIEN
   n'est supprimé : le gabarit, les ancres (`grp.anchorId`, `row.anchorId`)
   et le calcul de `alphabet` restent en place. Une seule ligne à retirer
   (`display:none`) pour le faire revenir tel quel.
   Le reste de la règle est conservé tel quel, pour la même raison. */
.fof-lx-rail{display:none;
  flex-shrink:0;position:sticky;top:calc(70 * var(--fof-px));align-self:flex-start;
  flex-direction:column;gap:calc(2 * var(--fof-px));padding:calc(6 * var(--fof-px)) calc(2 * var(--fof-px));}

/* ══════════════════════════════════════════════════════════════════════
   FICHE LIEU
   ══════════════════════════════════════════════════════════════════════ */
.fof-pl-head{display:flex;align-items:center;gap:calc(14 * var(--fof-px));padding:calc(16 * var(--fof-px)) calc(16 * var(--fof-px)) calc(12 * var(--fof-px));}
.fof-pl-avatar{flex:0 0 calc(56 * var(--fof-px));width:calc(56 * var(--fof-px));height:calc(56 * var(--fof-px));border-radius:var(--fof-r-lg);
  display:flex;align-items:center;justify-content:center;}
.fof-pl-title{flex:1;min-width:0;}
.fof-pl-name{margin:0;font-size:var(--fof-t-fiche);font-weight:600;letter-spacing:calc(-.3 * var(--fof-px));
  line-height:1.25;color:var(--fof-ink);}
.fof-pl-meta{margin-top:calc(3 * var(--fof-px));font-size:var(--fof-t-second);color:var(--fof-muted);}
/* Trois actions de 52 px, en haut de la zone de lecture. */
.fof-pl-actions{display:flex;gap:calc(8 * var(--fof-px));padding:0 calc(16 * var(--fof-px)) calc(14 * var(--fof-px));}
.fof-pl-action{flex:1 1 0;min-height:calc(52 * var(--fof-px));display:inline-flex;flex-direction:column;
  align-items:center;justify-content:center;gap:calc(3 * var(--fof-px));
  border:1px solid var(--fof-border);border-radius:var(--fof-r-md);
  background:var(--fof-surface);color:var(--fof-ink);text-decoration:none;
  font-family:inherit;font-size:var(--fof-t-badge);font-weight:600;cursor:pointer;}
.fof-pl-action:hover{background:var(--fof-surface-2);}
.fof-pl-action.is-off{opacity:.45;pointer-events:none;}
.fof-pl-topbar{display:flex;align-items:center;gap:calc(6 * var(--fof-px));padding:calc(8 * var(--fof-px)) calc(10 * var(--fof-px));
  background:var(--fof-surface);}
.fof-pl-status{display:flex;align-items:center;gap:calc(10 * var(--fof-px));padding:0 calc(16 * var(--fof-px)) calc(14 * var(--fof-px));
  background:var(--fof-surface);}
.fof-pl-status-label{font-size:var(--fof-t-badge);font-weight:600;color:var(--fof-muted);flex-shrink:0;}
.fof-pl-select{flex:1;min-width:0;height:var(--fof-field-h);padding:0 var(--fof-field-px);
  border:1px solid var(--fof-border);border-radius:var(--fof-field-radius);
  background:var(--fof-surface-2);color:var(--fof-ink);
  font-family:inherit;font-size:var(--fof-field-size);font-weight:600;outline:none;}
.fof-pl-select:focus{border-color:var(--fof-primary);
  box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);background:var(--fof-surface);}
.fof-pl-head,.fof-pl-actions{background:var(--fof-surface);}
.fof-pl-actions{border-bottom:1px solid var(--fof-border-soft);}

/* ══════════════════════════════════════════════════════════════════════
   SETLISTS
   ══════════════════════════════════════════════════════════════════════ */
.fof-sl-sub{margin-top:calc(4 * var(--fof-px));font-size:var(--fof-t-second);color:var(--fof-muted);}
.fof-sl-zone{display:flex;flex-direction:column;gap:calc(8 * var(--fof-px));padding-bottom:calc(12 * var(--fof-px));}

/* Une carte par morceau : numéro, titre 16, note en ligne secondaire,
   poignée de 44 px à droite. Plus de flèches ni de corbeille à 22 px. */
.fof-sl-card{display:flex;align-items:flex-start;gap:calc(12 * var(--fof-px));padding:calc(14 * var(--fof-px));
  background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);transition:transform .13s ease;}
/* ── Glisser-déposer ────────────────────────────────────────────────────
   La carte d'origine ne bouge pas : elle s'efface à moitié et sert de
   repère. Ce qui suit le curseur est une copie opaque (.fof-drag-ghost).
   Là où la carte va se poser, les voisines s'écartent : celle du dessus
   remonte de 14 px, celle du dessous descend d'autant — 28 px d'interstice,
   contre 8 px entre deux cartes au repos, donc impossible à confondre. */
.fof-sl-card.is-dragging{opacity:.5;}
.fof-sl-card.is-drop-here{position:relative;}
.fof-sl-card.is-drop-here::before{content:"";position:absolute;
  left:0;right:0;top:calc(-18 * var(--fof-px));height:calc(3 * var(--fof-px));border-radius:calc(2 * var(--fof-px));
  background:var(--fof-primary);}
.fof-sl-num{flex:0 0 auto;min-width:calc(22 * var(--fof-px));font-size:var(--fof-t-second);font-weight:700;
  color:var(--fof-faint);line-height:1.6;}
.fof-sl-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(8 * var(--fof-px));}
.fof-sl-line{display:flex;align-items:baseline;gap:calc(10 * var(--fof-px));}
.fof-sl-title{flex:1;min-width:0;font-size:var(--fof-t-corps);font-weight:600;color:var(--fof-ink);line-height:1.3;}
.fof-sl-dur{flex-shrink:0;font-size:var(--fof-t-badge);font-weight:600;color:var(--fof-faint);}
.fof-sl-note{width:100%;height:calc(44 * var(--fof-px));padding:0 calc(12 * var(--fof-px));font-family:inherit;font-size:var(--fof-t-second);
  color:var(--fof-ink-2);background:var(--fof-surface-2);outline:none;
  border:1px solid var(--fof-border);border-radius:var(--fof-r-md);}
.fof-sl-note:focus{border-color:var(--fof-primary);box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);
  background:var(--fof-surface);}
.fof-sl-remove,.fof-sl-grip{flex:0 0 calc(44 * var(--fof-px));width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));
  display:inline-flex;align-items:center;justify-content:center;
  border:none;border-radius:var(--fof-r-md);background:none;color:var(--fof-faint);cursor:pointer;}
.fof-sl-remove:hover{background:var(--fof-danger-soft);color:var(--fof-danger);}
.fof-sl-grip{cursor:grab;}
.fof-sl-grip:hover{background:var(--fof-surface-2);color:var(--fof-ink);}

/* Pied : « Ajouter des morceaux », et rien d'autre. La durée est passée en
   tête de la setlist (`.fof-sl-count`) — elle y est lue à côté du contenu
   qu'elle décrit, au lieu d'occuper une barre à elle en bas d'écran. */
.fof-sl-foot{position:sticky;bottom:0;display:flex;align-items:center;gap:calc(8 * var(--fof-px));
  padding:calc(10 * var(--fof-px)) 0 calc(10 * var(--fof-px) + env(safe-area-inset-bottom));
  background:var(--fof-bg);border-top:1px solid var(--fof-border);}
.fof-sl-foot .fof-sl-add{flex:1 1 auto;}

/* ── Éditeur de setlist : fenêtre par-dessus l'écran courant ──────────────
   L'éditeur ne vit plus DANS le menu Setlists : il se pose sur l'écran
   d'où on l'a ouvert. On ne change donc jamais de menu pour modifier une
   setlist, et en refermant on retrouve l'écran intact.
   z-index 58 : au-dessus des pages, en dessous de la feuille « Ajouter des
   morceaux » (60/61), de la fenêtre « Renommer » (70) et du mode scène (90). */
.fof-slmod{position:fixed;inset:0;z-index:58;overflow-y:auto;
  background:var(--fof-bg);}
/* Fond figé dès qu'une fenêtre se pose sur l'éditeur (« Renommer », feuille
   « Ajouter des morceaux », formulaire d'un morceau, confirmation…). Sans
   ce verrou, le doigt qui glisse sur le voile fait défiler la setlist
   derrière : on rouvre la fenêtre sur un écran qui a bougé tout seul.
   Les trois conteneurs qui défilent sont figés ensemble : la fenêtre
   elle-même sur téléphone, les deux colonnes sur ordinateur. La position
   de défilement est conservée, on la retrouve à la fermeture. */
.fof-slmod.is-locked,
.fof-slmod.is-locked .fof-sl-lib-list,
.fof-slmod.is-locked .fof-sl-col-main{overflow:hidden;}
.fof-slmod-inner{box-sizing:border-box;max-width:calc(900 * var(--fof-px));margin:0 auto;
  padding:calc(18 * var(--fof-px)) calc(20 * var(--fof-px)) calc(24 * var(--fof-px) + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;min-height:100%;}
.fof-sl-cols{flex:1 1 auto;min-height:0;display:block;}
/* La zone occupe toute la hauteur de sa colonne : la cible de dépôt est
   grande, on n'a pas à viser la dernière carte au pixel près. */
.fof-sl-col-main{min-width:0;display:flex;flex-direction:column;}
.fof-sl-col-main .fof-sl-zone{flex:1 1 auto;}
/* La colonne bibliothèque n'existe que sur ordinateur : sur téléphone, elle
   prendrait toute la largeur et repousserait la setlist hors de l'écran. */
.fof-sl-lib{display:none;}
/* Une carte de la bibliothèque se saisit par son corps ; ses deux boutons
   gardent le curseur de la main. */
.fof-sl-lib-grab{cursor:grab;}
body.fof-dragging .fof-sl-lib-grab{cursor:grabbing;}
.fof-sl-lib .fof-sl-item.is-dragging{opacity:.5;}
/* Compteur en tête de setlist. Il reprend AU CARACTÈRE PRÈS le gabarit de
   `.fof-btn-primary` / `.fof-sgl-new` — 52 px de haut, pleine largeur, même
   arrondi, même police, même taille, même graisse, même marge basse — pour
   que les deux colonnes s'ouvrent sur une ligne unique. Ce n'est pas un
   bouton : ni `cursor`, ni survol, ni tabulation. */
.fof-sl-count{display:flex;align-items:center;justify-content:center;
  box-sizing:border-box;width:100%;min-height:calc(52 * var(--fof-px));padding:0 calc(18 * var(--fof-px));
  margin-bottom:calc(14 * var(--fof-px));border-radius:var(--fof-r-md);
  background:var(--fof-surface);color:var(--fof-ink);
  border:1px solid var(--fof-border);
  font-family:var(--police-titre);font-size:var(--fof-t-titre-bouton);font-weight:400;
  letter-spacing:normal;white-space:nowrap;}
.fof-sl-empty-wide{display:none;}
.fof-slmod-title{display:flex;align-items:center;gap:calc(10 * var(--fof-px));min-width:0;}
/* Elle vit dans la ligne d'actions : même hauteur que « Renommer » et
   « Valider », sinon elle flotterait au milieu de la rangée. */
.fof-slmod-back{flex:0 0 auto;width:calc(52 * var(--fof-px));height:calc(52 * var(--fof-px));display:flex;
  align-items:center;justify-content:center;border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);background:var(--fof-surface);
  color:var(--fof-ink-2);cursor:pointer;}
.fof-slmod-back:hover{background:var(--fof-surface-2);color:var(--fof-ink);}

/* Feuille « Ajouter des morceaux » */
.fof-sl-sheet{position:fixed;left:0;right:0;bottom:0;z-index:61;
  display:flex;flex-direction:column;max-height:82vh;
  background:var(--fof-surface);border-top:1px solid var(--fof-border);
  border-radius:var(--fof-r-xl) var(--fof-r-xl) 0 0;
  padding:calc(16 * var(--fof-px)) calc(16 * var(--fof-px)) calc(16 * var(--fof-px) + env(safe-area-inset-bottom));
  box-shadow:var(--fof-shadow);}
.fof-sl-sheet::before{content:"";display:block;width:calc(38 * var(--fof-px));height:calc(4 * var(--fof-px));border-radius:calc(2 * var(--fof-px));
  background:var(--fof-border);margin:0 auto calc(14 * var(--fof-px));}
.fof-sl-sheet-head{display:flex;align-items:center;gap:calc(8 * var(--fof-px));}
.fof-sl-sheet-title{flex:1;margin:0;font-size:var(--fof-t-section);font-weight:600;color:var(--fof-ink);}
.fof-sl-sheet-search{width:100%;height:calc(44 * var(--fof-px));margin:calc(12 * var(--fof-px)) 0;padding:0 calc(14 * var(--fof-px));
  font-family:inherit;font-size:var(--fof-field-size);color:var(--fof-ink);
  background:var(--fof-surface-2);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);outline:none;}
.fof-sl-sheet-search:focus{border-color:var(--fof-primary);box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);}
.fof-sl-sheet-list{flex:1;overflow-y:auto;min-height:0;}
.fof-sl-pick{display:flex;align-items:center;gap:calc(12 * var(--fof-px));width:100%;min-height:calc(52 * var(--fof-px));
  padding:calc(8 * var(--fof-px)) calc(4 * var(--fof-px));border:none;background:none;color:inherit;font-family:inherit;
  text-align:left;cursor:pointer;border-bottom:1px solid var(--fof-border-soft);}
.fof-sl-pick-box{flex:0 0 calc(24 * var(--fof-px));width:calc(24 * var(--fof-px));height:calc(24 * var(--fof-px));border-radius:calc(7 * var(--fof-px));
  border:calc(1.5 * var(--fof-px)) solid var(--fof-border);display:inline-flex;align-items:center;
  justify-content:center;font-size:var(--fof-t-second);font-weight:700;}
.fof-sl-pick-title{flex:1;min-width:0;font-size:calc(15.5px * var(--fof-echelle-texte));font-weight:500;color:var(--fof-ink);}
.fof-sl-sheet-foot{display:flex;gap:calc(8 * var(--fof-px));padding-top:calc(12 * var(--fof-px));}
.fof-sl-sheet-foot > *{flex:1 1 0;}

/* Carte de setlist dans la liste */
.fof-sl-item{display:flex;align-items:center;gap:calc(4 * var(--fof-px));margin-bottom:calc(8 * var(--fof-px));
  background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);padding:calc(8 * var(--fof-px)) calc(10 * var(--fof-px));}
.fof-sl-item-main{flex:1;min-width:0;min-height:calc(56 * var(--fof-px));display:flex;align-items:center;
  border:none;background:none;color:inherit;font-family:inherit;text-align:left;cursor:pointer;}

/* ── Fenêtre « Liste des morceaux » ─────────────────────────────────────
   La bibliothèque n'était atteignable nulle part depuis la refonte : elle
   retrouve une fenêtre à elle, ouverte depuis l'en-tête du menu Setlists. */
.fof-sgl-head{display:flex;align-items:flex-start;gap:calc(10 * var(--fof-px));margin-bottom:calc(14 * var(--fof-px));}
.fof-sgl-new{width:100%;margin-bottom:calc(14 * var(--fof-px));}
/* La liste défile seule : l'en-tête et le bouton restent visibles même avec
   une centaine de morceaux. */
.fof-sgl-list{flex:1 1 auto;min-height:0;overflow-y:auto;margin:0 calc(-4 * var(--fof-px));padding:0 calc(4 * var(--fof-px));}

/* ══ Mode scène : lisible depuis un pied de micro ══ */
.fof-stage{position:fixed;inset:0;z-index:90;overflow-y:auto;
  background:var(--fof-bg);
  padding:calc(16 * var(--fof-px)) calc(20 * var(--fof-px)) calc(24 * var(--fof-px) + env(safe-area-inset-bottom));}
.fof-stage-head{display:flex;align-items:center;gap:calc(12 * var(--fof-px));margin-bottom:calc(16 * var(--fof-px));}
.fof-stage-name{flex:1;min-width:0;font-size:var(--fof-t-corps);font-weight:600;color:var(--fof-muted);}
.fof-stage-close{width:calc(52 * var(--fof-px));height:calc(52 * var(--fof-px));border:none;border-radius:var(--fof-r-md);
  background:var(--fof-surface);color:var(--fof-ink);font-size:calc(26px * var(--fof-echelle-texte));cursor:pointer;}
.fof-stage-list{margin:0;padding:0;list-style:none;}
.fof-stage-item{display:flex;align-items:baseline;gap:calc(16 * var(--fof-px));padding:calc(14 * var(--fof-px)) 0;
  border-bottom:1px solid var(--fof-border-soft);}
.fof-stage-num{flex:0 0 auto;min-width:calc(46 * var(--fof-px));font-size:calc(28px * var(--fof-echelle-texte));font-weight:700;color:var(--fof-faint);}
.fof-stage-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(4 * var(--fof-px));}
.fof-stage-title{font-size:var(--fof-t-page);font-weight:700;line-height:1.15;color:var(--fof-ink);}
.fof-stage-note{font-size:calc(20px * var(--fof-echelle-texte));color:var(--fof-muted);line-height:1.3;}

/* ══════════════════════════════════════════════════════════════════════
   DEVIS & FACTURES — trois étapes sur téléphone
   ══════════════════════════════════════════════════════════════════════ */
.fof-ed-stepper{display:flex;gap:calc(6 * var(--fof-px));margin-bottom:calc(18 * var(--fof-px));}
.fof-ed-stepbtn{flex:1 1 0;min-height:calc(44 * var(--fof-px));padding:calc(6 * var(--fof-px)) calc(8 * var(--fof-px));
  display:flex;flex-direction:column;align-items:flex-start;gap:calc(2 * var(--fof-px));
  border:none;border-top:calc(3 * var(--fof-px)) solid var(--fof-border);background:none;
  color:var(--fof-faint);font-family:inherit;font-size:var(--fof-t-badge);font-weight:600;
  text-align:left;cursor:pointer;}
.fof-ed-stepbtn .fof-eyebrow{color:inherit;}
.fof-ed-stepbtn.is-done{border-top-color:var(--fof-primary);color:var(--fof-muted);}
.fof-ed-stepbtn.is-current{border-top-color:var(--fof-primary);color:var(--fof-ink);}

/* Une seule section visible à la fois sous 1100 px. */
.fof-ed-step{display:none;}
.fof-ed-steps.is-step1 .fof-ed-step-1,
.fof-ed-steps.is-step2 .fof-ed-step-2,
.fof-ed-steps.is-step3 .fof-ed-step-3{display:block;}

/* Pied fixe : le total du document reste visible en permanence. */
.fof-ed-foot{position:sticky;bottom:0;display:flex;align-items:center;gap:calc(10 * var(--fof-px));
  margin-top:calc(18 * var(--fof-px));padding:calc(10 * var(--fof-px)) 0 calc(10 * var(--fof-px) + env(safe-area-inset-bottom));
  background:var(--fof-surface);border-top:1px solid var(--fof-border);}
.fof-ed-foot-total{flex:1;min-width:0;display:flex;flex-direction:column;}
.fof-ed-foot-value{font-size:var(--fof-t-section);font-weight:600;color:var(--fof-ink);}

/* Une ligne de prestation = une carte. Champs à 48 px. */
.fof-ln-card{background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-md);padding:calc(12 * var(--fof-px));display:flex;flex-direction:column;gap:calc(10 * var(--fof-px));}
.fof-ln-top{display:flex;align-items:center;gap:calc(6 * var(--fof-px));}
.fof-ln-desig{flex:1;min-width:0;height:var(--fof-field-h);padding:0 var(--fof-field-px);
  font-family:inherit;font-size:var(--fof-field-size);font-weight:600;color:var(--fof-ink);
  background:var(--fof-field-bg);border:1px solid var(--fof-border);
  border-radius:var(--fof-field-radius);outline:none;}
.fof-ln-btn{flex:0 0 calc(44 * var(--fof-px));width:calc(44 * var(--fof-px));height:calc(44 * var(--fof-px));display:inline-flex;
  align-items:center;justify-content:center;border:none;
  border-radius:var(--fof-r-md);background:none;color:var(--fof-faint);cursor:pointer;}
.fof-ln-btn:hover{background:var(--fof-surface-2);color:var(--fof-ink);}
.fof-ln-btn.is-danger:hover{background:var(--fof-danger-soft);color:var(--fof-danger);}
.fof-ln-desc{width:100%;min-height:var(--fof-field-h);padding:var(--fof-field-px);
  resize:vertical;
  font-family:inherit;font-size:var(--fof-t-second);line-height:1.5;color:var(--fof-muted);
  background:var(--fof-surface-2);border:1px solid var(--fof-border);
  border-radius:var(--fof-field-radius);outline:none;}
.fof-ln-row{display:flex;gap:calc(10 * var(--fof-px));}
.fof-ln-qty{flex:0 0 calc(88 * var(--fof-px));}
.fof-ln-pu,.fof-ln-total{flex:1;min-width:0;}
.fof-ln-label{display:block;margin-bottom:calc(4 * var(--fof-px));font-size:var(--fof-t-badge);font-weight:600;color:var(--fof-muted);}
.fof-ln-input{width:100%;height:var(--fof-field-h);padding:0 var(--fof-field-px);
  font-family:inherit;font-size:var(--fof-field-size);
  color:var(--fof-ink);background:var(--fof-field-bg);border:1px solid var(--fof-border);
  border-radius:var(--fof-field-radius);outline:none;}
.fof-ln-input:focus,.fof-ln-desig:focus,.fof-ln-desc:focus{
  border-color:var(--fof-primary);box-shadow:0 0 0 calc(3 * var(--fof-px)) var(--fof-focus);}
.fof-ln-value{height:calc(48 * var(--fof-px));display:flex;align-items:center;justify-content:flex-end;
  font-size:calc(15px * var(--fof-echelle-texte));font-weight:600;color:var(--fof-ink);}
/* Liste des devis et factures */
.fof-dv-line1{display:flex;align-items:center;gap:calc(8 * var(--fof-px));margin-bottom:calc(2 * var(--fof-px));}
.fof-dv-number{font-family:var(--police-mono);font-size:calc(12.5px * var(--fof-echelle-texte));color:var(--fof-muted);}

/* ══════════════════════════════════════════════════════════════════════
   DOCUMENTS
   ══════════════════════════════════════════════════════════════════════ */
.fof-doc-list{display:flex;flex-direction:column;gap:calc(12 * var(--fof-px));max-width:calc(760 * var(--fof-px));}
.fof-doc-card{background:var(--fof-surface);border:1px solid var(--fof-border);
  border-radius:var(--fof-r-lg);padding:calc(16 * var(--fof-px));}
.fof-doc-top{display:flex;align-items:flex-start;gap:calc(14 * var(--fof-px));}
.fof-doc-badge{flex:0 0 auto;padding:calc(6 * var(--fof-px)) calc(10 * var(--fof-px));border-radius:var(--fof-r-sm);
  background:var(--fof-danger-soft);color:var(--fof-danger);
  font-family:var(--police-mono);font-size:calc(12px * var(--fof-echelle-texte));font-weight:600;}
.fof-doc-text{flex:1;min-width:0;}
.fof-doc-label{font-size:var(--fof-t-ligne);font-weight:600;color:var(--fof-ink);line-height:1.3;}
.fof-doc-meta{margin-top:calc(3 * var(--fof-px));font-size:var(--fof-t-second);color:var(--fof-muted);}
.fof-doc-name{font-weight:600;color:var(--fof-ink-2);}
.fof-doc-actions{display:flex;align-items:center;gap:calc(8 * var(--fof-px));margin-top:calc(14 * var(--fof-px));}
.fof-doc-actions .fof-btn-primary{flex:1 1 auto;}
.fof-doc-empty{margin-top:calc(14 * var(--fof-px));padding:calc(18 * var(--fof-px)) calc(14 * var(--fof-px));text-align:center;
  border:calc(1.5 * var(--fof-px)) dashed var(--fof-border);border-radius:var(--fof-r-md);}
.fof-doc-empty-title{margin-bottom:calc(12 * var(--fof-px));font-size:var(--fof-t-libelle);color:var(--fof-muted);}

/* Écran encore à écrire : un cadre, une phrase, rien d'autre. Une seule
   règle pour tous les modules à venir — l'écart avec ce qui précède est
   celui de tous les écrans (`--fof-gap-e`), pas une valeur inventée ici. */
.fof-soon{margin-top:var(--fof-gap-e);padding:calc(22 * var(--fof-px)) calc(16 * var(--fof-px));text-align:center;
  border:calc(1.5 * var(--fof-px)) dashed var(--fof-border);border-radius:var(--fof-r-md);
  font-size:var(--fof-t-libelle);color:var(--fof-muted);}

/* ══════════════════════════════════════════════════════════════════════
   ÉCRAN « PLUS » (navigation mobile)
   ══════════════════════════════════════════════════════════════════════ */
.fof-plus-group{margin-bottom:calc(24 * var(--fof-px));}
.fof-plus-group > .fof-eyebrow{display:block;margin-bottom:calc(8 * var(--fof-px));}
.fof-plus-row{display:flex;align-items:center;gap:calc(12 * var(--fof-px));width:100%;min-height:calc(56 * var(--fof-px));
  padding:calc(10 * var(--fof-px)) calc(14 * var(--fof-px));background:var(--fof-surface);color:inherit;
  border:1px solid var(--fof-border);border-bottom:none;
  font-family:inherit;text-align:left;cursor:pointer;}
.fof-plus-row:first-of-type{border-radius:var(--fof-r-md) var(--fof-r-md) 0 0;}
.fof-plus-row:last-of-type{border-bottom:1px solid var(--fof-border);
  border-radius:0 0 var(--fof-r-md) var(--fof-r-md);}
.fof-plus-row:only-of-type{border-radius:var(--fof-r-md);}
.fof-plus-row:hover{background:var(--fof-surface-2);}
.fof-plus-row.is-danger .fof-plus-label{color:var(--fof-danger);}
.fof-plus-label{flex:1;min-width:0;font-size:var(--fof-t-corps);font-weight:600;color:var(--fof-ink);}
.fof-plus-hint{flex-shrink:0;font-size:var(--fof-t-badge);color:var(--fof-faint);}

/* ── Connexion et recherche ───────────────────────────────────────────── */
.fof-login-card{width:100%;min-width:0;padding:calc(30 * var(--fof-px)) calc(20 * var(--fof-px));}
/* ── L'ombre de la fenêtre de connexion ────────────────────────────────
   Elle « pixelisait » (constat d'Etienne, 2026-08-20) et ce n'était pas
   une image trop compressée : c'est du BANDING, l'escalier d'un dégradé
   très étalé sur un fond plat, en 8 bits par canal.
   Deux causes, corrigées ici toutes les deux.
     • L'ombre était TEINTÉE bordeaux — rgba(40,4,16,…) sur un fond
       #202124. Les trois canaux ne parcourent alors pas la même distance
       (le rouge MONTE de 32 à 36 pendant que le vert descend de 33 à 20),
       ils franchissent donc leurs marches à des endroits différents : on
       ne voyait pas des paliers gris mais des anneaux colorés, bien plus
       visibles que des paliers neutres. Une ombre NOIRE fait tomber les
       trois marches au même pixel.
     • La pente était trop douce : 70 px de flou pour une vingtaine de
       niveaux, soit une marche tous les 3 ou 4 pixels — largement assez
       large pour se lire. Trois ombres empilées, chacune plus courte et
       plus dense, raccourcissent la rampe sans alléger l'ombre.
   Mais AUCUN empilement ne suffit, et c'est une propriété de la gaussienne,
   pas un réglage à trouver : sa queue est plate, donc la DERNIÈRE marche —
   celle où l'ombre rejoint le fond — est toujours large. Modèle du profil
   quantifié à l'appui, elle fait 11 px avec les valeurs ci-dessous, et
   encore 7 px avec l'ombre la plus serrée qu'on puisse écrire sans la faire
   disparaître. C'est ce contour-là qui restait visible.
   D'où le TRAMAGE, qui n'est pas un supplément mais la vraie correction :
   un grain d'un écart-type de 1,7 niveau fait franchir l'arrondi au hasard
   de part et d'autre de la marche, et le profil moyen retrouve la rampe
   continue — à 0,07 niveau près sur toute la longueur.
   Le grain vit dans `assets/fof-grain.svg`, qui explique ses réglages. Il
   est OPAQUE et sa moyenne est calée sur #202124, il ne déplace donc pas
   la couleur du fond — un voile translucide, lui, ne peut qu'ÉCLAIRCIR un
   fond sombre.
   IL DOIT RESTER UN FICHIER À PART. Écrit en URL « data: » ici même, le
   moteur de gabarit réécrivait ses attributs camelCase jusque dans cette
   chaîne CSS (« baseFrequency » devenait « sc-camel-base-frequency ») :
   privée de sa fréquence, la turbulence retombait à zéro et le grain
   sortait uniforme — présent dans la feuille, sans effet à l'écran.
   `image-rendering:pixelated` : sur un écran à 2×, un agrandissement lissé
   moyennerait le grain et lui retirerait la moitié de son amplitude. En
   marches d'escalier, chaque texel devient un carré de 2 × 2 et garde
   toute la sienne.
   Il est sous la carte (`z-index:1` contre 2) : il grène le fond et
   l'ombre, jamais le texte ni les boutons. Si le fichier manque, la couche
   reste vide et le `background` du parent reprend la main. */
/* Les trois couches sont ici, et non dans l'attribut `style` de la carte,
   pour qu'un thème puisse les reprendre — un style en ligne l'emporterait
   sur toute règle. */
.fof-login-card{box-shadow:0 calc(3 * var(--fof-px)) calc(8 * var(--fof-px)) rgba(0,0,0,.58),
  0 calc(10 * var(--fof-px)) calc(20 * var(--fof-px)) rgba(0,0,0,.52),0 calc(22 * var(--fof-px)) calc(40 * var(--fof-px)) rgba(0,0,0,.46);}
/* ── En thème sombre, la même ombre allégée de 15 % ────────────────────
   Demande d'Etienne (2026-08-20), et l'écart qu'il a vu est réel même si
   l'ombre était déjà rigoureusement identique des deux côtés : c'est la
   CARTE qui change. En clair elle est blanche sur un fond à 32, l'ombre
   est un liseré sombre contre un bord éclatant. En sombre elle est à 27,
   donc PLUS SOMBRE que son propre fond, et le halo descend à 13 : carte,
   halo et fond forment une seule masse que l'œil lit en bloc, d'où une
   ombre qui paraît plus lourde à pixels égaux. L'alléger d'un facteur
   0,85 rétablit l'équilibre perçu.
   Le tramage suit sans peine : profil modélisé, la marche passe de 11 à
   12 px sans grain, et l'erreur reste à 0,07 niveau avec. */
[data-theme="dark"] .fof-login-card{box-shadow:0 calc(3 * var(--fof-px)) calc(8 * var(--fof-px)) rgba(0,0,0,.493),
  0 calc(10 * var(--fof-px)) calc(20 * var(--fof-px)) rgba(0,0,0,.442),0 calc(22 * var(--fof-px)) calc(40 * var(--fof-px)) rgba(0,0,0,.391);}
.fof-login-bg{position:relative;}
.fof-login-bg::before{content:'';position:absolute;inset:0;z-index:1;
  pointer-events:none;image-rendering:pixelated;
  background-image:url("/assets/img/fof-grain.svg");}
/* ── Connexion — l'écran du design system V4 ───────────────────────────
   Maquettes : « Figma Etienne/M_Connection_clair.svg » pour ce qui est
   écrit ici, « D_Connection_clair.svg » pour la reprise du bureau, dans
   6-adaptatif.css. Le téléphone d'abord, comme partout dans le projet.

   Les DEUX maquettes donnent les mêmes composants aux mêmes tailles —
   champ de 127 de haut, bouton de 515 × 132, œil de 44, rayons de 21,5 et
   de 40 — c'est la « taille de composants unique » voulue par le DS, et
   c'est pour ça qu'une seule unité, `--ds-unite`, sert aux deux formats.
   Elles donnent aussi les mêmes ÉCARTS, à quatre exceptions près : la
   largeur du panneau, ses retraits du haut et du bas, et l'écart au-dessus
   du message d'erreur. Tout le reste est écrit une seule fois, ici.

   Rien ici ne décrit une FORME : les formes sont les composants du DS
   (`DS_Fofboard_V4.css`). Ce bloc ne fait que les poser les uns par
   rapport aux autres, et chaque écart est mesuré sur la maquette, en
   unités du plan de travail.

   LES NOMBRES SONT CEUX DE LA MAQUETTE, sans conversion. C'est nouveau :
   jusqu'au 2026-09-01 il fallait rattraper l'écart entre la boîte de Figma
   et la boîte du navigateur, ce qui donnait des cotes introuvables sur le
   plan. Depuis que les textes du DS sont rognés à la hauteur de capitale
   (voir la section 5 de `DS_Fofboard_V4.css`), les deux boîtes coïncident :
   un écart lu sur la maquette s'écrit tel quel.

   Deux cotes seulement ne se lisent pas directement, et les deux sont des
   hauts de bloc — Figma pose ses textes à la ligne de base, il faut donc
   remonter d'une hauteur de capitale pour trouver le haut de la boîte :
   l'écart du bloc sous le bord de l'écran, et le retrait haut du panneau.
   Leur calcul est écrit sur place.

   Les repères verts (#00FF00) qui entourent les exports d'Etienne sont ses
   marques de travail. Ils sont tracés à l'EXTÉRIEUR du cadre : l'export
   mesure donc 20 unités de plus dans les deux sens, et toutes les cotes
   sont décalées de 10. C'est enlevé de tous les nombres ci-dessous.

   LA HAUTEUR DU BLOC dans la fenêtre n'est pas la même des deux côtés, et
   ce n'est pas un hasard de cadrage : au téléphone Etienne l'a
   volontairement remonté pour que le clavier, en montant, ne recouvre pas
   les champs. D'où un écart FIXE en haut et `auto` en bas, qui le maintient
   collé vers le haut. Au bureau il est centré (`6-adaptatif.css`), là où
   aucun clavier ne monte.

   Ni l'un ni l'autre ne passe par `justify-content` : sur une fenêtre plus
   courte que le bloc, il couperait le haut sans laisser défiler. */
.fof-conn-page{min-height:100vh;display:flex;background:var(--background-color);}
/* 110,36 : la maquette pose la ligne de base du titre à 194 du bord, et
   Bebas Neue lève ses capitales de 0,697 × 120 = 83,64 au-dessus d'elle. */
.fof-conn-bloc{margin:calc(110.36 * var(--ds-unite)) auto auto;
  display:flex;flex-direction:column;align-items:center;}
/* L'accroche, au-dessus du panneau. Les trois lignes se suivent à 10. */
.fof-conn-titre{margin:0;color:var(--text-color1);}
.fof-conn-soustitre{margin-top:calc(10 * var(--ds-unite));color:var(--text-color1);}
/* `white-space` : le slogan porte 47 espaces avant son tiret, dans les
   deux maquettes. Ils comptent — Figma centre la chaîne entière, espaces
   compris, et ce sont eux qui poussent la phrase à droite du centre. Sans
   cette ligne le navigateur les réduirait à un seul et la phrase
   reviendrait au milieu. « pre-wrap » et non « pre » : les espaces sont
   gardés, mais la ligne peut encore se replier sur un très petit écran au
   lieu de déborder — elle mesure 1023 unités, soit 341 px au téléphone, et
   ne tient donc plus au-dessous de 360 px de large. Etienne le sait : ces
   textes sont provisoires (2026-09-02). */
.fof-conn-slogan{margin-top:calc(10 * var(--ds-unite));color:var(--text-color1);
  white-space:pre-wrap;}
/* Le panneau. Sa largeur est celle du cadre du composant, 900 au
   téléphone ; ses retraits latéraux s'en déduisent — 900 − 2 traits de 3
   − 788 de champ, le tout en deux, soit 53. Sa HAUTEUR n'est pas écrite :
   le contenu la donne, et elle retombe sur les 1026 de la maquette. Un
   panneau dont la hauteur serait figée déborderait au premier texte qui
   s'allonge — et le message d'erreur, lui, s'allonge.

   70,8 en haut : la maquette pose la ligne de base de « Connexion » à
   143,5 du bord intérieur du panneau, et Bebas Neue lève ses capitales de
   0,697 × 100 = 69,7 au-dessus d'elle. */
.fof-conn-panneau{box-sizing:border-box;width:calc(900 * var(--ds-unite));
  display:flex;flex-direction:column;margin-top:calc(120 * var(--ds-unite));
  padding:calc(70.8 * var(--ds-unite)) calc(53 * var(--ds-unite)) calc(114.5 * var(--ds-unite));}
.fof-conn-h2{text-align:center;color:var(--text-color2);}
/* Les deux champs ont le même écart au-dessus d'eux, 60 : le premier le
   compte depuis la ligne de base de « Connexion », le second depuis le bas
   de la boîte de saisie précédente. Les deux sont sur la maquette, et les
   deux formats donnent les mêmes. (Le second valait 58,5 jusqu'au
   2026-09-03 : la boîte de `Champ_connection` descendait alors 1,5 trop bas,
   son trait ayant été lu comme intérieur.) */
.fof-conn-h2 + .fof-conn-champ{margin-top:calc(60 * var(--ds-unite));}
.fof-conn-champ + .fof-conn-champ{margin-top:calc(60 * var(--ds-unite));}
/* Le bouton qui porte l'œil. Il n'a aucune forme à lui : il rend l'icône
   cliquable, et rien d'autre — d'où le dépouillement complet de l'habillage
   que le navigateur pose d'office sur un `<button>`. */
.fof-conn-oeil{flex:none;display:flex;padding:0;border:none;background:none;cursor:pointer;}
/* Le message d'erreur GARDE SA PLACE quand il est vide (demande d'Etienne),
   sans quoi le bouton remonterait d'une ligne à chaque tentative ratée.
   D'où `visibility` et non `display`, et une hauteur minimale : une boîte
   vide, elle, ne fait aucune hauteur du tout. Les 33 unités sont la hauteur
   de capitale de `style_item_menuSB`, 0,66 × 50 — c'est-à-dire la boîte
   d'une ligne, rognage compris. Ce nombre SUIT ce style. */
.fof-conn-erreur{margin-top:calc(50 * var(--ds-unite));min-height:calc(33 * var(--ds-unite));
  text-align:center;color:var(--event-color);}
.fof-conn-erreur.is-vide{visibility:hidden;}
/* La largeur du bouton appartient à l'écran, pas au composant : le DS le
   dessine à 397, les deux maquettes de connexion à 515. */
.fof-conn-btn{margin-top:calc(60 * var(--ds-unite));width:calc(515 * var(--ds-unite));align-self:center;}
/* Sous le panneau. */
.fof-conn-pied{margin-top:calc(120 * var(--ds-unite));color:var(--text-color1);}
.fof-conn-inscription{margin-top:calc(10 * var(--ds-unite));color:var(--event-color);}

.fof-search{position:relative;flex:1 1 100%;}


/* ═══════════════════════════════════════════════════════════════════════════
   AGENDA — la pose des composants du design system V4
   ---------------------------------------------------------------------------
   Maquette « M_AGENDA_clair » du 2026-09-02, cadre de 1100 unités. Chaque
   nombre écrit ici est celui qui se lit sur la maquette : depuis que Figma
   rogne ses textes à la hauteur de capitale et que le CSS fait de même, les
   cotes se recopient sans arithmétique.

   Ce qui est ici est la POSE. La forme des pièces — leurs hauteurs, leurs
   rayons, leurs couleurs — est dans `DS_Fofboard_V4.css`, sous le nom que
   chacune porte dans Figma.
   ═══════════════════════════════════════════════════════════════════════════ */

/* L'écran annule le retrait que `.fof-main` pose encore pour les écrans non
   refaits, et met le sien : 40 sur les côtés, 20 en haut. */
/* La marge du bas annule le retrait que `.fof-main` réserve à la barre basse :
   celle-ci porte désormais sa propre réserve d'écran (« safe area »), et sans
   cela les deux retraits se cumuleraient. */
.fof-ag4-page{margin:calc(-16 * var(--fof-px)) calc(-20 * var(--fof-px))
              calc(0px - 106 * var(--fof-px) - env(safe-area-inset-bottom));
  padding:calc(20 * var(--ds-unite)) calc(40 * var(--ds-unite)) calc(280 * var(--ds-unite));
  background:var(--background-color);}
/* La barre du bas est COLLÉE à la fenêtre — une maquette Figma ne sait pas dire
   « fixe », mais une barre de menu au téléphone ne se lit pas autrement. Elle
   sert TOUS les écrans depuis le 2026-09-02 : elle a quitté l'agenda pour la
   coquille, où elle remplace l'ancienne `.fof-sidebar` du téléphone. */
.MenuMobile_Footer{position:fixed;left:0;right:0;bottom:0;z-index:35;
  height:calc(200 * var(--ds-unite) + env(safe-area-inset-bottom));
  padding-bottom:env(safe-area-inset-bottom);}
.fof-menu4-mitem{display:flex;align-items:center;justify-content:center;
  padding:0;border:none;border-radius:0;background:none;cursor:pointer;
  color:var(--text-color2);}
.fof-menu4-mitem.is-selected{background:none;color:var(--event-color);}

/* ── L'en-tête ─────────────────────────────────────────────────────────────
   132 de haut, la hauteur du bouton « + ». Le titre s'y aligne par sa
   CAPITALE et non par son cadratin : c'est le rognage qui rend ce centrage
   juste, et la maquette le confirme — les deux ont le même centre, à 86 du
   haut de la page. */
.fof-ag4-top{display:flex;align-items:center;justify-content:space-between;
  height:calc(132 * var(--ds-unite));}
.fof-ag4-addwrap{position:relative;display:flex;}
.fof-ag4-add{display:flex;padding:0;border:none;background:none;cursor:pointer;}

/* ── Les trois onglets ─────────────────────────────────────────────────────
   40 sous l'en-tête. Trois colonnes égales et 60 entre elles : 3 × 300 + 2 × 60
   font exactement 1020, la largeur du contenu. Écrire les colonnes en parts
   égales plutôt qu'à 300 laisse l'écran suivre la largeur du téléphone. */
.fof-ag4-seg{margin-top:calc(40 * var(--ds-unite));
  display:grid;grid-template-columns:repeat(3, 1fr);gap:calc(60 * var(--ds-unite));}

.fof-ag4-search{margin-top:calc(40 * var(--ds-unite));}

/* ── Le carrousel ──────────────────────────────────────────────────────────
   La piste et son glissé sont ceux de l'ancien écran (`.fof-ag-track`, dont le
   geste vit dans `05-barre-du-haut.js`) : seule la carte change. */
.fof-ag4-carousel{margin-top:calc(20 * var(--ds-unite));overflow:hidden;touch-action:pan-y;}
.fof-ag-track > .fof-ag4-next{flex:0 0 100%;}

/* ── LA CARTE « PROCHAINS CONCERTS (Mobile) » ──────────────────────────────
   Composant du DS depuis le 2026-09-04, posé dans « M_AGENDA_clair » et
   TÉLÉPHONE UNIQUEMENT — la maquette de bureau ne le dessine pas, et la logique
   ne le rend pas au-delà de 1101 px (`agShowNextBlock`).

   LA CARTE FAIT 1020 × 820, un `RoundedPanel is-degrade`, 40 de retrait tout
   autour. Ses blocs ont des places fixes, et c'est la condition posée par
   Etienne le 2026-09-02 : le glissé du carrousel ne doit faire sauter aucun
   contenu d'une fiche à l'autre. Ce qui manque laisse donc un vide, rien ne
   remonte.

        40   la rangée du statut, haute de 70 — nature, statut, décompte
        68   puis le titre, sur UNE ligne de Bebas 120
        68   puis la pastille du nom de groupe, 65
        30   puis la date, en jaune de décompte
        30   puis le lieu
        30   puis l'heure
        40   du bas : le pied, haut de 140 — la setlist à gauche, le get-in
             et son GPS à droite

   CE QUI A CHANGÉ LE 2026-09-04 : la carte n'a plus de sur-titre de date en
   première ligne mais une rangée de badges — la nature, le statut, et le
   décompte à droite ; la date, le lieu et l'heure sont descendus sous la
   pastille du groupe, en trois lignes ; le pied a perdu son badge de statut et
   gagné l'icône de la setlist. */
/* Les retraits valent 3 de moins que la maquette : `RoundedPanel` garde son
   trait, écrit en transparent pour que la boîte ne rétrécisse pas, et ce trait
   rentre. Ce qui est posé DEDANS part donc du bord intérieur — 40 − 3. */
.fof-ag4-next{position:relative;height:calc(820 * var(--ds-unite));
  padding:calc(37 * var(--ds-unite));
  cursor:pointer;-webkit-tap-highlight-color:transparent;}

/* ── La rangée du haut ─────────────────────────────────────────────────────
   70 de haut, celle du décompte. Le badge de statut, qui fait 76 avec son
   trait, y déborde de 3 en haut et en bas — comme dans la fiche.
   La nature et le statut sont collés à gauche, le décompte à droite. Les 40 de
   retrait supplémentaires devant la nature sont ceux de la maquette : elle
   pose son texte à 80 du bord de la carte quand le décompte s'arrête à 40. */
.fof-ag4-next-statut{display:flex;align-items:center;justify-content:space-between;
  height:calc(70 * var(--ds-unite));}
.fof-ag4-next-statut > .left{display:flex;align-items:center;
  gap:calc(45 * var(--ds-unite));padding-left:calc(40 * var(--ds-unite));}

/* ── Le titre ──────────────────────────────────────────────────────────────
   68 sous la rangée, et il tient sur UNE ligne : la carte a une hauteur fixe,
   un retour à la ligne pousserait tout ce qui suit et le carrousel ferait
   sauter le contenu d'une fiche à l'autre. Un titre trop long est donc coupé
   aux trois points, comme celui d'une ligne du panneau d'un mois.

   LE RETRAIT DU HAUT N'EST PAS UN ÉCART, C'EST DE LA PLACE POUR LES ACCENTS :
   `overflow:hidden` coupe au bord de la boîte, et le rognage a ramené cette
   boîte sur la hauteur de CAPITALE — le É et le À passeraient au-dessus. Le
   retrait rouvre la boîte vers le haut, la marge négative la remet en place. */
.fof-ag4-next-name{margin:calc(68 * var(--ds-unite)) 0 0;text-align:center;}
.fof-ag4-next-name > .style_titre_menu2{display:block;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  padding-top:calc(0.12 * var(--ds-taille) * var(--ds-unite));
  margin-top:calc(-0.12 * var(--ds-taille) * var(--ds-unite));}

/* ── La pastille du groupe, puis les trois lignes ──────────────────────────
   68 sous la ligne de base du titre, puis 30 entre chacune des trois lignes.
   La date reprend le jaune du décompte, à côté duquel elle était posée jusqu'au
   2026-09-04 ; le lieu et l'heure sont en blanc, sur le dégradé. */
/* La pastille GARDE SA PLACE même sans nom de groupe : sa hauteur est écrite
   sur la rangée, pas seulement sur la pastille. Sans cela, une fiche sans nom
   ferait remonter les trois lignes et le carrousel sauterait. */
.fof-ag4-next-band{margin-top:calc(68 * var(--ds-unite));
  height:calc(65 * var(--ds-unite));
  display:flex;justify-content:center;}
.fof-ag4-next-date,
.fof-ag4-next-lieu,
.fof-ag4-next-heure{margin-top:calc(30 * var(--ds-unite));text-align:center;}
.fof-ag4-next-date{color:var(--badge-decompte-bckgd);}

/* ── Le pied ───────────────────────────────────────────────────────────────
   140 de haut, à 40 des trois bords. La setlist à gauche, le get-in et son GPS
   à droite — et la marge automatique du get-in le garde à droite même quand la
   setlist manque.

   LA RÈGLE DU GET-IN N'A PAS BOUGÉ (feuille « Info - règles ») : sur une date
   confirmée ou en attente, le get-in et son icône paraissent ; sur tout autre
   statut, ils disparaissent. Le badge de statut, lui, ne se centre plus quand
   ils s'en vont — il a quitté le pied pour la rangée du haut.

   L'ICÔNE DE LA SETLIST ne paraît que si la date en a une, et elle ouvre le
   MODE SCÈNE de cette setlist — la lecture « live », la même fenêtre que l'œil
   du menu « Setlists » (Etienne, 2026-09-04). Sans setlist, pas d'icône : une
   tuile qui n'ouvrirait rien n'a rien à faire là. */
.fof-ag4-next-foot{position:absolute;
  left:calc(37 * var(--ds-unite));right:calc(37 * var(--ds-unite));
  bottom:calc(37 * var(--ds-unite));
  height:calc(140 * var(--ds-unite));
  display:flex;align-items:center;}
.fof-ag4-setlist{display:flex;padding:0;border:none;background:none;
  color:inherit;cursor:pointer;}
/* 16 entre le libellé du get-in et son carré : la cote de la maquette. Elle
   vaut 40 dans la fiche d'une date, où le couple est centré ; ici il est collé
   au bord droit et se resserre. */
.fof-ag4-getin{display:flex;align-items:center;margin-left:auto;
  gap:calc(16 * var(--ds-unite));}
.fof-ag4-gps{display:flex;color:inherit;}

/* ── Les points du carrousel ───────────────────────────────────────────────
   Un pas de 72, le point courant au milieu de la rangée. Le bouton fait 72 de
   côté : c'est la taille que donne la maquette, et elle vaut 24 px au
   téléphone — sous le plancher tactile de 44, comme les icônes du pied.
   Même remarque, même arbitrage à venir. */
/* ⚠ 4 ET NON 24 : la maquette pose le POINT à 24 sous la carte, et le point
   n'est pas le bouton. Le bouton fait 72 de côté quand le point actif n'en fait
   que 32 — il déborde donc de 20 en haut, qu'il faut retirer de l'écart.
   C'étaient 24 jusqu'au 2026-09-04, quand le point tombait 44 sous la carte. */
.fof-ag4-dots{margin-top:calc(4 * var(--ds-unite));
  display:flex;justify-content:center;}
.fof-ag4-dot{width:calc(72 * var(--ds-unite));height:calc(72 * var(--ds-unite));
  display:flex;align-items:center;justify-content:center;
  padding:0;border:none;background:none;cursor:pointer;}

/* ── L'intertitre d'un mois ────────────────────────────────────────────────
   « OCTOBRE 2026 » puis le nombre de dates, 40 plus loin, alignés l'un sur
   l'autre par le CENTRE de leurs capitales — ce que la maquette montre, et ce
   que `align-items:center` fait une fois les textes rognés.
   110 depuis le panneau du mois précédent, 114 depuis les points. */
.fof-ag4-month{margin-top:calc(110 * var(--ds-unite));
  display:flex;align-items:center;gap:calc(40 * var(--ds-unite));
  padding-left:calc(10 * var(--ds-unite));color:var(--text-color1);}
.fof-ag4-dots + .fof-ag4-month{margin-top:calc(114 * var(--ds-unite));}
.fof-ag4-month-n{color:var(--text-color2);}

/* ── Le panneau d'un mois ──────────────────────────────────────────────────
   30 sous l'intertitre, et PLUS AUCUN RETRAIT depuis le 2026-09-03 : les
   lignes le remplissent d'un bord à l'autre, chacune portant les siens. La
   maquette va jusqu'à les poser sur le bord EXTÉRIEUR du panneau, trait
   compris ; en CSS elles s'arrêtent au bord intérieur, et le panneau est donc
   plus haut de deux traits — 6 unités, 2 px au bureau. */
.fof-ag4-panel{margin-top:calc(30 * var(--ds-unite));padding:0;}
/* Le trait sépare deux lignes et court d'un bord à l'autre du panneau : il
   ressort donc du trait, des deux côtés. Aucune marge en haut ni en bas — les
   30 qui l'entourent appartiennent aux lignes. */
.fof-ag4-sep{margin:0 calc(-3 * var(--ds-unite));}

/* ── Une ligne ─────────────────────────────────────────────────────────────
   `Item_Agenda` porte la disposition ; il ne reste ici qu'à défaire le bouton
   et à rendre le texte à la gauche. Son retrait à elle vient du composant : on
   ne l'écrase pas. */
.fof-ag4-row{width:100%;border:none;background:none;
  text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.fof-ag4-row > .contenu{align-items:flex-start;}
.fof-ag4-row-title,
.fof-ag4-row-where{color:var(--text-color1);}
/* Le titre d'une ligne tient sur UNE ligne : la ligne fait 180 de haut, un
   retour à la ligne la ferait déborder. D'où la coupe aux trois points.

   LE RETRAIT DU HAUT N'EST PAS UN ÉCART, C'EST DE LA PLACE POUR LES ACCENTS.
   `overflow:hidden` coupe au bord de la boîte, et le rognage a justement ramené
   cette boîte sur la hauteur de CAPITALE : le É de « RÉPÉTITION » et le À de
   « À NIVEAU » passaient au-dessus, et disparaissaient. Le retrait rouvre la
   boîte vers le haut, la marge négative la remet où elle était. */
.fof-ag4-row-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  padding-top:calc(0.12 * var(--ds-taille) * var(--ds-unite));
  margin-top:calc(-0.12 * var(--ds-taille) * var(--ds-unite));}

/* ═══════════════════════════════════════════════════════════════════════════
   LA FICHE D'UNE DATE OU D'UNE RÉPÉTITION — la pose
   ---------------------------------------------------------------------------
   Maquette « BLOC_ReadEvent=Clair_v2 » du 2026-09-04, et la colonne de droite
   de « D_AGENDA_Clair_v2 » qui la reprend telle quelle sur 1271 unités au lieu
   de 1100 : mêmes écarts verticaux, mêmes retraits, seule la largeur change.
   Le bloc se pose donc sans rien savoir de sa largeur — colonne de droite sur
   ordinateur, écran plein au téléphone. Une répétition lit les mêmes balises
   qu'une date : elle n'en remplit que trois sections, et elle les porte en
   bleu.

   ⚠ CE N'EST PLUS UNE SUITE DE CARTES, MAIS UN SEUL PANNEAU. Les six
   `RoundedPanel` du 2026-08-28 n'en font plus qu'un, et ce sont des
   `BorderSeparate_horiz` qui séparent les sections à l'intérieur. Ce que la
   décision d'Etienne protégeait ne change pas pour autant : UNE SECTION VIDE
   NE PARAÎT PAS, et elle emporte son trait avec elle — le trait est écrit DANS
   la condition de la section qu'il ouvre, jamais avant.

   Le panneau ne connaît que DEUX retraits, et tout en découle :
       40   le bord du panneau — le crayon, les traits de section, le pied ;
       80   le contenu, qui prend 40 de plus.
   En CSS le trait de 3 du panneau rentre : 37 et 77. Ce qui doit revenir au
   bord du panneau ressort du contenu de 40 (`margin-inline: -40`).

   ⚠ LE LOGO DU GROUPE A QUITTÉ LA FICHE : la maquette n'ouvre plus le haut par
   le rectangle large de 450 × 200 ; il n'y reste que le crayon et les deux
   badges. Le logo n'a donc plus que deux emplacements dans l'application, le
   menu de gauche et l'en-tête des documents.

   ⚠ Le retrait du BAS ne se lit sur aucune des deux maquettes : leur panneau
   est un cadre de hauteur fixe (6720 unités) que le contenu ne remplit pas. Il
   est écrit à 40, comme le haut. À corriger si Etienne donne la cote.

   ⚠ LE PANNEAU N'EXISTE QUE SUR ORDINATEUR. Règle d'Etienne du 2026-09-04 : la
   colonne de droite montre « BLOC_ReadEvent=D_Event / D_Repet Clair », le
   téléphone « M_Event / M_Repet Clair ». Les quatre planches ont été comparées
   cote à cote — 199 éléments pour l'évènement, 37 pour la répétition : à la
   virgule près, elles ne diffèrent QUE par le `RoundedPanel`. Le M_ pose la
   fiche à même l'écran, sur un aplat blanc, sans trait ni arrondi ; ses
   retraits sont les MÊMES, 40 au bord et 80 pour le contenu.
   La classe bascule au rendu (`agDetail.blocCls4`) et non par media query :
   une media query ne saurait pas retirer un composant du design system.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Sans panneau, les 40 et les 80 se posent tels quels ; avec lui, son trait de
   3 les rentre — c'est la seule chose que la présence du composant change. */
.fof-rd-bloc {
  padding: calc(40 * var(--ds-unite)) calc(80 * var(--ds-unite));
}
.fof-rd-bloc.RoundedPanel {
  padding: calc(37 * var(--ds-unite)) calc(77 * var(--ds-unite));
}

/* ── « Header fixe » : ce qui coiffe la fiche ──────────────────────────────
   Arrivé le 2026-09-04. Une boîte de 445, à 40 du haut du panneau et à 40 de
   ses côtés — elle ressort donc des 80 du contenu — et qui se ferme sur un
   `BorderSeparate_horiz`. Dedans, dans cet ordre :

       132   la rangée du crayon : nature et statut à gauche, crayon à droite
        20   puis le bandeau du titre, 170
        27   puis la pastille du groupe, 65
        28   puis le trait, 3
       ---
       445   et le contenu ouvre 100 plus bas.

   ⚠ LA MAQUETTE L'APPELLE « HEADER FIXE ». Rien n'est écrit ici de ce que ce
   nom promet — un en-tête qui reste en place pendant que la fiche défile. La
   pose est celle de la planche, le comportement attend l'accord d'Etienne :
   il demanderait de choisir où l'en-tête se colle, ce que devient l'arrondi du
   panneau sous lui, et ce qu'il fait dans la feuille plein écran du téléphone.

   ⚠ LE CRAYON N'A PLUS SA TUILE : c'est la variante « Wire » du DS, un simple
   tracé. Voir `icon_modifier.is-wire`. */
.fof-rd-entete {
  margin: 0 calc(-40 * var(--ds-unite));
}
.fof-rd-entete > .BorderSeparate_horiz {
  margin-top: calc(28 * var(--ds-unite));
}

/* La rangée du haut : la nature et le statut collés à gauche, le crayon collé
   à droite, tous centrés sur la hauteur du crayon. */
.fof-rd-haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: calc(132 * var(--ds-unite));
}
.fof-rd-edit {
  display: flex;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

/* ── La nature et le statut ────────────────────────────────────────────────
   ⚠ LA MAQUETTE DESSINE LA NATURE COMME UN `badges_big` SANS BOÎTE — c'est la
   variante « concert » du composant, que la planche trace en texte seul. Le
   texte garde donc le retrait du badge, 25,2 de part et d'autre, alors que rien
   ne se voit autour ; et les 45 qui suivent sont l'écart entre les deux badges.
   40 + 25,2 pose « CONCERT » à 65,2, et la boîte du statut à 326,8 : la planche
   dit 65,4 et 327.
   On garde le texte tel quel plutôt que d'ajouter une variante sans fond à
   `badges_big` — c'est une pose, pas un composant neuf. */
.fof-rd-type {
  display: flex;
  align-items: center;
  gap: calc(45 * var(--ds-unite));
}
.fof-rd-type > .style_item_titre_item_agenda {
  padding: 0 calc(25.2 * var(--ds-unite));
}
/* ⚠ LA NATURE PREND LA COULEUR DE SA NATURE, et elle ne l'avait pas : le DS ne
   pose `--event-color` / `--repet-color` que DANS `Item_Agenda`, et la fiche
   n'est pas une ligne d'agenda — le mot y tombait donc en encre ordinaire.
   Relevé par Etienne le 2026-09-04.

   Les quatre variantes « nature » de `badges_big` sur la planche :
       concert Clair      #56011E   = --event-color clair
       concert Sombre     #FE6332   = --event-color sombre
       repetition Sombre  #679AFF   = --repet-color sombre
       repetition Clair   #2A5FA8   ← la seule qui ne soit pas sur sa nature
   La quatrième vaut --badge-repetition-txt, le jeton des badges de STATUT, dont
   le concert s'est justement écarté (--badge-concert-txt est un violet, #4C3BAF,
   que la planche ne dessine nulle part). Trois variantes sur quatre disent donc
   la couleur de nature, `Item_Agenda` la dit aussi pour le même mot dans le même
   thème, et c'est elle qui est écrite ici. À confirmer avec Etienne.

   Le sélecteur nomme le STYLE et pas seulement le modificateur : `is-repet` sert
   aussi à la pastille de date, il repeindrait ses trois lignes blanches. */
.fof-rd-type > .style_item_titre_item_agenda.is-event {
  color: var(--event-color);
}
.fof-rd-type > .style_item_titre_item_agenda.is-repet {
  color: var(--repet-color);
}

/* ── Le titre, sur son bandeau ─────────────────────────────────────────────
   Le titre est posé sur un bandeau depuis le 2026-09-03 : un Bebas 100 blanc
   sur le dégradé de la nature — le même `RoundedPanel is-degrade` que la carte
   du carrousel, bleu quand c'est une répétition.

   Le bandeau ÉPOUSE le titre : 75,25 de part et d'autre sur la maquette, dont
   3 pour le trait transparent que `is-degrade` laisse en place. Sa hauteur de
   170 est écrite en MINIMUM et non en hauteur : un titre trop long revient à
   la ligne et le bandeau grandit, au lieu de déborder du panneau. Les 47,15
   du haut et du bas sont ce qui reste de 170 une fois retirés les deux traits
   et la capitale de Bebas 100 (0,697 × 100).

   IL NE TIENT PAS DANS LES 80 DU CONTENU, et la maquette ne l'y met pas : sur
   le bloc de 1100 le bandeau fait 992 et commence à 54, quand le contenu n'a
   que 940 de large. Il n'a plus à ressortir de rien depuis le 2026-09-04 : il
   vit dans l'en-tête, qui est déjà à la ligne des 40 et lui laisse donc 1020
   avant de passer à la ligne. */
.fof-rd-nom {
  margin: calc(20 * var(--ds-unite)) 0 0;
  text-align: center;
}
.fof-rd-nom-bande {
  display: inline-block;
  max-width: 100%;
  min-height: calc(170 * var(--ds-unite));
  padding: calc(47.15 * var(--ds-unite)) calc(72.25 * var(--ds-unite));
}
/* ⚠ SUR UNE RÉPÉTITION, LE BANDEAU N'EST PAS UN DÉGRADÉ. « BLOC_ReadEvent=Repet
   Clair » (2026-09-04) le peint en aplat de `--repet-background`, cerné et écrit
   en `--repet-txt` — la paire de la `PastilleDATE` d'une répétition. C'est donc
   un `RoundedPanel` ORDINAIRE, dont le trait se VOIT ; et un trait qui se voit
   pousse la boîte de 3 sur chaque bord, 998 × 176 au lieu de 992 × 170, ses
   retraits de 3 avec elle. Le texte, lui, ne bouge pas : 841,6 dans les deux.
   C'est tout ce qui sépare les deux en-têtes — 451 de haut sur une répétition,
   445 sur une date. */
.fof-rd-nom-bande.is-repet {
  min-height: calc(176 * var(--ds-unite));
  padding: calc(50.15 * var(--ds-unite)) calc(75.25 * var(--ds-unite));
  background: var(--repet-background);
  border-color: var(--repet-txt);
  color: var(--repet-txt);
}
.fof-rd-band {
  display: flex;
  justify-content: center;
  margin-top: calc(27 * var(--ds-unite));
}

/* ── Les lignes d'information ──────────────────────────────────────────────
   Le trait qui sépare deux lignes : 40 sous la ligne de base de la précédente,
   40 au-dessus de la capitale de la suivante. Il ne ressort PAS du retrait —
   contrairement au trait de section, la maquette l'arrête au bord du contenu,
   80 et 1020. */
.fof-rd-sep {
  margin: calc(40 * var(--ds-unite)) 0;
}
.fof-rd-sep + .Read_item_text {
  margin-top: calc(40 * var(--ds-unite));
}

/* ── L'itinéraire ──────────────────────────────────────────────────────────
   L'heure du get-in et le carré, côte à côte et centrés. Une répétition n'a
   pas d'heure — le carré s'y retrouve seul, et le centrage le place au milieu
   sans une règle de plus.

   ⚠ SUR UNE DATE IL EST DÉSORMAIS ENCADRÉ : « BLOC_ReadEvent=D_Event Clair »
   du 2026-09-04 l'entoure d'un trait de 6 en couleur d'évènement, rayon 32,
   qui va d'un bord à l'autre des 40 — il ressort donc des 80 du contenu. Le
   cadre fait 252 de haut : 6 + 50 + les 140 du carré + 50 + 6. Et il ouvre 70
   sous la dernière ligne d'information, là où le carré seul ouvrait à 120.

   ⚠ UNE RÉPÉTITION N'EN A PAS, ET N'EN AURA PAS : « BLOC_ReadEvent=D/M_Repet
   Clair » gardent le carré nu à 120, et Etienne a confirmé le 2026-09-04 que
   ces deux planches sont dans leur ÉTAT DÉFINITIF. C'est donc `is-repet` qui
   pose cette différence, et elle est voulue — voir plus bas. */
.fof-rd-getin {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(40 * var(--ds-unite));
  margin: calc(70 * var(--ds-unite)) calc(-40 * var(--ds-unite)) 0;
  padding: calc(50 * var(--ds-unite)) 0;
  border: calc(6 * var(--ds-unite)) solid var(--event-color);
  border-radius: calc(32 * var(--ds-unite));
}
/* ── CE QUI SÉPARE UNE RÉPÉTITION D'UNE DATE ───────────────────────────────
   Décision d'Etienne du 2026-09-04, sur question : « les planches de répétition
   restent dans cet état, c'est leur état définitif. Un bouton d'édition pour
   l'ensemble de la fiche ici. »

   UNE RÉPÉTITION SE MODIFIE D'UN SEUL BOUTON, celui du haut. Ses titres de
   section n'ont donc pas de crayon, et n'étant plus des rangées de 70 ils
   redeviennent le seul libellé rogné. Son itinéraire n'est pas encadré et son
   pavé de texte garde ses 397. Trois différences, trois règles, et ce ne sont
   pas des provisoires : c'est le dessin. */
.fof-rd-bloc.is-repet > .fof-rd-getin {
  margin: calc(120 * var(--ds-unite)) 0 0;
  padding: 0;
  border: none;
}
.fof-rd-bloc.is-repet .fof-rd-titre {
  display: block;
  height: auto;
}
/* `display:none` et non `visibility` : le crayon quitte aussi le parcours au
   clavier. */
.fof-rd-bloc.is-repet .fof-rd-secedit {
  display: none;
}
/* Le pavé de texte a maigri de 397 à 360 sur les planches de date ; celle de la
   répétition le garde à 397. */
.fof-rd-bloc.is-repet .Item_Note {
  height: calc(397 * var(--ds-unite));
}
.fof-rd-getin-h {
  color: var(--text-color1);
}
.fof-rd-gps,
.fof-rd-tel {
  display: flex;
  color: inherit;
}

/* ── Les titres de section, et ce qui les suit ─────────────────────────────
   40 entre la ligne de base d'un titre et le haut de ce qu'il annonce ; 110
   quand une deuxième section s'ouvre SANS trait entre les deux — la note et
   les infos techniques, le client et le contact sur place, la road map sous
   l'itinéraire. Le premier bloc du panneau n'en prend aucun, et c'est ce qui
   rend l'écart juste quel que soit ce qui est rempli : sur une fiche sans
   note, ce sont les infos techniques qui ouvrent la section, et elles ouvrent
   sans écart. */
/* ⚠ UN TITRE DE SECTION PORTE SON CRAYON depuis le 2026-09-04 : le libellé à
   gauche, `icon_modify_70x70` collé à droite, sur une rangée haute de 70 — la
   taille de l'icône — où la CAPITALE du libellé est centrée.
   Les trois écarts ne changent pas de valeur pour autant, ils changent de
   point d'appui : ils se comptent depuis la RANGÉE et non plus depuis la
   capitale, et la maquette les redonne tels quels — 60 après un trait, 110
   quand une seconde section s'ouvre sans trait, 40 avant ce que le titre
   annonce.
   Le style rogné reste sur le LIBELLÉ et non sur la rangée : les deux
   pseudo-éléments du rognage deviendraient des éléments flex posés à côté du
   texte si on le mettait sur un conteneur `flex`.

   ⚠ CES SIX CRAYONS OUVRENT TOUS LE MÊME ÉCRAN pour l'instant, celui du crayon
   du haut : la planche donne l'icône et sa place, pas sa destination, et il
   n'existe pas encore d'écran de saisie par section. Etienne l'a confirmé le
   2026-09-04 — « oui, c'est prévu » : le jour où chaque section aura le sien,
   il n'y aura que le `onClick` de chaque bouton à changer dans le gabarit. */
.fof-rd-titre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(40 * var(--ds-unite));
  height: calc(70 * var(--ds-unite));
  color: var(--text-color1);
}
.fof-rd-secedit {
  display: flex;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}
.fof-rd-bloc > * + .fof-rd-titre,
.fof-rd-bloc > * + .fof-rd-lignes {
  margin-top: calc(110 * var(--ds-unite));
}
.fof-rd-titre + *,
.fof-rd-liste {
  margin-top: calc(40 * var(--ds-unite));
}
/* ⚠ APRÈS L'ITINÉRAIRE, UN TITRE N'EN PREND QUE 60 et non 110 : depuis qu'il
   est encadré, il ferme sa section comme le ferait un trait. C'étaient 110
   jusqu'au 2026-09-04, quand le carré y était nu. */
.fof-rd-bloc > .fof-rd-getin + .fof-rd-titre {
  margin-top: calc(60 * var(--ds-unite));
}
/* 100 sous l'en-tête, quoi qu'il y ait dessous. Écrit APRÈS la règle des 110,
   à spécificité égale, pour l'emporter sur elle. C'était 90 sous la pastille du
   groupe jusqu'au 2026-09-03, puis 70 ; la pastille est maintenant DANS
   l'en-tête, et c'est lui qui porte l'écart. */
.fof-rd-bloc > .fof-rd-entete + * {
  margin-top: calc(100 * var(--ds-unite));
}
.fof-rd-liste {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--ds-unite));
}
/* Le line up et les contacts respirent davantage : 30 au lieu de 10. */
.fof-rd-liste.is-lineup {
  gap: calc(30 * var(--ds-unite));
}

/* ── Le trait qui sépare deux sections ─────────────────────────────────────
   60 de part et d'autre, et il revient au bord du panneau : il ressort donc
   des 80 du contenu. Les deux 60 se rejoignent par fusion des marges — d'où la
   règle qui suit, qui doit venir APRÈS celle des 110 pour l'emporter sur elle
   à spécificité égale. */
.fof-rd-secsep {
  margin: calc(60 * var(--ds-unite)) calc(-40 * var(--ds-unite));
}
.fof-rd-bloc > .fof-rd-secsep + * {
  margin-top: calc(60 * var(--ds-unite));
}

/* ── Le pied : qui a créé la fiche, qui l'a modifiée ───────────────────────
   DANS le panneau depuis le 2026-09-04 — il en était sorti jusque-là. Son
   trait est celui des sections, 60 au-dessus ; en dessous, 20 seulement, et 20
   encore entre les deux mentions. C'étaient 40 : la maquette pose ses deux
   lignes de base à 40 l'une de l'autre, ce qui fait 20 entre la ligne de base
   de la première et la capitale de la seconde — la cote que le rognage
   demande. */
.fof-rd-pied {
  margin-top: calc(60 * var(--ds-unite));
  color: var(--text-color2);
}
.fof-rd-pied > .BorderSeparate_horiz {
  margin: 0 calc(-40 * var(--ds-unite)) calc(20 * var(--ds-unite));
}
.fof-rd-stamp + .fof-rd-stamp {
  margin-top: calc(20 * var(--ds-unite));
}
