/* ============================================================================
   NEXORA — habillage du service.

   Deux directions, arrêtées sur maquettes et validées :

   — **l'ouverture de session** est éditoriale : un panneau marine porte la
     marque, la saisie occupe une page blanche à côté. On l'ouvre deux fois par
     jour, elle peut se permettre une image ;

   — **les écrans du magasin** sont un poste de travail : rail sombre, densité
     assumée, fiche du certificat à droite de la saisie. On y passe la journée.

   Ce qui les relie n'est pas une mise en page commune mais un vocabulaire : le
   marine du logo en fond de marque, l'or réservé à ce qui est **calculé** ou
   **retenu** — jamais décoratif —, et les mêmes familles typographiques.

   Les couleurs sont échantillonnées sur le logo, pas choisies : l'hexagone
   donne les marines, le monogramme les ors.
   ========================================================================== */

:root {
  color-scheme: light;

  --marine-950: #060f22;
  --marine-900: #0a1a34;
  --marine-800: #0e2549;
  --marine-700: #143563;
  --marine-600: #17408a;
  --marine-500: #0b4ea8;
  --marine-300: #7fa3d8;
  --marine-100: #dbe5f3;

  --or-700: #8c6314;
  --or-600: #a8781c;
  --or-500: #c8961f;
  --or-400: #e1a430;
  --or-100: #f6ecd6;

  --encre: #14181f;
  --encre-moyenne: #414855;
  --encre-douce: #6b7280;
  --trait: #e3e0d8;
  --trait-froid: #e2e6ec;
  --papier: #ffffff;
  --ivoire: #f7f5f0;
  --plan: #eff1f5;

  --valide: #10603c;
  --valide-fond: #e9f4ee;
  --attention: #8a5a00;
  --attention-fond: #fdf3e0;
  --refus: #99231f;
  --refus-fond: #fcedec;

  /* Familles système : le service est servi hors de tout réseau public et ne
     charge aucune fonte distante. Le rendu est fidèle sur les postes Apple,
     substitué ailleurs — les replis sont ordonnés par ressemblance, pas par
     disponibilité. */
  --ui: 'Avenir Next', 'Avenir', 'Segoe UI', 'Helvetica Neue', system-ui, sans-serif;
  --didone: Didot, 'Bodoni 72', 'Bodoni MT', 'Times New Roman', Georgia, serif;
  --chiffres: 'SF Mono', ui-monospace, 'JetBrains Mono', Menlo, Consolas, monospace;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--ui);
  color: var(--encre);
  line-height: 1.5;
  background: var(--plan);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
p,
figure,
fieldset,
legend,
dl,
dd {
  margin: 0;
  padding: 0;
}

fieldset {
  border: 0;
  min-inline-size: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: var(--marine-700);
  text-underline-offset: 3px;
}

:focus-visible {
  outline: 2px solid var(--focus, var(--marine-500));
  outline-offset: 2px;
}

.tabulaire {
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ═══ Ouverture de session ══════════════════════════════════════════════════
   Partagée par la connexion et la reprise après verrouillage : ce sont les
   deux écrans où personne n'est encore au travail. */

.ouverture {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 47fr) minmax(0, 53fr);
  background: var(--papier);
}

.panneau {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(2.5rem, 4.5vw, 4rem);
  overflow: hidden;
  color: rgba(255, 255, 255, 0.72);
  background: var(--marine-950);
  isolation: isolate;
}

/* Lueur froide décentrée. Elle n'est pas un ornement : sans elle, un aplat
   #060f22 sur près de la moitié de l'écran se lit comme un trou noir. */
.panneau::before {
  content: '';
  position: absolute;
  z-index: -2;
  inset: -30% -40% auto -55%;
  aspect-ratio: 1;
  background: radial-gradient(
    circle at 50% 50%,
    rgba(23, 64, 138, 0.5) 0%,
    rgba(11, 78, 168, 0.14) 38%,
    rgba(6, 15, 34, 0) 68%
  );
}

/* L'hexagone du logo, redessiné en trait et débordant du cadre : la marque
   habite le fond sans que le logo y soit répété. */
.filigrane {
  position: absolute;
  z-index: -1;
  right: -16%;
  bottom: -22%;
  width: 78%;
  pointer-events: none;
}

.filigrane path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.07);
  stroke-width: 1.1;
}

.filigrane path.or {
  stroke: rgba(225, 164, 48, 0.16);
}

/* La signature de l'outil composée de ses deux pièces — monogramme et mot —, comme
   au rail du poste. La signature d'un seul tenant a été retirée : elle porte une
   enseigne dans ses pixels, et un écran du personnel ne nomme que celle de
   l'acteur. Composée, elle ne dépend plus d'un actif à recouper. */
.panneau__marque {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

/* La hauteur mène, la largeur suit : le monogramme est plus haut que large, et le
   borner en largeur le laisserait déborder le mot qu'il accompagne. 62 px de
   monogramme pour la ligne capitale de 1.5rem, soit à peu près l'encombrement de
   la signature d'un seul tenant qu'il remplace — la colonne du panneau ne se
   redessine pas. */
.panneau__marque img {
  width: auto;
  height: 62px;
}

.panneau__mot {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  color: #fff;
}

.manchette {
  max-width: 22ch;
  margin: auto 0 0;
  font-family: var(--didone);
  font-size: clamp(2rem, 3.4vw, 3.05rem);
  font-weight: 400;
  line-height: 1.14;
  letter-spacing: -0.015em;
  color: #fff;
}

.manchette em {
  display: block;
  font-style: normal;
  color: var(--or-400);
}

.panneau__propos {
  max-width: 34ch;
  margin-top: 1.6rem;
  font-size: 0.9375rem;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.6);
}

.assertions {
  display: grid;
  margin-top: 3rem;
  border-top: 1px solid rgba(255, 255, 255, 0.11);
}

.assertions li {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  align-items: baseline;
  padding: 0.85rem 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  border-bottom: 1px solid rgba(255, 255, 255, 0.11);
}

.assertions b {
  font-family: var(--chiffres);
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--or-400);
}

.page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(2.5rem, 5vw, 5rem) clamp(1.5rem, 6vw, 6rem);
}

.page__entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2.75rem;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.page h1 {
  max-width: 16ch;
  font-family: var(--didone);
  font-size: clamp(2.1rem, 3vw, 2.75rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.page .intro {
  max-width: 42ch;
  margin-top: 1rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--encre-douce);
}

.page form {
  max-width: 26rem;
  margin-top: 2.5rem;
}

.page .champ {
  margin-bottom: 1.15rem;
}

/* Le champ de saisie de l'ouverture : plus grand qu'ailleurs, encadré, et
   éclairci à la prise de focus. On y frappe deux fois par jour, pas trente. */
.boite {
  display: flex;
  align-items: center;
  background: #fbfaf8;
  border: 1px solid var(--trait);
  border-radius: 10px;
  transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
}

.boite:focus-within {
  background: var(--papier);
  border-color: var(--marine-600);
  box-shadow: 0 0 0 3px rgba(23, 64, 138, 0.12);
}

.boite input {
  flex: 1;
  min-width: 0;
  padding: 0.85rem 1rem;
  font-size: 1rem;
  background: transparent;
  border: 0;
}

.boite input:focus {
  outline: none;
}

.boite--code input {
  font-family: var(--chiffres);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.champ[data-refuse='oui'] .boite {
  border-color: var(--refus);
  background: var(--refus-fond);
}

.devoiler {
  align-self: stretch;
  padding: 0 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--encre-douce);
  background: none;
  border: 0;
  border-left: 1px solid var(--trait);
}

.devoiler:hover {
  color: var(--marine-600);
}

.barre {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-top: 1.75rem;
}

/* ═══ Rail du poste ═════════════════════════════════════════════════════════
   Il nomme le vendeur dont la session est ouverte et le magasin émetteur :
   c'est ce que le certificat gèlera, et cela doit être lisible avant
   l'émission, non découvert sur le document imprimé. */

.rail {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.55rem clamp(0.75rem, 2vw, 1.25rem);
  color: rgba(255, 255, 255, 0.6);
  background: var(--marine-950);
}

.rail img {
  height: 24px;
  width: auto;
}

.rail__mot {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: #fff;
}

/* Les deux destinations du poste, permanentes. La courante n'est pas un lien : elle
   est marquée d'un aplat discret et d'`aria-current`, de sorte que la distinction ne
   repose pas sur la seule couleur. */
.rail__fil {
  display: flex;
  gap: 0.35rem;
  padding-left: 0.8rem;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-left: 1px solid rgba(255, 255, 255, 0.15);
}

.rail__fil a,
.rail__fil span {
  padding: 0.2rem 0.5rem;
  color: inherit;
  text-decoration: none;
  border-radius: 5px;
}

.rail__fil a:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.1);
}

.rail__fil [aria-current='page'] {
  font-weight: 600;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

.rail__droite {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-left: auto;
  font-size: 0.75rem;
}

.rail__magasin {
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--or-400);
}

.rail__acteur {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.25rem 0.7rem;
  background: rgba(255, 255, 255, 0.07);
  border-radius: 999px;
}

.rail__acteur b {
  font-weight: 600;
  color: #fff;
}

.rail__action {
  padding: 0.3rem 0.6rem;
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.6);
  background: none;
  border: 0;
  border-radius: 5px;
}

.rail__action:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.1);
}

/* ═══ Plan de travail ══════════════════════════════════════════════════════ */

/* Les respirations haute et basse sont fixes et courtes. Les 4 rem de pied venaient d'une
   page qu'on lisait en défilant ; l'écran de suite se lit d'un coup d'œil entre deux clients,
   et cette réserve y coûtait la moitié de ce qui manquait au poste de caisse. */
.plan {
  max-width: 64rem;
  margin: 0 auto;
  padding: 1.25rem clamp(1rem, 3vw, 2rem) 0.6rem;
}

.plan h1 {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.plan .chapeau {
  max-width: 70ch;
  margin-top: 0.4rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--encre-douce);
}

/* Deux colonnes : la saisie, et la fiche du certificat qui se remplit à la
   frappe. La fiche n'est **pas** le document imprimé — celui-ci est produit par
   le gabarit, seule source du PDF (ADR-0005). Elle en reprend l'ordre des
   informations pour qu'aucune ne surprenne au tirage. */
.travail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24rem;
  gap: 1px;
  min-height: calc(100vh - 44px);
  background: var(--trait-froid);
  padding-bottom: 68px;
}

.saisie {
  padding: 1.15rem clamp(0.9rem, 2vw, 1.6rem) 1.5rem;
  background: var(--papier);
}

/* La colonne de saisie ne s'étire pas indéfiniment : au-delà d'une cinquantaine
   de caractères, l'œil perd la ligne entre un libellé et son champ. */
.saisie > * {
  max-width: 52rem;
}

.saisie__entete {
  margin-bottom: 1.25rem;
}

.saisie__entete h1 {
  font-size: 1.25rem;
  font-weight: 600;
}

.saisie__entete p {
  max-width: 68ch;
  margin-top: 0.35rem;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--encre-douce);
}

/* ═══ Rubriques et champs ══════════════════════════════════════════════════ */

.rubrique + .rubrique {
  margin-top: 1.15rem;
  padding-top: 1.15rem;
  border-top: 1px solid var(--trait-froid);
}

.rubrique__titre {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--marine-700);
}

.rubrique__titre::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--trait-froid);
}

.rubrique__titre .apposition {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--encre-douce);
}

.grille {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0.7rem 0.85rem;
}

.champ {
  grid-column: span 6;
}

.champ--plein {
  grid-column: span 12;
}

.champ--cinq {
  grid-column: span 5;
}

.champ--sept {
  grid-column: span 7;
}

.champ label,
.champ .intitule {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--encre-moyenne);
}

.page .champ label {
  margin-bottom: 0.4rem;
  font-size: 0.8125rem;
}

.facultatif {
  font-weight: 400;
  color: var(--encre-douce);
}

.champ input {
  width: 100%;
  height: 40px;
  padding: 0 0.7rem;
  font-size: 0.9375rem;
  background: #fafbfc;
  border: 1px solid var(--trait-froid);
  border-radius: 6px;
  transition: border-color 0.14s, background 0.14s, box-shadow 0.14s;
}

.champ input:focus {
  outline: none;
  background: var(--papier);
  border-color: var(--marine-500);
  box-shadow: 0 0 0 3px rgba(11, 78, 168, 0.13);
}

/* Un champ figé n'est pas désactivé : la saisie commune, une fois gelée sur un
   certificat émis, doit continuer d'accompagner les lignes qui restent — un
   champ désactivé n'est pas posté. */
.champ input[readonly] {
  color: var(--encre-douce);
  background: #f0f1f4;
  border-style: dashed;
}

.champ input[aria-invalid='true'] {
  border-color: var(--refus);
  background: var(--refus-fond);
}

.note {
  margin-top: 0.25rem;
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--encre-douce);
}

.erreur {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--refus);
}

.page .erreur {
  font-size: 0.8125rem;
}

.refus {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-bottom: 1.15rem;
  padding: 0.8rem 0.95rem;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--refus);
  background: var(--refus-fond);
  border-radius: 8px;
}

/* Les deux seules règles que cette feuille ait reçues depuis sa reprise octet pour octet du témoin.
   Elle vivait en ligne dans `src/app/emission/refus-de-sortie.ts`, page que le cadre
   TypeScript rendait à la main : une route de ressource ne traversait ni la mise en page
   racine ni la feuille empaquetée. La contrainte n'existe pas ici — la page de refus est un
   gabarit comme les autres —, mais la règle est partie avec le module. Valeurs recopiées de
   l'étiquette `typescript-avant-bascule`, sans rien y ajouter.

   Le numéro de certificat est composé de segments tirettés : sans `hyphens: none`, le
   navigateur le coupe en fin de ligne, et le vendeur lit un numéro sur deux lignes là où il
   cherche à le relever. */
/* Même composition qu'au panneau, sur fond clair : le monogramme plein et le mot
   à l'encre marine.

   La signature d'un seul tenant est partie avec la mention d'enseigne et de groupe
   qu'elle portait en petites capitales — la règle précédente la disait déjà, et
   c'est précisément ce qu'un écran du personnel ne nomme plus. */
.refus__marque {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 1.75rem;
}

.refus__marque img {
  width: auto;
  height: 46px;
}

.refus__marque span {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  color: var(--marine-900);
}

.refus__motif {
  margin-top: 0.9rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--encre-moyenne);
  text-wrap: pretty;
  hyphens: none;
}

.case {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  grid-column: span 12;
  font-size: 0.8125rem;
  color: var(--encre-moyenne);
}

.case input {
  width: 16px;
  height: 16px;
  flex: none;
  accent-color: var(--marine-700);
}

.case label {
  margin: 0;
  font-size: inherit;
  font-weight: 400;
}

.case .erreur {
  flex-basis: 100%;
}

/* ═══ Durée de garantie ════════════════════════════════════════════════════
   La durée est ce que le vendeur cherche : elle titre les groupes. La nature du
   produit est ce qui, au barème, la justifie : elle est le choix (ADR-0017).
   Un seul groupe de boutons radio pour les six natures — la présentation est en
   trois blocs, la valeur postée reste la catégorie, et le clavier parcourt les
   six options sans qu'aucune ne soit masquée. */

.garantie {
  grid-column: span 12;
}

.garantie > .intitule {
  display: block;
  margin-bottom: 0.45rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--encre-moyenne);
}

.durees {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.5rem;
}

.duree {
  display: block;
  padding: 0.85rem 0.75rem 0.9rem;
  background: #fafbfc;
  border: 1px solid var(--trait-froid);
  border-radius: 8px;
  cursor: pointer;
  text-align: center;
}

.duree:hover {
  background: rgba(20, 53, 99, 0.05);
}

/* Le contrôle est **dans** le document, jamais retiré : `sr-only` plutôt que
   `display: none`, qui le sortirait du parcours clavier et le rendrait muet aux
   lecteurs d'écran. La carte entière est le `<label>` : toute sa surface coche. */
.duree input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* La carte choisie se distingue : c'est la ligne du barème que le document mettra
   en avant. */
.duree:has(input:checked) {
  background: linear-gradient(180deg, rgba(225, 164, 48, 0.1), rgba(225, 164, 48, 0));
  border-color: var(--or-500);
}

/* Le focus est porté par la carte, le contrôle étant invisible : sans cela, un
   vendeur au clavier ne saurait pas où il se trouve dans le groupe. */
.duree:has(input:focus-visible) {
  outline: 2px solid var(--or-600);
  outline-offset: 2px;
}

.duree__valeur {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--marine-900);
}

.duree:has(input:checked) .duree__valeur {
  color: var(--or-700);
}

.garantie[data-refuse='oui'] .duree {
  border-color: var(--refus);
}

/* ═══ Signalements ═════════════════════════════════════════════════════════ */

/* Le doublon **avertit**, il n'interdit pas : le doublon légitime existe. La
   confirmation n'apparaît qu'après le signalement — offerte d'emblée, elle
   serait cochée par habitude et la trace ne vaudrait plus rien. */
.doublon {
  grid-column: span 12;
  padding: 0.7rem 0.85rem;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--attention);
  background: var(--attention-fond);
  border: 1px solid rgba(138, 90, 0, 0.22);
  border-radius: 6px;
}

.doublon b {
  display: block;
}

.doublon .case {
  grid-column: auto;
  margin-top: 0.4rem;
  font-size: 0.75rem;
  color: var(--attention);
}

.doublon .case input {
  accent-color: var(--attention);
}

.derogation {
  grid-column: span 12;
  padding: 0.7rem 0.85rem;
  background: #f5f8fd;
  border: 1px dashed var(--marine-300);
  border-radius: 6px;
}

.derogation__titre {
  margin-bottom: 0.55rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--marine-800);
}

.derogation__titre em {
  font-style: normal;
  font-weight: 400;
  color: var(--encre-douce);
}

.avis {
  display: flex;
  gap: 0.6rem;
  padding: 0.85rem 1rem;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--marine-800);
  background: #f2f6fc;
  border-radius: 8px;
}

.avis b {
  color: var(--attention);
}

/* ═══ Onglets des produits garantis ════════════════════════════════════════
   Un certificat par onglet : la profondeur de la page ne dépend plus du nombre
   de produits. Les lignes inactives restent dans le document — masquées, elles
   sont toujours postées, et une saisie qui disparaîtrait du formulaire
   disparaîtrait de la série. */

.onglets {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--trait-froid);
}

.onglet {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.8rem;
  margin-bottom: -1px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--encre-douce);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
}

.onglet[aria-selected='true'] {
  color: var(--marine-900);
  border-bottom-color: var(--marine-800);
}

.onglet em {
  font-style: normal;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--or-600);
}

.onglet--ajout {
  margin-left: auto;
  color: var(--marine-600);
  border-radius: 6px;
}

.onglet--ajout:hover {
  background: #f0f5fc;
}

.retirer {
  padding: 0.3rem 0.55rem;
  font-size: 0.75rem;
  color: var(--encre-douce);
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
}

.retirer:hover {
  color: var(--refus);
  border-color: rgba(153, 35, 31, 0.25);
  background: var(--refus-fond);
}

/* ═══ Fiche du certificat à émettre ════════════════════════════════════════ */

.apercu {
  padding: 1.15rem 1.25rem 1.5rem;
  background: #e6e9ee;
}

.apercu__entete {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.apercu__entete span {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

.fiche {
  position: sticky;
  top: 3.75rem;
  padding: 0.95rem 1rem 1.1rem;
  font-size: 0.75rem;
  background: var(--papier);
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(6, 15, 34, 0.12), 0 16px 34px -24px rgba(6, 15, 34, 0.6);
}

.fiche__entete {
  display: flex;
  gap: 0.7rem;
  padding-bottom: 0.7rem;
  border-bottom: 2px solid var(--marine-900);
}

/* L'aperçu ne porte plus que le **nom** de l'enseigne de l'acteur : ni logo, ni
   mention de groupe. Le logo est une donnée du référentiel qui voyage en URI de
   données, et cette fiche est un reflet de la frappe, redessiné à chaque saisie —
   le document le paie une fois par tirage, l'écran d'émission le paierait à
   chaque frappe. */
.fiche__enseigne {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.fiche__enseigne b {
  display: block;
  font-size: 0.6875rem;
}

.fiche h2 {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 700;
}

.fiche__numero {
  margin-top: 0.15rem;
  font-family: var(--chiffres);
  font-size: 0.625rem;
  color: var(--marine-700);
}

.fiche__lieu {
  margin-top: 0.2rem;
  font-size: 0.5625rem;
  line-height: 1.45;
  color: var(--encre-douce);
}

.fiche__frise {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin: 0.7rem 0;
  background: var(--trait);
  border: 1px solid var(--trait);
}

.fiche__frise > div {
  padding: 0.35rem 0.4rem;
  background: var(--papier);
}

/* L'échéance est **dérivée**, jamais saisie : c'est le seul champ de la fiche
   que personne ne frappe, et c'est pourquoi il porte l'or. */
.fiche__frise .echeance {
  background: var(--or-100);
}

.fiche__frise .echeance dt,
.fiche__frise .echeance dd {
  color: var(--or-700);
}

.fiche__frise dt {
  font-size: 0.5rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.fiche__frise dd {
  margin-top: 0.1rem;
  font-size: 0.75rem;
  font-weight: 700;
}

.fiche__cartes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

.fiche__carte {
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--trait);
  border-radius: 3px;
}

.fiche__carte h3 {
  margin-bottom: 0.3rem;
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.fiche__carte dl {
  display: grid;
  grid-template-columns: 4.2rem 1fr;
  gap: 0.12rem 0.3rem;
  font-size: 0.625rem;
}

.fiche__carte dt {
  color: var(--encre-douce);
}

.fiche__carte dd {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.fiche__bareme {
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--trait);
}

.fiche__bareme h3 {
  margin-bottom: 0.35rem;
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.pastilles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.pastille {
  padding: 0.2rem 0.45rem;
  font-size: 0.5625rem;
  color: var(--encre-douce);
  border: 1px solid var(--trait);
  border-radius: 999px;
}

.pastille b {
  color: var(--encre);
}

.pastille--retenue {
  color: var(--marine-900);
  background: var(--marine-100);
  border-color: var(--marine-300);
}

.fiche__mention {
  margin-top: 0.7rem;
  padding-top: 0.5rem;
  font-size: 0.5625rem;
  line-height: 1.5;
  color: var(--encre-douce);
  border-top: 1px solid var(--trait);
}

.fiche__mention b {
  color: var(--attention);
}

/* ═══ Barre d'action ═══════════════════════════════════════════════════════ */

.action {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 0.7rem clamp(0.9rem, 2vw, 1.6rem);
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--trait-froid);
}

.bilan {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-size: 0.8125rem;
}

.bilan b {
  font-weight: 600;
}

.bilan .separateur {
  width: 1px;
  height: 18px;
  background: var(--trait-froid);
}

.bilan .echeance {
  font-weight: 600;
  color: var(--or-700);
}

.bilan .vide {
  color: var(--encre-douce);
}

.action .droite {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-left: auto;
}

/* ═══ Boutons ══════════════════════════════════════════════════════════════ */

.principal {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  height: 42px;
  padding: 0 1.4rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: #fff;
  background: var(--marine-900);
  border: 0;
  border-radius: 7px;
  transition: background 0.16s, transform 0.08s;
}

.principal:hover:not(:disabled) {
  background: var(--marine-800);
}

.principal:active:not(:disabled) {
  transform: translateY(1px);
}

.principal:disabled {
  color: var(--encre-douce);
  background: #e4e7eb;
  cursor: not-allowed;
}

.page .principal {
  height: 46px;
  border-radius: 10px;
  box-shadow: 0 10px 24px -14px rgba(10, 26, 52, 0.9);
}

.secondaire {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 40px;
  padding: 0 1rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--marine-800);
  text-decoration: none;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 7px;
  transition: border-color 0.16s, background 0.16s;
}

.secondaire:hover {
  border-color: var(--marine-600);
  background: #f5f8fd;
}

/* Bouton d'action serveur rendu comme un lien : la fermeture de session et le
   verrouillage sont des écritures, elles ne peuvent pas être des liens. */
.lien {
  padding: 0;
  font: inherit;
  color: var(--encre-douce);
  background: none;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.lien:hover {
  color: var(--marine-800);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.25rem;
}

.grille > .actions {
  grid-column: span 12;
  margin-top: 0.35rem;
}

/* La suite du parcours, après le bloc de remise. Elle porte l'aplat du bouton `secondaire`,
   comme la sortie du document et comme la même suite sur la vue de série : c'est la charte de
   l'interface.

   Sa respiration haute est courte parce que l'aplat sépare déjà — un bouton n'a pas besoin du
   blanc dont un lien souligné avait besoin pour se détacher du relevé. Ces 6 px sont, avec la
   respiration basse du plan, ce qui rend au poste de caisse la hauteur que l'aplat lui coûte. */
.plan > .actions--suite {
  margin-top: 0.5rem;
}

/* La bobine tourne pendant que le serveur travaille. Elle est portée par le
   bouton lui-même : le vendeur ne doit pas avoir à chercher ailleurs si son
   geste a été pris. */
.principal[data-occupe='oui'] {
  color: transparent;
}

.principal[data-occupe='oui'] svg {
  opacity: 0;
}

.principal[data-occupe='oui']::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.28);
  border-top-color: var(--or-400);
  border-radius: 50%;
  animation: tourner 0.65s linear infinite;
}

@keyframes tourner {
  to {
    transform: rotate(360deg);
  }
}

.touche {
  font-family: var(--chiffres);
  font-size: 0.6875rem;
  color: var(--encre-douce);
}

.touche kbd {
  padding: 0.1rem 0.3rem;
  background: #eceff3;
  border: 1px solid var(--trait-froid);
  border-bottom-width: 2px;
  border-radius: 4px;
}

/* ═══ Certificats déjà émis, dans une série interrompue ════════════════════ */

.deja-emis {
  margin-bottom: 1rem;
  padding: 0.85rem 1rem;
  background: var(--valide-fond);
  border-left: 3px solid var(--valide);
  border-radius: 0 6px 6px 0;
}

.deja-emis h2 {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--valide);
}

.deja-emis p {
  margin-top: 0.3rem;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--encre-moyenne);
}

.deja-emis ul {
  margin-top: 0.5rem;
  display: grid;
  gap: 0.2rem;
  font-size: 0.8125rem;
}

.deja-emis a {
  font-family: var(--chiffres);
  font-size: 0.75rem;
}

/* ═══ Écrans de suite : fiche d'un certificat, série, remise ═══════════════ */

/* ── Les mentions exceptionnelles ───────────────────────────────────────────
   Doublon confirmé et dérogation de durée sont hors du relevé et au-dessus de lui : ce ne
   sont pas des champs du certificat mais des circonstances de son émission. Alignées entre
   deux champs, elles se lisaient comme des données ordinaires, et leur phrase de deux lignes
   déformait la rangée où elles étaient prises.

   Elles partagent **un seul** encadré : deux cartouches empilées coûtaient deux bordures,
   deux respirations et un intervalle, pour une distinction que le libellé en tête de ligne
   suffit à porter. Les jetons d'attention de la feuille en font l'exception qu'elles sont,
   sans l'alarme d'un refus. */
.mentions {
  margin-top: 0.45rem;
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--encre-moyenne);
  background: var(--attention-fond);
  border: 1px solid var(--or-100);
  border-radius: 10px;
}

/* Le libellé et sa phrase sur une même ligne : le libellé ne prend que sa laisse, la phrase
   occupe le reste. C'est ce qui tient les deux mentions alignées l'une sous l'autre. */
.mentions p {
  display: flex;
  gap: 0.7rem;
  margin: 0;
}

.mentions p + p {
  margin-top: 0.3rem;
}

.mentions b {
  flex: none;
  min-width: 5.5rem;
  color: var(--attention);
  font-weight: 600;
}

/* Le gabarit porte `releve` sur le `dl` lui-même : la grille est déclarée sur
   l'élément qui porte la classe, non sur un `dl` qui en descendrait. */
.releve {
  margin-top: 0.9rem;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
  overflow: hidden;
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr);
  font-size: 0.9375rem;
}

.releve dt {
  padding: 0.7rem 1rem;
  color: var(--encre-douce);
  border-top: 1px solid var(--trait-froid);
}

.releve dd {
  padding: 0.7rem 1rem;
  font-weight: 500;
  border-top: 1px solid var(--trait-froid);
  overflow-wrap: anywhere;
}

/* La première rangée est celle des **premières cellules**, non celle du premier `dt` :
   `:first-of-type` ne connaît pas les rangées d'une grille, et le viser laisserait un filet
   résiduel au milieu de la rangée dès que celle-ci porte plus d'une paire. Deux cellules ici,
   quatre sous le relevé en paires. */
.releve > :nth-child(-n + 2) {
  border-top: 0;
}

/* ── Le relevé en paires ────────────────────────────────────────────────────
   Quatre pistes au lieu de deux : libellé, valeur, libellé, valeur — les pistes de
   libellé dimensionnées au contenu, celles de valeur en fraction. Onze champs tiennent
   en cinq rangées au lieu de onze, sans que rien ne soit caché ni qu'un clic soit ajouté.

   Le placement reste **l'ordre du document** : aucune cellule n'est posée à la main, faute
   de quoi l'ajout d'un champ demanderait de renuméroter la grille. */
.releve--paires {
  grid-template-columns:
    minmax(8.5rem, auto) minmax(0, 1fr)
    minmax(8.5rem, auto) minmax(0, 1fr);
}

.releve--paires dt,
.releve--paires dd {
  padding: 0.5rem 1rem;
}

/* Un filet vertical sépare les deux paires d'une même rangée, posé sur le libellé de la
   seconde. Sans lui, l'œil lit quatre colonnes indépendantes et rattache la valeur de
   gauche au libellé de droite. */
.releve--paires dt:nth-of-type(2n) {
  border-left: 1px solid var(--trait-froid);
}

.releve--paires > :nth-child(-n + 4) {
  border-top: 0;
}

/* L'URL de vérification fait 78 caractères. À demi-largeur elle passe sur trois lignes et
   impose leur hauteur aux trois autres cellules de la rangée : elle prend donc la rangée
   entière, sa valeur s'étendant du libellé à la fin de la grille. Elle reste **en clair** —
   le vendeur la dicte au client dont le téléphone ne scanne pas le QR. */
.releve__large {
  grid-column: 2 / -1;
}

.releve .numero {
  font-family: var(--chiffres);
  font-weight: 600;
  color: var(--marine-800);
}

.releve .echeance {
  font-weight: 600;
  color: var(--or-700);
}

.serie {
  display: grid;
  gap: 0.85rem;
  margin-top: 1.5rem;
}

.serie > li {
  padding: 0.95rem 1.15rem;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
}

.serie h2 {
  font-family: var(--chiffres);
  font-size: 0.875rem;
  font-weight: 700;
}

.serie dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.6rem 1rem;
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--trait-froid);
  font-size: 0.875rem;
}

.serie dt {
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.serie dd {
  margin-top: 0.15rem;
  font-weight: 500;
}

/* ═══ Archive du magasin ═══════════════════════════════════════════════════
   La première lecture multi-résultats du service. Un tableau, et non des
   fiches : les colonnes sont les mêmes d'une ligne à l'autre, et c'est en les
   balayant qu'on retrouve un certificat. Aucune colonne n'y porte de nom de
   client — le type que la page reçoit ne peut pas en porter (ADR-0013). */

.archive__recherche {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.5rem;
}

.archive__recherche label {
  flex: 1 0 100%;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.archive__recherche input {
  flex: 1 1 22rem;
  padding: 0.55rem 0.75rem;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--encre);
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 8px;
}

.archive__recherche input:focus {
  border-color: var(--marine-500);
  outline: 0;
  box-shadow: 0 0 0 3px rgba(28, 58, 102, 0.12);
}

.archive {
  width: 100%;
  margin-top: 1.5rem;
  font-size: 0.875rem;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
}

.archive th,
.archive td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  vertical-align: top;
}

.archive thead th {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
  white-space: nowrap;
  border-bottom: 1px solid var(--trait-froid);
}

.archive tbody tr + tr th,
.archive tbody tr + tr td {
  border-top: 1px solid var(--trait-froid);
}

.archive tbody tr:hover th,
.archive tbody tr:hover td {
  background: #f7f8fa;
}

.archive__numero {
  font-family: var(--chiffres);
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
}

/* La date et la durée tiennent sur une ligne : les replier au milieu d'un
   quantième ou entre le nombre et son unité coûte une ligne à toute la table
   sans rien apprendre. */
.archive__serre {
  white-space: nowrap;
}

.archive__vendeur span {
  display: block;
  margin-top: 0.1rem;
  font-family: var(--chiffres);
  font-size: 0.75rem;
  color: var(--encre-douce);
}

/* La pastille d'état reprend les aplats de la page publique : le même fait ne
   se dit pas de deux façons selon le lecteur. Elle est plus discrète, la
   couverture n'étant ici qu'une colonne parmi sept.

   Ses modificateurs sont les siens et non ceux de `.statut` : emprunter
   `statut--neutre` à un autre bloc aurait accolé à `etiquette` un modificateur
   orphelin, et le premier réglage de `.statut` se serait propagé ici sans que
   rien ne l'annonce. Les couleurs, elles, sont bien les mêmes variables. */
.etiquette {
  display: inline-block;
  padding: 0.2rem 0.55rem;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  border-radius: 999px;
}

.etiquette--actif {
  color: var(--valide);
  background: var(--valide-fond);
}

/* Deux faits sans rapport, un seul aplat : la couverture échue et la remise que
   personne n'atteste appellent l'une et l'autre le même degré d'attention. Les
   deux noms subsistent parce que les deux faits sont distincts — les fondre
   ferait afficher `etiquette--expire` sur une colonne qui ne parle pas de
   couverture, et le premier réglage de l'une se propagerait à l'autre. */
.etiquette--expire,
.etiquette--attention {
  color: var(--attention);
  background: var(--attention-fond);
}

/* Le seul aplat rouge des étiquettes, et il est réservé au certificat sans
   document (ADR-0019) : irrattrapable dans le service, et non pas seulement
   fâcheux. Un second emploi devra soutenir la comparaison. */
.etiquette--refus {
  color: var(--refus);
  background: var(--refus-fond);
}

.etiquette--neutre {
  color: var(--encre-moyenne);
  background: #eef0f3;
}

/* Le neutre **creux**, pour ce qui n'appelle aucune alerte mais n'est pas
   encore acquis — la remise en attente, seule à ce jour.

   Le plein et le creux disent l'acquis et le pendant, là où deux gris se
   seraient confondus sur un écran de caisse et où une quatrième teinte aurait
   fait concurrence aux deux défauts. La distinction tient donc à la forme, et
   se lit encore en niveaux de gris comme à l'impression.

   Le contour remplace le fond au lieu de s'y ajouter : une pastille pleine
   cerclée pèserait plus que l'ambre qu'elle ne doit pas concurrencer. Il est
   en revanche plus soutenu que `--trait-froid`, qui trace les filets du
   tableau : un contour de la même valeur que les lignes de la table se serait
   fondu dans la grille, et les deux neutres seraient restés jumeaux. */
.etiquette--creuse {
  color: var(--encre-douce);
  background: var(--papier);
  box-shadow: inset 0 0 0 1px #c2cad6;
}

/* Le critère frappé est repris dans le message. Il vient d'une URL : rien n'en borne
   la longueur, et un paragraphe collé doit se replier au lieu d'élargir la page. */
.archive__vide {
  margin-top: 1.5rem;
  padding: 1.5rem;
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
  color: var(--encre-douce);
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
}

.archive__pages {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.archive__rang {
  font-size: 0.8125rem;
  color: var(--encre-douce);
}

/* Le bloc suit les liens de sortie parce qu'il suit le geste : imprimer, faire
   signer, confirmer. */
.remise {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-top: 1.25rem;
  padding: 0.95rem 1.15rem;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
}

.remise__indication {
  flex: 1 1 18rem;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--encre-douce);
}

/* Acquise, la remise n'est plus une action ; en attente d'un tirage, elle ne
   l'est pas encore. Ni l'une ni l'autre ne porte d'aplat : un bouton
   suggérerait un acte disponible là où il ne l'est pas. */
.remise--acquise,
.remise--attente,
.remise--sans-document {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--encre-moyenne);
  background: #f7f8fa;
}

/* La fiche doit dire ce que la liste signale (ADR-0019) : le rouge de la colonne
   « Remise » se retrouve ici, faute de quoi le responsable envoyé sur la fiche
   par une ligne rouge y lirait un bloc que rien ne distingue et douterait de la
   liste. */
.remise--sans-document {
  color: var(--refus);
  background: var(--refus-fond);
  border-color: var(--refus);
}

/* ═══ Page publique de vérification ════════════════════════════════════════
   Atteinte au téléphone, par scan. Les trois réponses se ressemblent à dessein :
   rien ne doit distinguer un certificat inconnu d'une demande refusée, sans
   quoi la page devient un oracle (ADR-0004). */

.verification {
  max-width: 32rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3rem) 1.25rem 3rem;
}

.verification__marque {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 1.75rem;
}

/* Le logo est désormais celui du référentiel, téléversé par un administrateur :
   la feuille ne sait plus rien de ses proportions, de son fond ni de ses marges.
   Trois conséquences, toutes tenues ici plutôt que supposées de l'actif.

   `object-fit: contain` : un logo qui n'est pas carré serait autrement étiré. La
   boîte reste carrée pour que la ligne ne se redessine pas d'une enseigne à
   l'autre ; c'est le logo qui s'y inscrit.

   La tuile blanche cesse d'être la conséquence d'un actif à fond opaque pour
   devenir une garantie : une charte au trait sombre et au fond transparent se
   rendrait sur le `--plan` de la page, où elle se lit mal. Le fond posé la place
   sur du papier, quelle que soit la charte.

   54 px, comme avant : c'est la hauteur du nom qu'elle accompagne. Au-delà, la
   vignette écrase l'enseigne au lieu de l'introduire. */
.verification__marque img {
  width: 54px;
  height: 54px;
  object-fit: contain;
  background: var(--papier);
  border-radius: 11px;
}

.verification__marque b {
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--encre);
}

.verification h1 {
  font-family: var(--didone);
  font-size: 1.75rem;
  font-weight: 400;
}

.statut {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.25rem;
  padding: 0.85rem 1rem;
  font-size: 1rem;
  font-weight: 600;
  border-radius: 10px;
}

.statut::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
}

.statut--actif {
  color: var(--valide);
  background: var(--valide-fond);
}

.statut--expire {
  color: var(--attention);
  background: var(--attention-fond);
}

.statut--neutre {
  color: var(--encre-moyenne);
  background: #eef0f3;
}

.verification dl {
  margin-top: 1.5rem;
  background: var(--papier);
  border: 1px solid var(--trait-froid);
  border-radius: 10px;
  overflow: hidden;
}

.verification dt {
  padding: 0.75rem 1rem 0;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.verification dd {
  padding: 0.15rem 1rem 0.75rem;
  font-size: 1rem;
  font-weight: 500;
  border-bottom: 1px solid var(--trait-froid);
}

.verification dd:last-child {
  border-bottom: 0;
}

.verification .chapeau {
  margin-top: 1.5rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--encre-douce);
}

/* ═══ Accueil ══════════════════════════════════════════════════════════════ */

.accueil {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem 1.25rem;
  text-align: center;
  background: var(--marine-950);
  color: rgba(255, 255, 255, 0.6);
}

.accueil img {
  width: 260px;
  height: auto;
  margin: 0 auto 2rem;
}

.accueil h1 {
  font-family: var(--didone);
  font-size: clamp(1.75rem, 3vw, 2.4rem);
  font-weight: 400;
  color: #fff;
}

.accueil p {
  max-width: 44ch;
  margin: 0.9rem auto 0;
  font-size: 0.9375rem;
  line-height: 1.7;
}

.accueil .actions {
  justify-content: center;
  margin-top: 1.75rem;
}

.accueil .principal {
  color: var(--marine-950);
  background: var(--or-400);
}

.accueil .principal:hover {
  background: var(--or-500);
}

.accueil dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.3rem 1.5rem;
  margin: 2.75rem auto 0;
  padding-top: 1.5rem;
  font-size: 0.8125rem;
  text-align: left;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.accueil dt {
  color: rgba(255, 255, 255, 0.42);
}

.accueil dd {
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.78);
}

.hors-production {
  font-weight: 700;
  color: var(--or-400);
}

/* ═══ Adaptations ══════════════════════════════════════════════════════════ */

@media (max-width: 78rem) {
  .travail {
    grid-template-columns: minmax(0, 1fr);
  }

  .apercu {
    order: -1;
  }

  .fiche {
    position: static;
  }
}

@media (max-width: 62rem) {
  .ouverture {
    grid-template-columns: minmax(0, 1fr);
  }

  .panneau {
    min-height: 42vh;
  }

  .manchette {
    margin-top: 2.25rem;
  }

  .assertions {
    display: none;
  }

  /* ── Premier repli du relevé : deux pistes ────────────────────────────────
     Le parti « densifier » est tributaire de la largeur : deux paires côte à côte n'existent
     que s'il reste de la place pour deux paires. Ce qu'il gagne, il le rend ici — c'est une
     propriété du parti retenu, non un défaut à corriger.

     Aucune de ces règles n'est gardée par le contrôle d'appariement de `transport_test.py`,
     qui écarte les `@media` par construction : leur garde est la couture Chromium de
     `hauteur_des_ecrans_test.py`, seule à avoir une fenêtre. */
  .releve--paires {
    grid-template-columns: minmax(8.5rem, auto) minmax(0, 1fr);
  }

  /* Il n'y a plus deux paires à séparer. */
  .releve--paires dt:nth-of-type(2n) {
    border-left: 0;
  }

  /* La première rangée n'est plus celle des quatre premières cellules mais celle des deux
     premières : les deux suivantes reprennent le filet qui ouvre la seconde rangée. */
  .releve--paires > :nth-child(-n + 4) {
    border-top: 1px solid var(--trait-froid);
  }

  .releve--paires > :nth-child(-n + 2) {
    border-top: 0;
  }
}

@media (max-width: 46rem) {
  .champ,
  .champ--cinq,
  .champ--sept {
    grid-column: span 12;
  }

  .bilan .separateur,
  .touche {
    display: none;
  }

  .rail__acteur span,
  .rail__fil {
    display: none;
  }
}

/* ── Second repli du relevé : une piste ─────────────────────────────────────
   La paire elle-même ne tient plus : le libellé passe au-dessus de sa valeur, et le vendeur
   lit une fiche et non une grille comprimée. Le relevé redevient alors l'empilement de onze
   rangées qu'il corrigeait sur le poste de caisse ; la spécification l'assume.

   Cette bascule vivait à 46 rem, où elle avait été reprise du témoin. Elle est portée ici à
   son seuil — 40 rem, celui de la maquette de référence —, et sur le modificateur : le seul
   relevé que le service rende est celui en paires, et une règle qui n'apparie rien est le code
   mort que ce chantier a entrepris de bannir. */
@media (max-width: 40rem) {
  .releve--paires {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Le libellé perd sa respiration basse et la valeur son filet haut : les deux deviennent un
     même bloc. Un trait entre eux les ferait lire comme deux rangées distinctes. */
  .releve--paires dt {
    padding-bottom: 0;
  }

  /* Les valeurs sont les cellules de rang pair. C'est une formule de rang, et non
     `.releve--paires dd`, parce qu'il lui faut l'emporter sur le filet rétabli plus haut pour
     la seconde rangée : à une piste, la quatrième cellule est une valeur et non une rangée. */
  .releve--paires > :nth-child(2n) {
    border-top: 0;
  }

  /* Il n'y a plus de piste de libellé à sauter. Sans cette règle, la valeur viserait encore la
     seconde piste et en créerait une **implicite** : le relevé reprendrait deux colonnes que
     le style calculé de la grille ne montre même pas. */
  .releve__large {
    grid-column: 1 / -1;
  }
}

/* Sous 34 rem, le libellé de la mention exceptionnelle et sa phrase ne tiennent plus sur une
   ligne. Le libellé prend la largeur entière pour que la phrase passe dessous : les laisser se
   partager la ligne comprimerait la phrase sur une laisse de deux mots. */
@media (max-width: 34rem) {
  .mentions p {
    flex-wrap: wrap;
    gap: 0.1rem 0.7rem;
  }

  .mentions b {
    flex-basis: 100%;
  }
}
