/* =============================================================================
   FAB NORD — feuille de style
   =============================================================================
   Charte reprise du logiciel LOGIFAB (édition AP-HP) : institutionnelle,
   claire, bleu et ambre. Sources de vérité relevées dans le dépôt :
     - palativm/core/constants.py     (APHP_CLAIR_COLORS, APHP_SOMBRE_COLORS,
                                        FONT_SIZES, SPACING, RADIUS)
     - palativm/ui/styles/aphp.qss    (proportions des boutons, tableaux,
                                        en-têtes, rail de navigation)
     - Information/generateur_presentation_fab/theme.py
                                       (cartes, bandeaux, surtitres ambre,
                                        statistiques, filets, citations)

   Règle absolue du contrat de conception : AUCUNE couleur en dur. Tout passe
   par les jetons ci-dessous, dans les deux thèmes. Une variation de teinte
   (survol, pression) se fabrique par composition de jetons existants —
   `background: var(--carte-bleue)`, `filter: brightness(...)` — jamais par
   un hex supplémentaire glissé au fil du fichier.

   Sommaire :
     1. Jetons        6. Blocs          11. Impression
     2. Base           7. Composants     12. Responsive
     3. Structure       8. Formulaires
     4. Rail             9. Tableaux
     5. Bandeau          10. États
   ============================================================================= */


/* =============================================================================
   1. JETONS
   ============================================================================= */

:root{
  /* Fonds */
  --fond:#F7F9FC; --carte:#FFFFFF; --carte-bleue:#E8F0F8; --bande:#EEF3F9;
  /* Encre */
  --ink:#16202C; --ink-soft:#55647A; --ink-faint:#8494A8;
  /* Bleus */
  --bleu:#0B4F87; --bleu-clair:#2E77B0; --bleu-fonce:#06375F; --bleu-nuit:#04223C;
  /* Ambre */
  --ambre:#C8891B; --ambre-clair:#E8B45A; --ambre-pale:#F5E6C8;
  /* Variantes TEXTE uniquement (jamais en fond ni en trait) — --ambre et
     --bleu sont calibrés pour servir de fond ou de trait ; utilisés comme
     couleur de texte sur --fond/--carte ils passent sous l'AA. Ces deux
     jetons dérivés sont réservés à cet usage précis (revue d'accessibilité) :
     --ambre-encre pour le surtitre et les dates de journal, --lien pour le
     texte des liens courants. */
  --ambre-encre:#8C6013; --lien:#0B4F87;
  /* Filets */
  --ligne:#D7E0EA; --ligne-forte:#B6C7D8;
  /* Sémantique */
  --ok:#1E7A46; --ok-doux:#DCEFE3; --sur-ok:#FFFFFF;
  --alerte:#C8891B; --alerte-doux:#F5E6C8; --sur-alerte:#16202C;
  --err:#B3261E; --err-doux:#F6DEDC; --sur-err:#FFFFFF;
  /* Rail de navigation */
  --rail-fond:#04223C; --rail-survol:#06375F; --rail-actif:#06375F;
  --rail-texte:#F7F9FC; --rail-groupe:#E8B45A; --rail-lisere:#C8891B;
  --sur-accent:#FFFFFF;
  /* Formes — échelle RADIUS du logiciel : 4 / 6 / 10 / 14 */
  --r-sm:4px; --r:6px; --r-lg:10px; --r-xl:14px; --r-pill:999px;
  --ombre:0 10px 30px -18px rgba(4,34,60,.45);
  --ombre-sm:0 4px 14px -10px rgba(4,34,60,.35);
  /* Rythme — échelle SPACING du logiciel : 4 / 8 / 12 / 16 / 24 / 32 */
  --e-xs:4px; --e-sm:8px; --e-md:12px; --e-lg:16px; --e-xl:24px; --e-xxl:32px;
  --largeur:1180px; --rail-largeur:264px;
  /* Polices — celles du logiciel en édition LOGIFAB (aucun téléchargement
     de police : pas de requête vers un tiers, RGPD) */
  --f-titre:"Segoe UI Semibold","Segoe UI",system-ui,-apple-system,Roboto,"Helvetica Neue",Arial,sans-serif;
  --f-corps:"Segoe UI",system-ui,-apple-system,Roboto,"Helvetica Neue",Arial,sans-serif;
  --f-citation:Georgia,"Times New Roman",serif;
  --f-mono:"Cascadia Mono",Consolas,"Courier New",monospace;

  color-scheme: light;
}
[data-theme="sombre"]{
  --fond:#04223C; --carte:#06375F; --carte-bleue:#0F3A5C; --bande:#052D4E;
  --ink:#F7F9FC; --ink-soft:#9FB4C8; --ink-faint:#4A6478;
  --bleu:#2E77B0; --bleu-clair:#4A8CC2; --bleu-fonce:#0B4F87;
  --ambre:#E8B45A; --ambre-clair:#E8B45A; --ambre-pale:#3A2C12;
  --ambre-encre:#E8B45A; --lien:#7AACD8;
  --ligne:#123655; --ligne-forte:#1C4A70;
  --ok:#5BB98A; --ok-doux:#16301F; --sur-ok:#04223C;
  --alerte:#E8B45A; --alerte-doux:#3A2C12; --sur-alerte:#04223C;
  --err:#E08079; --err-doux:#3A1512; --sur-err:#04223C;
  --rail-fond:#021A2E; --rail-survol:#04223C; --rail-actif:#06375F;
  --ombre:0 10px 30px -18px rgba(0,0,0,.6);

  color-scheme: dark;
}

/* Le thème par défaut du document (posé par entete.php) est « clair » : le
   serveur ne sait rien du choix mémorisé côté navigateur. `assets/js/theme.js`,
   chargé en tout premier dans <head>, relit `localStorage` et repose l'attribut
   AVANT le premier rendu — sans ce script, `prefers-color-scheme` sert de repli
   uniquement si rien n'a jamais été mémorisé. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]){
    --fond:#04223C; --carte:#06375F; --carte-bleue:#0F3A5C; --bande:#052D4E;
    --ink:#F7F9FC; --ink-soft:#9FB4C8; --ink-faint:#4A6478;
    --bleu:#2E77B0; --bleu-clair:#4A8CC2; --bleu-fonce:#0B4F87;
    --ambre:#E8B45A; --ambre-clair:#E8B45A; --ambre-pale:#3A2C12;
    --ambre-encre:#E8B45A; --lien:#7AACD8;
    --ligne:#123655; --ligne-forte:#1C4A70;
    --ok:#5BB98A; --ok-doux:#16301F; --sur-ok:#04223C;
    --alerte:#E8B45A; --alerte-doux:#3A2C12; --sur-alerte:#04223C;
    --err:#E08079; --err-doux:#3A1512; --sur-err:#04223C;
    --rail-fond:#021A2E; --rail-survol:#04223C; --rail-actif:#06375F;
    --ombre:0 10px 30px -18px rgba(0,0,0,.6);
    color-scheme: dark;
  }
  /* Sans `assets/js/theme.js` (JavaScript désactivé), aucun attribut
     data-theme n'est jamais posé : ce repli est alors la SEULE source du
     thème sombre, donc les redéfinitions .carte-titre / legend ci-dessus
     (qui ciblent [data-theme="sombre"]) doivent être répétées ici pour
     rester lisibles dans ce cas. */
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .carte-titre,
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) legend,
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .pastille-encours,
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .pastille-info{
    color:var(--ink);
  }
}


/* =============================================================================
   2. BASE
   ============================================================================= */

*, *::before, *::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; text-size-adjust:100%; }
html, body{ height:100%; }

body{
  margin:0;
  background:var(--fond);
  color:var(--ink);
  font-family:var(--f-corps);
  font-size:16px;
  line-height:1.6;
  overflow-x:hidden; /* le corps ne défile jamais horizontalement (contrat §2) */
}

img, svg, video{ max-width:100%; height:auto; display:block; }

a{ color:var(--lien); text-decoration:underline; text-decoration-color:var(--ligne-forte); text-underline-offset:.15em; }
a:hover{ color:var(--bleu-clair); text-decoration-color:currentColor; }
a:focus-visible{ text-decoration-color:currentColor; }

h1, h2, h3, h4, h5, h6{
  font-family:var(--f-titre);
  color:var(--ink);
  font-weight:600;
  line-height:1.22;
  margin:0 0 .5em;
}
h1{ font-size:2rem; }
h2{ font-size:1.5rem; }
h3{ font-size:1.2rem; }
h4{ font-size:1.05rem; }

p{ margin:0 0 1em; }
ul, ol{ margin:0 0 1em; padding-left:1.3em; }
small{ font-size:.85em; }
strong{ font-weight:600; }

code, kbd, samp, pre{ font-family:var(--f-mono); font-size:.92em; }
pre{
  background:var(--bande);
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-md);
  overflow-x:auto;
}

hr{ border:0; border-top:1px solid var(--ligne); margin:var(--e-xl) 0; }

::selection{ background:var(--carte-bleue); color:var(--ink); }

/* Barre de défilement : discrète, dans les jetons du thème (Firefox + WebKit).
   Pas de reprise du motif « rail perlé » de l'application — un ornement
   graphique de bureau alourdirait une page web sans rien y apporter. */
*{ scrollbar-color: var(--ligne-forte) var(--bande); scrollbar-width: thin; }
*::-webkit-scrollbar{ width:10px; height:10px; }
*::-webkit-scrollbar-track{ background:var(--bande); }
*::-webkit-scrollbar-thumb{ background:var(--ligne-forte); border-radius:var(--r-pill); }
*::-webkit-scrollbar-thumb:hover{ background:var(--bleu-clair); }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
}

.visually-hidden{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}


/* =============================================================================
   3. STRUCTURE
   ============================================================================= */

/* Lien d'évitement — premier élément du <body> (contrat §2). Invisible tant
   qu'il n'a pas le focus clavier, pour ne gêner ni la lecture ni l'écran. */
.saut{
  position:absolute; left:var(--e-md); top:-3rem;
  background:var(--bleu-fonce); color:var(--sur-accent);
  padding:.6em 1em; border-radius:var(--r);
  z-index:200; transition:top .15s ease;
}
.saut:focus{ top:var(--e-md); color:var(--sur-accent); }

/* Ossature générale : rail à gauche (hauteur pleine), colonne à droite
   (bandeau + contenu + pied), sur le modèle du logiciel — un rail persistant,
   une zone de travail qui défile. */
.app{
  display:flex;
  align-items:stretch;
  min-height:100vh;
}

.colonne{
  flex:1 1 0%;
  min-width:0; /* empêche un contenu large (tableau, journal) de pousser le
                  corps en défilement horizontal — cf. règle body ci-dessus */
  display:flex;
  flex-direction:column;
}

.zone, .zone-large{
  flex:1 1 auto;
  padding:var(--e-xxl) var(--e-xl);
}
.zone{
  width:100%;
  max-width:var(--largeur);
  margin-inline:auto;
}
.zone-large{
  width:100%;
}

.hero{
  display:flex;
  align-items:center;
  gap:var(--e-xxl);
  margin-bottom:var(--e-xxl);
}
.hero-texte{ flex:1 1 420px; }
.hero-visuel{
  flex:1 1 360px;
  display:flex;
  align-items:center;
  justify-content:center;
}
.hero-visuel img, .hero-visuel svg{
  border-radius:var(--r-lg);
  box-shadow:var(--ombre);
}

/* Pied de page — atteignable depuis toute page (obligation légale des liens
   mentions/confidentialité), donc posé dans la colonne, sous le contenu. */
.pied{
  border-top:1px solid var(--ligne);
  background:var(--bande);
  margin-top:var(--e-xxl);
}
.pied-inner{
  max-width:var(--largeur);
  margin-inline:auto;
  padding:var(--e-xl);
  display:flex;
  flex-wrap:wrap;
  gap:var(--e-lg) var(--e-xxl);
  justify-content:space-between;
}
.pied-inner nav{
  display:flex;
  flex-wrap:wrap;
  gap:var(--e-xs) var(--e-lg);
}
.pied-inner a{ color:var(--ink-soft); text-decoration:none; }
.pied-inner a:hover{ color:var(--bleu); text-decoration:underline; }
.pied-legal{
  max-width:var(--largeur);
  margin-inline:auto;
  padding:0 var(--e-xl) var(--e-xl);
  display:flex;
  flex-wrap:wrap;
  gap:var(--e-xs) var(--e-lg);
  align-items:center;
  font-size:.85rem;
  color:var(--ink-faint);
}
.pied-legal a{ color:var(--ink-faint); }
.pied-legal a:hover{ color:var(--bleu); }

/* Bloc d'identité du pied (marque + baseline) — propre à `pied.php`, comme
   `.rail-marque` l'est à `rail.php` : même logique, même endroit. */
.pied-marque{
  font-family:var(--f-titre);
  font-weight:700;
  color:var(--ink);
  margin:0;
}
.pied-baseline{
  display:block;
  margin-top:.2em;
  font-family:var(--f-corps);
  font-weight:400;
  font-size:.85rem;
  color:var(--ink-faint);
}


/* =============================================================================
   4. RAIL DE NAVIGATION
   ============================================================================= */
/* Signature visuelle de LOGIFAB : colonne bleu nuit, intitulés de groupe en
   ambre capitales, élément actif au fond --rail-actif et liseré ambre de 3 px
   à gauche. Sous 960 px, le rail se replie en tiroir — au moyen d'un élément
   <details> natif (rail.php), pour que l'ouverture/fermeture fonctionne SANS
   JavaScript. `fabnord.js` ne fait qu'améliorer l'expérience (fermeture au
   clic sur un lien, état replié par défaut). */

.rail-tiroir{
  background:var(--rail-fond);
}
.rail-tiroir > summary{
  list-style:none;
  cursor:pointer;
}
.rail-tiroir > summary::-webkit-details-marker{ display:none; }

.rail-bouton{
  display:flex;
  align-items:center;
  gap:.6em;
  width:100%;
  padding:var(--e-md) var(--e-lg);
  color:var(--rail-texte);
  font-family:var(--f-titre);
  font-weight:600;
  font-size:.95rem;
}
.rail-bouton::before{
  content:"";
  width:1.1em; height:.85em;
  flex:none;
  background:currentColor;
  clip-path:polygon(0 0,100% 0,100% 16%,0 16%,0 42%,100% 42%,100% 58%,0 58%,0 84%,100% 84%,100% 100%,0 100%);
  /* trois barres (icône « menu ») dessinées sans image externe */
}
.rail-bouton:hover, .rail-bouton:focus-visible{ background:var(--rail-survol); }

.rail{
  background:var(--rail-fond);
  color:var(--rail-texte);
  width:100%;
  padding:var(--e-lg) var(--e-md) var(--e-xl);
  display:flex;
  flex-direction:column;
  gap:2px;
}

.rail-marque{
  display:block;
  padding:var(--e-sm) var(--e-md) var(--e-lg);
  margin-bottom:var(--e-sm);
  border-bottom:1px solid color-mix(in srgb, var(--rail-texte) 14%, transparent);
}
.rail-marque img{
  display:block;
  width:100%;
  max-width:210px;
  height:auto;
}

.rail-groupe{
  margin:var(--e-md) var(--e-sm) 2px;
  font-family:var(--f-titre);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--rail-groupe);
}
.rail-groupe:first-of-type{ margin-top:0; }

.rail-item{
  display:flex;
  align-items:center;
  gap:.7em;
  padding:.6em var(--e-md);
  border-left:3px solid transparent;
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  color:var(--rail-texte);
  text-decoration:none;
  font-size:.92rem;
  line-height:1.3;
}
.rail-item:hover, .rail-item:focus-visible{
  background:var(--rail-survol);
}
.rail-item.is-actif{
  background:var(--rail-actif);
  border-left-color:var(--rail-lisere);
  font-weight:600;
}

/* Entrée réservée aux membres : reste VISIBLE et cliquable (la page cible
   redirige elle-même vers la connexion) — seule l'apparence dit « ce n'est
   pas encore pour vous », jamais une disparition qui ferait croire que la
   fonction n'existe pas. */
.rail-item.is-desactive{
  /* --ink-faint est calibré pour du texte sur fond CLAIR : ce fond de rail
     reste sombre dans les deux thèmes du site, donc on retient plutôt
     --rail-texte assourdi par l'opacité (contraste AA vérifié dans les
     deux thèmes — revue d'accessibilité). */
  color:var(--rail-texte);
  opacity:.6;
}
.rail-item.is-desactive:hover, .rail-item.is-desactive:focus-visible{
  background:var(--rail-survol);
  opacity:1;
}
.rail-item-etat{
  margin-left:auto;
  flex:none;
  font-size:.68rem;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--rail-groupe);
  opacity:.85;
}

.rail-bas{
  margin-top:auto;
  padding-top:var(--e-lg);
  border-top:1px solid color-mix(in srgb, var(--rail-texte) 14%, transparent);
  display:flex;
  flex-direction:column;
  gap:var(--e-sm);
}

.bascule-theme{
  display:inline-flex;
  align-items:center;
  gap:.6em;
  width:100%;
  padding:.55em var(--e-md);
  border:1px solid color-mix(in srgb, var(--rail-texte) 22%, transparent);
  border-radius:var(--r);
  background:transparent;
  color:var(--rail-texte);
  font-family:var(--f-corps);
  font-size:.85rem;
  cursor:pointer;
}
.bascule-theme:hover, .bascule-theme:focus-visible{
  background:var(--rail-survol);
  border-color:var(--rail-groupe);
}
/* Libellé « Thème clair »/« Thème sombre » (assets/js/fabnord.js le
   réécrit selon le thème actif) — sans cette règle il hérite du flex par
   accident plutôt que par choix. */
.bascule-theme-texte{
  flex:1 1 auto;
  text-align:left;
}
.bascule-theme .bascule-theme-piste{
  position:relative;
  flex:none;
  width:2.1em; height:1.15em;
  border-radius:var(--r-pill);
  background:color-mix(in srgb, var(--rail-texte) 22%, transparent);
}
.bascule-theme .bascule-theme-curseur{
  position:absolute; top:2px; left:2px;
  width:calc(1.15em - 4px); height:calc(1.15em - 4px);
  border-radius:50%;
  background:var(--rail-groupe);
  transition:left .15s ease;
}
[data-theme="sombre"] .bascule-theme .bascule-theme-curseur{
  left:calc(100% - 1.15em + 2px);
}

.rail-identite{
  display:flex;
  align-items:center;
  gap:.6em;
  padding:.4em var(--e-md);
  color:var(--rail-texte);
  font-size:.85rem;
}
.rail-identite-nom{ font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rail-identite-role{ display:block; color:var(--rail-groupe); font-size:.75rem; }


/* =============================================================================
   5. BANDEAU
   ============================================================================= */
/* En-tête de page : bleu foncé, texte blanc, liseré ambre de 2 px en bas —
   c'est le « header_accent » des tableaux du logiciel, reporté ici en signature
   de chaque page. */

.bandeau{
  background:var(--bleu-fonce);
  border-bottom:2px solid var(--ambre);
  color:var(--sur-accent);
}
.bandeau-inner{
  max-width:var(--largeur);
  margin-inline:auto;
  padding:var(--e-xl);
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:var(--e-lg);
  flex-wrap:wrap;
}
.bandeau-fil{
  margin:0 0 .35em;
  font-family:var(--f-titre);
  font-size:.75rem;
  font-weight:700;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ambre-clair);
}
.bandeau-titre{
  margin:0;
  color:var(--sur-accent);
  font-size:1.7rem;
}
.bandeau-actions{
  display:flex;
  gap:var(--e-sm);
  flex-wrap:wrap;
}
/* Les boutons du bandeau reposent sur fond bleu foncé : le fantôme et le
   secondaire ont besoin d'un contour clair pour rester lisibles ici. */
.bandeau-actions .btn-fantome{
  border-color:color-mix(in srgb, var(--sur-accent) 55%, transparent);
  color:var(--sur-accent);
}
.bandeau-actions .btn-fantome:hover{ background:color-mix(in srgb, var(--sur-accent) 12%, transparent); }
.bandeau-actions .btn:not(.btn-primaire):not(.btn-fantome):not(.btn-danger){
  background:color-mix(in srgb, var(--sur-accent) 8%, transparent);
  border-color:color-mix(in srgb, var(--sur-accent) 30%, transparent);
  color:var(--sur-accent);
}
.bandeau-actions .btn:not(.btn-primaire):not(.btn-fantome):not(.btn-danger):hover{
  background:color-mix(in srgb, var(--sur-accent) 16%, transparent);
}


/* =============================================================================
   6. BLOCS
   ============================================================================= */

.surtitre{
  display:block;
  font-family:var(--f-titre);
  font-size:.78rem;
  font-weight:700;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--ambre-encre); /* --ambre nu est sous l'AA comme texte en thème clair */
  margin-bottom:.5em;
}

/* Respiration entre deux sections. Les pages de la vitrine enveloppent leurs
   sections dans un <section> ; les pages de travail (maintenance, tickets)
   enchaînent les surtitres au fil du contenu, et une nouvelle section y
   collait au bloc précédent. Les deux cas obtiennent ici le même écart, sans
   se cumuler : un surtitre ouvrant un <section> reste son premier enfant. */
.zone > section + section,
.zone-large > section + section{ margin-top:var(--e-xxl); }
.zone > .surtitre:not(:first-child),
.zone-large > .surtitre:not(:first-child){ margin-top:var(--e-xxl); }

.titre-section{
  font-size:1.6rem;
  margin-bottom:.4em;
}

.chapo{
  font-size:1.15rem;
  line-height:1.65;
  color:var(--ink-soft);
  max-width:62ch;
  margin-bottom:var(--e-xl);
}

/* Filet ambre sous un titre de section centré. */
.filet{
  width:180px;
  height:2.4px;
  background:var(--ambre);
  border:0;
  border-radius:var(--r-pill);
  margin:.9rem auto var(--e-xl);
}

.citation{
  font-family:var(--f-citation);
  font-style:italic;
  font-size:1.25rem;
  line-height:1.55;
  color:var(--ink);
  border-left:3px solid var(--ambre);
  padding:.2em 0 .2em var(--e-lg);
  margin:var(--e-xl) 0;
}
.citation cite{
  display:block;
  margin-top:.6em;
  font-style:normal;
  font-family:var(--f-corps);
  font-size:.85rem;
  color:var(--ink-soft);
}
.citation cite::before{ content:"— "; }

.legende{
  font-size:.85rem;
  color:var(--ink-faint);
  font-style:italic;
  margin-top:.4em;
}

.separateur{
  border:0;
  border-top:1px solid var(--ligne);
  margin:var(--e-xl) 0;
}

/* --- Cartes ------------------------------------------------------------- */
.carte{
  background:var(--carte);
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-lg);
  box-shadow:var(--ombre-sm);
}
.carte-accent{
  background:var(--carte-bleue);
  border:1.5px solid var(--bleu);
}

/* Carte entièrement cliquable. Sans ces règles, le soulignement de `a` bavait
   sur le titre ET sur le corps de la carte : trois paragraphes soulignés d'un
   bout à l'autre, illisibles. Ici la carte se comporte comme une surface — le
   survol la relève et souligne son seul titre, comme le fait le logiciel. */
a.carte{
  display:block;
  color:inherit;
  text-decoration:none;
}
a.carte:hover, a.carte:focus-visible{
  border-color:var(--bleu);
  box-shadow:var(--ombre);
}
a.carte:hover .carte-titre, a.carte:focus-visible .carte-titre{
  text-decoration:underline;
  text-underline-offset:.15em;
}
.carte-surtitre{
  display:block;
  font-family:var(--f-titre);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ambre-encre); /* --ambre nu est sous l'AA comme texte en thème clair */
  margin-bottom:.5em;
}
.carte-titre{
  margin:0 0 .4em;
  font-size:1.1rem;
  color:var(--bleu-fonce);
}
/* En thème sombre, --carte et --carte-bleue sont eux-mêmes des nuances de
   bleu foncé : --bleu-fonce y devient illisible en texte (1,4:1). --ink
   redonne l'AA (>11:1) sans rien changer en thème clair. */
[data-theme="sombre"] .carte-titre{ color:var(--ink); }
.carte-texte{
  margin:0;
  color:var(--ink-soft);
  line-height:1.55;
}
.carte-pied{
  margin-top:var(--e-md);
  padding-top:var(--e-md);
  border-top:1px solid var(--ligne);
  display:flex;
  align-items:center;
  justify-content:space-between;
  /* Le pied passe à la ligne plutôt que d'écraser ses boutons : à trois
     colonnes, « Notes de version » se coupait en deux au milieu du mot. */
  flex-wrap:wrap;
  gap:var(--e-sm);
  font-size:.85rem;
  color:var(--ink-faint);
}
.carte-pied .btn{ white-space:nowrap; }

/* Nuance d'accent par jeton — consommée par le catalogue des logiciels
   (inc/catalogue.php, champ « couleur » : un nom de jeton SANS le préfixe
   `--`, ex. 'bleu-clair'). Une page compose `class="carte accent-bleu-clair"`
   pour teinter une carte à la couleur du logiciel : aucun `style="…"` à
   écrire, la règle absolue du contrat sur les couleurs en dur reste entière. */
.carte.accent-bleu, .carte.accent-bleu-clair, .carte.accent-bleu-fonce,
.carte.accent-ambre, .carte.accent-ambre-clair{
  border-width:1.5px;
}
.carte.accent-bleu{ border-color:var(--bleu); }
.carte.accent-bleu-clair{ border-color:var(--bleu-clair); }
.carte.accent-bleu-fonce{ border-color:var(--bleu-fonce); }
.carte.accent-ambre{ border-color:var(--ambre); }
.carte.accent-ambre-clair{ border-color:var(--ambre-clair); }

/* --- Grilles -------------------------------------------------------------
   `auto-fit` + `minmax` : les colonnes se reforment seules sous 960 px,
   sans media query dédiée à chaque grille (contrat §2, responsive). */
.grille{
  display:grid;
  gap:var(--e-lg);
  grid-template-columns:repeat(auto-fit, minmax(240px, 1fr));
}
.grille-2{ grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); }
.grille-3{ grid-template-columns:repeat(auto-fit, minmax(230px, 1fr)); }
.grille-4{ grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); }

/* --- Encarts --------------------------------------------------------------
   Distincts des cartes accentuées (bleu) : les encarts prennent l'ambre,
   pour que les deux mécaniques d'emphase restent visuellement séparées. */
.encart{
  background:var(--bande);
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-lg);
}
.encart-accent{
  background:var(--ambre-pale);
  border-color:var(--ambre);
  color:var(--ink);
}

/* --- Statistiques ---------------------------------------------------------
   Reprend `stat()` de theme.py : grand chiffre, légende dessous. */
.stat{
  background:var(--carte);
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-lg);
  text-align:center;
}
.stat-valeur{
  display:block;
  font-family:var(--f-titre);
  font-weight:700;
  font-size:2.2rem;
  color:var(--bleu);
  line-height:1.1;
}
.stat-legende{
  display:block;
  margin-top:.4em;
  color:var(--ink-soft);
  font-size:.9rem;
}
/* Statistique cliquable (les compteurs de la file d'attente mènent à la liste
   filtrée). Même correctif que pour a.carte : sans lui, le grand chiffre et sa
   légende arrivaient soulignés. */
a.stat{
  display:block;
  color:inherit;
  text-decoration:none;
}
a.stat:hover, a.stat:focus-visible{
  border-color:var(--bleu);
  box-shadow:var(--ombre-sm);
}
a.stat:hover .stat-legende, a.stat:focus-visible .stat-legende{
  color:var(--lien);
  text-decoration:underline;
  text-underline-offset:.15em;
}

/* Pastille ronde ambre numérotée (étapes, méthode en N points). Texte sur
   ambre : encre, jamais blanc (le blanc ne porte pas sur l'ambre — même
   convention que le logiciel, cf. constants.py). */
.jeton{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex:none;
  width:2rem; height:2rem;
  border-radius:50%;
  background:var(--ambre);
  color:var(--sur-alerte);
  font-family:var(--f-titre);
  font-weight:700;
  font-size:.95rem;
}

.liste-puces{
  list-style:none;
  padding:0;
  margin:0 0 1em;
}
.liste-puces li{
  position:relative;
  padding-left:1.3em;
  margin-bottom:.5em;
  line-height:1.55;
}
.liste-puces li::before{
  content:"";
  position:absolute;
  left:0; top:.55em;
  width:.5em; height:.5em;
  background:var(--bleu);
  border-radius:2px;
}

/* --- Fil d'Ariane ---------------------------------------------------------
   Distinct du `bandeau-fil` (sur-titre de page) : un fil de navigation à
   plusieurs niveaux, posé dans le contenu (ex. page de détail d'un ticket). */
.fil-ariane{
  display:flex;
  flex-wrap:wrap;
  gap:.35em;
  list-style:none;
  padding:0;
  margin:0 0 var(--e-lg);
  font-size:.85rem;
  color:var(--ink-faint);
}
.fil-ariane li{ display:flex; align-items:center; gap:.35em; }
.fil-ariane li + li::before{ content:"›"; color:var(--ink-faint); }
.fil-ariane a{ color:var(--ink-soft); text-decoration:none; }
.fil-ariane a:hover{ color:var(--bleu); text-decoration:underline; }
.fil-ariane li:last-child{ color:var(--ink); font-weight:600; }

/* --- Journal des versions ---------------------------------------------------
   Frise verticale : un filet continu, une entrée par version, un jeton
   d'ancrage sur le filet. */
.journal{
  position:relative;
  list-style:none;
  margin:0;
  padding:0 0 0 2.4rem;
}
.journal::before{
  content:"";
  position:absolute;
  left:.6rem; top:.4rem; bottom:.4rem;
  width:2px;
  background:var(--ligne);
}
.journal-entree{
  position:relative;
  padding-bottom:var(--e-xl);
}
.journal-entree:last-child{ padding-bottom:0; }
.journal-entree::before{
  content:"";
  position:absolute;
  left:-2.4rem; top:.3rem;
  width:.85rem; height:.85rem;
  border-radius:50%;
  background:var(--carte);
  border:2.5px solid var(--bleu);
}
.journal-date{
  display:block;
  font-family:var(--f-titre);
  font-size:.78rem;
  font-weight:700;
  letter-spacing:.06em;
  color:var(--ambre-encre); /* --ambre nu est sous l'AA comme texte en thème clair */
  text-transform:uppercase;
  margin-bottom:.3em;
}

/* --- Galerie de vignettes --------------------------------------------------
   Captures d'écran d'un logiciel : grille de vignettes, ouverture en
   visionneuse (assets/js/fabnord.js) — un lien simple sans JavaScript. */
.media-galerie{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(140px, 1fr));
  gap:var(--e-sm);
  list-style:none;
  padding:0;
  margin:var(--e-lg) 0;
}
.media-vignette{
  display:block;
  border:1px solid var(--ligne);
  border-radius:var(--r);
  overflow:hidden;
  background:var(--bande);
  aspect-ratio:4 / 3;
}
.media-vignette img{
  width:100%; height:100%;
  object-fit:cover;
}
a.media-vignette:hover, a.media-vignette:focus-visible{
  border-color:var(--bleu);
}

.avatar{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex:none;
  width:2.25rem; height:2.25rem;
  border-radius:50%;
  background:var(--carte-bleue);
  color:var(--bleu);
  font-family:var(--f-titre);
  font-weight:700;
  font-size:.9rem;
}


/* =============================================================================
   7. COMPOSANTS
   ============================================================================= */

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.5em;
  border:1px solid var(--ligne-forte);
  border-radius:var(--r);
  background:var(--carte);
  color:var(--ink);
  font-family:var(--f-corps);
  font-size:.92rem;
  font-weight:600;
  line-height:1.2;
  padding:var(--e-sm) var(--e-lg);
  min-height:38px;
  cursor:pointer;
  text-decoration:none;
}
.btn:hover{ background:var(--carte-bleue); border-color:var(--bleu-clair); }
.btn:active{ filter:brightness(.96); }
.btn[disabled], .btn.is-desactive{
  cursor:not-allowed;
  opacity:.55;
  pointer-events:none;
}

.btn-primaire{
  background:var(--bleu);
  border-color:var(--bleu);
  color:var(--sur-accent);
}
.btn-primaire:hover{ background:var(--bleu-clair); border-color:var(--bleu-clair); }
.btn-primaire:active{ filter:brightness(.92); }

.btn-fantome{
  background:transparent;
  border-color:var(--bleu);
  color:var(--bleu);
}
.btn-fantome:hover{ background:var(--carte-bleue); }

.btn-danger{
  background:var(--err);
  border-color:var(--err);
  color:var(--sur-err);
}
.btn-danger:hover{ filter:brightness(1.08); }
.btn-danger:active{ filter:brightness(.92); }

.btn-sm{
  padding:.4em .9em;
  min-height:30px;
  font-size:.82rem;
}

.btn-bloc{
  display:flex;
  width:100%;
}

/* --- Pastilles d'état -------------------------------------------------------
   Le texte porte TOUJOURS le nom de l'état en toutes lettres : la couleur
   renforce, elle ne remplace jamais le mot (contrat §2, accessibilité). */
.pastille{
  display:inline-flex;
  align-items:center;
  gap:.45em;
  padding:.28em .8em;
  border-radius:var(--r-pill);
  font-size:.8rem;
  font-weight:600;
  line-height:1.3;
  white-space:nowrap;
}
.pastille::before{
  content:"";
  flex:none;
  width:.5em; height:.5em;
  border-radius:50%;
  background:currentColor;
}
.pastille-ok{ background:var(--ok-doux); color:var(--ok); }
.pastille-attente{ background:var(--alerte-doux); color:var(--ink); }
.pastille-attente::before{ background:var(--alerte); }
.pastille-encours{ background:var(--carte-bleue); color:var(--bleu); }
/* .pastille-encours et .pastille-info partagent le même fond --carte-bleue ;
   en thème sombre --bleu et --bleu-clair y tombent tous deux sous l'AA
   (2,46:1 et 3,27:1) — --ink les remplace, sans rien changer en clair. */
[data-theme="sombre"] .pastille-encours,
[data-theme="sombre"] .pastille-info{ color:var(--ink); }
.pastille-clos{ background:var(--bande); color:var(--ink-soft); }
.pastille-clos::before{ background:var(--ink-faint); }
/* --bleu-clair, en thème clair, tombe à 4,17:1 sur --carte-bleue (sous
   l'AA pour un texte de .8rem en gras) : --bleu, plus soutenu, passe à
   7,35:1 sans rien perdre côté distinction (le libellé, jamais la seule
   couleur, dit l'état — contrat §2). */
.pastille-info{ background:var(--carte-bleue); color:var(--bleu); }
.pastille-neutre{ background:var(--bande); border:1px solid var(--ligne); color:var(--ink-soft); }
.pastille-neutre::before{ background:var(--ink-faint); }

/* --- Journal / paiement de version : jauge -------------------------------- */
.barre{
  width:100%;
  height:.6rem;
  border-radius:var(--r-pill);
  background:var(--bande);
  border:1px solid var(--ligne);
  overflow:hidden;
}
.barre-jauge{
  height:100%;
  background:var(--bleu);
  border-radius:var(--r-pill);
  /* La largeur (%) est posée en `style` par la page — seul cas autorisé par
     le contrat pour un attribut `style`, calculé côté PHP. */
}

/* --- Pagination ------------------------------------------------------------ */
.pagination{
  display:flex;
  flex-wrap:wrap;
  gap:.4em;
  align-items:center;
  margin:var(--e-xl) 0;
  list-style:none;
  padding:0;
}
.pagination a, .pagination span{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:2.2rem;
  height:2.2rem;
  padding:0 .5em;
  border:1px solid var(--ligne);
  border-radius:var(--r-sm);
  color:var(--ink-soft);
  text-decoration:none;
  font-size:.88rem;
}
.pagination a:hover{ background:var(--carte-bleue); border-color:var(--bleu-clair); color:var(--bleu); }
/* Même défaut, même correctif que .pastille-encours/.pastille-info : --bleu
   tombe à 2,46:1 sur --carte-bleue en thème sombre. */
[data-theme="sombre"] .pagination a:hover{ color:var(--ink); }
.pagination .est-courante{
  background:var(--bleu);
  border-color:var(--bleu);
  color:var(--sur-accent);
  font-weight:700;
}
.pagination .est-inactive{
  opacity:.4;
  pointer-events:none;
}

/* --- Compteur de caractères ------------------------------------------------ */
.compteur{
  display:block;
  margin-top:.35em;
  font-size:.8rem;
  color:var(--ink-faint);
  text-align:right;
  font-variant-numeric:tabular-nums;
}
.compteur.est-proche-limite{ color:var(--alerte); }
.compteur.est-au-dela{ color:var(--err); font-weight:600; }


/* =============================================================================
   8. FORMULAIRES
   ============================================================================= */

.champ{
  margin-bottom:var(--e-lg);
}
.champ:last-child{ margin-bottom:0; }

.libelle{
  display:block;
  margin-bottom:.4em;
  font-weight:600;
  font-size:.92rem;
  color:var(--ink);
}
.libelle .est-facultatif{
  font-weight:400;
  color:var(--ink-faint);
  font-size:.85em;
}

.saisie, .zone-texte, .selecteur{
  display:block;
  width:100%;
  background:var(--carte);
  color:var(--ink);
  border:1px solid var(--ligne-forte);
  border-radius:var(--r-sm);
  padding:.55em .7em;
  font-family:var(--f-corps);
  font-size:.95rem;
  line-height:1.4;
}
.saisie{ min-height:38px; }
.saisie:focus, .zone-texte:focus, .selecteur:focus{
  outline:2px solid var(--ambre);
  outline-offset:1px;
  border-color:var(--bleu);
}
.saisie[disabled], .zone-texte[disabled], .selecteur[disabled]{
  background:var(--bande);
  color:var(--ink-faint);
  cursor:not-allowed;
}
.saisie::placeholder, .zone-texte::placeholder{ color:var(--ink-faint); }

.zone-texte{
  min-height:8rem;
  resize:vertical;
}

/* `.selecteur` : chevron dessiné en dégradés (deux triangles), sans image
   externe et sans hex figé — il suit `currentColor`, donc les jetons. */
.selecteur{
  -webkit-appearance:none;
  appearance:none;
  padding-right:2.4em;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 1.15em) center,
    calc(100% - .75em) center;
  background-size:.4em .4em, .4em .4em;
  background-repeat:no-repeat;
  color:var(--ink-soft);
  cursor:pointer;
}
.selecteur:focus{ color:var(--ink); }

/* Barre de filtre d'une page de liste : le champ et son bouton sur une même
   ligne, alignés par le bas. Un `.champ` seul dans un formulaire s'étirait sur
   toute la largeur de la page — une liste déroulante de 1 100 px pour choisir
   un logiciel, et le bouton renvoyé à la ligne suivante. */
.filtre-barre{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  gap:var(--e-md);
  margin-bottom:var(--e-xl);
}
.filtre-barre .champ{
  flex:0 1 22rem;
  min-width:14rem;
  margin-bottom:0;
}

.aide{
  display:block;
  margin-top:.4em;
  font-size:.85rem;
  color:var(--ink-soft);
  line-height:1.5;
}

fieldset{
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-lg);
  margin:0 0 var(--e-lg);
}
legend{
  padding:0 .5em;
  font-family:var(--f-titre);
  font-weight:600;
  color:var(--bleu-fonce);
}
/* Même défaut, même correctif que .carte-titre ci-dessus. */
[data-theme="sombre"] legend{ color:var(--ink); }

/* Case à cocher / bouton radio : la zone cliquable inclut le libellé. */
.champ-case{
  display:flex;
  align-items:flex-start;
  gap:.6em;
  cursor:pointer;
}
.champ-case input{
  margin-top:.2em;
  width:1.05em; height:1.05em;
  accent-color:var(--bleu);
  flex:none;
}

/* --- Messages (flash + validation) ----------------------------------------
   Mêmes classes pour le flash de bandeau et une erreur de champ : même
   vocabulaire visuel, un seul endroit à faire évoluer. */
.message{
  display:flex;
  align-items:flex-start;
  gap:.6em;
  padding:.8em var(--e-lg);
  border-radius:var(--r);
  border:1px solid var(--ligne);
  background:var(--bande);
  color:var(--ink);
  margin-bottom:var(--e-md);
  line-height:1.5;
}
.message:last-child{ margin-bottom:0; }
.message-ok{ background:var(--ok-doux); border-color:var(--ok); color:var(--ink); }
.message-err{ background:var(--err-doux); border-color:var(--err); color:var(--ink); }
.message-info{ background:var(--carte-bleue); border-color:var(--bleu); color:var(--ink); }

/* --- Champ de dépôt d'image (contentieux RGPD, cf. champ_image.php) -------- */
.champ-image .message-err strong{ display:block; margin-bottom:.2em; }

.pochoir{
  margin-top:var(--e-md);
  border:1px solid var(--ligne);
  border-radius:var(--r);
  padding:var(--e-md);
  background:var(--bande);
}
.pochoir-barre{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.5em;
  margin-bottom:var(--e-sm);
}
.pochoir-etat{
  margin-left:auto;
  font-size:.85rem;
  color:var(--ink-soft);
}
.pochoir-toile{
  border:1px dashed var(--ligne-forte);
  border-radius:var(--r-sm);
  background:var(--carte);
  overflow:auto;
  max-height:60vh;
  display:flex;
}
.pochoir-toile canvas{
  max-width:100%;
  cursor:crosshair;
}
.pochoir-toile canvas.est-masquage{ cursor:cell; }


/* =============================================================================
   9. TABLEAUX
   ============================================================================= */
/* En-tête bleu foncé sur blanc avec liseré ambre (header_accent), lignes
   alternées, survol bleu pâle — même patron que QHeaderView::section et
   QTableWidget::item:hover dans aphp.qss. */

.tableau-wrap{
  width:100%;
  overflow-x:auto;
  border:1px solid var(--ligne);
  border-radius:var(--r);
  margin-bottom:var(--e-lg);
}
.tableau{
  width:100%;
  border-collapse:collapse;
  font-size:.92rem;
}
.tableau caption{
  text-align:left;
  padding:.6em var(--e-md);
  font-size:.85rem;
  color:var(--ink-soft);
  background:var(--bande);
}
.tableau thead th{
  background:var(--bleu-fonce);
  color:var(--sur-accent);
  text-align:left;
  font-weight:600;
  padding:.65em var(--e-md);
  border-bottom:2px solid var(--ambre);
  white-space:nowrap;
}
.tableau thead th:not(:last-child){
  border-right:1px solid color-mix(in srgb, var(--sur-accent) 18%, transparent);
}
.tableau tbody td, .tableau tbody th{
  padding:.6em var(--e-md);
  border-bottom:1px solid var(--ligne);
  vertical-align:top;
}
.tableau tbody tr:nth-child(even){ background:var(--bande); }
.tableau tbody tr:hover{ background:var(--carte-bleue); }
.tableau tbody tr:last-child td, .tableau tbody tr:last-child th{ border-bottom:0; }
.tableau td.num, .tableau th.num{
  text-align:right;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.tableau tfoot td{
  padding:.6em var(--e-md);
  border-top:2px solid var(--ligne-forte);
  font-weight:600;
  background:var(--bande);
}


/* =============================================================================
   10. ÉTATS
   ============================================================================= */

/* Anneau de focus visible, ambre, cohérent sur toute la page — élément natif
   ou composant (contrat §2, accessibilité). `:focus-visible` seul (pas
   `:focus`) : un clic de souris ne doit pas déclencher l'anneau, seule la
   navigation au clavier le justifie. */
:focus-visible{
  outline:2px solid var(--ambre);
  outline-offset:2px;
  border-radius:var(--r-sm);
}
.rail-item:focus-visible, .rail-bouton:focus-visible, .bascule-theme:focus-visible{
  outline-offset:-2px;
}

/* État vide : liste, recherche ou file sans résultat. Un filet en pointillé
   plutôt qu'une icône — aucune bibliothèque d'icônes n'est chargée ici. */
.vide{
  text-align:center;
  padding:var(--e-xxl) var(--e-lg);
  border:1.5px dashed var(--ligne-forte);
  border-radius:var(--r-lg);
  color:var(--ink-soft);
}
.vide-titre{
  display:block;
  font-family:var(--f-titre);
  font-weight:600;
  color:var(--ink);
  margin-bottom:.4em;
}
.vide .btn{ margin-top:var(--e-md); }

/* Lien « désactivé » générique (hors .rail-item, cf. section 4). */
.est-desactive, [aria-disabled="true"]{
  opacity:.55;
  cursor:not-allowed;
}

/* Visionneuse d'image (assets/js/fabnord.js) — dégrade en simple lien
   d'ouverture d'image quand JavaScript est absent. */
.visionneuse{
  position:fixed;
  inset:0;
  z-index:300;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:var(--e-xl);
  background:color-mix(in srgb, var(--bleu-nuit) 82%, transparent);
}
.visionneuse[hidden]{ display:none; }
.visionneuse img{
  max-width:100%;
  max-height:90vh;
  border-radius:var(--r);
  box-shadow:var(--ombre);
}
.visionneuse-fermer{
  position:absolute;
  top:var(--e-lg); right:var(--e-lg);
  width:2.4rem; height:2.4rem;
  border-radius:50%;
  border:1px solid color-mix(in srgb, var(--sur-accent) 40%, transparent);
  background:color-mix(in srgb, var(--bleu-nuit) 60%, transparent);
  color:var(--sur-accent);
  font-size:1.3rem;
  line-height:1;
  cursor:pointer;
}
.visionneuse-fermer:hover{ background:var(--bleu-fonce); }


/* =============================================================================
   11. IMPRESSION
   ============================================================================= */
/* Une note de version ou un ticket doit pouvoir s'imprimer proprement : fond
   blanc, encre noire, rail et actions superflues masqués.

   SEULE section de ce fichier à écrire des couleurs en dur : c'est le but
   même de ces règles que d'ignorer les jetons du thème courant. Si la page
   est imprimée depuis le thème sombre, `var(--ink)`/`var(--fond)` vaudraient
   alors « texte clair sur fond nuit » — illisible une fois sur papier, et
   ruineux en encre. Le papier veut du noir sur blanc, quel que soit
   `data-theme` au moment de l'impression. */

@media print{
  .rail-tiroir, .bandeau-actions, .btn, .rail-bouton,
  .pagination, .pochoir-barre, .visionneuse{
    display:none !important;
  }
  .app{ display:block; }
  .zone, .zone-large{ max-width:none; padding:0; }
  .bandeau{
    background:none !important;
    color:#000 !important;
    border-bottom:1px solid #000;
  }
  .bandeau-titre, .bandeau-fil{ color:#000 !important; }
  body{ background:#FFFFFF; color:#000000; }
  .carte, .encart, .stat, .tableau-wrap{
    box-shadow:none;
    border:1px solid #999;
  }
  a{ color:#000; text-decoration:underline; }
  a[href^="http"]::after{ content:" (" attr(href) ")"; font-size:.8em; color:#333; }
  .pied{ border-top:1px solid #999; }
}


/* =============================================================================
   12. RESPONSIVE
   ============================================================================= */
/* Seuil unique à 960 px (contrat §2) : au-delà, le rail est une colonne fixe
   à gauche ; en-deçà, il devient un tiroir (<details>) ouvert par un bouton
   pleine largeur en tête de page. */

@media (min-width: 960px){
  .rail-tiroir{
    display:contents; /* le <details>/<summary> sortent du flux : seul
                          .rail reste, comme enfant flex direct de .app */
  }
  .rail-tiroir > summary{ display:none; }
  .rail{
    width:var(--rail-largeur);
    flex:none;
    position:sticky;
    top:0;
    align-self:flex-start;
    /* HAUTEUR PLEINE, et non `height:auto` : avec `align-self:flex-start`, un
       rail dimensionné par son contenu s'arrêtait à mi-page et laissait une
       colonne vide sous lui — le contraire du rail persistant du logiciel, qui
       tient toute la fenêtre. `100dvh` suit la barre d'adresse mobile ; le
       repli `100vh` sert aux navigateurs qui ignorent l'unité dynamique. */
    height:100vh;
    height:100dvh;
    overflow-y:auto;
  }
}

@media (max-width: 959.98px){
  .app{ flex-direction:column; }
  .rail-tiroir{ border-bottom:1px solid color-mix(in srgb, var(--rail-texte) 14%, transparent); }
  .rail{ padding-top:var(--e-md); }
  .bandeau-inner{ align-items:flex-start; }
  .hero{ flex-direction:column; align-items:stretch; }
}

@media (max-width: 599.98px){
  .zone, .zone-large{ padding:var(--e-xl) var(--e-md); }
  .bandeau-inner{ padding:var(--e-lg) var(--e-md); }
  .bandeau-titre{ font-size:1.4rem; }
  .pied-inner, .pied-legal{ padding-inline:var(--e-md); }
  .stat-valeur{ font-size:1.8rem; }
}
