.sd{
  /* ══ LES JETONS, RELEVES DANS FIGMA ═══════════════════════════════
     Plus rien n'est estime ici : ces valeurs viennent de get_variable_defs
     sur les cadres du prototype, via le serveur Dev Mode. Elles confirment
     que le produit pose la palette Flowbite sur le bleu SPEOS.

     Ce que j'avais faux, et qui est corrige : le bleu principal (#0f0e4b
     releve sur une capture, alors que le jeton dit #19177d), le rayon des
     boutons (8 au lieu de 4), celui des cartes (12 au lieu de 8), le vert
     et le rouge.                                                        */

  /* marque */
  --speos-500:#19177d; --speos-400:#7574b1; --speos-200:#c5c5de;
  --speos-gris:#f3f5fc; --speos-encre:#1e3050;
  --or:#efbe4b;                        /* logotype uniquement */

  /* gris Flowbite */
  --g50:#f9fafb; --g100:#f3f4f6; --g200:#e5e7eb; --g300:#d1d5db;
  --g400:#9ca3af; --g500:#6b7280; --g700:#374151; --g800:#1f2a37; --g900:#111928;
  --gris-sombre:#5c6168;

  /* semantique Flowbite */
  --vert-100:#def7ec; --vert-500:#0e9f6e; --vert-800:#03543f;
  --rouge-100:#fde8e8; --rouge-700:#c81e1e; --rouge-800:#9b1c1c;
  --jaune-100:#fdf6b2; --jaune-800:#723b13;
  --info-50:#eaeafb; --info-700:#19177d;

  /* roles, exprimes a partir des jetons ci-dessus */
  --encre:var(--speos-500); --encre-2:var(--speos-500); --marque:var(--speos-500);
  --fond:var(--speos-gris); --surface:#fff; --gris:var(--g50); --lavande:var(--info-50);
  --action:var(--speos-500); --action-vive:var(--speos-400);
  /* Les series d'un graphique sont des jetons comme les autres : ecrites en
     dur dans le JS, elles ne suivaient pas le theme, et un jaune choisi pour
     du blanc restait tel quel sur du bleu nuit. */
  --serie-1:#4f4ddb; --serie-2:#2563eb; --serie-3:#0d9488;
  --serie-4:#d97706; --serie-ok:#0e9f6e; --serie-ko:#c81e1e;
  --papier:#fff; --papier-trait:var(--g300); --papier-marque:var(--g400);
  --vert:var(--vert-100); --vert-fort:var(--vert-500);
  --trait:var(--g200); --ambre:var(--or);
  /* les deux gris de texte : g700 porte le texte lu, gris-sombre les
     metadonnees. Mesures a 8,6:1 et 5,3:1 sur le fond. */
  --mate:var(--g700); --mate-2:var(--gris-sombre);

  /* rayons : Radius-1 4, rounded-md 6, rounded-lg 8 */
  --r:8px; --r-s:6px; --r-btn:4px;
  /* espacements : 0 4 8 12 16 20 24 48 */
  --e1:4px; --e2:8px; --e3:12px; --e4:16px; --e5:20px; --e6:24px;
  /* l'ombre du jeton « shadow », ses deux couches */
  --ombre:0 1px 2px -1px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.1);

  --pas:.42s cubic-bezier(.22,.61,.36,1);
  /* silka est la police du produit ; elle n'est pas librement diffusable,
     Inter la remplace : meme classe, memes chasses approchantes. */
  font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  color:var(--speos-encre); background:var(--fond);
  /* body garde sa marge de 8 px par defaut : 100dvh + 16 px, et la page
     debordait de seize pixels sans qu'on voie pourquoi. */
  margin:0; height:100dvh; display:flex; flex-direction:column; overflow:hidden;
}
.sd *,.sd *::before,.sd *::after{ box-sizing:border-box; }

/* ── l'en-tete du produit ─────────────────────────────────────────── */
.sd-top{ flex:0 0 auto; background:var(--surface); border-bottom:1px solid var(--trait);
  display:flex; align-items:center; gap:16px; padding:12px 20px; position:sticky;
  top:0; z-index:20; }
.sd-logo{ display:block; height:20px; width:auto; flex:0 0 auto; }
.sd-marque{ font-weight:600; font-size:13px; letter-spacing:.01em; color:var(--mate);
  padding-left:13px; margin-left:2px; border-left:1px solid var(--trait); }
.sd-top__fin{ margin-left:auto; display:flex; align-items:center; gap:14px; }
.sd-rond{ width:30px; height:30px; border-radius:50%; background:var(--lavande);
  display:grid; place-items:center; color:var(--encre-2); }
.sd-quitter{ background:transparent; color:var(--encre); border:1px solid var(--trait);
  border-radius:var(--r-s);
  padding:8px 14px; font:inherit; font-size:13px; font-weight:600; cursor:pointer;
  text-decoration:none; display:inline-block; }
.sd-quitter:hover{ background:var(--gris); border-color:var(--g300); }

/* ── la progression : segments, comme dans le prototype ───────────── */
.sd-prog{ flex:0 0 auto; background:var(--surface); border-bottom:1px solid var(--trait);
  display:flex; align-items:center; gap:10px; padding:9px 20px; }
.sd-prog__barres{ display:flex; gap:5px; flex:1; min-width:0; }
.sd-prog__b{ flex:1; height:4px; border-radius:2px; background:var(--trait);
  overflow:hidden; }
.sd-prog__f{ display:block; height:100%; border-radius:2px; background:var(--action);
  transform-origin:left center; transition:transform var(--pas) cubic-bezier(.3,.8,.4,1); }
.sd-prog__n{ font-size:12px; font-weight:600; color:var(--encre-2);
  white-space:nowrap; }

/* ── le corps : barre laterale + scene ────────────────────────────── */
.sd-corps{ flex:1; display:grid; grid-template-columns:264px 1fr; min-height:0;
  align-items:stretch; }

.sd-nav{ background:var(--surface); border-right:1px solid var(--trait);
  padding:22px 14px; display:flex; flex-direction:column; gap:4px; }
.sd-nav__k{ font-size:11px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--mate-2); padding:0 10px 10px; }
.sd-etape{ display:flex; align-items:center; gap:12px; padding:4px 8px;
  min-height:44px; border-radius:var(--r-btn); background:none; border:0; width:100%; text-align:left;
  font:inherit; color:var(--mate-2); cursor:default; transition:background var(--pas),color var(--pas); }
.sd-etape__p{ width:30px; height:30px; border-radius:50%; background:var(--gris);
  display:grid; place-items:center; flex:0 0 auto; transition:background var(--pas),color var(--pas); }
.sd-etape__t{ font-size:14px; font-weight:600; line-height:1.25; }
.sd-etape__s{ font-size:12px; color:var(--mate-2); line-height:1.3; }
.sd-etape.est-active{ background:var(--lavande); color:var(--encre); }
.sd-etape.est-active .sd-etape__p{ background:var(--action); color:#fff; }
.sd-etape.est-active .sd-etape__s{ color:var(--encre-2); }
.sd-etape.est-faite{ color:var(--encre); }
.sd-etape.est-faite .sd-etape__p{ background:var(--vert-100); color:var(--vert-fort); }

.sd-scene{ padding:34px 30px 60px; overflow-x:hidden; overflow-y:auto;
  display:flex; flex-direction:column; }
.sd-vue{ max-width:940px; margin:0 auto; width:100%; }
.sd-vue--large{ max-width:1360px; }
.sd-vue--centre{ margin-top:auto; margin-bottom:auto; }

/* ── l'entree en scene : chaque vue arrive de sa droite ───────────── */
@keyframes sd-entree{ from{ opacity:0; transform:translate3d(18px,0,0); }
  to{ opacity:1; transform:none; } }
.sd-vue.arrive{ animation:sd-entree var(--pas) both; }
.sd-vue.arrive > *{ animation:sd-entree var(--pas) both; }
.sd-vue.arrive > *:nth-child(2){ animation-delay:.05s; }
.sd-vue.arrive > *:nth-child(3){ animation-delay:.1s; }
.sd-vue.arrive > *:nth-child(4){ animation-delay:.15s; }

/* ── l'etat vide, qui ouvre chaque domaine ────────────────────────── */
.sd-vide{ text-align:center; padding:56px 20px; }
.sd-vide__illu{ display:block; width:auto; height:auto;
  max-height:230px; max-width:min(100%, 320px); margin:0 auto 28px;
  object-fit:contain; }
.sd-vide h2{ font-size:30px; font-weight:800; letter-spacing:-.02em; margin:0 0 10px;
  text-wrap:balance; }
.sd-vide p{ color:var(--mate); font-size:15px; line-height:1.55; margin:0 auto 24px;
  max-width:44ch; text-wrap:pretty; }

/* ── surfaces, tableaux, formulaires ──────────────────────────────── */
.sd-carte{ background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r); padding:24px; box-shadow:var(--ombre); }
.sd-carte__tete{ display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  margin:0 0 20px; }
.sd-carte__tete h2{ font-size:20px; font-weight:700; margin:0; letter-spacing:-.01em; }
.sd-carte__tete .sd-btn{ margin-left:auto; }

/* Gabarit Flowbite : le conteneur porte la bordure, le rayon et le
   defilement ; la table porte la largeur pleine et rien d'autre. */
.sd-tblx{ overflow-x:auto; border:1px solid var(--trait); border-radius:8px;
  background:var(--surface); }
.sd-tbl{ width:100%; border-collapse:collapse; font-size:13.5px; }
.sd-tbl thead{ background:var(--gris); }
.sd-tbl th{ text-align:left; font-size:11px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--mate-2); padding:12px 18px; }
.sd-tbl td{ padding:16px 18px; border-top:1px solid var(--trait); }
.sd-tbl tr:hover td{ background:var(--gris); }
.sd-pastille{ display:inline-block; width:7px; height:7px; border-radius:50%;
  background:var(--vert-fort); margin-right:8px; vertical-align:middle; }

.sd-grille{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.sd-champ{ display:flex; flex-direction:column; gap:6px; min-width:0; }
.sd-champ > span{ font-size:12.5px; font-weight:600; }
.sd-champ > span b{ color:var(--rouge-700); font-weight:700; }
.sd-champ input,.sd-champ select,.sd-champ textarea{ font:inherit; font-size:14px;
  padding:10px 12px; border:1px solid var(--trait); border-radius:var(--r-s);
  background:var(--surface); color:var(--encre); width:100%;
  transition:border-color .18s, box-shadow .18s; }
.sd-champ input::placeholder,.sd-champ textarea::placeholder{ color:var(--mate-2); }
.sd-champ input:focus,.sd-champ select:focus,.sd-champ textarea:focus{ outline:0;
  border-color:var(--encre-2); box-shadow:0 0 0 3px rgba(25,23,125,.16); }
.sd-champ--large{ grid-column:1 / -1; }

.sd-bloc{ background:var(--gris); border-radius:var(--r); padding:16px; }
.sd-bloc__tete{ display:flex; align-items:center; gap:10px; margin:0 0 12px; }
.sd-bloc__tete h3{ font-size:14px; font-weight:700; margin:0; }
.sd-mono{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; }

/* ── boutons ──────────────────────────────────────────────────────── */
.sd-btn{ font:inherit; font-size:16px; font-weight:500; padding:11px 16px;
  min-height:44px; border-radius:var(--r-btn); border:1px solid transparent; cursor:pointer;
  display:inline-flex; align-items:center; gap:8px;
  transition:transform .12s, box-shadow .18s, background .18s, opacity .18s; }
.sd-btn:active{ transform:translateY(1px); }
.sd-btn--fort{ background:var(--action); color:#fff; }
.sd-btn--fort:hover{ box-shadow:0 6px 18px rgba(25,23,125,.24); }
.sd-btn--fin{ background:var(--surface); color:var(--encre); border-color:var(--trait); }
.sd-btn--fin:hover{ background:var(--gris); }
.sd-btn--petit{ font-size:14px; padding:8px 14px; min-height:36px; }
.sd-btn[disabled]{ opacity:.45; cursor:not-allowed; }
.sd-pied{ display:flex; gap:10px; justify-content:flex-end; margin-top:22px;
  padding-top:18px; border-top:1px solid var(--trait); flex-wrap:wrap; }

/* ── la confirmation, moment fort du parcours ─────────────────────── */
.sd-ok{ background:var(--vert); border:1px solid var(--vert-100); border-radius:var(--r);
  padding:16px 18px; display:flex; gap:13px; align-items:flex-start; margin:0 0 18px; }
.sd-ok__p{ width:26px; height:26px; border-radius:50%; background:var(--vert-fort);
  color:#fff; display:grid; place-items:center; flex:0 0 auto; font-size:14px; }
.sd-ok h3{ margin:0 0 3px; font-size:15px; font-weight:700; }
.sd-ok p{ margin:0; font-size:13.5px; color:var(--vert-800); }

.sd-copie{ position:relative; }
.sd-copie button{ position:absolute; right:7px; top:50%; transform:translateY(-50%);
  background:none; border:0; cursor:pointer; color:var(--mate-2); padding:5px;
  border-radius:6px; line-height:0; }
.sd-copie button:hover{ background:var(--lavande); color:var(--encre); }
.sd-copie input{ padding-right:38px; }
.sd-copie.est-copie button{ color:var(--vert-fort); }

/* la cle se genere sous les yeux du lecteur : le trait avance, puis le bloc tombe */
.sd-cle__barre{ height:4px; border-radius:2px; background:var(--trait); overflow:hidden;
  margin-top:12px; }
.sd-cle__barre i{ display:block; height:100%; width:0; background:var(--encre-2);
  transition:width 1.5s cubic-bezier(.3,.8,.4,1); }
.sd-cle__sortie{ margin-top:12px; padding:12px; border-radius:var(--r-s);
  background:#0f0e2b; color:#cbd5e1; font-family:ui-monospace,Menlo,monospace;
  font-size:11.5px; line-height:1.6; word-break:break-all; max-height:0;
  overflow:hidden; opacity:0; transition:max-height .5s ease, opacity .4s ease,
  padding .4s ease; padding-block:0; }
.sd-cle__sortie.est-la{ max-height:150px; opacity:1; padding-block:12px; }

/* ── les canaux : six cartes, chacune avec son etat et son action ──
   Le prototype en pose six, pas quatre, et deux sont specifiquement belges,
   e-Box et Doccle. Chaque carte porte une icone, une etiquette d'etat, sa
   description et son bouton : ce n'est pas une case a cocher, c'est un
   service qu'on active. */
.sd-page__h{ font-size:29px; font-weight:800; letter-spacing:-.02em; margin:0 0 7px;
  text-wrap:balance; }
.sd-page__p{ font-size:14.5px; color:var(--mate); margin:0 0 22px; max-width:58ch; }

.sd-canaux{ display:grid; grid-template-columns:repeat(auto-fit,minmax(232px,1fr));
  gap:14px; }
.sd-canal{ background:var(--surface); border:1.5px solid var(--trait);
  border-radius:var(--r); padding:18px; display:flex; flex-direction:column;
  gap:9px; transition:border-color var(--pas), box-shadow var(--pas), transform .16s; }
.sd-canal:hover{ transform:translateY(-2px); box-shadow:0 8px 22px rgba(25,23,125,.07); }
.sd-canal.est-reco{ border-color:var(--encre); }
.sd-canal.est-armé{ border-color:var(--vert-fort); }
.sd-canal__h{ display:flex; align-items:center; gap:9px; }
.sd-canal__i{ width:34px; height:34px; border-radius:9px; background:var(--gris);
  display:grid; place-items:center; color:var(--mate); flex:0 0 auto; }
.sd-canal.est-armé .sd-canal__i{ background:var(--vert-100); color:var(--vert-fort); }
.sd-canal.est-reco .sd-canal__i{ background:var(--lavande); color:var(--encre-2); }
.sd-canal__h .sd-etiq{ margin-left:auto; }
.sd-canal__n{ font-size:15.5px; font-weight:700; }
.sd-canal__d{ font-size:12.5px; color:var(--mate); line-height:1.45; min-height:2.9em; }
.sd-canal .sd-btn{ width:100%; justify-content:center; margin-top:auto; }
.sd-etiq--gris{ background:var(--gris); color:var(--mate); }
.sd-btn--doux{ background:var(--lavande); color:var(--encre-2); }
.sd-btn--doux:hover{ background:#e2e6f7; }
.sd-canal.est-armé .sd-btn{ background:var(--vert-100); color:var(--vert-800); }

/* ── le trajet de bout en bout, la derniere etape ─────────────────── */
.sd-flux{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:12px;
  margin:22px 0 0; }
.sd-jalon{ background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r); padding:15px; position:relative;
  opacity:.4; transition:opacity var(--pas), border-color var(--pas),
  transform var(--pas); }
.sd-jalon.est-passe{ opacity:1; border-color:var(--vert-100); transform:translateY(-2px); }
.sd-jalon__n{ font-size:11px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--mate-2); }
.sd-jalon__t{ font-size:14px; font-weight:700; margin-top:5px; }
.sd-jalon__d{ font-size:12.5px; color:var(--mate); margin-top:4px; line-height:1.4; }
.sd-jalon.est-passe .sd-jalon__n{ color:var(--vert-fort); }

/* ── le retour au cas ─────────────────────────────────────────────── */
.sd-sortie{ margin:auto 14px 16px; padding:0; text-align:left; }
.sd-sortie a{ color:var(--encre-2); font-size:13.5px; font-weight:600;
  text-decoration:none; border-bottom:1px solid currentColor; padding-bottom:2px; }
.sd-sortie a:hover{ color:var(--encre); }

/* ── responsive : c'est tout l'objet de cette reecriture ──────────── */
@media (max-width:900px){
  /* la barre laterale devient une file d'etapes horizontale, qui defile.
     Empiler cinq lignes couterait un ecran entier avant le contenu. */
  .sd-corps{ grid-template-columns:1fr; }
  /* La file vit dans .sd-nav__l depuis qu'elle est une liste ordonnee :
     ces regles visaient encore .sd-nav, et les six etapes restaient
     empilees. Elles occupaient 309 px avant le premier mot du contenu. */
  .sd-nav{ border-right:0; border-bottom:1px solid var(--trait); padding:0;
    overflow:visible; }
  /* le repli horizontal de la file est pose en fin de feuille : ecrit ici,
     il serait annule par la regle de base declaree plus bas, a specificite
     egale. Une requete media ne gagne pas contre l'ordre. */
  .sd-nav__k{ display:none; }
  .sd-etape{ width:auto; flex:0 0 auto; padding:8px 12px; gap:9px; }
  .sd-etape__s{ display:none; }
  .sd-etape__p{ width:24px; height:24px; }
  .sd-etape__t{ font-size:13px; white-space:nowrap; }
  /* l'en-tete colle sur ordinateur, ou la page est longue. Sur telephone,
     la file d'etapes defile juste dessous et son fragment affleurait sous
     l'en-tete : chaque etape tient dans un ecran ou deux, le collage
     n'apporte rien et coute ce defaut. */
  .sd-top{ position:static; }
  .sd-scene{ padding:22px 16px 48px; }
  .sd-grille{ grid-template-columns:1fr; }
  .sd-vide{ padding:34px 4px; }
  .sd-page__h{ font-size:22px; }
  .sd-canaux{ grid-template-columns:1fr; }
  .sd-canal__d{ min-height:0; }
  .sd-vide h2{ font-size:23px; }
  .sd-flux{ grid-template-columns:1fr 1fr; }
  .sd-carte{ padding:16px; }
  .sd-carte__tete .sd-btn{ margin-left:0; }
  .sd-pied{ flex-direction:column-reverse; }
  .sd-pied .sd-btn{ width:100%; justify-content:center; }
  /* un tableau ne se replie pas : il defile dans sa propre boite */
  .sd-tbl th{ padding:10px 14px; }
  .sd-tbl td{ padding:13px 14px; }
  .sd-tbl{ min-width:520px; }
}
@media (max-width:560px){
  .sd-top{ padding:10px 14px; gap:10px; }
  .sd-marque{ display:none; }
  .sd-prog{ padding:8px 14px; }
  .sd-flux{ grid-template-columns:1fr; }
  .sd-vide h2{ font-size:20px; }
}

@media (prefers-reduced-motion:reduce){
  .sd *{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* ══ LA PARTIE SUIVI ════════════════════════════════════════════════
   L'activation prepare, le suivi prouve. C'est le deuxieme prototype :
   un batch qui avance, ses fichiers, ses erreurs. Les valeurs sont celles
   de la maquette, pas des chiffres inventes pour la demonstration.
-------------------------------------------------------------------*/

/* les filtres qui coiffent le tableau de bord */
.sd-filtres{ display:flex; gap:12px; flex-wrap:wrap; margin:0 0 20px; }
.sd-filtres select{ font:inherit; font-size:13px; padding:8px 12px;
  border:1px solid var(--trait); border-radius:var(--r-s); background:var(--surface);
  color:var(--encre); min-width:0; }
.sd-filtres .sd-btn{ margin-left:auto; }

/* les quatre indicateurs */
.sd-kpi{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px;
  margin:0 0 20px; }
/* Une carte portait une ligne de pourcentage que les trois autres n'avaient
   pas : la grille etirait les quatre, et il restait un vide sous le chiffre.
   Le pourcentage passe a cote du nombre, les quatre cartes retrouvent la
   meme hauteur naturelle. Rembourrage 16, l'echelle Flowbite. */
.sd-kpi__c{ background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r); padding:16px; display:flex; gap:12px; align-items:center; }
.sd-kpi__i{ width:36px; height:36px; border-radius:9px; display:grid; place-items:center;
  flex:0 0 auto; background:var(--gris); color:var(--encre-2); }
.sd-kpi__i.est-vert{ background:var(--vert-100); color:var(--vert-fort); }
.sd-kpi__i.est-rouge{ background:var(--rouge-100); color:var(--rouge-700); }
/* le libelle et le nombre etaient deux span inline : ils se collaient en
   « Transferred documents100 000 ». Chacun prend sa ligne. */
.sd-kpi__c > span:last-child{ min-width:0; display:block; }
.sd-kpi__k{ font-size:12px; font-weight:600; color:var(--mate); line-height:1.3;
  display:block; }
.sd-kpi__n{ display:block; font-size:25px; font-weight:800; letter-spacing:-.02em; line-height:1.15;
  font-variant-numeric:tabular-nums; margin-top:2px; }
.sd-kpi__d{ font-size:12px; font-weight:700; margin-left:7px;
  display:inline-block; vertical-align:middle; }
.sd-kpi__d.est-haut{ color:var(--vert-fort); }
.sd-kpi__d.est-bas{ color:var(--rouge-700); }

/* la ligne de production, et son detail */
/* un span reste inline et n'a pas de largeur : la colonne Progress
   apparaissait vide. */
.sd-jauge{ display:block; width:100%; min-width:78px; height:6px; border-radius:3px;
  background:var(--trait); overflow:hidden; }
.sd-jauge i{ display:block; height:100%; background:var(--encre-2); width:0;
  transition:width 1.1s cubic-bezier(.3,.8,.4,1); }
.sd-etiq{ display:inline-block; font-size:11.5px; font-weight:700; padding:3px 9px;
  border-radius:99px; white-space:nowrap; }
.sd-etiq--ok{ background:var(--vert-100); color:var(--vert-800); }
.sd-etiq--ko{ background:var(--rouge-100); color:var(--rouge-800); }
.sd-etiq--info{ background:var(--lavande); color:var(--encre-2); }

.sd-detail{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:14px; margin-top:14px; }
.sd-detail__c{ background:var(--gris); border-radius:var(--r); padding:16px; }
.sd-gros{ font-size:23px; font-weight:800; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; }
.sd-gros + p{ margin:2px 0 16px; font-size:12.5px; color:var(--mate); }
.sd-parts{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px;
  margin-bottom:13px; }
.sd-part__k{ font-size:12.5px; color:var(--mate); }
.sd-part__n{ font-size:19px; font-weight:800; letter-spacing:-.01em; }
.sd-part__s{ font-size:12px; color:var(--mate-2); font-variant-numeric:tabular-nums; }
.sd-empile{ display:flex; height:9px; border-radius:5px; overflow:hidden; }
.sd-empile i{ display:block; height:100%; width:0; transition:width .9s ease; }

.sd-onglets{ display:flex; gap:6px; margin:0 0 16px; flex-wrap:wrap; }
.sd-onglet{ font:inherit; font-size:12.5px; font-weight:600; padding:7px 13px;
  border-radius:var(--r-s); border:1px solid transparent; background:none;
  color:var(--mate); cursor:pointer; transition:background var(--pas), color var(--pas); }
.sd-onglet.est-choisi{ background:var(--action); color:#fff; }

.sd-statut{ display:grid; grid-template-columns:106px 1fr; gap:12px;
  align-items:center; margin-bottom:13px; font-size:13px; }
.sd-statut__n{ display:flex; align-items:center; gap:8px; font-weight:600; }
.sd-statut__p{ width:8px; height:8px; border-radius:50%; flex:0 0 auto; }
.sd-statut__j{ position:relative; }
.sd-statut__j > i{ display:block; height:5px; border-radius:3px; background:var(--trait); }
.sd-statut__j > i > b{ display:block; height:100%; border-radius:3px; width:0;
  transition:width 1s cubic-bezier(.3,.8,.4,1); }
.sd-statut__v{ font-size:11.5px; color:var(--mate-2); text-align:right;
  font-variant-numeric:tabular-nums; margin-bottom:3px; }

/* la recherche de documents */
.sd-cherche{ display:flex; gap:9px; flex-wrap:wrap; margin:0 0 14px; }
.sd-cherche input{ font:inherit; font-size:14px; padding:9px 12px; flex:1 1 190px;
  min-width:0; border:1px solid var(--trait); border-radius:var(--r-s);
  background:var(--surface); color:var(--encre); }
.sd-cherche input:focus{ outline:0; border-color:var(--encre-2);
  box-shadow:0 0 0 3px rgba(25,23,125,.16); }
.sd-compte{ font-size:12.5px; color:var(--mate); margin:0 0 10px; }
.sd-compte b{ color:var(--encre); }

@media (max-width:900px){
  .sd-kpi{ grid-template-columns:1fr 1fr; }
  .sd-detail{ grid-template-columns:1fr; }
  .sd-parts{ grid-template-columns:1fr 1fr; }
  .sd-filtres select{ flex:1 1 44%; }
  .sd-filtres .sd-btn{ margin-left:0; width:100%; justify-content:center; }
}
@media (max-width:560px){
  .sd-kpi{ grid-template-columns:1fr; }
  .sd-kpi__n{ font-size:22px; }
  .sd-statut{ grid-template-columns:88px 1fr; }
}

/* ══ LE DETAIL D'UN BATCH, ET SES ERREURS ═══════════════════════════
   C'est le moment ou le produit prouve quelque chose : un document part
   en erreur, on voit ou il s'est arrete, pourquoi, et ce qu'on peut en
   faire sans quitter l'ecran. Le repli papier apres 24 h est la reponse
   exacte a la boite noire que le cas decrit.
-------------------------------------------------------------------*/
.sd-retour{ display:inline-flex; align-items:center; gap:7px; font-size:13.5px;
  font-weight:600; color:var(--encre-2); background:none; border:0; cursor:pointer;
  padding:0; margin-bottom:14px; font-family:inherit; }
.sd-retour:hover{ color:var(--encre); }

.sd-tete-batch{ display:flex; align-items:baseline; gap:11px; flex-wrap:wrap;
  margin-bottom:3px; }
.sd-tete-batch h2{ font-size:22px; font-weight:800; margin:0; letter-spacing:-.02em; }
.sd-planning{ font-size:12.5px; color:var(--mate); margin:0 0 16px; }
.sd-encours{ margin-left:auto; display:inline-flex; align-items:center; gap:7px;
  font-size:13px; font-weight:600; color:var(--mate); }
.sd-encours i{ width:8px; height:8px; border-radius:50%; background:#f97316;
  animation:sd-pulse 1.6s ease-in-out infinite; }
@keyframes sd-pulse{ 0%,100%{ opacity:1; } 50%{ opacity:.35; } }

.sd-trois{ display:grid; grid-template-columns:1.4fr 1fr 1fr; gap:12px; margin-bottom:16px; }
.sd-trois__c{ border-radius:var(--r); padding:16px; background:var(--lavande); }
.sd-trois__c--neutre{ background:var(--lavande); text-align:center; }
.sd-trois__c--rouge{ background:var(--rouge-100); text-align:center; }
.sd-trois__n{ font-size:27px; font-weight:800; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; line-height:1.1; }
.sd-trois__c--rouge .sd-trois__n{ color:var(--rouge-700); }
.sd-trois__k{ font-size:12.5px; color:var(--mate); margin-top:3px; }
.sd-trois__c--rouge .sd-trois__k{ color:var(--rouge-700); }
.sd-trois__h{ display:flex; justify-content:space-between; font-size:12.5px;
  font-weight:600; margin-bottom:8px; }
.sd-trois__s{ font-size:12px; color:var(--mate); margin-top:7px; }

/* la ligne depliee : trois colonnes, chronologie, log, apercu */
.sd-deplie{ display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.5fr) minmax(0,.85fr);
  gap:20px; padding:18px 12px 4px; border-top:1px solid var(--trait); }
.sd-deplie h3{ font-size:14.5px; font-weight:700; margin:0 0 14px; }

.sd-chrono{ list-style:none; margin:0; padding:0; }
.sd-chrono li{ display:grid; grid-template-columns:26px 1fr; gap:11px;
  padding-bottom:16px; position:relative; }
.sd-chrono li:not(:last-child)::before{ content:""; position:absolute; left:13px;
  top:26px; bottom:0; width:2px; background:var(--vert-100); }
.sd-chrono__p{ width:26px; height:26px; border-radius:50%; display:grid;
  place-items:center; background:var(--vert-100); color:var(--vert-fort); font-size:12px; }
.sd-chrono li.est-ko .sd-chrono__p{ background:var(--rouge-100); color:var(--rouge-700); }
.sd-chrono li.est-ko::before{ background:var(--rouge-100); }
.sd-chrono__t{ font-size:13.5px; font-weight:700; color:var(--mate); }
.sd-chrono li.est-ko .sd-chrono__t{ color:var(--rouge-700); }
.sd-chrono__d{ font-size:12px; color:var(--mate-2); font-variant-numeric:tabular-nums; }

.sd-log{ display:flex; gap:11px; align-items:flex-start; margin-bottom:14px; }
.sd-log__p{ width:22px; height:22px; border-radius:50%; background:var(--rouge-700); color:#fff;
  display:grid; place-items:center; font-size:13px; font-weight:700; flex:0 0 auto; }
.sd-log p{ margin:0; font-size:13.5px; line-height:1.55; }
.sd-log b{ font-family:ui-monospace,Menlo,monospace; font-size:12.5px; }
.sd-actions{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:11px; }
.sd-repli{ font-size:12px; color:var(--mate); margin:0; line-height:1.5; }

.sd-apercu{ border:1px solid var(--papier-trait); border-radius:var(--r-s); overflow:hidden;
  background:var(--papier); aspect-ratio:1/1.35; padding:11px; display:flex;
  flex-direction:column; gap:5px; }
.sd-apercu i{ display:block; border-radius:2px; background:var(--papier-marque); height:5px; }
.sd-apercu i.est-titre{ height:9px; width:52%; background:var(--action); }
.sd-apercu i.est-court{ width:64%; }
.sd-apercu i.est-mi{ width:80%; }
.sd-apercu .sd-apercu__b{ margin-top:auto; height:26px; border-radius:4px;
  background:var(--action); opacity:.16; }

/* les notifications */
.sd-notes{ display:flex; flex-direction:column; gap:9px; }
.sd-jour{ font-size:13px; font-weight:700; color:var(--mate); margin:6px 0 2px; }
.sd-note{ background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r); padding:14px 16px; display:flex; gap:12px;
  align-items:flex-start; }
.sd-note__p{ width:26px; height:26px; border-radius:50%; display:grid;
  place-items:center; flex:0 0 auto; font-size:13px; font-weight:700; color:#fff; }
.sd-note__p.est-ko{ background:var(--rouge-700); }
.sd-note__p.est-attente{ background:#f97316; }
.sd-note__p.est-info{ background:var(--vert-fort); }
.sd-note__t{ font-size:13.5px; line-height:1.5; margin:0; }
.sd-note__d{ font-size:12px; color:var(--mate-2); margin:4px 0 0; }

@media (max-width:900px){
  .sd-trois{ grid-template-columns:1fr; }
  .sd-deplie{ grid-template-columns:1fr; gap:22px; }
  .sd-apercu{ max-width:200px; }
  .sd-encours{ margin-left:0; }
  .sd-actions .sd-btn{ flex:1 1 100%; justify-content:center; }
}


/* ══ LA MODALE D'ACTIVATION ═════════════════════════════════════════
   Dans le prototype, un formulaire d'onboarding ne remplace pas la page :
   il se pose par dessus, dans la zone a droite de la barre laterale, et
   la page reste visible derriere sous un voile. On voit donc en meme temps
   ce qu'on remplit et ce que ca va nourrir. Poser le formulaire a plat,
   comme je l'avais fait, perdait ce lien.
-------------------------------------------------------------------*/
.sd-scene{ position:relative; }
/* Le voile ne couvre que la zone de contenu : dans le prototype, la barre
   laterale reste claire pendant qu'un formulaire est ouvert, parce qu'elle
   dit ou on en est.

   En absolu dans la scene, il s'arretait a la hauteur du contenu et laissait
   un rectangle gris flottant. En fixe, decale de la largeur de la barre, il
   couvre exactement ce qu'il doit couvrir, quelle que soit la hauteur. */
/* Le voile s'arrete a la barre laterale et sous le bandeau : mesure, pas
   estime, 264 px et 91 px. La barre reste claire parce qu'elle dit ou on en
   est, et le bandeau parce qu'il porte la progression. */
.sd-voile{ position:fixed; top:91px; right:0; bottom:0; left:264px;
  background:rgba(30,32,51,.42); backdrop-filter:blur(1px);
  z-index:1; animation:sd-fondu .25s both; }
/* .sd-vue porte un transform : son contexte d'empilement vaut z-index auto,
   donc le voile passait devant la modale. On lui en donne un. */
.sd-scene > .sd-vue{ position:relative; z-index:2; }
@keyframes sd-fondu{ from{ opacity:0; } to{ opacity:1; } }

.sd-modale{ position:relative; z-index:2; max-width:760px; margin:min(6vh,54px) auto;
  background:var(--surface); border-radius:14px;
  box-shadow:0 22px 60px rgba(25,23,125,.26), 0 2px 8px rgba(25,23,125,.1);
  animation:sd-monte .34s cubic-bezier(.22,.61,.36,1) both; overflow:hidden; }
@keyframes sd-monte{ from{ opacity:0; transform:translate3d(0,14px,0) scale(.985); }
  to{ opacity:1; transform:none; } }
.sd-modale__tete{ display:flex; align-items:flex-start; gap:14px;
  padding:20px 22px 14px; border-bottom:1px solid var(--trait); }
.sd-modale__tete h2{ font-size:19px; font-weight:700; margin:0; letter-spacing:-.01em; }
.sd-modale__tete p{ margin:3px 0 0; font-size:13.5px; color:var(--mate); }
.sd-modale__x{ margin-left:auto; background:none; border:0; cursor:pointer;
  width:30px; height:30px; border-radius:50%; display:grid; place-items:center;
  color:var(--mate); flex:0 0 auto; }
.sd-modale__x:hover{ background:var(--gris); color:var(--encre); }
.sd-modale__corps{ padding:20px 22px; max-height:min(58dvh,540px); overflow-y:auto; }
.sd-modale__pied{ display:flex; gap:10px; justify-content:flex-end;
  padding:15px 22px; border-top:1px solid var(--trait); background:var(--gris);
  flex-wrap:wrap; }

@media (max-width:900px){
  /* sur telephone, la modale prend la largeur : un dialogue centre a
     260 px de large ne serait plus un dialogue, juste une carte etroite. */
  .sd-modale{ max-width:none; border-radius:12px; }
  .sd-modale__corps{ max-height:none; padding:16px; }
  .sd-modale__tete{ padding:16px; }
  .sd-modale__pied{ padding:14px 16px; flex-direction:column-reverse; }
  .sd-modale__pied .sd-btn{ width:100%; justify-content:center; }
  .sd-voile{ display:none; }
}


/* Les pastilles d'etat portent desormais un SVG et non un caractere :
   elles centrent leur contenu et lui donnent sa couleur, sans graisse. */
.sd-note__p svg, .sd-log__p svg, .sd-chrono__p svg, .sd-kpi__i svg, .sd-ok__p svg{
  display:block; }
.sd-note__p, .sd-log__p{ font-weight:400; }
.sd-kpi__i.est-rouge{ color:var(--rouge-700); }


/* ══ CE QUE L'AUDIT A TROUVE ════════════════════════════════════════

   Le focus n'etait dessine nulle part : ni :focus, ni :focus-visible dans
   toute la feuille. Le navigateur posait son anneau par defaut, mesure a
   2,38 : 1 sur le bleu de marque, sous le seuil de 3:1, et de forme
   differente selon le navigateur. Sur une demo qu'on parcourt au clavier,
   c'est le defaut le plus couteux.
-------------------------------------------------------------------*/
/* :not([tabindex="-1"]) : on pose le focus sur le titre du nouvel ecran pour
   que le clavier reparte de la, mais un titre n'est pas une commande. Sans
   cette exclusion, Chrome lui dessinait l'anneau et l'ecran s'ouvrait avec un
   cadre bleu autour de son titre. */
.sd :focus-visible:not([tabindex="-1"]){ outline:2px solid var(--encre);
  outline-offset:2px; border-radius:var(--r-btn); }
/* Et il faut l'ecrire : ne pas poser d'anneau ne retire pas celui du
   navigateur, qui dessinait un cadre de 1 px autour du titre a chaque ecran. */
.sd [tabindex="-1"]:focus, .sd [tabindex="-1"]:focus-visible{ outline:none; }
.sd-btn--fort:focus-visible, .sd-quitter:focus-visible,
.sd-onglet.est-choisi:focus-visible{
  outline-color:#fff; box-shadow:0 0 0 4px var(--encre); }
.sd-champ input:focus-visible, .sd-champ select:focus-visible,
.sd-champ textarea:focus-visible, .sd-cherche input:focus-visible{
  outline:2px solid var(--encre); outline-offset:1px; }

/* La ligne en erreur portait bien sa classe, mais .est-erreur n'existait
   nulle part : la ligne qui porte tout l'interet de l'ecran n'etait pas
   teintee. */
.sd-tbl tr.est-erreur td{ background:var(--rouge-100); }
.sd-tbl tr.est-erreur:hover td{ background:#fbd5d5; }

/* Trois selects rendus par le systeme a cote de trois selects stylees, a un
   ecran d'intervalle : autre rayon, autre fleche, et 19 px de haut contre
   37 sous 375. */
.sd-cherche select{ font:inherit; font-size:13px; padding:9px 11px;
  align-self:stretch; min-height:44px; border:1px solid var(--trait);
  border-radius:var(--r-s); background:var(--surface); color:var(--encre);
  min-width:0; }

/* Cibles tactiles. 36 et 40 sont deliberes la ou 44 casserait la densite
   d'une barre d'outils ; les boutons de copie et le lien de retour, eux,
   echouaient vraiment. */
.sd-copie button{ padding:5px; min-width:44px; min-height:44px;
  display:grid; place-items:center; right:2px; border-radius:var(--r-s); }
.sd-copie input{ padding-right:48px; }
.sd-retour{ min-height:44px; padding:0 2px; margin-left:-2px; }
.sd-modale__x{ width:44px; height:44px; }
.sd-onglet{ min-height:36px; }
.sd-quitter{ min-height:40px; display:inline-flex; align-items:center; }
.sd-btn--petit{ min-height:40px; }
.sd-champ input, .sd-champ select, .sd-champ textarea{ min-height:44px; }

/* Un lien deguise en bouton heritait du soulignement : le dernier bouton
   principal du parcours etait souligne quand les dix-sept autres non. */
a.sd-btn{ text-decoration:none; }

/* Le texte annonce aux lecteurs d'ecran, invisible a l'oeil. */
.sd-annonce{ position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0; }

/* Un champ obligatoire vide se voit. */
.sd-champ input[aria-invalid="true"], .sd-champ textarea[aria-invalid="true"]{
  border-color:var(--rouge-700); box-shadow:0 0 0 3px rgba(200,30,30,.12); }

/* La cle ne se lit pas avant d'exister, et elle se replie au lieu d'etre
   rognee : <pre> est en white-space:pre par defaut. */
.sd-cle__sortie{ white-space:pre-wrap; }
.sd-cle__barre{ display:none; }
.sd-cle__barre.est-la{ display:block; }

/* La navigation n'est pas une rangee de boutons : ce sont des etapes. */
.sd-nav__l{ list-style:none; margin:0; padding:0; display:flex;
  flex-direction:column; gap:4px; }

/* prefers-reduced-motion ne coupait ni les delais echelonnes ni la pulsation
   infinie de l'indicateur « Processing ». */
@media (prefers-reduced-motion:reduce){
  .sd *{ animation-delay:0ms !important; animation-iteration-count:1 !important; }
  .sd-canal:hover, .sd-jalon.est-passe{ transform:none; }
}

@media (max-width:900px){
  /* Sur telephone, la colonne Statut est la huitieme : la ligne en erreur,
     la raison d'etre de l'ecran, sortait de l'ecran sans que rien ne le
     laisse deviner. Elle se fige a droite, et un degrade dit qu'on defile. */

}


/* La zone de depot et la ligne de fichier de l'ecran « New data tool ».
   Le prototype montre un zip de 41,5 Mo a 75 % : c'est le moment ou le
   client donne sa matiere, et mes quatre menus deroulants l'effacaient. */
.sd-depot{ border:1.5px dashed var(--trait); border-radius:var(--r);
  padding:26px 16px; text-align:center; background:var(--surface); }
.sd-depot p{ margin:0; font-size:14px; line-height:1.6; }
.sd-depot b{ font-weight:700; }
.sd-depot span{ color:var(--mate); font-size:13px; }
.sd-fichier{ display:flex; align-items:center; gap:12px; margin-top:12px;
  padding:11px 13px; background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r-s); font-size:13px; }
.sd-fichier .sd-jauge{ flex:1; min-width:60px; }
.sd-fichier__t{ color:var(--mate); white-space:nowrap;
  font-variant-numeric:tabular-nums; }
@media (max-width:560px){
  .sd-fichier{ flex-wrap:wrap; }
  .sd-fichier .sd-jauge{ order:3; flex-basis:100%; }
}


/* Le bouton d'arret d'un lot en cours : rouge, comme dans le prototype. */
.sd-btn--danger{ background:var(--rouge-100); color:var(--rouge-800);
  border-color:#f8b4b4; }
.sd-btn--danger:hover{ background:var(--rouge-100); border-color:var(--rouge-700); }
html.theme-dark .sd-btn--danger:hover{ background:#4a1a28; }
.sd-btn--danger svg{ display:block; }

/* Une notification a un titre, un corps, un moment. Les trois etaient
   melanges dans deux champs, et le resume s'affichait sous le paragraphe
   qu'il devait titrer. */
.sd-note__k{ font-size:13.5px; font-weight:700; margin:0 0 3px; }
.sd-note__t{ font-size:13.5px; line-height:1.5; margin:0; color:var(--mate); }
.sd-note__m{ margin-left:auto; align-self:flex-start; background:none;
  border:0; cursor:pointer; color:var(--mate-2); width:32px; height:32px;
  border-radius:var(--r-s); display:grid; place-items:center; flex:0 0 auto; }
.sd-note__m:hover{ background:var(--gris); color:var(--encre); }
/* la pastille d'info portait un fond vert de succes : un « i » dans un rond
   vert dit « c'est reussi », pas « pour information ». */
.sd-note__p.est-info{ background:var(--speos-500); }

/* ══ LE CANEVAS DE CORRESPONDANCE ═══════════════════════════════════
   Deux colonnes de champs, un noeud de transformation au milieu, et des
   fils traces entre les deux. C'est le geste que la demo pretend rejouer,
   et il etait remplace par quatre menus deroulants.

   Les fils sont en SVG parce que ce sont des courbes entre deux points
   mesures : en CSS il faudrait les deviner.
-------------------------------------------------------------------*/
.sd-modale--large{ max-width:1080px; }
.sd-map{ position:relative; display:grid;
  grid-template-columns:minmax(0,1fr) 230px minmax(0,1fr); gap:0; align-items:start; }
/* Les fils passaient sous les colonnes : un fil qui disparait derriere une
   carte ne dit plus rien du lien qu'il represente. Ils passent au-dessus, et
   un halo de la couleur du fond les detache la ou ils croisent une carte. */
.sd-map__fils{ position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; overflow:visible; z-index:5; }
.sd-fil-halo{ fill:none; stroke:var(--surface); stroke-width:6;
  stroke-linecap:round; }
.sd-fil{ fill:none; stroke:var(--speos-500); stroke-width:2;
  stroke-linecap:round;
  stroke-dasharray:var(--l,400); stroke-dashoffset:var(--l,400);
  animation:sd-tracer .7s cubic-bezier(.4,0,.2,1) .1s forwards; }
.sd-fil.est-cible{ stroke:var(--rouge-700); animation-delay:.5s; }
@keyframes sd-tracer{ to{ stroke-dashoffset:0; } }

.sd-map__k{ font-size:13px; font-weight:700; margin:0 0 12px; }
.sd-map__col{ display:flex; flex-direction:column; gap:10px; min-width:0; position:relative; z-index:2; }
.sd-map__mid{ display:flex; flex-direction:column; align-items:center;
  justify-content:flex-start; padding-top:96px; position:relative; z-index:2; }

.sd-groupe{ border:1px solid var(--trait); border-radius:var(--r-s);
  background:var(--surface); overflow:hidden; }
.sd-groupe__h{ display:flex; align-items:center; gap:9px; width:100%;
  padding:12px 14px; background:none; border:0; font:inherit; font-size:14px;
  font-weight:600; color:var(--speos-encre); cursor:pointer; text-align:left; }
.sd-groupe.est-ouvert .sd-groupe__h{ background:var(--gris);
  border-bottom:1px solid var(--trait); }
.sd-groupe.est-ouvert .sd-groupe__h svg{ transform:rotate(180deg); }
.sd-groupe__h svg{ transition:transform var(--pas); flex:0 0 auto; }
.sd-groupe__i{ width:16px; height:16px; border-radius:50%; background:var(--g200);
  color:var(--mate); font-size:10px; font-weight:700; display:grid;
  place-items:center; flex:0 0 auto; }

.sd-champ-map{ display:flex; align-items:center; justify-content:space-between;
  padding:10px 14px; font-size:13.5px; color:var(--mate);
  border-bottom:1px solid var(--trait); background:var(--lavande); }
.sd-champ-map:last-child{ border-bottom:0; }
/* L'attribut data-cote est porte par .sd-champ-map elle-meme : ecrit en
   selecteur de descendance, la regle ne matchait rien et les deux points se
   retrouvaient au bord droit. Le fil traversait donc toute la carte cible
   pour rejoindre son point. Ils se font face. */
/* Le point passe a gauche pour faire face a la source, mais le libelle reste
   ferre a gauche : row-reverse le rejetait contre le bord droit, et on lisait
   le nom du champ a l'oppose de son point d'accroche. */
.sd-champ-map[data-cote="t"] .sd-plot{ order:-1; }
.sd-champ-map[data-cote="t"] .sd-champ-map__n{ margin-right:auto; }

/* la pastille de connexion : creuse tant qu'elle ne porte rien */
.sd-plot{ width:11px; height:11px; border-radius:50%; flex:0 0 auto;
  background:var(--surface); border:2px solid var(--g300);
  transition:border-color var(--pas), transform var(--pas); }
.sd-plot.est-relie{ border-color:var(--speos-500); transform:scale(1.15); }
.sd-plot.est-relie.est-cible{ border-color:var(--rouge-700); }

.sd-noeud{ display:flex; align-items:center; gap:6px; padding:7px 9px;
  background:var(--surface); border:1px solid var(--trait);
  border-radius:var(--r-s); box-shadow:var(--ombre); }
.sd-noeud .sd-plot.est-entree{ border-color:var(--speos-500); }
.sd-noeud .sd-plot.est-sortie{ border-color:var(--rouge-700); }
.sd-noeud__b{ background:none; border:0; cursor:pointer; padding:5px;
  border-radius:5px; color:var(--mate); display:grid; place-items:center; }
.sd-noeud__b:hover{ background:var(--gris); color:var(--encre); }
.sd-noeud__b.est-danger{ color:var(--rouge-700); }
.sd-noeud__b.est-danger:hover{ background:var(--rouge-100); }

@media (max-width:900px){
  /* Sous 900, les trois colonnes s'empilent : des fils traces entre des
     boites superposees ne diraient plus rien, ils tombent. Ce qui reste,
     les pastilles reliees et le noeud, porte le propos. */
  .sd-map{ grid-template-columns:1fr; gap:16px; }
  .sd-map__fils{ display:none; }
  .sd-map__mid{ padding-top:0; }
  .sd-modale--large{ max-width:none; }
  .sd-champ-map[data-cote="t"]{ flex-direction:row; }
}
@media (prefers-reduced-motion:reduce){
  .sd-fil{ animation:none; stroke-dashoffset:0; }
}

/* Un champ porte son nom et son type, comme dans un vrai schema. */
.sd-champ-map__n{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.sd-champ-map__n em{ font-style:normal; font-size:11.5px; color:var(--mate-2); }
[data-cote="t"] .sd-champ-map__n{ align-items:flex-end; }
/* La regle portee par le noeud : c'est elle qui explique pourquoi deux
   champs source n'en alimentent qu'un. */
.sd-noeud__r{ margin:9px 0 0; font-size:11px; color:var(--mate);
  text-align:center; line-height:1.4; white-space:nowrap; }

/* Un repeteur : des lignes qu'on ajoute et qu'on retire. */
.sd-bloc__tete{ justify-content:space-between; }
.sd-bloc__a{ display:inline-flex; align-items:center; gap:5px; background:none;
  border:0; font:inherit; font-size:12.5px; font-weight:600; color:var(--speos-500);
  cursor:pointer; padding:4px 6px; border-radius:var(--r-btn); }
.sd-bloc__a:hover{ background:var(--lavande); }
.sd-ligne{ display:flex; gap:8px; align-items:center; margin-top:8px; }
.sd-ligne input{ flex:1; min-width:0; font:inherit; font-size:14px; padding:10px 12px;
  min-height:44px; border:1px solid var(--trait); border-radius:var(--r-s);
  background:var(--surface); color:var(--speos-encre); }
.sd-ligne__x{ background:none; border:0; cursor:pointer; color:var(--mate-2);
  width:44px; height:44px; border-radius:var(--r-s); display:grid; place-items:center;
  flex:0 0 auto; }
.sd-ligne__x:hover{ background:var(--rouge-100); color:var(--rouge-700); }

/* Les liens de documentation que le prototype pose sous chaque formulaire. */
.sd-doc{ margin:16px 0 0; font-size:13px; display:flex; flex-direction:column; gap:5px; }
.sd-doc span{ font-weight:700; }
.sd-doc a{ color:var(--speos-500); }

/* La confirmation de creation : courte, une seule action. */
.sd-modale--court{ max-width:440px; }
.sd-succes{ text-align:center; padding:30px 24px 26px; }
.sd-succes__p{ width:46px; height:46px; border-radius:50%; background:var(--vert-100);
  color:var(--vert-500); display:grid; place-items:center; margin:0 auto 16px; }
.sd-succes__p svg{ width:24px; height:24px; }
.sd-succes h2{ font-size:19px; font-weight:700; margin:0; text-wrap:balance; }

/* Les actions par ligne de tableau. */
.sd-actions-l{ display:inline-flex; gap:6px; }
.sd-actions-l .sd-btn{ min-height:32px; padding:5px 11px; font-size:12.5px; }

/* Le pied de tableau : combien on voit, sur combien, et les pages. */
.sd-tbl__pied{ display:flex; align-items:center; justify-content:space-between;
  gap:14px; flex-wrap:wrap; padding:14px 2px 0; margin-top:12px;
  border-top:1px solid var(--trait); font-size:12.5px; color:var(--mate); }
.sd-pages{ display:inline-flex; gap:3px; }
.sd-page{ min-width:32px; height:32px; border:1px solid var(--trait);
  background:var(--surface); border-radius:var(--r-btn); font:inherit; font-size:12.5px;
  color:var(--mate); cursor:pointer; }
.sd-page.est-la{ background:var(--lavande); border-color:var(--speos-200);
  color:var(--speos-500); font-weight:700; }
.sd-page:hover{ background:var(--gris); }

/* ══ LE MODE SOMBRE ═════════════════════════════════════════════════
   Le prototype Figma n'en a pas : c'est un concept, il vit dans un seul
   theme. Le folio, lui, en a un, et le visiteur qui arrive sur la demo y
   arrive avec son choix deja fait. Ne pas le respecter, c'est lui jeter
   une page blanche a la figure.

   Les valeurs ne sont pas des inversions mecaniques. Le bleu de marque
   #19177d, illisible sur fond nuit, cede la place a une variante claire
   derivee de speos blue/400. Les onze paires sont mesurees : la plus
   basse est a 5,18 : 1, la plus haute a 15,73.
-------------------------------------------------------------------*/
html.theme-dark .sd,
.sd[data-theme="dark"]{
  --speos-500:#9a99d8; --speos-400:#7574b1; --speos-200:#3a3b6e;
  --speos-gris:#0f1020; --speos-encre:#e9eaf4;

  --g50:#1f2136; --g100:#23253a; --g200:#2d3049; --g300:#3a3e5c;
  --g400:#878ca6; --g500:#a3a7bd; --g700:#c3c6d6; --g800:#dcdeea; --g900:#e9eaf4;
  --gris-sombre:#a3a7bd;

  --vert-100:#12301f; --vert-500:#3ddc97; --vert-800:#8ff0c4;
  --rouge-100:#3a1520; --rouge-700:#ff8a8a; --rouge-800:#ffb4b4;
  --jaune-100:#33290a; --jaune-800:#f5d98a;
  --info-50:#22234a; --info-700:#9a99d8;

  --encre:var(--speos-500); --encre-2:var(--speos-500);
  --fond:var(--speos-gris); --surface:#181a2c; --gris:#1f2136;
  --lavande:var(--info-50); --trait:var(--g200);
  /* Le bleu SPEOS remonte en luminosite pour tenir sur fond sombre, sans
     virer : c'est la meme teinte, pas une autre marque. */
  --action:#4f4ddb; --action-vive:#635fe8;
  /* Sur fond nuit les memes teintes remontent en luminosite : meme serie,
     meme lecture, contraste tenu. */
  --serie-1:#8b89f0; --serie-2:#60a5fa; --serie-3:#2dd4bf;
  --serie-4:#fbbf24; --serie-ok:#3ddc97; --serie-ko:#ff8a8a;
  /* La feuille reste une feuille : elle s'assombrit, elle ne s'inverse pas. */
  --papier:#e7e8f0; --papier-trait:#4a4d68; --papier-marque:#9ea2bd;
  --mate:var(--g500); --mate-2:var(--g400);
  --ombre:0 1px 2px -1px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
}

/* Ce qui ne suit pas les jetons et doit etre repris a la main. */
html.theme-dark .sd-btn--fort:hover{ box-shadow:0 6px 18px rgba(79,77,219,.45); }
html.theme-dark .sd-quitter:hover{ background:var(--g100); }
html.theme-dark .sd-etape.est-active .sd-etape__p{ color:var(--fond); }
html.theme-dark .sd-voile{ background:rgba(4,4,12,.62); }
html.theme-dark .sd-cle__sortie{ background:#0a0b16; color:#a9b0c8; }
html.theme-dark .sd-btn--doux{ background:var(--lavande); color:var(--speos-500); }
html.theme-dark .sd-btn--doux:hover{ background:#2b2c5c; }
html.theme-dark .sd-canal.est-armé .sd-btn{ background:var(--vert-100); color:var(--vert-500); }
html.theme-dark .sd-etiq--ok{ background:var(--vert-100); color:var(--vert-500); }
html.theme-dark .sd-etiq--ko{ background:var(--rouge-100); color:var(--rouge-700); }
html.theme-dark .sd-etiq--gris{ background:var(--g100); color:var(--mate); }
html.theme-dark .sd-tbl tr.est-erreur:hover td{ background:#4a1a28; }
html.theme-dark .sd-note__p.est-info{ background:var(--speos-500); color:var(--fond); }
html.theme-dark .sd-log__p{ background:var(--rouge-700); color:var(--fond); }
html.theme-dark .sd-succes__p{ color:var(--vert-500); }
html.theme-dark .sd-chrono li:not(:last-child)::before{ background:var(--vert-100); }
/* le logotype officiel est bicolore sur fond clair : sur fond nuit, on
   eclaircit son bleu sans toucher a son or. */
html.theme-dark .sd-logo{ filter:brightness(1.9) saturate(.85); }
/* l'illustration de l'etat vide porte des blancs en dur */
/* Les regles qui reteintaient l'ancien SVG dessine a la main n'ont plus de
   cible : l'illustration est desormais un <img>, et sa palette est fixee
   dans le fichier pour tenir sur les deux fonds. */

/* Le bouton de bascule, aligne sur celui du folio. */
.sd-theme{ width:34px; height:34px; border-radius:50%; border:1px solid var(--trait);
  background:var(--surface); color:var(--mate); cursor:pointer; display:grid;
  place-items:center; flex:0 0 auto; transition:background var(--pas), color var(--pas); }
.sd-theme:hover{ background:var(--gris); color:var(--encre); }
.sd-theme .est-nuit{ display:none; }
html.theme-dark .sd-theme .est-nuit{ display:block; }
html.theme-dark .sd-theme .est-jour{ display:none; }

/* ══ LA CONCLUSION ══════════════════════════════════════════════════
   Le prototype s'arrete sur ses notifications. Un parcours qui ne conclut
   pas laisse le lecteur juger seul de ce qu'il vient de voir, et un
   recruteur qui ferme l'onglet a cet instant n'emporte rien.

   Celui-ci recapitule ce que le visiteur a configure, avec ses valeurs a
   lui, et rend la main a l'etude de cas.
-------------------------------------------------------------------*/
.sd-fin{ max-width:660px; margin:0 auto; padding:40px 4px 20px; }
.sd-fin__k{ font-size:11px; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--speos-500); margin:0 0 10px; }
.sd-fin h2{ font-size:30px; font-weight:800; letter-spacing:-.02em; margin:0 0 12px;
  text-wrap:balance; line-height:1.15; }
.sd-fin__p{ font-size:15px; line-height:1.6; color:var(--mate); margin:0 0 28px;
  max-width:52ch; text-wrap:pretty; }

.sd-recap{ list-style:none; margin:0 0 30px; padding:0;
  display:flex; flex-direction:column; gap:2px; }
.sd-recap li{ display:grid; grid-template-columns:26px 1fr; gap:13px;
  align-items:start; padding:13px 14px; border-radius:var(--r-s);
  font-size:14px; line-height:1.5; color:var(--mate);
  animation:sd-entree .45s cubic-bezier(.22,.61,.36,1) both;
  animation-delay:calc(var(--n) * 70ms + 120ms); }
.sd-recap li:nth-child(odd){ background:var(--gris); }
.sd-recap b{ color:var(--speos-encre); font-weight:700; }
.sd-recap__p{ width:26px; height:26px; border-radius:50%; background:var(--vert-100);
  color:var(--vert-500); display:grid; place-items:center; }
.sd-fin__a{ margin:0; }
.sd-fin__a .sd-btn{ text-decoration:none; }

@media (max-width:560px){
  .sd-fin{ padding:26px 0 12px; }
  .sd-fin h2{ font-size:23px; }
  .sd-fin__a .sd-btn{ width:100%; justify-content:center; }
}
@media (prefers-reduced-motion:reduce){
  .sd-recap li{ animation:none; }
}

/* ══ LE PANNEAU GUIDE ═══════════════════════════════════════════════
   Figma le pose en colonne fixe a droite, ses quatre jalons visibles en
   permanence. Ici il est contextuel : il repond a la seule question qu'on
   se pose devant un ecran d'activation, « pourquoi on me demande ca ».

   Un panneau qui montre tout tout le temps fait lire quatre fois la meme
   chose ; celui-ci change avec l'etape, et se lit une fois.
-------------------------------------------------------------------*/
.sd-cote{ background:var(--surface); border-right:1px solid var(--trait);
  display:flex; flex-direction:column; min-width:0; overflow-y:auto; }
.sd-cote .sd-nav{ border-right:0; flex:0 0 auto; }
.sd-guide{ margin:0 14px 18px; padding:16px; border-radius:var(--r);
  background:linear-gradient(160deg, var(--lavande), transparent 140%);
  border:1px solid var(--trait); }
.sd-guide__k{ font-size:10.5px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:var(--speos-500); margin:0; }
.sd-guide__s{ font-size:11px; color:var(--mate-2); margin:2px 0 10px;
  font-variant-numeric:tabular-nums; }
.sd-guide__t{ font-size:14.5px; font-weight:700; margin:0 0 6px; line-height:1.3;
  text-wrap:balance; }
.sd-guide__d{ font-size:12.5px; line-height:1.55; color:var(--mate); margin:0;
  text-wrap:pretty; }

/* .sd-cote remplace .sd-nav comme premier enfant de la grille ; la grille
   elle-meme est deja declaree plus haut, avec son repli sous 900 px. La
   redeclarer ici, sans condition, ecrasait ce repli a toutes les largeurs. */
.sd-nav{ border-right:0; }

@media (max-width:900px){
  /* Sur telephone le panneau passe SOUS la file d'etapes et avant le
     contenu : c'est la qu'on le lit, juste avant d'agir. */
  .sd-cote{ border-right:0; border-bottom:1px solid var(--trait);
    overflow:visible; }
  /* Le panneau garde son role — dire pourquoi on demande ceci — mais pas
     son encombrement : au-dessus du contenu, chaque ligne se paie. Titre,
     etape, et deux lignes d'explication. */
  .sd-guide{ margin:0 12px 10px; padding:10px 12px; }
  .sd-guide__k{ display:none; }
  .sd-guide__s{ margin:0 0 4px; }
  .sd-guide__t{ font-size:14px; margin-bottom:3px; }
  /* Le rognage a deux lignes coupait deux des six explications en pleine
     phrase. Le panneau prend la place qu'il lui faut : 36 px sur quatre
     etapes, 54 sur les deux plus longues. */
  .sd-guide__d{ font-size:12.5px; line-height:1.45; }
  /* Le retour au cas quitte le haut de l'ecran : sur telephone il se lit en
     fin de parcours, pas avant d'avoir commence. */
  .sd-cote .sd-sortie{ display:none; }
}

/* ══ LA FINITION ════════════════════════════════════════════════════
   Ce qui separe une interface juste d'une interface qu'on a envie de
   toucher. Rien ici n'est decoratif : chaque effet dit un etat, et tout
   se coupe sous prefers-reduced-motion.
-------------------------------------------------------------------*/

/* Le bouton principal : il s'enfonce, il ne clignote pas. */
.sd-btn{ transition:transform .14s cubic-bezier(.3,.8,.4,1),
  box-shadow .22s, background .18s, border-color .18s, color .18s; }
.sd-btn--fort:hover{ transform:translateY(-1px); }
.sd-btn--fort:active{ transform:translateY(0) scale(.985); }
.sd-btn--fin:hover, .sd-btn--doux:hover{ transform:translateY(-1px); }

/* Un champ qui prend le focus se souleve d'un cheveu : on sait ou on est
   sans avoir a chercher le curseur. */
.sd-champ input, .sd-champ select, .sd-champ textarea, .sd-cherche input{
  transition:border-color .18s, box-shadow .2s, background .18s; }
.sd-champ input:hover, .sd-champ textarea:hover, .sd-cherche input:hover{
  border-color:var(--g300); }

/* Les lignes de tableau : le survol porte sur la ligne entiere, y compris
   la colonne figee a droite sur telephone. */
.sd-tbl tbody tr{ transition:background .16s; }
.sd-tbl tbody tr:hover td:last-child{ background:var(--gris); }
html.theme-dark .sd-tbl tbody tr:hover td{ background:var(--g100); }
html.theme-dark .sd-tbl tbody tr:hover td:last-child{ background:var(--g100); }

/* Les cartes de canal : l'ombre suit la marque au lieu du noir pur. */
.sd-canal:hover{ box-shadow:0 10px 26px -8px rgba(25,23,125,.18); }
html.theme-dark .sd-canal:hover{ box-shadow:0 10px 26px -8px rgba(0,0,0,.5); }
.sd-canal .sd-canal__i{ transition:background var(--pas), color var(--pas),
  transform var(--pas); }
.sd-canal:hover .sd-canal__i{ transform:scale(1.06); }

/* Une etiquette qui change d'etat le fait savoir. */
@keyframes sd-etiq{ from{ transform:scale(.9); opacity:.5; } to{ transform:none; opacity:1; } }
.sd-canal.est-armé .sd-etiq{ animation:sd-etiq .3s cubic-bezier(.3,1.4,.5,1) both; }

/* Les plaques d'etape : la coche arrive, elle n'apparait pas. */
@keyframes sd-coche{ from{ transform:scale(.6) rotate(-12deg); opacity:0; } to{ transform:none; opacity:1; } }
.sd-etape.est-faite .sd-etape__p svg{ animation:sd-coche .34s cubic-bezier(.3,1.5,.5,1) both; }

/* Le panneau guide change de contenu : il glisse d'un cheveu pour que
   l'oeil sache que le texte n'est plus le meme. */
@keyframes sd-guide{ from{ opacity:0; transform:translate3d(0,5px,0); } to{ opacity:1; transform:none; } }
.sd-guide > *{ animation:sd-guide .32s cubic-bezier(.22,.61,.36,1) both; }
.sd-guide > *:nth-child(2){ animation-delay:.03s; }
.sd-guide > *:nth-child(3){ animation-delay:.06s; }
.sd-guide > *:nth-child(4){ animation-delay:.09s; }

/* Les barres de progression : la barre courante se distingue des faites. */
.sd-prog__b{ transition:background var(--pas), transform var(--pas); }
.sd-prog__b.est-fait:last-of-type{ transform:scaleY(1.6); }

/* Le rythme vertical : un titre de carte respire plus qu'un libelle. */
.sd-carte__tete h2{ line-height:1.25; }
.sd-carte + .sd-carte{ margin-top:14px; }

/* Le curseur dit ce qui est vivant. */
.sd-canal, .sd-groupe__h, .sd-onglet, .sd-page, .sd-note__m{ cursor:pointer; }
.sd-champ-map{ cursor:default; }

@media (prefers-reduced-motion:reduce){
  .sd-btn--fort:hover, .sd-btn--fin:hover, .sd-btn--doux:hover,
  .sd-canal:hover .sd-canal__i{ transform:none; }
  .sd-guide > *, .sd-canal.est-armé .sd-etiq,
  .sd-etape.est-faite .sd-etape__p svg{ animation:none; }
  .sd-prog__b.est-fait:last-of-type{ transform:none; }
}

@media (max-width:560px){
  /* Au doigt, une cible de 32 px se rate. Les boutons d'action de ligne et
     les pages sont les seuls a passer sous 40 sur telephone : ils s'elargissent
     la, et gardent leur densite sur ecran. */
  .sd-actions-l{ display:grid; grid-template-columns:repeat(3,1fr); gap:6px; width:100%; }
  .sd-actions-l .sd-btn{ min-height:40px; justify-content:center; }
  .sd-page{ min-width:40px; height:40px; }
  .sd-note__m{ width:40px; height:40px; }
  .sd-theme{ width:40px; height:40px; }
  .sd-noeud__b{ min-width:40px; min-height:40px; }
  .sd-groupe__h{ min-height:44px; }
}

/* Les liens de documentation sont du texte courant : 44 px de haut n'a pas
   de sens pour eux, mais au doigt il leur faut une zone. Ils la prennent en
   hauteur de ligne plutot qu'en boite. */
.sd-doc a{ display:inline-block; padding:6px 0; line-height:1.5; }
@media (max-width:560px){ .sd-doc a{ padding:9px 0; } }

/* Le journal, une fois l'arbitrage rendu : le vert dit que c'est clos, et
   la phrase dit ce qu'on a echange pour cela. */
.sd-log.est-resolu{ background:var(--vert-100); border-color:var(--vert-500); }
.sd-log.est-resolu .sd-log__p{ color:var(--vert-fort); }
[data-erreurs].a-change{ animation:sd-compte-baisse .5s ease-out; }
@keyframes sd-compte-baisse{ 0%{ transform:scale(1.22); } 100%{ transform:scale(1); } }
@media (prefers-reduced-motion:reduce){ [data-erreurs].a-change{ animation:none; } }

/* Ce qui se lit d'un seul tenant ne se coupe pas : etiquettes, pastilles de
   statut, identifiants, dates. Le tableau defile dans son conteneur, il n'a
   pas besoin de casser ses mots pour rentrer. */
.sd-etiq, .sd-encours, .sd-page, .sd-tbl th{ white-space:nowrap; }
.sd-tbl td.sd-mono, .sd-tbl td.est-date{ white-space:nowrap; }

/* Le retour au cas existe a deux endroits : dans la colonne sur ordinateur,
   sous la scene sur telephone ou la colonne est devenue une bande. Un seul
   des deux s'affiche a la fois. */
.sd-sortie--bas{ display:none; }
@media (max-width:900px){
  .sd-sortie--bas{ display:block; flex:0 0 auto; margin:0;
    padding:14px 16px 18px; background:var(--surface);
    border-top:1px solid var(--trait); }
}

/* ══ LE REPLI DE LA FILE D'ETAPES ═══════════════════════════════════
   Pose ici, apres .sd-nav__l, parce qu'une requete media ne l'emporte pas
   sur une regle de meme specificite declaree plus loin dans la feuille.
   C'est la faute qui a laisse les six etapes empilees sur 285 px avant le
   premier mot du contenu.
-------------------------------------------------------------------*/
@media (max-width:900px){
  .sd-nav__l{ flex-direction:row; gap:8px; padding:10px 12px; overflow-x:auto;
    scrollbar-width:none; -webkit-overflow-scrolling:touch; }
  .sd-nav__l::-webkit-scrollbar{ display:none; }
  .sd-nav__l > li{ flex:0 0 auto; }
}

/* Trois cartes empilees prenaient 500 px pour trois nombres. La progression
   garde toute la largeur — c'est une barre, elle en a besoin ; les deux
   compteurs se rangent cote a cote, ce qui les rend comparables au lieu de
   les faire defiler l'un apres l'autre. */
@media (max-width:900px){
  .sd-trois{ grid-template-columns:1fr 1fr; }
  .sd-trois > :first-child{ grid-column:1 / -1; }
  .sd-trois__n{ font-size:26px; }
  .sd-trois__c{ padding:14px 16px; }
}

/* Le bandeau de confirmation. Il remplace l'ecran plein que l'entite etait
   seule a obtenir : la meme information, posee sur la liste ou l'on vient
   de la creer, sans couter un clic. */
.sd-fait{ display:flex; align-items:center; gap:10px; margin:0 0 16px;
  padding:11px 14px; border-radius:var(--r);
  background:var(--vert-100); border:1px solid var(--vert-500);
  font-size:13.5px; color:var(--vert-800); }
.sd-fait__p{ display:flex; color:var(--vert-fort); flex:0 0 auto; }
.sd-fait b{ font-weight:700; }

/* ══ LE PANNEAU QUI MONTRE LE RAISONNEMENT ═════════════════════════
   Il ne dit plus seulement ce que fait l'ecran : il cite l'irritant releve
   en recherche, puis ce que l'ecran en fait, puis la famille a laquelle il
   appartient. C'est la difference entre montrer un produit et montrer
   pourquoi il est fait comme ca.
-------------------------------------------------------------------*/
.sd-guide__k{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.sd-guide__k .sd-guide__s{ margin:0; font-size:10.5px; font-weight:700;
  color:var(--mate-2); font-variant-numeric:tabular-nums; letter-spacing:0; }
.sd-guide__pain{ margin:0 0 8px; padding:0 0 0 10px;
  border-left:2px solid var(--action); font-size:12.5px; line-height:1.5;
  color:var(--encre); font-style:italic; text-wrap:pretty; }
.sd-guide__f{ margin:9px 0 0; }
.sd-guide__f span{ display:inline-block; font-size:10px; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; padding:3px 8px;
  border-radius:99px; background:var(--surface); border:1px solid var(--trait);
  color:var(--mate-2); white-space:nowrap; }
@media (max-width:900px){
  /* J'avais replie l'explication pour gagner de la place. Seize ecrans
     mobiles sur seize perdaient alors le maillon entre l'irritant et ce que
     l'ecran en fait : c'est precisement ce que le panneau existe pour dire.
     Il garde les deux, et rien n'est tronque. */
  .sd-guide__pain{ font-size:12.5px; margin-bottom:8px; }
  .sd-guide__f{ margin-top:8px; }
}

/* ══ LES TRANSITIONS DE VUE ════════════════════════════════════════
   Baseline depuis octobre 2025. Le navigateur photographie l'ecran sortant
   et l'ecran entrant, puis anime entre les deux. Ce que la couche CSS ne
   savait pas faire : la file d'etapes et la barre de progression portent
   leur propre nom, donc elles se deplacent au lieu de clignoter.
-------------------------------------------------------------------*/
.sd-scene{ view-transition-name: sd-scene; }
.sd-cote{ view-transition-name: sd-cote; }
.sd-prog{ view-transition-name: sd-prog; }

/* Quand l'API prend la main, l'ancienne animation d'entree se retire :
   deux animations sur le meme element en font une troisieme, ratee. */
html.sd-transite .sd-vue.arrive{ animation:none; }

::view-transition-old(sd-scene){
  animation: sd-vt-sort .22s cubic-bezier(.4,0,1,1) both; }
::view-transition-new(sd-scene){
  animation: sd-vt-entre .34s cubic-bezier(.16,1,.3,1) both; }
@keyframes sd-vt-sort{ to{ opacity:0; transform:translate3d(-14px,0,0); } }
@keyframes sd-vt-entre{ from{ opacity:0; transform:translate3d(20px,0,0); } }

/* La colonne et la barre ne bougent pas d'un ecran a l'autre : on coupe
   leur fondu croise, sinon elles scintillent a chaque clic. */
::view-transition-old(sd-cote), ::view-transition-new(sd-cote),
::view-transition-old(sd-prog), ::view-transition-new(sd-prog){
  animation:none; mix-blend-mode:normal; }

/* Et surtout la racine. Tout ce qui n'a pas de nom — l'en-tete, le fond —
   se retrouve dans le groupe « root », que le navigateur fond en croise par
   defaut. Sur une page qui ne change pas a cet endroit, ce fondu se voit
   comme un sautillement de rechargement a chaque clic. */
::view-transition-old(root), ::view-transition-new(root){
  animation:none; mix-blend-mode:normal; }
::view-transition-group(root){ animation-duration:0s; }

@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*){
    animation:none !important; }
}

/* ══ LES REQUETES DE CONTENEUR ═════════════════════════════════════
   Une requete media interroge la fenetre ; un composant vit dans sa colonne.
   A 1024 px de fenetre, la scene fait 744 px — moins qu'a 768 px, ou la
   colonne laterale est repliee. Les grilles se pliaient donc au mauvais
   moment, et rien dans la fenetre ne pouvait le dire.

   Pose en fin de feuille : a specificite egale, c'est l'ordre qui tranche,
   et ces regles doivent l'emporter sur les replis media qu'elles remplacent.
-------------------------------------------------------------------*/
.sd-scene{ container-type:inline-size; container-name:scene; }

@container scene (max-width: 780px){
  .sd-grille{ grid-template-columns:1fr; }
  .sd-kpi{ grid-template-columns:1fr 1fr; }
  .sd-detail{ grid-template-columns:1fr; }
  .sd-parts{ grid-template-columns:1fr 1fr; }
  .sd-deplie{ grid-template-columns:1fr; }
  .sd-trois{ grid-template-columns:1fr 1fr; }
  .sd-trois > :first-child{ grid-column:1 / -1; }
  .sd-flux{ grid-template-columns:1fr 1fr; }
  .sd-canaux{ grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); }
}
@container scene (max-width: 480px){
  .sd-kpi{ grid-template-columns:1fr; }
  .sd-parts{ grid-template-columns:1fr; }
  .sd-flux{ grid-template-columns:1fr; }
  .sd-canaux{ grid-template-columns:1fr; }
}

/* L'illustration se dimensionne sur la place que lui laisse la scene, pas
   sur la fenetre : dans une colonne etroite elle doit ceder, pas deborder. */
@container scene (max-width: 780px){
  .sd-vide__illu{ max-height:170px; max-width:min(100%, 240px); margin-bottom:22px; }
}
@container scene (max-width: 480px){
  .sd-vide__illu{ max-height:130px; max-width:min(100%, 190px); margin-bottom:18px; }
}

/* ══ LES ILLUSTRATIONS ══════════════════════════════════════════════
   Toutes viennent d'unDraw et vivent dans le depot. Chacune se dimensionne
   sur la place que lui laisse son conteneur : une illustration qui deborde
   d'une colonne fait plus de mal que pas d'illustration du tout.
-------------------------------------------------------------------*/
.sd-illu-cote{ display:block; height:auto; width:auto;
  max-height:74px; max-width:110px; margin-left:auto; opacity:.9; }
.sd-fin__illu{ display:block; height:auto; width:auto;
  max-height:180px; max-width:min(100%, 250px); margin:0 0 22px; }
@container scene (max-width: 780px){
  .sd-illu-cote{ max-height:56px; max-width:84px; }
  .sd-fin__illu{ max-height:140px; max-width:min(100%, 200px); margin-bottom:18px; }
}
@container scene (max-width: 480px){
  .sd-illu-cote{ display:none; }
  .sd-fin__illu{ max-height:110px; max-width:min(100%, 160px); }
}

/* Le pourcentage se lit a cote du chiffre, pas sous lui : une ligne de plus
   dans une seule carte etirait les quatre et laissait un vide. */
.sd-kpi__n{ display:flex; align-items:baseline; gap:8px; }
.sd-kpi__d{ font-size:12px; font-weight:600; color:var(--mate); }

/* ══ L'ECRAN DE CORRESPONDANCE ═════════════════════════════════════
   Ce qu'il doit prouver : le moteur retrouve la grande majorite des champs
   tout seul, et le reste se decide ici, sans ticket.
-------------------------------------------------------------------*/
.sd-auto{ display:flex; align-items:center; gap:16px; margin:0 0 20px;
  padding:14px 16px; border-radius:var(--r);
  background:var(--vert-100); border:1px solid var(--vert-500); }
.sd-auto__t{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.sd-auto__t b{ font-size:14px; font-weight:700; color:var(--vert-800); }
.sd-auto__t span{ font-size:12.5px; color:var(--mate); }
.sd-auto__j{ flex:1 1 120px; min-width:80px; height:6px; border-radius:3px;
  background:var(--surface); overflow:hidden; }
.sd-auto__j i{ display:block; height:100%; border-radius:3px;
  background:var(--vert-fort); }
.sd-auto__p{ font-size:16px; font-weight:800; color:var(--vert-800);
  font-variant-numeric:tabular-nums; white-space:nowrap; }

/* Un champ retrouve par le moteur dit vers ou il est parti. */
.sd-champ-map__vers{ display:inline-flex; align-items:center; gap:5px;
  margin-left:10px; font-size:11.5px; font-weight:600; color:var(--vert-fort); }
.sd-champ-map__vers span{ font-family:var(--mono, ui-monospace, monospace); }
.sd-champ-map.est-auto{ background:var(--surface); color:var(--mate-2); }

/* Un champ qui attend une decision se voit : c'est la ou l'humain travaille. */
.sd-champ-map.est-manuel{ background:var(--lavande);
  box-shadow:inset 3px 0 0 var(--action); color:var(--encre); font-weight:600; }
.sd-champ-map[data-cote="t"].est-manuel{
  box-shadow:inset -3px 0 0 var(--rouge-700); }

/* ══ LA COLONNE FIGEE ══════════════════════════════════════════════
   Elle a ete ecrite pour un tableau : celui du suivi, dont la derniere
   colonne porte le statut, la raison d'etre de l'ecran. Posee sur .sd-tbl
   elle s'appliquait aux quatre, et sur telephone elle ecrasait la colonne
   « E-mail admin » du tableau des entites a deux caracteres. Elle vaut
   maintenant a toute largeur, mais pour ce seul tableau.
-------------------------------------------------------------------*/
.sd-tbl--fige td:last-child{ position:sticky; right:0; background:var(--surface);
  box-shadow:-6px 0 8px -6px rgba(30,32,51,.18); }
.sd-tbl--fige th:last-child{ position:sticky; right:0; background:var(--gris);
  box-shadow:-6px 0 8px -6px rgba(30,32,51,.18); }
.sd-tbl--fige tr.est-erreur td:last-child{ background:var(--rouge-100); }
html.theme-dark .sd-tbl--fige tr.est-erreur td:last-child{ background:#4a1a28; }

/* Le repere de reconstruction. Un recruteur doit savoir en une seconde qu'il
   regarde une reconstruction et non le produit en service : sans lui, la
   demo laisse croire a un acces au produit de SPEOS. */
.sd-repere{ font-size:11px; font-weight:600; letter-spacing:.02em;
  color:var(--mate); padding:4px 10px; border:1px solid var(--trait);
  border-radius:99px; white-space:nowrap; }
@media (max-width:900px){ .sd-repere{ display:none; } }

/* La base d'une ventilation se nomme : « Channel split of 100,000
   transferred ». Sans elle, Peppol a 60 000 se lisait sous un titre qui
   annoncait 40 000, et le lecteur concluait que la somme etait fausse. */
.sd-part__t{ margin:0 0 8px; font-size:12.5px; font-weight:600; color:var(--mate); }

/* Les identifiants du connecteur : deux champs larges et un port etroit, sur
   une seule rangee. Le port ne demande que 110 px (12 de rembourrage, 35 de
   texte, 48 pour le bouton copier) et en occupait 376. */
.sd-grille--cle{ grid-template-columns:minmax(0,1fr) minmax(0,1fr) 110px; }
@container scene (max-width: 780px){ .sd-grille--cle{ grid-template-columns:1fr; } }
