/* Réinitialisation — équivalent du squelette fourni par le runtime Artifact,
   nécessaire ici puisque la page est servie en fichier local autonome. */
html{color-scheme:light dark}
html[data-theme="light"]{color-scheme:light}
html[data-theme="dark"]{color-scheme:dark}
body{margin:0}
img{max-width:100%}
[hidden]{display:none!important}

:root{
  --paper:#EEF0EC;
  --surface:#F7F8F5;
  --surface-2:#E4E7E1;
  --ink:#15191A;
  --ink-2:#3D4644;
  --mist:#5C6864;
  --line:#CBD1CA;
  --line-strong:#A9B2AA;
  --line-control:#747F78;
  --petrol:#14535F;
  --petrol-soft:#D8E5E6;
  --rouille:#9A3F1B;
  --rouille-soft:#F0DFD5;
  --olive:#456A38;
  --olive-soft:#DCE6D5;
  --flottement:0 8px 24px rgba(0,0,0,.14);
  /* Échelle typographique. Le préfixe suit `--f-` : `--t-` pour les corps de
     texte, `--l-` pour les étiquettes en chasse fixe. Dix rôles nommés
     remplacent 34 valeurs, dont onze tenaient entre 10,4 et 12,6 px — des
     écarts de 2 % qui ne portaient aucune hiérarchie et se recopiaient d'un
     composant à l'autre. Les pas font ~9 % : chacun se voit.

     Plancher à 11 px pour tout texte porteur d'information — étiquette,
     compteur, sceau, marqueur. C'est la borne en dessous de laquelle une
     chasse fixe en capitales cesse de se lire d'un coup d'œil, et le marqueur
     de réserve y monte depuis 8,5 px : il porte une réserve sur une colonne,
     et rien ne la redonde à l'œil. Sa subordination à l'intitulé de colonne
     tient désormais à sa rouille et à son lavis, non à sa taille. */
  --t-display:clamp(2.1rem,4.6vw,3.4rem);
  --t-headline:1.62rem;
  --t-title:1.09rem;
  --t-chapeau:18px;
  --t-body:17px;
  --t-prose:15.5px;
  --t-dense:14px;
  --t-data:12.5px;
  --l-lg:12px;
  --l-md:11px;
  --f-display:"Archivo","Helvetica Neue",Arial,sans-serif;
  --f-body:"Newsreader",Georgia,"Times New Roman",serif;
  --f-mono:"IBM Plex Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#0F1413;
    --surface:#161C1B;
    --surface-2:#1E2625;
    --ink:#E5E9E4;
    --ink-2:#B6C0BA;
    --mist:#87938D;
    --line:#2C3634;
    --line-strong:#42504D;
    --line-control:#6A7B76;
    --petrol:#5FB3C0;
    --petrol-soft:#15302F;
    --rouille:#DE8D62;
    --rouille-soft:#33211A;
    --olive:#93BC7C;
    --olive-soft:#1D2A1B;
    --flottement:0 8px 24px rgba(0,0,0,.5);
  }
}
:root[data-theme="dark"]{
  --paper:#0F1413;
  --surface:#161C1B;
  --surface-2:#1E2625;
  --ink:#E5E9E4;
  --ink-2:#B6C0BA;
  --mist:#87938D;
  --line:#2C3634;
  --line-strong:#42504D;
  --line-control:#6A7B76;
  --petrol:#5FB3C0;
  --petrol-soft:#15302F;
  --rouille:#DE8D62;
  --rouille-soft:#33211A;
  --olive:#93BC7C;
  --olive-soft:#1D2A1B;
  --flottement:0 8px 24px rgba(0,0,0,.5);
}

/* Trois filets et non deux. `--line` sépare, `--line-strong` structure — ni
   l'un ni l'autre n'atteint 3:1 sur `--surface`, ce qui leur est sans
   conséquence : un filet de table n'identifie aucun contrôle. `--line-control`
   est la **seule frontière visuelle** d'un champ, d'un `select`, d'un sommaire
   de menu ou d'un bouton de Volet — rien ne la double, ni ombre ni fond
   contrasté —, et elle tient donc 3:1 sur les trois fonds, dans les deux
   thèmes (WCAG 2.2, SC 1.4.11). L'employer comme filet décoratif la ferait
   dériver vers `--line-strong` au premier ajustement. */

*{box-sizing:border-box}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:var(--t-body);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1240px;margin:0 auto;padding:0 28px 96px}

/* ---------- Masthead ---------- */
.masthead{border-bottom:2px solid var(--ink);padding:44px 0 22px;margin-bottom:0}
.eyebrow{
  font-family:var(--f-mono);font-size:var(--l-lg);font-weight:500;
  letter-spacing:.16em;text-transform:uppercase;color:var(--petrol);
  display:flex;flex-wrap:wrap;gap:10px 18px;align-items:baseline;
}
.eyebrow span::before{content:"";display:inline-block;width:0}
h1{
  font-family:var(--f-display);font-weight:700;font-size:var(--t-display);
  line-height:1.04;letter-spacing:-.024em;margin:16px 0 12px;text-wrap:balance;max-width:20ch;
}
.standfirst{font-size:var(--t-chapeau);color:var(--ink-2);max-width:62ch;margin:0 0 26px}
.standfirst strong{color:var(--ink);font-weight:500}

/* ---------- Manifest ---------- */
.manifest{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(232px,1fr));
  gap:0;border-top:1px solid var(--line);
}
.mf{padding:16px 20px 18px;border-bottom:1px solid var(--line);border-right:1px solid var(--line)}
.mf:last-child{border-right:0}
.mf-name{font-family:var(--f-mono);font-size:var(--t-data);font-weight:500;color:var(--ink);word-break:break-all;line-height:1.4}
.mf-rows{margin-top:10px;display:flex;flex-direction:column;gap:3px}
.mf-row{display:flex;justify-content:space-between;gap:12px;font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist)}
.mf-row b{color:var(--ink-2);font-weight:500;font-variant-numeric:tabular-nums}
.mf-flag{color:var(--rouille)}

/* ---------- Shell ---------- */
.shell{display:grid;grid-template-columns:1fr;gap:0;margin-top:52px}
@media (min-width:1060px){.shell{grid-template-columns:196px 1fr;gap:56px}}
/* Le rail n'a sa colonne qu'à partir de 1060 px. En dessous — fenêtre de poste
   réduite ou partagée, jamais un téléphone : ce n'est pas un contexte de ce
   produit — il ne disparaît pas, il se replie en bande au-dessus du contenu.
   Le masquer coûtait deux choses : le sommaire des sections, seul chemin dans
   un rapport de huit sections qu'on parcourt autrement à l'aveugle, et le
   `← Accueil` qui en est la dernière entrée. Sur le rapport servi, ce lien
   n'est doublé par aucun bouton du flux : le masquer laissait l'écran sans
   sortie autre que le « précédent » du navigateur.

   Bande et non colonne repliée : les entrées se lisent en ligne, chacune
   gardant son filet gauche — la grammaire ne change pas, seule la direction
   de lecture change. */
.rail{display:flex;flex-wrap:wrap;gap:2px 4px;margin-bottom:32px;padding-bottom:14px;
  border-bottom:1px solid var(--line)}
@media (min-width:1060px){
  .rail{display:block;position:sticky;top:28px;align-self:start;max-height:calc(100vh - 56px);
    overflow:auto;margin-bottom:0;padding-bottom:0;border-bottom:0}
  /* Le pied est sorti de `<main>` pour redevenir le repère `contentinfo` du
     document. Troisième enfant de la grille, il se poserait sous le rail : il
     est replacé dans la colonne du contenu, où sa mesure est celle qu'il avait. */
  .shell>footer{grid-column:2}
}
.rail-t{flex:0 0 100%;font-family:var(--f-mono);font-size:var(--l-md);letter-spacing:.16em;text-transform:uppercase;color:var(--mist);padding-bottom:10px;border-bottom:1px solid var(--line);margin-bottom:12px}
.rail a{
  display:grid;grid-template-columns:22px 1fr;gap:8px;align-items:baseline;
  text-decoration:none;color:var(--ink-2);padding:6px 10px;font-size:var(--t-dense);line-height:1.3;
  border-left:2px solid transparent;transition:color .15s,border-color .15s;
}
@media (min-width:1060px){.rail a{padding-right:0}}
.rail a:hover{color:var(--petrol);border-left-color:var(--petrol)}
.rail a .n{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist);font-variant-numeric:tabular-nums}

main{min-width:0;max-width:none}

/* ---------- Sections ---------- */
section{padding-top:8px;margin-bottom:60px;scroll-margin-top:24px}
h2{
  font-family:var(--f-display);font-weight:600;font-size:var(--t-headline);letter-spacing:-.014em;
  margin:0 0 6px;padding-bottom:10px;border-bottom:1px solid var(--line-strong);
  display:grid;grid-template-columns:auto 1fr;gap:14px;align-items:baseline;text-wrap:balance;
}
h2 .num{font-family:var(--f-mono);font-size:var(--t-dense);font-weight:500;color:var(--petrol);letter-spacing:0}
h3{
  font-family:var(--f-display);font-weight:600;font-size:var(--t-title);letter-spacing:-.005em;
  margin:34px 0 10px;color:var(--ink);
}
h3 code,h2 code{font-size:.95em}
p{max-width:72ch;margin:0 0 14px}
ul,ol{max-width:72ch;padding-left:1.15em;margin:0 0 16px}
li{margin-bottom:7px}
strong{font-weight:500;color:var(--ink)}
/* Relatif, mais jamais sous le plancher : `.855em` d'un parent à 12 px donne
   10,3 px, sous la borne que l'échelle vient de poser. Le `max()` garde la
   proportion là où le parent est grand et la coupe là où il est petit. */
code{font-family:var(--f-mono);font-size:max(11px,.855em);background:var(--surface-2);padding:.1em .34em;border-radius:2px;color:var(--ink);word-break:break-word}
a{color:var(--petrol)}
.lede{font-size:var(--t-body);color:var(--ink-2);max-width:68ch}

/* ---------- Findings ---------- */
.findings{list-style:none;padding:0;margin:22px 0 0;max-width:none;display:grid;gap:1px;background:var(--line);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.findings li{
  margin:0;background:var(--paper);padding:16px 18px 16px 0;
  display:grid;grid-template-columns:34px 1fr;gap:14px;align-items:start;
}
.findings .fn{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--petrol);font-weight:500;padding-left:12px;border-left:3px solid var(--petrol);padding-top:2px}
.findings li.warn .fn{color:var(--rouille);border-left-color:var(--rouille)}
.findings p{margin:0;max-width:68ch;font-size:var(--t-prose)}

/* ---------- Tables ---------- */
.tw{overflow-x:auto;margin:14px 0 22px;border-top:1px solid var(--line-strong);border-bottom:1px solid var(--line-strong)}
table{border-collapse:collapse;width:100%;font-size:var(--t-dense);font-family:var(--f-body)}
caption{
  caption-side:top;text-align:left;font-family:var(--f-mono);font-size:var(--l-md);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);padding:0 0 8px;
}
th{
  text-align:left;font-family:var(--f-display);font-weight:600;font-size:var(--l-lg);
  letter-spacing:.07em;text-transform:uppercase;color:var(--ink-2);
  padding:10px 14px 9px 0;border-bottom:1px solid var(--line-strong);white-space:nowrap;vertical-align:bottom;
}
td{padding:9px 14px 9px 0;border-bottom:1px solid var(--line);vertical-align:top;color:var(--ink-2)}
tbody tr:last-child td{border-bottom:0}
td:first-child,th:first-child{padding-left:0}
td strong{color:var(--ink)}
.num-col{font-family:var(--f-mono);font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink)}
td code{background:transparent;padding:0}
table code{font-size:var(--t-data)}

/* severity stripe on join rows */
.joins td:first-child{
  font-family:var(--f-mono);font-weight:500;color:var(--ink);
  border-left:3px solid var(--line-strong);padding-left:11px;white-space:nowrap;
}
.joins tr.ok td:first-child{border-left-color:var(--olive)}
.joins tr.frag td:first-child{border-left-color:var(--rouille)}
.joins tr.none td:first-child{border-left-color:var(--line-strong);color:var(--mist)}

.tag{
  display:inline-block;font-family:var(--f-mono);font-size:var(--l-md);font-weight:500;
  letter-spacing:.06em;text-transform:uppercase;padding:2px 7px;border-radius:2px;white-space:nowrap;
}
.tag.ok{background:var(--olive-soft);color:var(--olive)}
.tag.warn{background:var(--rouille-soft);color:var(--rouille)}
.tag.neutral{background:var(--surface-2);color:var(--mist)}

/* ---------- Callout ---------- */
.callout{
  border-left:3px solid var(--rouille);background:var(--rouille-soft);
  padding:16px 20px;margin:22px 0;max-width:74ch;
}
.callout p{margin:0;max-width:none;font-size:var(--t-prose);color:var(--ink)}
.callout .ct{
  font-family:var(--f-mono);font-size:var(--l-md);letter-spacing:.14em;text-transform:uppercase;
  color:var(--rouille);display:block;margin-bottom:6px;
}
.callout.info{border-left-color:var(--petrol);background:var(--petrol-soft)}
.callout.info .ct{color:var(--petrol)}

/* ---------- Schema ---------- */
figure{margin:24px 0 10px}
.schema{width:100%;height:auto;display:block;background:var(--surface);border:1px solid var(--line);padding:10px 0}
.s-box{fill:var(--surface);stroke:var(--line-strong);stroke-width:1.2}
.s-box-pk{fill:var(--surface);stroke:var(--petrol);stroke-width:2}
.s-ghost{fill:none;stroke:var(--line-strong);stroke-width:1.2;stroke-dasharray:5 4;opacity:.85}
.s-t{font-family:var(--f-mono);font-size:var(--t-data);font-weight:600;fill:var(--ink)}
.s-t-ghost{font-family:var(--f-mono);font-size:var(--t-data);font-weight:600;fill:var(--mist)}
.s-f{font-family:var(--f-mono);font-size:var(--l-md);fill:var(--ink-2)}
.s-k{font-family:var(--f-mono);font-size:var(--l-md);font-weight:600;fill:var(--petrol)}
.s-m{font-family:var(--f-mono);font-size:var(--l-md);fill:var(--mist)}
.s-e{stroke:var(--line-strong);stroke-width:1.4;fill:none}
.s-e-d{stroke:var(--line-strong);stroke-width:1.2;fill:none;stroke-dasharray:5 4}
.s-e-f{stroke:var(--rouille);stroke-width:1.6;fill:none}
.s-lbl{font-family:var(--f-mono);font-size:var(--l-md);font-weight:500;fill:var(--ink-2)}
.s-lbl-f{font-family:var(--f-mono);font-size:var(--l-md);font-weight:500;fill:var(--rouille)}
figcaption{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist);margin-top:10px;line-height:1.5;max-width:74ch}

/* ---------- Footer ---------- */
footer{border-top:2px solid var(--ink);margin-top:70px;padding-top:20px;font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist);display:flex;flex-wrap:wrap;gap:8px 28px;justify-content:space-between}

:focus-visible{outline:2px solid var(--petrol);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
/* Sous 640 px, c'est l'échelle qui se resserre, non deux sélecteurs choisis :
   redéfinir les jetons fait descendre d'un cran tout ce qui en dépend, au lieu
   de laisser le reste à sa taille de poste. Les deux règles d'origine —
   `body` et `table` — disaient exactement cela, une valeur à la fois. */
@media (max-width:640px){
  :root{--t-body:16px;--t-dense:13.5px}
  .wrap{padding:0 18px 64px}
}

/* ---------- Bascule de thème ---------- */
.theme-toggle{
  position:absolute;top:26px;right:0;
  display:inline-flex;gap:0;border:1px solid var(--line-control);border-radius:2px;overflow:hidden;
  background:var(--surface);
}
.theme-toggle button{
  appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:var(--f-mono);font-size:var(--l-md);letter-spacing:.1em;text-transform:uppercase;
  color:var(--mist);padding:6px 11px;line-height:1.4;
  border-right:1px solid var(--line);transition:background .15s,color .15s;
}
.theme-toggle button:last-child{border-right:0}
.theme-toggle button:hover{color:var(--ink)}
.theme-toggle button[aria-pressed="true"]{background:var(--petrol);color:var(--paper)}
.masthead{position:relative}
@media (max-width:720px){
  .theme-toggle{position:static;margin-bottom:18px}
}

/* ---------- Section courante dans le rail ---------- */
.rail a.active{color:var(--petrol);border-left-color:var(--petrol);font-weight:500}

/* ---------- Filtres ---------- */
.filtres{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px;margin:14px 0 22px}
.filtres label{
  position:relative;
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--f-mono);font-size:var(--l-md);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);
}
.filtres select{
  appearance:none;border:1px solid var(--line-control);border-radius:2px;
  background:var(--surface);color:var(--ink);font-family:var(--f-mono);
  font-size:var(--l-md);padding:6px 26px 6px 10px;line-height:1.3;cursor:pointer;
}
/* appearance:none retire le chevron natif du select, sans quoi le contrôle se
   lit comme une étiquette statique. Il est rendu par un pseudo-élément dans les
   jetons de la feuille — ni image distante, ni jeu d'icônes tiers — et --mist
   étant redéfini par thème, il suit les trois états sans surcharge. */
.filtres label::after{
  content:"";position:absolute;right:11px;top:calc(50% - 4px);
  width:5px;height:5px;pointer-events:none;
  border-right:1.5px solid var(--mist);border-bottom:1.5px solid var(--mist);
  transform:rotate(45deg);
}
.filtres label:hover::after{border-color:var(--ink)}
.filtres .compte{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist);font-variant-numeric:tabular-nums}

/* ---------- Ligne source brute ---------- */
code.brut{
  display:block;background:var(--surface-2);font-family:var(--f-mono);font-size:var(--t-data);
  white-space:pre-wrap;word-break:break-all;padding:10px 14px;margin:14px 0;
  border-left:3px solid var(--line-strong);
}
code.brut.avant{border-left-color:var(--rouille)}
code.brut.apres{border-left-color:var(--olive)}

/* ---------- Restitution champ par champ ---------- */
/* bordure gauche réservée (transparente au repos) pour éviter un décalage de
   mise en page au moment où une ligne bascule à l'état "changé" */
.champs td:first-child{
  font-family:var(--f-mono);font-weight:500;color:var(--ink);
  border-left:3px solid transparent;padding-left:11px;white-space:nowrap;
}
.champs tr.chg td:first-child{border-left-color:var(--rouille)}

/* ---------- État vide ---------- */
.vide{font-family:var(--f-mono);font-size:var(--t-data);color:var(--mist);padding:16px 0;margin:0}


/* ---------- Dépôt et actions ---------- */
/* Primitives des écrans de l'application — dépôt d'une Extraction, suivi d'un
   Import. Elles vivent dans cette feuille et non à côté : l'identité visuelle
   s'écrit en un seul endroit, et le rapport comme l'application y puisent les
   mêmes jetons. Le rapport ne les emploie pas ; c'est sans conséquence, une
   feuille décrit un langage, pas une page. */
.depot{display:flex;flex-wrap:wrap;align-items:center;gap:12px 22px;margin:18px 0 10px}
.depot input[type="file"]{
  font-family:var(--f-mono);font-size:var(--l-lg);color:var(--ink-2);max-width:100%;
  border:1px solid var(--line-control);border-radius:2px;background:var(--surface);padding:8px 10px;
}
.bouton{
  display:inline-block;font-family:var(--f-mono);font-size:var(--l-lg);font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;text-decoration:none;cursor:pointer;
  color:var(--surface);background:var(--petrol);border:1px solid var(--petrol);
  border-radius:2px;padding:9px 16px;line-height:1.2;
}
.bouton:hover{background:var(--ink);border-color:var(--ink)}
.bouton.discret{background:transparent;color:var(--petrol)}
.bouton.discret:hover{background:var(--petrol-soft);border-color:var(--petrol);color:var(--petrol)}
.actions{display:flex;flex-wrap:wrap;gap:10px 14px;margin:18px 0 22px}

/* ---------- Étapes d'un traitement ---------- */
/* Même grammaire que .findings : une grille d'une ligne par étape, marquée par
   un filet de gauche. Le filet dit l'état — franchie, courante, à venir — sans
   introduire ni icône ni couleur nouvelle. */
.etapes{list-style:none;padding:0;margin:18px 0 22px;max-width:none;display:grid;gap:1px;background:var(--line);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.etapes li{
  margin:0;background:var(--paper);padding:11px 18px 11px 0;
  display:grid;grid-template-columns:34px 1fr auto;gap:14px;align-items:baseline;
  font-size:var(--t-prose);color:var(--mist);
}
.etapes .n{font-family:var(--f-mono);font-size:var(--l-lg);font-weight:500;color:var(--mist);padding-left:12px;border-left:3px solid transparent}
.etapes li.faite{color:var(--ink-2)}
.etapes li.faite .n{color:var(--olive);border-left-color:var(--olive)}
.etapes li.courante{color:var(--ink)}
.etapes li.courante .n{color:var(--petrol);border-left-color:var(--petrol)}
.etapes li.arretee{color:var(--ink)}
.etapes li.arretee .n{color:var(--rouille);border-left-color:var(--rouille)}

/* ---------- Recherche d'un Article ---------- */
/* Champ texte repris des jetons de .filtres. Étiquette au-dessus et non à côté :
   une saisie de 13 caractères y repousserait le contrôle suivant hors du regard.
   Aucun ::placeholder : la consigne de format doit rester lisible pendant la
   frappe, elle vit donc dans .aide. */
.recherche{display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px 22px;margin:18px 0 10px}
.recherche label{
  position:relative;
  display:inline-flex;flex-direction:column;gap:7px;
  font-family:var(--f-mono);font-size:var(--l-md);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);
}
.recherche input[type="text"],.recherche select{
  appearance:none;border:1px solid var(--line-control);border-radius:2px;
  background:var(--surface);color:var(--ink);font-family:var(--f-mono);
  font-size:var(--t-data);padding:8px 11px;line-height:1.3;
  letter-spacing:normal;text-transform:none;min-width:20ch;
}
.recherche select{padding-right:27px;cursor:pointer}
.recherche label:has(select)::after{
  content:"";position:absolute;right:11px;bottom:15px;
  width:5px;height:5px;pointer-events:none;
  border-right:1.5px solid var(--mist);border-bottom:1.5px solid var(--mist);
  transform:rotate(45deg);
}
.recherche label:hover:has(select)::after{border-color:var(--ink)}
.recherche input[type="text"]:focus-visible,.recherche select:focus-visible{
  outline:2px solid var(--petrol);outline-offset:1px;border-color:var(--petrol);
}
.aide{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--ink-2);line-height:1.6;margin:0;max-width:80ch}
.recherche .aide{flex-basis:100%}

/* ---------- Saisie d'identité ---------- */
/* Connexion, inscription d'un Compte. Même langage que .recherche — étiquette
   au-dessus, champ mono, liseré pétrole au focus — mais empilé et non en ligne :
   un formulaire d'identité se lit de haut en bas, et un mot de passe n'a aucun
   voisin avec lequel il se composerait. La mesure est bornée à 46ch : un champ
   qui traverserait la colonne de lecture ferait perdre le rapport entre
   l'étiquette et ce qu'on y saisit. */
.formulaire{display:flex;flex-direction:column;align-items:flex-start;gap:16px;
  margin:18px 0 10px;max-width:46ch}
.formulaire label{
  display:flex;flex-direction:column;gap:7px;width:100%;
  font-family:var(--f-mono);font-size:var(--l-md);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);
}
.formulaire input[type="text"],.formulaire input[type="password"],.formulaire select{
  appearance:none;border:1px solid var(--line-control);border-radius:2px;
  background:var(--surface);color:var(--ink);font-family:var(--f-mono);
  font-size:var(--t-data);padding:8px 11px;line-height:1.3;
  letter-spacing:normal;text-transform:none;width:100%;
}
.formulaire select{cursor:pointer}
.formulaire input:focus-visible,.formulaire select:focus-visible{
  outline:2px solid var(--petrol);outline-offset:1px;border-color:var(--petrol);
}

/* ---------- Clés d'API ---------- */
/* Trois primitives, et chacune répond à une contrainte du ticket 08.

   `.callout.cle` porte la Clé qui vient d'être engendrée. Une variante et non
   le `.callout` nu : celui-ci est rouille, c'est-à-dire la couleur des refus,
   et une génération réussie ne doit pas se lire comme un échec. L'olive est
   déjà celle de `.tag.ok`.

   `.cle-engendree` est le seul point de toute l'application où un secret
   s'affiche. `user-select:all` le fait sélectionner d'un clic — il est
   affiché une seule fois, et une sélection manuelle qui en tronquerait un
   caractère donnerait une Clé qui ne fonctionne pas, sans que rien ne dise
   pourquoi. `overflow-wrap` plutôt qu'un défilement : une Clé coupée hors de
   l'écran serait recopiée incomplète.

   `.case` renverse la mise en colonne de `.formulaire label` : une case à
   cocher se lit à côté de son étiquette et non sous elle, et l'étiquette d'une
   case est une valeur — un nom de profil — qu'on ne met ni en capitales ni en
   interlettrage. */
.callout.cle{border-left-color:var(--olive);background:var(--olive-soft)}
.callout.cle .ct{color:var(--olive)}
.callout p+p{margin-top:10px}
/* L'identifiant public d'une Clé ne se coupe pas : `code` porte
   `word-break:break-word`, et une colonne étroite le rendait un caractère par
   ligne. Un identifiant recopié d'un écran vers une commande doit se lire d'un
   trait. */
.cle-id{white-space:nowrap;word-break:normal}
/* L'état d'une Clé et le bouton qui le change partagent une cellule : deux
   colonnes faisaient déborder la table. Elles se composent verticalement, le
   marqueur d'abord — on lit l'état avant d'agir dessus. */
.etat-cle{display:flex;flex-direction:column;align-items:flex-start;gap:7px}
.cle-engendree{
  display:block;font-family:var(--f-mono);font-size:var(--t-data);
  background:var(--surface);border:1px solid var(--line-control);border-radius:2px;
  padding:10px 12px;overflow-wrap:anywhere;user-select:all;color:var(--ink);
}
.formulaire input[type="date"]{
  appearance:none;border:1px solid var(--line-control);border-radius:2px;
  background:var(--surface);color:var(--ink);font-family:var(--f-mono);
  font-size:var(--t-data);padding:8px 11px;line-height:1.3;
  letter-spacing:normal;text-transform:none;width:100%;
}
.formulaire fieldset{
  border:1px solid var(--line);border-radius:2px;padding:12px 14px;margin:0;width:100%;
  display:flex;flex-direction:column;gap:8px;
}
.formulaire legend{
  font-family:var(--f-mono);font-size:var(--l-md);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);padding:0 6px;
}
.formulaire label.case{
  flex-direction:row;align-items:center;gap:9px;width:auto;
  font-family:var(--f-mono);font-size:var(--t-data);font-weight:400;
  letter-spacing:normal;text-transform:none;color:var(--ink);
}
.formulaire label.case input[type="checkbox"]{width:auto;accent-color:var(--petrol)}

/* ---------- Bandeau d'identité ---------- */
/* Qui est connecté, et par où se déconnecter. Écrit une seule fois, dans le
   gabarit commun : deux copies auraient divergé au premier changement, comme
   l'aurait fait la bascule de thème. L'écran-outil du Consolidé courant
   l'incorpore dans sa barre de titre, faute de masthead — d'où la variante,
   qui n'en change que la mesure et jamais le contenu. */
.session{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin:0 0 20px;
  font-family:var(--f-mono);font-size:var(--l-md);font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mist);
}
.session strong{color:var(--ink);font-weight:500}
.session .bouton{padding:5px 11px;font-size:var(--l-md);letter-spacing:.1em}
.barre-titre .session{margin:0}

/* ------------------------------------------------------------------ */
/* Exploration du Consolidé courant : groupes de colonnes, table large  */
/* ------------------------------------------------------------------ */

/* Sélecteur de groupes de colonnes : le groupe est l'unité cochable, jamais la
   colonne — le compteur dit combien de colonnes chaque case apporte. */
.colonnes{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;margin:14px 0 22px;
  padding:12px 14px;border:1px solid var(--line);border-radius:2px;background:var(--surface-2)}
.colonnes .c-case{display:flex;align-items:center;gap:6px;font-size:var(--t-data);cursor:pointer;white-space:nowrap}

/* Table d'exploration. Le défilement horizontal reste dans `.tw` ; `.tw-fige`
   n'ajoute qu'un contexte pour les deux colonnes collantes. Une largeur fixe
   sur les colonnes figées est indispensable : la seconde se cale sur la
   première, et sans largeur connue elle se superposerait à elle. */
.tw-fige{position:relative}
table.explorer{border-collapse:separate;border-spacing:0}
table.explorer th,table.explorer td{white-space:nowrap}
table.explorer thead th{position:sticky;top:0;z-index:2;background:var(--surface);
  vertical-align:bottom;padding-bottom:5px}
table.explorer th.fige,table.explorer td.fige{position:sticky;z-index:1;background:var(--surface)}
table.explorer thead th.fige{z-index:3}
table.explorer .fige-0{left:0;width:104px;min-width:104px;max-width:104px}
table.explorer .fige-1{left:104px;width:230px;min-width:230px;max-width:230px;
  overflow:hidden;text-overflow:ellipsis}
/* Le filet vertical marque la frontière du figé : sans lui, une colonne qui
   défile sous une colonne fixe se lit comme une colonne tronquée. */
table.explorer .fige-1::after{content:"";position:absolute;top:0;right:0;bottom:0;
  width:1px;background:var(--line-strong)}
table.explorer tbody th.fige a{font-family:var(--f-mono);font-variant-numeric:tabular-nums}

/* En-tête triable : l'intitulé est un lien, la base fiscale une seconde ligne
   qui ne l'est pas — elle qualifie la colonne, elle ne la trie pas. */
table.explorer .tri{display:block;text-decoration:none;border-bottom:0}
table.explorer .tri:hover{text-decoration:underline}
table.explorer .tri-actif{font-weight:700}
table.explorer .tri-actif::after{content:"";margin-left:4px;font-size:10px}
table.explorer th[aria-sort="ascending"] .tri-actif::after{content:"▲"}
table.explorer th[aria-sort="descending"] .tri-actif::after{content:"▼"}
table.explorer .base{display:block;font-size:var(--l-md);font-weight:400;letter-spacing:.03em;
  text-transform:none;color:var(--mist)}

/* Pagination. Le numéro courant n'est pas un lien : il ne mène nulle part, et
   le rendre cliquable ferait douter de la page qu'on lit. */
.pages{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;margin:14px 0 22px;
  font-family:var(--f-mono);font-size:var(--l-lg)}
/* 24 × 24 au moins : à 12 px sur l'interligne de 1,45 de l'écran-outil, la
   boîte tombe à ~23 px sur les deux axes, et deux numéros voisins deviennent
   une cible unique pour qui pointe mal (WCAG 2.2, SC 2.5.8). Le minimum porte
   sur la boîte, jamais sur la police : la bande de pagination garde sa
   chasse. Le numéro courant et les coupures le reçoivent aussi — ce ne sont
   pas des cibles, mais une rangée dont un élément sur deux serait plus court
   se lirait comme un défaut d'alignement. */
.pages a,.pages span{display:inline-flex;align-items:center;justify-content:center;
  min-width:24px;min-height:24px;padding:2px 7px;border:1px solid transparent;border-radius:2px}
.pages a{text-decoration:none;border-color:var(--line)}
.pages a:hover{border-color:var(--line-strong)}
.pages .courante{font-weight:700;background:var(--surface-2);border-color:var(--line-strong)}
.pages .inactif,.pages .coupure{color:var(--mist)}

@media (max-width:900px){
  /* Sous cette largeur, deux colonnes figées consomment la moitié de l'écran :
     le figé est abandonné plutôt que réduit à un moignon illisible. */
  table.explorer th.fige,table.explorer td.fige{position:static}
  table.explorer .fige-1::after{display:none}
}

/* Accès aux Consolidés courants depuis l'accueil : une entrée par Groupe de
   magasins, alignées comme des actions et non comme une liste à puces. */
.acces{display:flex;flex-wrap:wrap;gap:10px 14px;margin:14px 0 18px;padding:0;list-style:none}

/* ------------------------------------------------------------------ */
/* Écran-outil : le Consolidé courant occupe la fenêtre, pas la colonne */
/* ------------------------------------------------------------------ */

/* `.wrap` mesure un écran-document — accueil, rapport, fiche d'un Article —
   et lui donne sa colonne de lecture de 1240 px. Un écran-outil n'a pas cette
   mesure : le tableau y occupe la page dès le premier pixel, la barre de titre
   et la barre d'outils sont figées, et seul le corps de table défile. Les deux
   régimes coexistent dans cette feuille parce qu'ils partagent la palette, la
   typographie et les primitives de table ; ce qui change est la mise en page,
   pas le langage. */
body:has(.ecran-outil){overflow:hidden}
.ecran-outil{position:relative;height:100dvh;display:flex;flex-direction:column;
  font-family:var(--f-display);font-size:var(--t-data);line-height:1.45}

/* ---------- Barre de titre, ~48 px ---------- */
/* Elle porte ce qui situe l'écran — Groupe de magasins, Extraction, nombres —
   et rien de ce qui le pilote. Le `h1` et le standfirst se replient sous le
   bouton d'information : ils décrivent l'écran, ils ne s'y consultent pas à
   chaque lecture, et 200 px de prose en tête d'une grille de données poussent
   les lignes sous la ligne de flottaison. */
/* Elle se replie, elle ne se tronque pas. Ses dix éléments demandent 1122 px
   au minimum, quand le régime d'écran-outil s'ouvre à 1060 : entre les deux,
   `overflow:hidden` sur le corps rognait silencieusement la fin de bande — la
   bascule de thème devenait inatteignable, sans même une barre de défilement
   pour le dire. En dessous de 1060, où la page défile à nouveau, la même bande
   poussait le document 92 px vers la droite.

   Hauteur libre et non plus 48 px figés : une bande qui se replie sur deux
   lignes et garde sa hauteur d'une seule rognerait ce qu'elle vient de faire
   passer à la ligne. `.corps` absorbe la différence — c'est lui qui porte le
   `flex:1` de la colonne. */
.barre-titre{position:relative;flex:0 0 auto;min-height:48px;display:flex;flex-wrap:wrap;
  align-items:center;gap:4px 14px;padding:4px 14px;
  background:var(--surface);border-bottom:2px solid var(--ink)}
/* Le titre de la barre **est** le `h1` de l'écran : la règle globale `h1` porte
   l'échelle d'affichage d'un masthead, sans objet sur une bande de 48 px. */
.bt-t{font-family:var(--f-display);font-weight:700;font-size:var(--t-dense);line-height:1;
  letter-spacing:-.01em;white-space:nowrap;margin:0;max-width:none}
.bt-m{font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);letter-spacing:.13em;
  text-transform:uppercase;color:var(--petrol);white-space:nowrap}
.bt-sep{width:1px;height:18px;background:var(--line-strong)}
/* Le retour à l'accueil dans la barre de titre. L'écran-outil n'a pas de rail :
   ce lien y tient la place que `← Accueil` occupe ailleurs en dernière entrée du
   sommaire, et en reprend le libellé pour que les deux s'apprennent une fois.
   Cible de pointage à 24 px, comme les autres contrôles de la barre. */
.bt-r{display:inline-flex;align-items:center;gap:6px;min-height:24px;padding:0 6px;
  margin-left:-6px;border-radius:2px;text-decoration:none;color:var(--ink-2);
  font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);letter-spacing:.13em;
  text-transform:uppercase;white-space:nowrap}
.bt-r:hover{background:var(--surface-2);color:var(--petrol)}
.bt-r .n{font-size:var(--l-lg);letter-spacing:0;color:var(--mist)}
.bt-r:hover .n{color:var(--petrol)}
.bt-c{font-family:var(--f-mono);font-weight:500;font-size:var(--l-lg);color:var(--ink-2);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.bt-c strong{color:var(--ink);font-weight:600}
.bt-fin{margin-left:auto;display:flex;align-items:center;gap:10px}
.barre-titre .theme-toggle{position:static}

/* Le bouton d'information est un `<details>` et non un bouton scripté : le
   repli est natif, atteignable au clavier, et l'écran ne doit rien au script. */
.bt-info>summary{list-style:none;width:24px;height:24px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid var(--line-control);border-radius:50%;cursor:pointer;
  font-family:var(--f-mono);font-weight:600;font-size:var(--l-lg);color:var(--mist)}
.bt-info>summary::-webkit-details-marker{display:none}
.bt-info[open]>summary{background:var(--ink);color:var(--paper);border-color:var(--ink)}
/* La note se déplie sous la barre de titre plutôt qu'en menu : elle porte une
   phrase de prose, que 270 px de menu couperaient en dix lignes. Elle recouvre
   au lieu de pousser — un repli qui déplacerait la grille ferait perdre la ligne
   qu'on lisait —, et sa largeur est bornée à une mesure de lecture : la fin de
   la barre d'outils, où vivent Colonnes et Exporter, reste atteignable pendant
   qu'on la lit. */
.bt-note{position:absolute;left:14px;top:100%;z-index:30;
  width:min(78ch,calc(100% - 28px));
  background:var(--surface-2);border:1px solid var(--ink);border-left-width:3px;
  box-shadow:var(--flottement);
  padding:12px 16px;font-family:var(--f-body);font-size:var(--t-dense);line-height:1.55;color:var(--ink-2)}
.bt-note .standfirst{max-width:78ch;margin:0;font-size:var(--t-body)}

/* ---------- Contrôles de la barre d'outils ---------- */
/* Une seule primitive de 26 px pour un champ, un `select` et le sommaire d'un
   menu : trois hauteurs différentes sur une bande de 44 px se verraient. */
.ctl,.menu>summary{height:26px;display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--line-control);background:var(--surface);border-radius:2px;
  padding:0 8px;font-family:var(--f-display);font-size:var(--l-lg);color:var(--ink);
  cursor:pointer;white-space:nowrap;text-decoration:none}
select.ctl{appearance:none;padding-right:20px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-size:5px 5px,5px 5px;background-position:right 9px center,right 5px center;background-repeat:no-repeat}
input.ctl{cursor:text}
input[type="search"].ctl{width:236px}
input[type="number"].ctl{width:64px;font-family:var(--f-mono)}
.ctl:hover,.menu>summary:hover{border-color:var(--ink-2)}
.ctl.prim{background:var(--petrol);border-color:var(--petrol);color:var(--surface);font-weight:500}
.lab{font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);letter-spacing:.12em;
  text-transform:uppercase;color:var(--mist)}
.grp{display:flex;flex-direction:column;gap:3px}
.grp-h{display:flex;align-items:center;gap:6px}
.cpt{font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);color:var(--mist);
  font-variant-numeric:tabular-nums}

/* Menus déroulants : `<details>` natifs. Aucun script n'en ouvre ni n'en ferme
   un ; `exploration.js` ne fait que refermer celui qu'on a quitté du regard. */
.menu{position:relative}
.menu>summary{list-style:none}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary::after{content:"▾";font-size:9px;color:var(--mist)}
.menu[open]>summary{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.menu[open]>summary::after{color:var(--paper)}
/* La borne de fenêtre l'emporte sur la largeur voulue : sous 604 px de
   fenêtre, un dépliant de 560 px déborderait et ferait défiler la page
   entière horizontalement — la barre d'outils étant figée, la moitié droite
   du panneau deviendrait inatteignable. Les 44 px réservés couvrent les
   14 px de garde de la barre de chaque côté et la barre de défilement
   verticale, que `100vw` compte à tort dans la largeur. */
.menu-c{position:absolute;top:calc(100% + 4px);left:0;z-index:40;
  min-width:min(270px,calc(100vw - 44px));max-width:calc(100vw - 44px);
  background:var(--surface);border:1px solid var(--ink);box-shadow:var(--flottement);
  padding:8px;border-radius:2px}
/* Les deux menus de fin de bande portent des libellés longs — un groupe de
   colonnes nommé, la réserve d'un export — que 270 px couperaient en dix
   lignes. */
.menu-c.droite{left:auto;right:0;min-width:min(348px,calc(100vw - 44px))}
.menu-t{font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);letter-spacing:.12em;
  text-transform:uppercase;color:var(--mist);padding:2px 6px 6px;
  border-bottom:1px solid var(--line);margin-bottom:5px}
.menu-c label{display:flex;align-items:center;gap:7px;padding:4px 6px;font-size:var(--t-data);
  cursor:pointer;border-radius:2px}
.menu-c label:hover{background:var(--surface-2)}
.menu-c label .cpt{margin-left:auto}
.menu-a{display:flex;flex-direction:column;gap:1px}
.menu-a a{display:flex;align-items:baseline;gap:10px;padding:6px;color:var(--ink);
  text-decoration:none;border-radius:2px;font-size:var(--t-data)}
.menu-a a:hover{background:var(--surface-2)}
.menu-a .cpt{margin-left:auto}
/* La réserve d'une entrée d'export vit sous elle et nulle part ailleurs : le
   point décimal du CSV se lit au moment où l'on choisit le CSV. */
.menu-l{display:block;font-family:var(--f-body);font-size:var(--l-lg);line-height:1.4;
  color:var(--mist);padding:2px 6px 7px;max-width:38ch}
.menu-a .inactif{display:flex;align-items:baseline;gap:10px;padding:6px;color:var(--mist);font-size:var(--t-data)}
.menu-a .inactif .tag{margin-left:auto}
.menu-fin{border-top:1px solid var(--line);margin-top:6px;padding-top:6px;display:flex;gap:6px;
  flex-wrap:wrap;padding-left:6px}
.menu-champs{display:flex;flex-direction:column;gap:9px;padding:2px 6px 4px}
.menu-champs .f-bornes{border:0;padding:0;margin:0}
.menu-champs .f-bornes legend{padding:0}
/* Une facette porte plusieurs valeurs (ADR-0009) : ses cases sont listées, et la
   liste est **bornée en hauteur**. Le Rayon en compte 37 à 52 sous un Secteur, et
   115 sans Secteur retenu ; dépliée dans le flux, une seule facette ferait un
   menu plus haut que la fenêtre — que la barre d'outils figée ne laisse pas
   défiler. Deux colonnes pour la même raison : six listes bornées empilées
   rendraient le dépliant aussi haut que ce qu'il est censé abréger. */
/* `.filtres` nomme deux choses dans cette feuille : la barre de sélecteurs d'un
   écran-document, en `display:flex`, et ce dépliant. Le second héritait donc du
   premier sans que rien ne le demande. À 560 px le repli de la ligne rendait le
   résultat indiscernable d'un empilement, et la collision restait invisible ;
   elle se voyait au premier élargissement, l'intitulé, la grille des facettes
   et le bouton se rangeant côte à côte. La disposition est déclarée ici plutôt
   que subie. */
.menu-c.filtres{display:block;min-width:min(560px,calc(100vw - 44px))}
.menu-c.filtres .menu-champs{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}
/* Deux colonnes dans un panneau borné à la fenêtre donneraient deux listes de
   dix caractères de large : sous cette borne, la seconde colonne repasse
   dessous, et le panneau redevient plus haut — ce qu'il pouvait se permettre
   dès lors que la page défile à nouveau. */
@media (max-width:660px){.menu-c.filtres .menu-champs{grid-template-columns:1fr}}
.menu-champs .f-cases{border:0;padding:0;margin:0;min-width:0}
.menu-champs .f-cases legend{padding:0}
.menu-champs .cases{max-height:132px;overflow-y:auto;border:1px solid var(--line);
  border-radius:2px;padding:2px}
.menu-champs .cases .c-case{white-space:nowrap}
/* La condition d'une facette subordonnée occupe la place de ses cases, dans
   le même cadre : le dépliant ne se réorganise donc pas au moment où la
   liste se peuple. Même teinte que les gloses de menu. */
.menu-champs .cases .f-cond{margin:0;padding:4px 6px;font-size:var(--t-data);color:var(--mist)}
/* `.colonnes` est une carte encadrée quand elle occupe une section ; dans un
   menu, le cadre du menu est déjà là et le second se verrait. */
.menu-c .colonnes{display:block;margin:0;padding:0;border:0;background:transparent}
.menu-c .c-case{padding:4px 6px;border-radius:2px;white-space:normal}
.menu-c .c-case:hover{background:var(--surface-2)}

/* ---------- Bande des critères actifs, ~44 px ---------- */
/* Un écran non filtré n'y montre presque rien : le champ de recherche, son
   mode, `+ Filtre`. Chaque critère posé y ajoute son jeton, et un critère posé
   puis oublié se lit donc dans son propre jeton. Le dépliant `+ Filtre` reste
   le seul endroit où se découvre un critère **jamais** posé : il liste les
   sept contrôles en permanence, actifs ou non. */
.barre-outils{flex:0 0 auto;display:flex;flex-wrap:wrap;align-items:center;gap:7px;
  min-height:44px;padding:7px 14px;background:var(--paper);
  border-bottom:1px solid var(--line-strong)}
.criteres{display:flex;flex-wrap:wrap;align-items:center;gap:7px;flex:1 1 auto;min-width:0;margin:0}
.barre-fin{margin-left:auto;display:flex;align-items:center;gap:7px}
.jeton{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 2px 0 10px;
  border:1px solid var(--petrol);background:var(--petrol-soft);color:var(--petrol);
  border-radius:14px;font-size:var(--l-lg);white-space:nowrap}
.jeton strong{color:var(--petrol);font-weight:600}
/* Le `×` est un lien vers l'adresse courante privée de ce seul critère : sans
   script, il retire bien ce critère et ramène à la page 1. */
/* 24 × 24 au moins : sous cette taille, deux `×` de jetons voisins deviennent
   une cible unique pour qui pointe mal (WCAG 2.2, SC 2.5.8). Le jeton grandit
   d'autant, pas le `×` seul — une cible qui déborde de son jeton mordrait sur
   le suivant. */
.j-x{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;
  border-radius:50%;color:var(--petrol);text-decoration:none;font-family:var(--f-mono);font-size:var(--t-data)}
.j-x:hover{background:var(--petrol);color:var(--surface)}

/* ---------- Corps : la grille, et le Volet à sa droite ---------- */
.corps{flex:1;min-height:0;display:flex}
.zone{flex:1;min-width:0;display:flex;flex-direction:column;background:var(--surface)}
.grille{flex:1;min-height:0;overflow:auto}
.grille .tw{overflow:visible;margin:0;border:0}
/* La légende reste le nom accessible de la table, et cesse d'occuper une ligne :
   ce qu'elle dit — le Groupe de magasins, l'Extraction, la réserve d'ADR-0001 —
   est déjà lisible dans la barre de titre et sous chaque en-tête de prix, et
   l'écran-outil doit rendre la table dès le premier pixel. */
.grille caption{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;padding:0}

/* ---------- Pied de grille ---------- */
.pied{flex:0 0 38px;display:flex;align-items:center;gap:14px;padding:0 14px;
  border-top:1px solid var(--line-strong);background:var(--paper)}
.pied .pages{margin:0}
.rangs{font-family:var(--f-mono);font-size:var(--l-lg);color:var(--mist);font-variant-numeric:tabular-nums}
.sceau{margin-left:auto;font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);
  letter-spacing:.1em;text-transform:uppercase;color:var(--mist);white-space:nowrap}

/* ---------- Densité de la table d'exploration ---------- */
/* 26 px par ligne et le corps en Archivo. Le serif de lecture est ce qui, à lui
   seul, fait lire une grille de données comme un paragraphe ; les colonnes
   numériques gardent la chasse fixe, sans quoi les montants cessent de
   s'aligner. Archivo n'est chargé qu'en 500, 600 et 700 (les trois graisses du
   rapport de référence, que cette feuille ne peut pas élargir) : le corps de
   table est donc en 500 et non en 400. */
.grille table.explorer{width:max-content;min-width:100%;font-family:var(--f-display);
  font-weight:500;font-size:var(--t-data)}
.grille table.explorer th,.grille table.explorer td{height:26px;padding:0 12px;
  border-bottom:1px solid var(--line);vertical-align:middle}
.grille table.explorer thead th{background:var(--surface-2);vertical-align:bottom;height:auto;
  padding:7px 12px 5px;border-bottom:1px solid var(--line-strong);font-size:var(--l-md);line-height:1.15}
.grille table.explorer th.fige,.grille table.explorer td.fige{background:var(--surface)}
.grille table.explorer thead th.fige{background:var(--surface-2)}
.grille table.explorer tbody tr:hover>*{background:var(--surface-2)}
/* La ligne dont le Volet est ouvert reste visible et surlignée : le Volet
   comprime la table, il ne la recouvre pas, et le va-et-vient ligne → fiche →
   ligne est le geste réel de l'analyste. */
.grille table.explorer tbody tr.ouvert>*{background:var(--petrol-soft)}
.grille table.explorer tbody tr.ouvert th.fige-0{box-shadow:inset 3px 0 0 var(--petrol)}
.grille table.explorer .num-col{text-align:right}
.grille table.explorer thead th.num-col{text-align:right}
/* L'intitulé triable redevient en ligne : le marqueur de réserve le suit sur la
   même ligne, la base fiscale garde la sienne en dessous. */
.grille table.explorer .tri{display:inline}
.grille table.explorer thead th{white-space:nowrap}
.grille table.explorer .rsv-g{white-space:normal}

/* Marqueur de réserve dans un en-tête : la glose se déplie au survol **et au
   focus**. Un `title` seul ne s'ouvre pas au clavier, et la réserve serait
   alors inatteignable pour qui ne pointe pas. */
.rsv{position:relative;display:inline-block;margin-left:5px;font-family:var(--f-mono);
  font-weight:500;font-size:var(--l-md);letter-spacing:.08em;text-transform:uppercase;
  color:var(--rouille);background:var(--rouille-soft);padding:2px 4px;border-radius:2px;
  cursor:help;border:0;text-decoration:none}
/* La glose est repliée par recadrage et non par `visibility:hidden` : masquée
   ainsi, elle quitterait l'arbre d'accessibilité, et la réserve deviendrait
   invisible à qui lit l'écran autrement qu'à l'œil. Elle reste donc lue en
   permanence, et n'est dépliée à l'œil qu'au survol ou au focus. */
.rsv .rsv-g{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  padding:0;border:0}
/* `Échap` replie la glose sans déplacer le pointeur ni le focus (WCAG 2.2,
   SC 1.4.13) : elle recouvre des lignes de la grille, l'exception « n'obscurcit
   rien » ne joue donc pas. La classe rétablit le recadrage que le survol ou le
   focus viennent de lever, et `exploration.js` la retire dès qu'on quitte le
   marqueur — replier n'est pas fermer pour de bon. */
.rsv.repliee:hover .rsv-g,.rsv.repliee:focus-visible .rsv-g{
  top:auto;left:auto;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  padding:0;border:0;box-shadow:none}
.rsv:hover .rsv-g,.rsv:focus-visible .rsv-g{
  top:calc(100% + 5px);left:0;z-index:20;width:34ch;height:auto;overflow:visible;
  clip-path:none;background:var(--surface);border:1px solid var(--rouille);border-left-width:3px;
  padding:8px 10px;font-family:var(--f-body);font-weight:400;font-size:var(--l-lg);line-height:1.45;
  letter-spacing:0;text-transform:none;color:var(--ink);
  box-shadow:var(--flottement)}

/* ---------- Volet ---------- */
/* Compression, jamais recouvrement : la table se réduit à la largeur restante,
   les colonnes figées restent lisibles et la ligne ouverte reste visible. Aucun
   voile — le Volet n'est pas une modale. Sous 1060 px, il passe en recouvrement
   plein écran, où deux colonnes figées et un panneau ne tiennent plus ensemble. */
.volet-article{flex:0 0 auto;width:min(46vw,640px);background:var(--surface);
  border-left:2px solid var(--ink);overflow:hidden}
.volet-in{width:100%;height:100%;display:flex;flex-direction:column}
.v-tete{flex:0 0 auto;padding:12px 16px 0;border-bottom:1px solid var(--line-strong)}
.v-h{display:flex;align-items:flex-start;gap:10px}
.v-code{font-family:var(--f-mono);font-weight:500;font-size:var(--l-lg);letter-spacing:.1em;
  text-transform:uppercase;color:var(--petrol)}
.v-nom{font-family:var(--f-display);font-weight:600;font-size:var(--t-body);line-height:1.25;
  letter-spacing:-.012em;margin:5px 0 0;color:var(--ink);max-width:none}
.v-act{margin-left:auto;display:flex;gap:4px;flex:0 0 auto}
.v-b{width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line-control);background:var(--surface);border-radius:2px;cursor:pointer;
  font-family:var(--f-mono);font-weight:500;font-size:var(--l-lg);color:var(--ink-2);padding:0}
.v-b:hover{border-color:var(--ink);color:var(--ink)}
.v-b[disabled]{opacity:.35;cursor:default}
.v-sf{font-family:var(--f-body);font-size:var(--t-data);line-height:1.5;color:var(--mist);
  margin:8px 0 0;max-width:60ch}
/* Le sommaire du rail de la fiche devient des ancres internes : le Volet
   défile pour lui-même, et un rail de page ne le suivrait pas. */
.v-onglets{display:flex;flex-wrap:wrap;gap:0 2px;margin-top:10px}
.v-onglets a{padding:6px 9px 7px;font-family:var(--f-mono);font-weight:500;font-size:var(--l-md);
  letter-spacing:.09em;text-transform:uppercase;color:var(--mist);text-decoration:none;
  border-bottom:2px solid transparent;white-space:nowrap}
.v-onglets a:hover{color:var(--ink)}
.v-onglets a.actif{color:var(--ink);border-bottom-color:var(--petrol)}
.v-corps{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:0 16px 40px}
.v-corps:focus-visible{outline-offset:-2px}
/* Le titre reçoit le focus à chaque ouverture pour annoncer l'Article ; ce
   n'est pas une cible qu'on atteint au clavier, et un liseré permanent y
   signalerait une interaction qui n'existe pas. */
.v-nom:focus{outline:none}
.v-nom:focus-visible{outline:2px solid var(--petrol);outline-offset:2px}
.v-corps section{padding-top:18px;margin-bottom:0;scroll-margin-top:8px}
.v-corps h2{font-family:var(--f-display);font-weight:600;font-size:var(--l-lg);letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink);margin:0 0 10px;padding-bottom:8px;
  grid-template-columns:auto 1fr;gap:8px}
.v-corps h2 .num{font-size:var(--l-lg)}
.v-corps h3{font-family:var(--f-display);font-weight:600;font-size:var(--l-lg);letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-2);margin:16px 0 7px}
.v-corps p{font-size:var(--t-dense);line-height:1.55;margin:0 0 10px;max-width:62ch}
.v-corps .lede{font-size:var(--t-dense)}
.v-corps table{font-size:var(--t-data);font-family:var(--f-display);font-weight:500}
.v-corps th{font-size:var(--l-md);padding:5px 10px 5px 0}
.v-corps td{padding:5px 10px 5px 0}
.v-corps .tw{margin:0 0 10px}
.v-corps .callout{padding:11px 14px;margin:12px 0 0;max-width:none}
.v-corps .callout p{font-size:var(--t-data)}
.v-corps .actions{margin:14px 0 0}
.v-pied{flex:0 0 auto;border-top:1px solid var(--line-strong);padding:9px 16px;display:flex;
  gap:10px;align-items:center;background:var(--paper)}
.v-pied .aide{margin-left:auto;font-size:var(--l-md);white-space:nowrap}

/* ---------- Repli sous 1060 px ---------- */
/* Le régime hauteur de fenêtre suppose une fenêtre haute et large. Sous cette
   borne, l'écran redevient un flux de page — la barre d'outils défile avec le
   reste — et le Volet recouvre au lieu de comprimer. */
@media (max-width:1059px){
  body:has(.ecran-outil){overflow:auto}
  .ecran-outil{height:auto;display:block}
  .corps{display:block}
  .grille{overflow-x:auto}
  .volet-article{position:fixed;inset:0;width:100%;z-index:60;border-left:0}

  /* Un dépliant cesse de pendre sous son sommaire pour se caler sur la bande
     entière. Borner sa largeur ne suffisait pas : ancré à son `<summary>`, il
     part d'où celui-ci a échoué dans la bande repliée — le dépliant des
     critères, troisième contrôle d'une ligne, commençait à 117 px et sortait
     de la fenêtre malgré sa largeur bornée. Sous cette borne il s'ouvre donc
     sous la bande, d'un bord à l'autre, et le point d'ancrage cesse de
     dépendre de l'endroit où le contrôle est tombé. */
  .barre-outils{position:relative}
  .menu{position:static}
  .menu-c{left:14px;right:auto;width:min(270px,calc(100vw - 28px));min-width:0;max-width:none}
  .menu-c.droite{left:14px;right:auto;width:min(348px,calc(100vw - 28px))}
  .menu-c.filtres{left:14px;right:auto;width:min(560px,calc(100vw - 28px))}

  /* Le pied ne se tronque pas : le sceau passe à la ligne plutôt que de
     pousser le document vers la droite. */
  .pied{flex-wrap:wrap;height:auto;min-height:38px;padding:6px 14px}
  .sceau{margin-left:0}
}
