:root{
  /* ── LE SOL, L'ENCRE, LES GRIS ─────────────────────────────────────────
     Une craie froide, et jamais de blanc pur en fond de page : le blanc est
     réservé aux objets posés dessus, c'est lui qui les détache. */
  --craie:#F0F2F6; --blanc:#FFFFFF; --creux:#F7F9FC; --brume:#E4E8EF; --filet:#D7DCE6;
  --encre:#0E1726; --encre-2:#1B2740; --ardoise:#55627A;
  /* DEUX GRIS TERTIAIRES, et aucun seul ne pouvait faire les deux.
     Le tertiaire se pose sur deux fonds opposés : le rail à l'encre et les
     surfaces claires. Pour tenir 4,5:1 des deux côtés il faudrait un gris à
     la fois plus clair que #8A94A8 et plus sombre que lui. Un seul jeton
     mentait donc forcément d'un côté, et c'était celui des surfaces claires :
     #8A94A8 y plafonnait à 3,05:1 sur blanc et 2,72:1 sur la craie, pour des
     capitales de 10,5 px. --estompe garde le rail (5,89:1 sur l'encre),
     --estompe-clair prend le reste (5,05:1 sur blanc, 4,51:1 sur la craie). */
  --estompe:#8A94A8; --estompe-clair:#626F89;
  /* Le fond du rail est un JETON depuis le 22/09/2026. Il était écrit en dur
     à deux endroits de v3-style.ts, dont un sous media query : la refonte a
     passé le rail à l'encre, la seconde occurrence est restée ivoire, et le
     bandeau de marque est devenu blanc sur ivoire en dessous de 820 px. Une
     couleur qu'une refonte doit reprendre ne s'écrit pas deux fois.
     Aucun accent grave d'ouverture ici : ce fichier est un littéral TS. */
  --rail-fond:var(--encre);
  /* Et son TEXTE, qui ne peut pas rester en arrière. Le 23/09/2026, la règle
     du rail portait encore la couleur d'encre : de l'encre sur l'encre depuis
     que le fond avait viré au sombre. Rien ne se voyait, parce que chaque
     enfant du rail (la marque, les liens, le pied) refixe sa couleur ; mais le
     premier élément ajouté là sans sa propre règle serait devenu invisible.
     Un fond et son texte sont un couple : ils changent ensemble ou pas du tout.
     Pas d'accent grave ici non plus, pour la raison dite juste au-dessus. */
  --rail-texte:#C9D1E0;
  /* L'ACTION, et rien d'autre : un seul bouton plein par écran. */
  --cobalt:#1D3FD8; --cobalt-vif:#3B6BFF; --cobalt-fonce:#152FA5; --cobalt-voile:#E9EDFF;
  /* LES TROIS GRAVITÉS : teintes ET clartés distinctes, lisibles sans couleur.
     La menthe dit « c'est fait », et ne se confond plus avec l'action depuis
     que l'action n'est plus verte. */
  --menthe:#0A7C72; --menthe-fonce:#06564F; --menthe-voile:#DDF0ED;
  --ambre:#A35D00; --ambre-fonce:#7A4600; --ambre-voile:#F7EBD8;
  --grenat:#C42350; --grenat-fonce:#9B1B3F; --grenat-voile:#FCE4EA;
  /* QUI ÉCRIT. Deux teintes d'IDENTITÉ, et elles ne paraissent que dans le
     carnet de bord de l'équipe. Elles ne disent ni un état ni une action : dans
     un carnet il n'y a ni l'un ni l'autre à dire, il y a des mains. Elles sont
     choisies hors des teintes de la maison (198° et 15°, contre 229 pour le
     cobalt, 175 pour la menthe, 34 pour l'ambre) et elles tiennent 5,67:1,
     7,31:1 et 7,32:1 sur blanc. Une quatrième personne prendra un quatrième
     jeton, pas une gravité recyclée : la prune est déjà prise, elle dit
     « c'est un agent qui parle » et ne peut pas dire un nom. */
  --equipe-a:#0B6E99; --equipe-a-voile:#E3F1F7;
  --equipe-b:#9A3412; --equipe-b-voile:#F8EAE4;
  --equipe-c:#A21B62; --equipe-c-voile:#F9E7EF;
  /* LA VOIX DES AGENTS. Jamais un état, jamais une action. */
  --prune:#6D3A8E; --prune-fonce:#572D74; --prune-voile:#EFE6F6;
  /* LE COBALT QUAND IL EST DU TEXTE (un lien, un chiffre actif, une icône
     posée sur la surface) : tout « color:var(--cobalt) » des écrans qui
     tiennent la nuit est passé sur lui. LE LIEN, séparé de l'action le 24/09/2026. Le jour ils ont la même
     valeur ; la nuit ils ne PEUVENT pas l'avoir : un bleu assez sombre pour
     porter du blanc (bouton plein) est trop sombre pour se lire sur un fond
     noir (lien). Aucun bleu ne tient 4,5:1 des deux côtés. */
  --lien:var(--cobalt);
  /* LE TEXTE POSÉ SUR UN APLAT PLEIN (cobalt, grenat…). Blanc le jour ET la
     nuit. Aujourd'hui ces textes s'écrivent encore var(--blanc), qui veut dire
     « la surface » et vire au sombre la nuit : ils passent sur ce jeton écran
     par écran, et c'est ce qui bloque l'allumage de la nuit. */
  --sur-plein:#FFFFFF;
  /* LES SURFACES INVERSÉES : la bulle du rail, le toast, la barre de lot.
     Le jour elles sont à l'encre ; la nuit, l'encre devient le texte clair,
     elles ne peuvent donc plus la prendre pour fond. Elles portent du
     --sur-plein, dans les deux lumières. */
  --inverse:var(--encre);
  /* LE SURVOL D'UNE ENTRÉE DU RAIL. Il valait --encre-2 (un bleu nuit sous du
     blanc), qui devient un gris clair la nuit : le blanc y disparaissait. */
  --rail-survol:var(--encre-2);
  /* LES APLATS QUI PORTENT DU TEXTE : l'étiquette d'agent, le bouton qui
     détruit. Le jour ce sont la prune et le grenat eux-mêmes. La nuit, ces
     deux teintes s'éclaircissent pour se lire en TEXTE sur du noir, et le
     blanc posé dessus tombait à 2,5:1 et 3:1 : un aplat a donc sa teinte à lui,
     plus sombre. Même dilemme que --lien, dans l'autre sens. */
  --prune-plein:var(--prune); --grenat-plein:var(--grenat);
  /* La coche « fait » est un aplat de menthe sous du blanc : même dilemme,
     même réponse. */
  --menthe-plein:var(--menthe);
  /* LE SURVOL D'UN APLAT D'ACTION. Le jour il fonce : --cobalt-fonce. La nuit
     --cobalt-fonce est le texte posé sur le voile, donc un bleu CLAIR, et le
     blanc du bouton survolé tombait à 1,75:1. Le survol a son jeton. */
  --cobalt-survol:var(--cobalt-fonce);

  /* Deux ombres, et c'est tout le relief : plus aucun objet n'est cerné. */
  --ombre-1:0 1px 2px rgba(14,23,38,.05), 0 8px 20px -12px rgba(14,23,38,.22);
  --ombre-2:0 2px 6px rgba(14,23,38,.07), 0 20px 40px -16px rgba(14,23,38,.42);
  /* ── LA MATIÈRE DE LA PAGE D'ACCUEIL, MONTÉE AU SOCLE LE 23/09/2026 ──────
     Le verre, les deux nappes et la trame de points étaient écrits en clair
     dans accueil-style.ts, cantonnés sous body.lp. C'était la bonne décision
     tant qu'ils ne servaient qu'à une page ; dès qu'un deuxième écran les
     veut, ce sont des valeurs recopiées, et deux copies d'une couleur
     divergent toujours. Ce qui est partagé monte au socle.

     Les teintes ne sont pas nouvelles : la nappe chaude est le cobalt vif à
     16 %, la nappe froide la menthe à 10 %, la trame l'encre à 16 %. Elles
     s'écrivent en rgba parce qu'une variable ne se glisse pas dans un
     hexadécimal ; c'est la seule raison, et c'est pour ça que le jeton porte
     la FORME entière (la nappe, l'ombre) plutôt que la seule couleur. */
  --verre:linear-gradient(180deg,rgba(255,255,255,.72),rgba(255,255,255,.50));
  --verre-plein:rgba(255,255,255,.94);
  --verre-flou:blur(22px) saturate(190%);
  --verre-bord:rgba(255,255,255,.72);
  /* LE HALO DE FOCUS, une fois pour toutes. Il était écrit à la main partout,
     et dans trois teintes : du cobalt, et deux restes du vert d'avant. Un
     anneau de focus qui change de couleur selon l'écran ne se reconnaît plus. */
  --halo:0 0 0 3px var(--cobalt-voile);
  --halo-faux:0 0 0 3px var(--grenat-voile);
  /* LES DEUX OMBRES DU VERRE : celle qui décolle vers le bas, celle qui
     décolle vers le haut pour une surface collée en bas d'écran.

     PLUS D'ARÊTE CLAIRE (27/09/2026). Elles portaient une ombre intérieure
     d'un pixel en haut, un reflet : sur une carte, Karim y voyait un trait en
     haut, de jour comme de nuit. Le verre se lit à son flou et à son cadre ;
     test/en-dur.test.ts interdit le retour de l'arête. */
  --verre-haut:0 1px 2px rgba(14,23,38,.04),0 8px 22px -14px rgba(14,23,38,.22);
  --verre-bas:0 -10px 26px -20px rgba(14,23,38,.3);
  --verre-ombre:0 12px 40px -18px rgba(14,23,38,.48);
  --verre-reflet:linear-gradient(180deg,rgba(255,255,255,.55),rgba(255,255,255,0));
  --nappes:radial-gradient(900px 520px at 78% -8%, rgba(59,107,255,.16), transparent 62%),radial-gradient(760px 460px at 4% 12%, rgba(10,124,114,.10), transparent 60%);
  --trame:radial-gradient(rgba(14,23,38,.16) 1px, transparent 1px);
  --trame-pas:26px 26px;
  /* LES NAPPES DE L'APPLICATION, plus franches que celles de l'accueil : sous
     un écran chargé de cartes en verre, trois halos (cobalt, menthe, prune)
     sont ce qui donne au verre quelque chose à flouter. Fixes, ils ne
     défilent pas avec la page. */
  --nappes-app:radial-gradient(1100px 700px at 88% -10%, rgba(59,107,255,.26), transparent 60%),radial-gradient(900px 640px at -6% 38%, rgba(10,124,114,.18), transparent 62%),radial-gradient(900px 620px at 70% 112%, rgba(109,58,142,.16), transparent 60%);
  /* L'ombre colorée du bouton plein. Elle n'existe que sous le cobalt : une
     ombre teintée sous un bouton neutre donne une tache, pas du relief. */
  --ombre-cobalt:0 1px 0 rgba(255,255,255,.28) inset,0 10px 26px -12px rgba(29,63,216,.9);
  --ombre-cobalt-haut:0 14px 32px -12px rgba(29,63,216,1);

  /* ── L'ÉCHELLE DES RAYONS ────────────────────────────────────────────────
     Cinq crans, et pas un de plus. L'écran d'immatriculation en comptait
     VINGT-DEUX à lui seul : 2, 4, 5, 8, 9, 10, 11, 12, 14, 18, 20 px, plus
     99px et 999px pour la même pastille. Personne n'a décidé ça : ça s'est
     accumulé, un composant à la fois, et c'est ce qui donne l'impression que
     rien ne va ensemble. Rien ne se répète, donc rien ne fait système.

     Le cran suit l'échelle de l'objet : un champ n'a pas le rayon d'une
     surface flottante, et les deux n'ont pas à être choisis à chaque fois. */
  --r-1:8px;    /* champ, petite pastille, segment */
  --r-2:12px;   /* bouton, carte de choix */
  --r-3:16px;   /* carte principale, panneau */
  --r-4:20px;   /* surface flottante, boîte de dialogue */
  --r-plein:999px;
  /* Les deux anciens noms restent, et ils POINTENT sur l'échelle : cent
     soixante références les citent, les renommer d'un coup casserait quarante
     écrans pour un gain d'esthétique de nommage. */
  --radius:var(--r-3); --radius-sm:var(--r-1);

  --sortie:cubic-bezier(.2,.8,.2,1);
  /* Cinq durées, chacune pour une famille de gestes. */
  --d-instant:90ms;   /* un appui : le bouton s'enfonce */
  --d-court:160ms;    /* un survol, un changement de couleur */
  --d-moyen:280ms;    /* un panneau qui s'ouvre, un onglet qui glisse */
  --d-long:520ms;     /* une entrée à l'écran, une barre qui se remplit */
  --d-recit:900ms;    /* un chiffre qui défile, un anneau qui se trace */
  /* Trois courbes. --c-sortie est l'ancienne --sortie : ce qui arrive freine. */
  --c-sortie:var(--sortie);
  --c-ressort:cubic-bezier(.34,1.4,.64,1);   /* ce qui répond, avec un léger rebond */
  --c-glisse:cubic-bezier(.65,0,.35,1);      /* ce qui se déplace d'un point à un autre */
  /* L'écart entre deux cartes qui entrent en cascade. */
  --cascade:45ms;

  /* UNE SEULE FAMILLE, ET DEUX NOMS POUR ELLE.
     --titre et --sans valent la même chose depuis le 22/09/2026 : ce qui
     distingue un titre d'un paragraphe n'est plus le dessin de la lettre, c'est
     la taille, la graisse et l'interlettrage (l'échelle est dans v4-style.ts).
     Les deux noms restent parce qu'ils disent le RÔLE, et que le jour où un
     écran voudra une police d'affichage, un seul jeton changera. Voir
     web/polices.ts pour le pourquoi de la famille unique. */
  --sans:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --titre:var(--sans);
  /* L'ÉCHELLE, en jetons depuis le 24/09/2026. Ce sont les six crans que
     test/echelle.test.ts tient déjà (11, 13, 15, 17, 22, 32) et les quatre
     rangs de chiffres (20, 26, 34, 54) : rien de nouveau, ils avaient une
     règle et pas encore de nom. Un écran repris écrit var(--t-13), plus 13px. */
  --t-11:11px; --t-13:13px; --t-15:15px; --t-17:17px; --t-22:22px; --t-32:32px;
  --chiffre-20:20px; --chiffre-26:26px; --chiffre-34:34px; --chiffre-54:54px;

  /* La géométrie de la coquille est un jeton : la barre de lot et l'éditeur se
     calent dessus, ils n'ont pas à connaître la largeur du rail.
     --w-agent est la largeur OUVERTE de la colonne de l'agent. Un écran qui
     n'en déclare pas passe en .app.sans-agent, qui la remet à zéro ET retire
     la colonne de la grille : le défaut ne coûte rien à ceux qui n'ont pas
     d'agent. Il valait 0 jusqu'au 31/08, la colonne était alors invisible sur
     tout écran de plus de 1240 px, y compris pour les briques qui en
     déclaraient un. */
  --w-rail:256px; --w-agent:344px;
  /* L'ÉCHELLE D'ESPACEMENT, relevée sur ce que la maison écrit déjà : chaque
     cran porte son nombre, il n'y a donc rien à traduire de tête. Les plus
     employés sont --space-8 en gouttière (60 usages), --space-18 en padding
     intérieur (58) et --space-30 pour le retrait de la zone de travail.
     Elle DÉCRIT l'existant, elle ne le redresse pas : les valeurs impaires
     encore en dur (5, 7, 9, 11, 13, 15) se rapprochent d'un cran au prochain
     passage sur le composant, jamais en masse : une retouche globale
     d'espacement casse des alignements qu'aucun test ne voit. */
  --space-2:2px; --space-4:4px; --space-6:6px; --space-8:8px;
  --space-10:10px; --space-12:12px; --space-14:14px; --space-16:16px;
  --space-18:18px; --space-20:20px; --space-22:22px; --space-30:30px;

  --marque-ovh:#000E9C; --marque-linkedin:#0A66C2; --marque-google:#4285F4;
  --marque-analytics:#E8710A; --marque-fiche-google:#34A853; --marque-bing:#008373;
  --marque-instagram:linear-gradient(45deg,#F9CE34,#EE2A7B 55%,#6228D7);
  /* Le site public du centre, tel que le modèle l'écrit : bordeaux et cuivre. */
  --site-c1:#7A2E4E; --site-c2:#C2703A; --site-ligne:#E9DFDA; --site-encre:#221A1E;
  --site-texte:#4A3F44; --site-ardoise:#6C5F64; --site-doux:#7A6D72; --site-pale:#8A7C81;
  --site-fond:#FCF8F5; --site-trou:#FDF4EC; --site-trou-survol:#FBEADC; --site-trou-texte:#8A4A1E;
  --site-clair:#FFFFFF;
  --site-hero:linear-gradient(140deg,#F7EDF1,#FBF2E9);
  --site-photo:linear-gradient(120deg,#4A2233,#7A2E4E 45%,#C2703A);
}
:root[data-theme="nuit"]{
  --craie:#090C13; --blanc:#10151F; --creux:#0C1119; --brume:#1A2130; --filet:#262E3E;
  --encre:#E8ECF4; --encre-2:#C9D1E0; --ardoise:#A3AEC2;
  --estompe:#7D889E; --estompe-clair:#8994AA;
  --rail-fond:#06080D; --rail-texte:#A9B3C6;
  --cobalt:#3D5CF5; --cobalt-vif:#7C95FF; --cobalt-fonce:#B3C1FF; --cobalt-voile:#18214A;
  --menthe:#2FC6A8; --menthe-fonce:#8BE3D1; --menthe-voile:#0E2A29;
  --ambre:#F0A941; --ambre-fonce:#F8CD8C; --ambre-voile:#2D2414;
  --grenat:#FF5C7F; --grenat-fonce:#FFA3B6; --grenat-voile:#34161F;
  --equipe-a:#5BB8E3; --equipe-a-voile:#0F2733;
  --equipe-b:#F2956B; --equipe-b-voile:#2F1C14;
  --equipe-c:#F283BE; --equipe-c-voile:#301726;
  --prune:#B98CFF; --prune-fonce:#D8BFFF; --prune-voile:#251B3A;
  --lien:#8FA5FF;
  --sur-plein:#FFFFFF;
  --inverse:#2A3345;
  --rail-survol:#1A2130;
  --prune-plein:#7A4FD0; --grenat-plein:#C8284F;
  --menthe-plein:#0E7F71;
  --cobalt-survol:#2A47D9;

  --ombre-1:0 0 0 1px rgba(255,255,255,.03);
  --ombre-2:0 20px 40px -16px rgba(0,0,0,.7);
  --verre:linear-gradient(180deg,rgba(16,21,31,.78),rgba(16,21,31,.60));
  --verre-plein:rgba(16,21,31,.94);
  --verre-bord:rgba(255,255,255,.08);
  --verre-haut:0 8px 22px -14px rgba(0,0,0,.6);
  --verre-bas:0 -10px 26px -20px rgba(0,0,0,.7);
  --verre-ombre:0 12px 40px -18px rgba(0,0,0,.8);
  --verre-reflet:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,0));
  --nappes:radial-gradient(900px 520px at 78% -8%, rgba(76,111,255,.20), transparent 62%),radial-gradient(760px 460px at 4% 12%, rgba(47,198,168,.08), transparent 60%);
  --trame:radial-gradient(rgba(255,255,255,.07) 1px, transparent 1px);
  --nappes-app:radial-gradient(1100px 700px at 88% -10%, rgba(76,111,255,.30), transparent 60%),radial-gradient(900px 640px at -6% 38%, rgba(47,198,168,.14), transparent 62%),radial-gradient(900px 620px at 70% 112%, rgba(185,140,255,.14), transparent 60%);
  --ombre-cobalt:0 1px 0 rgba(255,255,255,.18) inset,0 10px 26px -12px rgba(61,92,245,.8);
  --ombre-cobalt-haut:0 14px 32px -12px rgba(61,92,245,.95);
  color-scheme:dark}

*{box-sizing:border-box} html,body{margin:0;padding:0}
/* 15 px, comme dans la plateforme connectée : une porte de connexion qui se
   lit en 14 et un espace qui se lit en 15 sont deux produits. */
body{font-family:var(--sans);background:var(--craie);color:var(--encre);font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased}
a{color:var(--lien);text-decoration:none} a:hover{text-decoration:underline}
h1{font-family:var(--titre);font-weight:600;font-size:32px;letter-spacing:-.03em;
  line-height:1.1;margin:.2rem 0 .6rem}
h2{font-family:var(--titre);font-weight:600;font-size:22px;letter-spacing:-.02em;margin:0 0 .5rem}
button{font-family:inherit;cursor:pointer}
/* ── contenu ── */
.entete{display:flex;align-items:center;gap:14px;margin-bottom:18px;flex-wrap:wrap}
.entete .souffle{color:var(--ardoise);font-size:15px}
.entete .actions{margin-left:auto;display:flex;gap:8px}
/* ══ LA CARTE ══════════════════════════════════════════════════════════════
   Une surface, trois variantes, et c'est tout ce dont quarante écrans ont
   besoin. Elle existait déjà ici ; aucun écran du parcours ne s'en servait, et
   chacun redessinait la sienne. Onze couleurs et dix-sept ombres écrites à la
   main sur l'immatriculation, pour finir par dessiner la même chose.

   Ce qui change avec elle : quand on décide que les cartes sont un peu moins
   arrondies, on le décide UNE fois. */
.carte{background:var(--blanc);border:1px solid var(--filet);
  border-radius:var(--radius);box-shadow:var(--ombre-1);
  padding:18px 20px;margin-bottom:16px}

/* CE QUI SE CHOISIT. Les trois cartes « Chez moi / Dans un local / Une société
   de domiciliation ». Le survol propose, le choix se voit sans qu'on cherche :
   un filet cobalt à gauche, posé en « inset » pour que la carte ne bouge pas d'un
   pixel : une carte qui grandit à la sélection fait sauter les deux voisines. */
.carte.choix{margin:0;padding:14px 16px;border-radius:var(--r-2);
  box-shadow:none;text-align:left;font:inherit;color:var(--encre);line-height:1.45;
  cursor:pointer;transition:border-color .16s,background .16s,box-shadow .16s}
.carte.choix:hover{border-color:var(--cobalt);background:var(--cobalt-voile)}
.carte.choix:focus-visible{outline:2px solid var(--cobalt);outline-offset:2px}
.carte.choix[aria-pressed="true"],.carte.choix.prise{
  border-color:var(--cobalt);background:var(--cobalt-voile);
  box-shadow:inset 3px 0 0 var(--cobalt)}
.carte.choix b{display:block;margin-bottom:2px}
.carte.choix span{color:var(--ardoise);font-size:13px}

/* CE QUI FLOTTE. La barre d'étapes, le champ de l'agent, tout ce qui passe
   au-dessus du contenu. Trois choses font le verre, et aucune n'est une
   couleur : la saturation, sans quoi ce qui passe dessous devient gris et la
   surface a l'air sale ; l'arête claire d'un pixel, qui donne l'épaisseur :
   une surface translucide sans arête est un calque, pas une matière ; et une
   ombre très basse qui décolle au lieu de cerner. */
.carte.verre{background:color-mix(in srgb,var(--blanc) 66%,transparent);
  backdrop-filter:saturate(180%) blur(20px);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  border-color:color-mix(in srgb,var(--filet) 70%,transparent);
  border-radius:var(--r-4);box-shadow:var(--verre-ombre)}

/* CE QUI PORTE LA QUESTION. Une seule par écran, donc elle a le droit d'être
   la plus présente : le cran au-dessus, et l'ombre qui la détache du fond. */
.carte.scene{border-radius:var(--r-3);box-shadow:var(--ombre-2);padding:26px 28px;
  margin:0;scroll-margin-top:20px}
.carte.scene:empty{display:none}
@media(max-width:640px){.carte.scene{padding:20px 18px}}
.grille{display:grid;gap:14px}
.grille.tuiles{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.tuile{background:var(--blanc);border:1px solid var(--filet);border-radius:var(--radius);box-shadow:var(--ombre-1);padding:16px 18px;display:block;color:var(--encre)}
.tuile:hover{text-decoration:none;border-color:var(--cobalt)}
.tuile .chiffre{font-weight:500;font-size:34px;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--cobalt-fonce)}
.tuile .lib{color:var(--ardoise);font-size:15px}
/* ══ LE BOUTON ═════════════════════════════════════════════════════════════
   Il existait, et six écrans en redessinaient un à côté. Ce qu'il lui manquait
   n'était pas du style, c'étaient des ÉTATS : pas de focus visible, pas de
   désactivé, pas de taille. Un composant sans ses états n'est pas réutilisable,
   et c'est pour ça que chacun refaisait le sien.

   Trois tailles, trois tons, et tous les états. Rien de plus, parce que la
   quatrième taille est celle qu'on ajoute le jour où on n'a pas regardé les
   trois autres. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  border:1px solid var(--filet);background:var(--blanc);color:var(--encre);
  border-radius:var(--r-1);padding:8px 15px;font-size:15px;line-height:1.2;
  font-family:var(--sans);font-weight:500;cursor:pointer;text-decoration:none;
  transition:background .16s,border-color .16s,color .16s,box-shadow .16s}
.btn:hover{border-color:var(--cobalt);color:var(--cobalt-fonce);text-decoration:none}
/* LE FOCUS SE VOIT, ET IL SE VOIT PARTOUT PAREIL. Il n'existait nulle part :
   au clavier, on traversait l'écran sans savoir où l'on était. */
.btn:focus-visible{outline:2px solid var(--cobalt);outline-offset:2px}
.btn:active{transform:translateY(1px)}
/* UN BOUTON ÉTEINT NE SE SURVOLE PAS ET NE S'ENFONCE PAS. Sans cette règle, il
   répond au geste et ne fait rien : c'est la pire réponse possible. */
.btn[disabled],.btn[aria-disabled="true"]{background:var(--brume);
  border-color:var(--filet);color:var(--estompe);cursor:default;pointer-events:none}

/* LES TONS. Le plein porte l'action principale, et il n'y en a qu'UNE par
   écran : deux boutons pleins côte à côte, c'est ne pas avoir tranché. */
.btn.plein{background:var(--cobalt);border-color:var(--cobalt);color:var(--sur-plein);
  box-shadow:var(--ombre-cobalt)}
.btn.plein:hover{background:var(--cobalt-survol);border-color:var(--cobalt-survol);color:var(--sur-plein)}
.btn.plein[disabled]{background:var(--brume);border-color:var(--filet);
  color:var(--estompe);box-shadow:none}
.btn.doux{border-color:transparent;background:var(--brume)}
.btn.doux:hover{background:var(--cobalt-voile);color:var(--cobalt-fonce)}
.btn.nu{border-color:transparent;background:none;padding-left:8px;padding-right:8px}
.btn.nu:hover{background:var(--cobalt-voile)}
.btn.danger{color:var(--grenat);border-color:var(--grenat-voile)}
.btn.danger:hover{background:var(--grenat-voile);border-color:var(--grenat);color:var(--grenat)}

/* LES TAILLES. La moyenne n'a pas de classe : c'est celle qu'on prend quand on
   ne se pose pas la question, et c'est bien qu'elle soit la plus courte à
   écrire. */
.btn.grand{padding:13px 24px;font-size:17px;border-radius:var(--r-2)}
.btn.petit{padding:5px 11px;font-size:13px}
.btn.bloc{display:flex;width:100%}
/* ══ LE CHAMP ══════════════════════════════════════════════════════════════
   Il existait, et cinq écrans en redessinaient un à côté. Même raison que pour
   le bouton : ce qui lui manquait n'était pas du style, c'étaient ses ÉTATS.
   Ni désactivé, ni erreur, ni lecture seule, ni texte d'invite, ni focus au
   clavier. Un champ sans ses états n'est pas réutilisable, donc chacun refait
   le sien, et les cinq divergent.

   La vraie règle est celle du bas : ce qui est FAUX ne se dit pas par la
   couleur seule. Un liseré rouge est invisible pour huit hommes sur cent, et
   un champ qu'on ne peut pas remplir sans savoir pourquoi est un cul-de-sac. */
.champ{display:block;margin-bottom:12px}
.champ>span{display:block;font-size:13px;color:var(--ardoise);margin-bottom:3px}
.champ>span b.req{color:var(--grenat)}
.champ small{display:block;color:var(--estompe-clair);font-size:13px;margin-top:2px}
input[type=text],input[type=email],input[type=tel],input[type=date],input[type=number],input[type=password],select,textarea{
  width:100%;padding:10px 12px;border:1px solid var(--filet);border-radius:var(--r-1);
  font-family:var(--sans);font-size:15px;line-height:1.45;background:var(--creux);color:var(--encre);
  transition:border-color .16s,box-shadow .16s,background .16s}

/* LE FOCUS : un halo, pas un contour. Le contour du navigateur se pose HORS du
   champ et fait sauter d'un pixel tout ce qui l'entoure ; le halo se pose
   dessus et rien ne bouge. */
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--cobalt);
  box-shadow:var(--halo);background:var(--blanc)}
input::placeholder,textarea::placeholder{color:var(--estompe);opacity:1}

/* CE QU'ON NE PEUT PAS REMPLIR LE DIT AUTREMENT QUE PAR SA COULEUR : le curseur
   change, et le fond s'éteint. */
input[disabled],select[disabled],textarea[disabled]{background:var(--brume);
  color:var(--estompe);cursor:not-allowed}
/* EN LECTURE SEULE, CE N'EST PAS PAREIL : la valeur compte et se lit, elle ne
   s'éteint donc pas. Elle se sélectionne, elle ne se change pas. */
input[readonly],textarea[readonly]{background:var(--brume);border-style:dashed;cursor:default}

/* CE QUI EST FAUX SE DIT PAR TROIS CHOSES À LA FOIS, jamais par la couleur
   seule : le filet, le halo, et le message que la page pose sous le champ. */
input[aria-invalid="true"],select[aria-invalid="true"],textarea[aria-invalid="true"]{
  border-color:var(--grenat);background:var(--grenat-voile)}
input[aria-invalid="true"]:focus,select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus{border-color:var(--grenat);
  box-shadow:var(--halo-faux)}
.champ .faux{display:block;color:var(--grenat);font-size:13px;margin-top:4px}

textarea{min-height:84px;resize:vertical}
.champ.case{display:flex;align-items:flex-start;gap:8px}
.champ.case input{width:auto;margin-top:3px}
.form-grille{display:grid;grid-template-columns:1fr 1fr;gap:0 22px}
.form-grille .pleine{grid-column:1/-1}
.erreur{background:var(--grenat-voile);color:var(--grenat);border-radius:var(--radius-sm);padding:10px 14px;margin-bottom:14px}
.ok{background:var(--cobalt-voile);color:var(--cobalt-fonce);border-radius:var(--radius-sm);padding:10px 14px;margin-bottom:14px}
/* ── listes ── */
table.liste{width:100%;border-collapse:collapse;background:var(--blanc);border:1px solid var(--filet);border-radius:var(--radius);overflow:hidden}
table.liste th{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ardoise);text-align:left;padding:10px 14px;border-bottom:1px solid var(--filet);background:var(--creux)}
table.liste td{padding:10px 14px;border-bottom:1px solid var(--brume)}
table.liste tr:last-child td{border-bottom:none}
table.liste tr:hover td{background:var(--creux)}
.vide{color:var(--ardoise);text-align:center;padding:36px 0}
.recherche{display:flex;gap:8px;margin-bottom:14px}
.recherche input{max-width:340px}
/* La feuille de l'ANCIENNE porte vivait ici : .porte, 420 px de large, une
   marque en serif centrée et le sous-titre qui allait avec. Elle a survécu
   deux jours à la refonte du 22/09/2026, sans qu'aucun HTML ne porte plus
   class="porte". Le test qui traque les restes de l'ancienne peau ne
   regardait que web/public.ts, pas les feuilles. Un style mort ne se voit
   pas : il se relit, se copie, et finit par revenir. La porte est dans
   web/porte.ts.

   .porte DÉSIGNE AUTRE CHOSE DEPUIS : le mur de l'offre (web/shell-style.ts,
   CSS_OFFRE), habillé de bout en bout là-bas. Ces règles-ci ne l'abîmaient
   pas (la coquille charge après la base et écrase chaque propriété), mais
   deux composants sans rapport sous un même nom finissent toujours par se
   rencontrer, et c'est la seconde raison de retirer celles-là.
   (Pas d'accent grave d'ouverture ici : on est dans un littéral TS.) */
.chip{display:inline-block;background:var(--prune-voile);color:var(--prune);border-radius:99px;padding:1px 10px;font-size:13px}
@media(max-width:860px){
  .form-grille{grid-template-columns:1fr}
}

@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/polices/inter-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/polices/inter-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
