/*
 * Sama Control — Le Guichet.
 *
 * Une affaire à la fois. Un écran, une décision, deux boutons.
 *
 * Hérite du thème de l'app vendeur (apps/vendor/lib/theme.dart) : vert #0F7A4D,
 * blanc, arrondi 16. C'est déjà la couleur de la marque — le favicon de la
 * boutique acheteur est ce vert. L'équipe qui regarde la console et celle qui
 * regarde l'app vendeur sont les mêmes personnes.
 *
 * Trois valeurs sont partagées avec les deux autres surfaces et ne se
 * renégocient pas ici : cible 56 px, unité d'espacement 16, colonne 560.
 * Voir apps/buyer/public/app.css:17 et apps/vendor/lib/adaptation.dart:42.
 */

@font-face {
  font-family: Fig;
  font-weight: 300 900;
  font-display: swap;
  src: url(/figtree-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074,
                 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Le wolof a besoin de ŋ (U+014A/014B), hors du sous-ensemble latin. */
@font-face {
  font-family: Fig;
  font-weight: 300 900;
  font-display: swap;
  src: url(/figtree-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02AF, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF;
}

:root {
  --vert: #0F7A4D; --vert-fonce: #0A5334; --vert-doux: #E8F4EE;
  --encre: #12100E; --encre-douce: #57534E;
  --trait: #E0DCD5; --fond-doux: #F4F2EE;
  --alerte: #B3261E; --alerte-douce: #FDECEA;
  --or: #9A5D06; --or-doux: #FBF3E3;
  --r: 16px; --cible: 56px; --m: 16px;
}

* { box-sizing: border-box }
html { font-size: 17px; -webkit-text-size-adjust: 100% }
body {
  margin: 0; background: #fff; color: var(--encre);
  font-family: Fig, system-ui, sans-serif; line-height: 1.5;
  font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased;
}
::selection { background: var(--vert-doux); color: var(--vert-fonce) }
:focus-visible { outline: 2.5px solid var(--vert); outline-offset: 3px; border-radius: 4px }
svg {
  width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; flex: none;
}
a { color: var(--vert-fonce) }

.page { max-width: 900px; margin: 0 auto; padding: 0 var(--m) }

/* ─── la colonne de navigation ──────────────────────────────────────────── */
/*
 * Elle était en haut. Une barre horizontale coûte sa hauteur sur CHAQUE
 * écran, et la console se lit longtemps : ces soixante-quatre pixels
 * manquaient à la file, au journal, à la liste des boutiques. En colonne,
 * elle occupe une largeur dont une page de 900 px n'avait pas l'usage.
 */
body { display: flex; align-items: flex-start; min-height: 100vh }
/* `min-width: 0` : sans lui, un tableau large pousserait la colonne de
   contenu au-delà de l'écran au lieu de se replier. */
.colonne { flex: 1; min-width: 0 }

.barre {
  flex: none; width: 248px;
  /* Collante sur toute la hauteur : la navigation reste atteignable au bas
     d'un journal de deux cents lignes. */
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column; gap: 24px;
  padding: 24px 14px 16px;
  border-right: 1px solid var(--trait); background: #fff; z-index: 9;
}
.marque {
  font-weight: 800; letter-spacing: -.03em; font-size: 1.12rem;
  padding: 0 10px; text-decoration: none; color: inherit;
}
.marque em { font-style: normal; color: var(--vert) }

.barre nav { display: flex; flex-direction: column; gap: 2px }
/* Jamais d'icône seule : toujours l'icône ET le mot (PRODUCT.md). */
.barre nav a {
  display: flex; align-items: center; gap: 11px; padding: 11px 12px; border-radius: 12px;
  text-decoration: none; color: var(--encre-douce); font-weight: 600; font-size: .98rem;
}
.barre nav a svg { width: 21px; height: 21px; flex: none }
.barre nav a:hover { background: var(--fond-doux); color: var(--encre) }
.barre nav a[aria-current] { background: var(--vert-doux); color: var(--vert-fonce); font-weight: 700 }

/* L'identité descend en bas, détachée par un filet : « Sortir » n'est pas une
   destination, et le voir au milieu des onglets invitait à le cliquer. */
.qui {
  margin-top: auto; display: flex; align-items: center; gap: 10px;
  padding: 14px 8px 0; border-top: 1px solid var(--trait);
}
.qui .ini { width: 36px; height: 36px; font-size: .82rem }
.qui-nom { min-width: 0; flex: 1 }
.qui-nom strong { display: block; font-size: .9rem; font-weight: 700;
                  white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.qui-nom > span { display: block; font-size: .78rem; color: var(--encre-douce) }
.qui form { display: contents }
.qui button {
  background: none; border: 0; padding: 6px 4px; font: inherit; font-size: .84rem;
  color: var(--encre-douce); text-decoration: underline; cursor: pointer; flex: none;
}
.qui button:hover { color: var(--alerte) }

/* ─── titres ─────────────────────────────────────────────────────────────── */
.compte { margin: 38px 0 6px; font-size: clamp(2.2rem, 7vw, 3.2rem); font-weight: 800;
          letter-spacing: -.04em; line-height: 1 }
.compte-sous { margin: 0 0 32px; color: var(--encre-douce); font-size: 1.05rem }
h2.section { margin: 44px 0 14px; font-size: 1.35rem; font-weight: 800; letter-spacing: -.025em }

/* Les filtres étaient des liens en ligne séparés par une marge. Sans espace
   entre eux dans le HTML, le navigateur n'a AUCUN point de coupure : la rangée
   est un seul mot, et à 200 % elle sortait de l'écran. Un conteneur flex qui
   se replie règle la cause au lieu du symptôme. */
.onglets { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0 0 32px }
.onglets a { color: var(--encre-douce); text-decoration: none; padding: 6px 0;
             border-bottom: 2px solid transparent }
.onglets a:hover { color: var(--encre) }
.onglets a[aria-current] { color: var(--vert-fonce); font-weight: 700;
                           border-bottom-color: var(--vert) }

/* ─── la file ────────────────────────────────────────────────────────────── */
.file { display: flex; flex-direction: column }
.affaire {
  display: flex; align-items: center; gap: 18px; padding: 20px 2px;
  border-top: 1px solid var(--trait); text-align: left; text-decoration: none; color: inherit;
}
.affaire:last-child { border-bottom: 1px solid var(--trait) }
.affaire:hover { background: var(--fond-doux) }
.pastille { width: 46px; height: 46px; border-radius: var(--r); display: flex;
            align-items: center; justify-content: center; font-size: 21px; flex: none }
.p-attente { background: var(--or-doux); color: var(--or) }
.p-argent { background: var(--alerte-douce); color: var(--alerte) }
.p-direct { background: var(--vert-doux); color: var(--vert) }
.affaire .quoi { min-width: 0; flex: 1 }
.affaire .quoi strong { display: block; font-size: 1.12rem; font-weight: 700; letter-spacing: -.01em }
.affaire .quoi span { display: block; color: var(--encre-douce); font-size: .95rem; margin-top: 2px }
.affaire .depuis { color: var(--encre-douce); font-size: .9rem; white-space: nowrap }
.affaire .fleche { color: var(--vert); font-size: 20px; flex: none }

.vide { margin: 28px 0; padding: 34px 26px; border-radius: var(--r); background: var(--vert-doux);
        color: var(--vert-fonce); text-align: center }
.vide strong { display: block; font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em }
.vide span { color: var(--encre-douce) }

.note { margin-top: 32px; background: var(--fond-doux); border-radius: var(--r);
        padding: 18px 20px; color: var(--encre-douce); font-size: .95rem; line-height: 1.6 }
.note strong { color: var(--encre) }

/* ─── un dossier ─────────────────────────────────────────────────────────── */
.dossier { border: 2px solid var(--trait); border-radius: var(--r); overflow: hidden; margin-top: 28px }
.dossier > header { padding: 24px 26px 20px; border-bottom: 2px solid var(--trait) }
.dossier h1 { margin: 0 0 4px; font-size: 1.8rem; font-weight: 800; letter-spacing: -.03em }
.dossier header p { margin: 0; color: var(--encre-douce) }
.corps { padding: 24px 26px }

.etat { display: inline-flex; align-items: center; gap: 7px; font-size: .82rem; font-weight: 700;
        padding: 6px 12px; border-radius: 999px; margin-bottom: 10px }
.et-pending { background: var(--or-doux); color: var(--or) }
.et-verified { background: var(--vert-doux); color: var(--vert-fonce) }
.et-restricted, .et-suspended { background: var(--alerte-douce); color: var(--alerte) }

.faits { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
         gap: 20px 28px; margin: 0 0 26px }
.faits > div > span { display: block; font-size: .78rem; font-weight: 700; letter-spacing: .09em;
                      text-transform: uppercase; color: var(--encre-douce); margin-bottom: 4px }
.faits > div > b { font-size: 1.08rem; font-weight: 600; letter-spacing: -.01em }
.faits b.absent { color: var(--alerte); font-weight: 700 }

/* ─── formulaires ────────────────────────────────────────────────────────── */
label.eti { display: block; font-size: .82rem; font-weight: 700; letter-spacing: .06em;
            text-transform: uppercase; color: var(--encre-douce); margin-bottom: 8px }
input, textarea, select {
  width: 100%; font: inherit; color: inherit; background: #fff;
  border: 2px solid var(--trait); border-radius: var(--r); padding: 14px 16px;
  min-height: var(--cible);
}
textarea { min-height: 92px; resize: vertical; line-height: 1.55 }
input:focus, textarea:focus, select:focus { border-color: var(--vert); outline-offset: 1px }
.aide { margin: 8px 0 0; font-size: .88rem; color: var(--encre-douce) }
/* ⚠ `minmax(0, 1fr)` et non `1fr` ni `auto`. Une piste de grille a pour
   minimum le max-content de ses enfants : la rangée de boutons imposait sa
   largeur naturelle à TOUTE la grille, labels et champs compris. Invisible
   tant qu'il y avait du mou — mesuré le 2026-10-30 dans un tiroir de 390 px,
   où les lignes faisaient 432 et débordaient de 98. */
.champs { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; margin-bottom: 22px }
.deux { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px }

.gestes { display: flex; gap: 14px; padding: 20px 26px; border-top: 2px solid var(--trait);
          background: var(--fond-doux); flex-wrap: wrap }
.bouton {
  flex: 1; min-width: 210px; min-height: var(--cible); border-radius: var(--r); border: 2px solid;
  display: flex; align-items: center; justify-content: center; gap: 10px; cursor: pointer;
  font-family: inherit; font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
  text-decoration: none; padding: 0 20px;
}
.b-oui { background: var(--vert); border-color: var(--vert); color: #fff }
.b-oui:hover { background: var(--vert-fonce); border-color: var(--vert-fonce) }
.b-non { background: #fff; border-color: var(--trait); color: var(--alerte) }
.b-non:hover { border-color: var(--alerte) }
.b-neutre { background: #fff; border-color: var(--trait); color: var(--encre) }
button:disabled { opacity: .5; cursor: not-allowed }

/* ─── annonces ───────────────────────────────────────────────────────────── */
.annonce { margin: 20px 0; padding: 16px 20px; border-radius: var(--r); border: 2px solid;
           font-weight: 600; display: flex; align-items: flex-start; gap: 12px }
.a-ok { background: var(--vert-doux); border-color: var(--vert); color: var(--vert-fonce) }
.a-mal { background: var(--alerte-douce); border-color: var(--alerte); color: var(--alerte) }
.annonce span { font-weight: 400; display: block; color: var(--encre-douce); margin-top: 3px }

/* ─── gens ───────────────────────────────────────────────────────────────── */
.gens { border: 2px solid var(--trait); border-radius: var(--r); overflow: hidden; margin-top: 24px }
.gens > header { display: flex; align-items: center; gap: 14px; padding: 20px 24px;
                 border-bottom: 2px solid var(--trait) }
.gens h2 { margin: 0; font-size: 1.4rem; font-weight: 800; letter-spacing: -.025em }
.gens > header span { color: var(--encre-douce); font-size: .95rem }
.personne { display: flex; align-items: center; gap: 16px; padding: 16px 24px;
            border-bottom: 1px solid var(--trait); flex-wrap: wrap }
.personne:last-of-type { border-bottom: 0 }
.personne.partie { opacity: .55 }
.ini { width: 46px; height: 46px; border-radius: var(--r); background: var(--vert-doux);
       color: var(--vert-fonce); display: flex; align-items: center; justify-content: center;
       font-weight: 800; font-size: 1rem; flex: none }
.personne .qui2 { flex: 1; min-width: 160px }
.personne .qui2 strong { display: block; font-size: 1.06rem; font-weight: 700 }
.personne .qui2 span { display: block; color: var(--encre-douce); font-size: .92rem }
.role { font-size: .82rem; font-weight: 700; padding: 6px 12px; border-radius: 999px; white-space: nowrap }
.r-owner { background: var(--vert-doux); color: var(--vert-fonce) }
.r-autre { background: var(--fond-doux); color: var(--encre-douce) }
.ajouter { padding: 20px 24px; border-top: 2px solid var(--trait); background: var(--fond-doux) }
details > summary { cursor: pointer; font-weight: 700; padding: 8px 0; list-style: none }
details > summary::-webkit-details-marker { display: none }
details > summary::before { content: '+ '; color: var(--vert); font-weight: 800 }
details[open] > summary::before { content: '– ' }

/* ─── argent ─────────────────────────────────────────────────────────────── */
.chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
            gap: 26px; margin: 28px 0 32px }
.chiffres span { display: block; font-size: .8rem; font-weight: 700; letter-spacing: .09em;
                 text-transform: uppercase; color: var(--encre-douce); margin-bottom: 6px }
/* Les chiffres sont les plus gros éléments de leur écran (PRODUCT.md). */
.chiffres b { font-size: clamp(1.7rem, 4.4vw, 2.4rem); font-weight: 800; letter-spacing: -.04em;
              line-height: 1; display: block;
              /* Sans ceci, « 203 600 » et son « F » se séparent sur deux lignes :
                 le franc n'est pas une légende, il fait partie du nombre. */
              white-space: nowrap }
/* `display: inline` n'est pas décoratif : la règle `.chiffres span` au-dessus
   met TOUS les spans en bloc pour styler les étiquettes, et attrapait aussi le
   « F ». Le franc partait à la ligne, en petites capitales grises — il avait
   l'air d'une légende au lieu d'appartenir au nombre. Aucun `nowrap` ne pouvait
   rattraper ça : un bloc ne se replie pas, il descend. */
.chiffres b .f { display: inline; font-size: .44em; font-weight: 600; letter-spacing: 0;
                 text-transform: none; margin: 0; color: var(--encre-douce) }
.chiffres .pas-tranche { font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em;
                         color: var(--encre-douce); white-space: normal }
/* Zéro remboursement est une bonne nouvelle : la couleur d'alerte mentirait. */
.chiffres b.rien { color: var(--encre-douce) }

.liste { border-top: 1px solid var(--trait) }
.bq { display: flex; align-items: center; gap: 16px; padding: 16px 2px;
      border-bottom: 1px solid var(--trait); text-decoration: none; color: inherit; flex-wrap: wrap }
.bq:hover { background: var(--fond-doux) }
.bq strong { flex: 1; font-weight: 600; min-width: 140px }
.bq .n { font-weight: 700; letter-spacing: -.02em; white-space: nowrap }
.bq .doux { color: var(--encre-douce); font-weight: 600 }
.ecart { background: var(--alerte-douce); color: var(--alerte); font-size: .82rem; font-weight: 700;
         padding: 5px 11px; border-radius: 999px; white-space: nowrap }

.aregler { margin-top: 32px; border: 2px solid var(--alerte); border-radius: var(--r); overflow: hidden }
.aregler > header { padding: 16px 22px; background: var(--alerte-douce); color: var(--alerte);
                    font-weight: 800; font-size: 1.05rem; letter-spacing: -.01em }
.aregler .ligne { display: flex; align-items: center; gap: 16px; padding: 16px 22px;
                  border-top: 1px solid var(--trait); flex-wrap: wrap }
.aregler .ligne strong { display: block }
.aregler .ligne span { display: block; color: var(--encre-douce); font-size: .9rem }
.aregler .ligne .n { margin-left: auto; font-weight: 800; letter-spacing: -.02em;
                     color: var(--or); white-space: nowrap }

/* ─── journal ────────────────────────────────────────────────────────────── */
.trace { border-top: 1px solid var(--trait); padding: 14px 2px; display: grid;
         grid-template-columns: 150px 1fr; gap: 4px 20px }
.trace time { color: var(--encre-douce); font-size: .9rem }
.trace .quoi2 strong { font-weight: 700 }
.trace .motif { color: var(--encre-douce); font-size: .94rem; grid-column: 2 }

/* ─── entrer ─────────────────────────────────────────────────────────────── */
.entrer { max-width: 440px; margin: 10vh auto 0; padding: 0 var(--m) }
.entrer h1 { font-size: 2.1rem; font-weight: 800; letter-spacing: -.03em; margin: 0 0 8px }
.entrer h1 em { font-style: normal; color: var(--vert) }
.entrer > p { color: var(--encre-douce); margin: 0 0 28px }
.entrer .bouton { width: 100% }
/* Le QR est rendu par le serveur et servi dans un `img` en data-URI.
   Pas de script, pas de requête distante, le secret ne quitte pas la page.
 
   Et surtout : À L'INTÉRIEUR D'UN `img`, LE CSS DE LA PAGE N'ENTRE PAS.
   C'est la raison du choix. En SVG inline, la règle globale des icônes
   (`svg { fill:none; stroke:currentColor; stroke-width:1.8 }`) s'appliquait au
   QR — dont les modules sont tracés en épaisseur 1. À 1,8 ils se touchent, les
   trois repères d'angle disparaissent, et le code devient un carré noir
   illisible. Aucune application n'aurait pu le scanner, et la personne aurait
   accusé son téléphone. */
.qr { background: #fff; border: 2px solid var(--trait); border-radius: var(--r);
      padding: 14px; display: block; margin: 0 auto;
      width: 100%; max-width: 258px; height: auto }
/* La clé en clair, pour qui ne peut pas scanner. Groupée par quatre : on la
   recopie à la main, et vingt-six caractères d'affilée se perdent. */
.secret { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
          font-size: 1.02rem; letter-spacing: .06em; word-break: break-all;
          background: var(--fond-doux); border-radius: 10px; padding: 12px 14px; margin: 0 }

/* ─── en dessous de 900 px : la colonne passe en bas ─────────────────────
 *
 * Une colonne latérale sur un téléphone mange la moitié de la largeur. Et la
 * console n'embarque aucun JavaScript : pas de tiroir qui s'ouvre, pas de
 * bouton hamburger. Le repli honnête est une barre BASSE — atteignable au
 * pouce, et c'est déjà le geste de l'app vendeur.
 *
 * La marque disparaît : sur un écran de six cents pixels, savoir qu'on est
 * dans Sama Control coûte moins cher que de voir une entrée de plus. */
@media (max-width: 900px) {
  body { display: block }
  .barre {
    position: fixed; inset: auto 0 0 0; width: auto; height: auto;
    flex-direction: row; gap: 0; z-index: 20;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
    border-right: 0; border-top: 1px solid var(--trait);
  }
  .barre .marque { display: none }
  .barre nav { flex-direction: row; flex: 1; gap: 0 }
  .barre nav a {
    flex: 1; min-width: 0; flex-direction: column; gap: 3px; padding: 7px 2px;
    font-size: .7rem; text-align: center; border-radius: 10px;
  }
  .barre nav a span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100% }
  /* Le bloc d'identité devient une cellule comme les autres : les initiales
     tiennent lieu d'icône, et le mot « Sortir » reste écrit — une pastille
     seule serait une icône sans texte. */
  .qui {
    margin: 0; flex: none; flex-direction: column; gap: 3px;
    padding: 7px 8px; border-top: 0; border-left: 1px solid var(--trait);
  }
  .qui .ini { width: 22px; height: 22px; font-size: .62rem; border-radius: 7px }
  .qui-nom { display: none }
  .qui button { font-size: .7rem; padding: 0; text-decoration: none }
  /* La hauteur de la barre basse, rendue au contenu : sans quoi le dernier
     élément de chaque page se cache dessous. */
  .colonne { padding-bottom: 84px }
}

@media (max-width: 620px) {
  /* La ligne se replie en deux : le fait, puis l'ancienneté. Le chevron
     restait seul sur une troisième ligne, sous le texte, et ressemblait à un
     bouton cassé — alors que toute la ligne est déjà cliquable. */
  .affaire { flex-wrap: wrap }
  .affaire .quoi { flex-basis: calc(100% - 64px) }
  .affaire .depuis { width: 100%; padding-left: 64px; order: 3 }
  .affaire .fleche { display: none }
  .deux { grid-template-columns: 1fr }
  .trace { grid-template-columns: 1fr }
  .trace .motif { grid-column: 1 }
}

/* ─── observer un vendeur ─────────────────────────────────────────────────
 *
 * Le bandeau est la pièce la plus importante de l'écran, et la seule qu'on ne
 * doit jamais pouvoir perdre de vue. Collant en haut, de la couleur de
 * l'attente et non de l'erreur : regarder chez quelqu'un n'est pas une panne,
 * c'est un état qu'on oublie. Il porte sa propre sortie — si « arrêter »
 * demandait de retrouver un écran, personne n'arrêterait. */
.observe {
  position: sticky; top: 0; z-index: 20;
  background: var(--or); color: #fff;
  /* Le trait sombre évite que le bandeau se confonde avec un en-tête de page
     quand la barre de navigation est juste au-dessus. */
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .18);
}
/* La colonne est celle de `.page`, réutilisée et non recopiée : le bandeau
   doit s'aligner sur le texte qu'il surplombe. */
.observe > .page { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 12px var(--m) }
.observe p { margin: 0; display: flex; align-items: center; gap: 12px; flex: 1; min-width: 220px }
.observe svg { width: 22px; height: 22px; flex: none }
.observe strong { display: block; font-weight: 800; letter-spacing: -.01em }
.observe p > span > span { display: block; font-size: .88rem; opacity: .92; font-weight: 500 }
.observe-gestes { display: flex; align-items: center; gap: 10px; flex: none }
.observe-gestes a, .observe-gestes button {
  font: inherit; font-weight: 700; font-size: .92rem; cursor: pointer;
  padding: 10px 16px; border-radius: 999px; border: 2px solid rgba(255, 255, 255, .55);
  background: transparent; color: #fff; text-decoration: none; white-space: nowrap;
}
.observe-gestes button { background: #fff; color: var(--or); border-color: #fff }
.observe-gestes a:hover { background: rgba(255, 255, 255, .16) }
.observe-gestes form { display: contents }

.observer { margin-top: 22px; border: 2px dashed var(--trait); border-radius: var(--r); padding: 16px 20px }
.observer > summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  font-weight: 700; color: var(--encre-douce);
}
.observer > summary svg { width: 20px; height: 20px }
.observer[open] { border-color: var(--or); border-style: solid }
.observer[open] > summary { color: var(--or); margin-bottom: 12px }

/* Le bandeau passe en colonne quand les deux blocs ne tiennent plus côte à
   côte : les gestes y restent accessibles au pouce plutôt que comprimés. */
@media (max-width: 620px) {
  .observe > .page { align-items: flex-start }
  .observe-gestes { width: 100% }
  .observe-gestes a, .observe-gestes button { flex: 1; text-align: center }
}

/* Une ligne de liste en deux temps : le nom, puis l'état et le montant.
   Sans cela l'enroulement dépend de la longueur du libellé — « retournée »
   tient sur la ligne, « en attente de paiement » non — et deux lignes voisines
   n'ont pas la même forme. Une liste qu'on parcourt du regard a besoin que
   toutes ses lignes se ressemblent. */
@media (max-width: 560px) {
  .bq strong { flex: 1 0 100%; min-width: 0 }
  .bq .n:last-child { margin-left: auto }
}

/* ─── règles reprises des attributs `style` ───────────────────────────────────
 *
 * Elles vivaient en ligne dans les gabarits. La console n'avait pas encore de
 * CSP ; en lui en donnant une (`style-src 'self'`), chacune de ces règles
 * serait tombée en silence — c'est exactement ce qui arrivait à la boutique
 * acheteur depuis le premier jour, sans que personne ne le voie.
 *
 * Trois valeurs arbitraires ont été ramenées à une : les boutons courts
 * mesuraient 260, 320 et 340 px selon l'écran, et les formulaires dépliés
 * 260 ou 280. Une console se parcourt du regard ; trois largeurs pour la même
 * chose se remarquent sans qu'on sache dire pourquoi. */

/* Un paragraphe qui ne porte qu'un lien de navigation. */
.lien-seul { margin: 26px 0 0 }
.lien-seul a { display: inline-flex; align-items: center; gap: 8px;
               text-decoration: none; font-weight: 600 }

/* Le titre d'une annonce hérite de la couleur de l'annonce, pas de la page. */
.annonce-titre { font-weight: 700; color: inherit }

/* Ce qu'on dit à qui n'a pas le droit de décider. */
.gestes p { margin: 0; color: var(--encre-douce) }

/* Un dépliant qui ouvre un geste dangereux l'annonce par sa couleur. */
summary.alerte { color: var(--alerte) }

/* Le formulaire à l'intérieur d'un dépliant. */
details .champs { margin-top: 12px; min-width: 280px }

/* Le pied d'une liste de personnes : celles qu'on a retirées. */
.retires { padding: 14px 24px; border-top: 1px solid var(--trait) }

/* Un bouton qui ne prend pas toute la largeur : une seule mesure. */
.bouton.court { max-width: 340px }

/* Dans une ligne de liste, la pastille d'état n'a pas à pousser ses voisines. */
.bq .etat { margin: 0 }
.bq .fleche { color: var(--vert) }

/* Une étiquette qui signale une attente plutôt qu'un fait acquis. */
.role.attente { background: var(--or-doux); color: var(--or) }

/* L'écran d'erreur, centré bas dans la page plutôt que collé en haut. */
.haut-page { margin-top: 12vh }
.espace { margin-top: 22px }
/* Le motif sous le nom d'un opérateur, dans l'historique des passages. */
.motif-passage { display: block; font-weight: 400; font-size: .9rem; color: var(--encre-douce) }
/* Un montant qui doit alerter : du remboursement, pas de la recette. */
.chiffres b.alerte { color: var(--alerte) }

/* ─── « ce que vous pouvez faire ici » ───────────────────────────────────────
 *
 * Replié par défaut, déplié tant que la personne n'a rien décidé. Ce n'est pas
 * un tutoriel : un tutoriel se ferme et ne revient jamais, alors que la
 * question « où est-ce que je règle ça déjà ? » revient au bout de trois
 * semaines. Un dépliant reste, et ne coûte une ligne qu'à ceux qui savent. */
.orientation { margin: 0 0 34px; border: 2px solid var(--trait); border-radius: var(--r) }
.orientation > summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 16px 20px; font-weight: 700; color: var(--encre);
}
.orientation > summary svg { width: 20px; height: 20px; color: var(--vert) }
.orientation[open] > summary { border-bottom: 1px solid var(--trait) }
.orientation-corps { padding: 18px 20px 20px; font-size: .98rem; line-height: 1.6 }
.orientation-corps > p { margin: 0 0 12px; color: var(--encre-douce) }
.orientation-corps > p strong { color: var(--encre) }

.orientation-plan { margin: 20px 0 0; display: grid; grid-template-columns: auto 1fr; gap: 10px 18px }
.orientation-plan dt { font-weight: 700; white-space: nowrap }
.orientation-plan dd { margin: 0; color: var(--encre-douce) }

.orientation-debut {
  margin: 22px 0 0 !important; padding: 14px 16px;
  background: var(--vert-doux); border-radius: 12px; color: var(--vert-fonce) !important;
}
.orientation-debut strong { color: inherit !important }

/* Le sous-titre d'une section, collé à son titre. */
.sous-titre-section { margin: -8px 0 14px }

/* Ce que la ligne attend de vous, avant les faits qui la décrivent. */
.quoi-faire { color: var(--vert-fonce); font-weight: 700 }

@media (max-width: 620px) {
  .orientation-plan { grid-template-columns: 1fr; gap: 2px 0 }
  .orientation-plan dd { margin: 0 0 12px }
}
/* Ce que le bouton va faire, à côté du bouton — pas dans une note de bas de
   page que personne ne lit avant d'avoir cliqué. */
.gestes-quoi { margin: 0 0 4px; flex: 1 0 100%; color: var(--encre-douce); font-size: .95rem; line-height: 1.55 }

/* ─── le design porte le sens, pas la prose ─────────────────────────────────
 *
 * Neuf pavés gris expliquaient ce que les écrans faisaient. Ils sont partis :
 * un écran qui a besoin d'un paragraphe n'est pas compris, il est documenté.
 * Ce qu'ils disaient vit maintenant dans les mots des boutons, dans les noms
 * des états, et dans ce qui suit. */

/* L'état se lit AVANT son mot : un point de couleur, puis le texte. Pour qui
   parcourt une liste de trente boutiques, la couleur arrive à l'œil une
   fixation avant la lecture. */
.etat::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; flex: none;
}

/* Les chiffres qu'on compare s'alignent en colonne. Sans cela, « 1 » et « 8 »
   n'ont pas la même largeur et une liste de montants ondule. */
.bq .n, .faits b, .affaire .depuis, .aregler .n, .personne .qui2 span,
.trace, .liste .n { font-variant-numeric: tabular-nums }

/* ─── les surfaces que le navigateur dessine à notre place ───────────────── */
html { scrollbar-color: var(--trait) transparent; scrollbar-width: thin }
::-webkit-scrollbar { width: 12px; height: 12px }
::-webkit-scrollbar-thumb {
  background: var(--trait); border-radius: 99px; border: 3px solid #fff;
}
::-webkit-scrollbar-thumb:hover { background: var(--encre-douce) }
::-webkit-scrollbar-track { background: transparent }
/* Le curseur de saisie et les contrôles natifs prennent la couleur de marque :
   une case à cocher bleu système dans une console verte se remarque sans
   qu'on sache dire pourquoi. */
input, textarea, select { caret-color: var(--vert) }
:root { accent-color: var(--vert) }

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

/* ─── l'en-tête d'un dossier annonce son état ───────────────────────────────
 *
 * La pastille flottait au-dessus du nom, de la taille d'une étiquette. Une
 * boutique qui ne vend pas est la chose la plus importante de cet écran : la
 * teinte prend tout l'en-tête, et on le sait avant d'avoir lu. */
.dossier > header { position: relative }
.dossier > header::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: currentColor; opacity: .13;
}
.dossier > header > * { position: relative }
.dossier.d-pending > header { color: var(--or) }
.dossier.d-verified > header { color: var(--vert) }
.dossier.d-restricted > header,
.dossier.d-suspended > header { color: var(--alerte) }
.dossier h1, .dossier header p { color: var(--encre) }
.dossier header p { color: var(--encre-douce) }

/* ─── la file : ce qui attend une décision a du poids ─────────────────────── */
.affaire { border-radius: 14px; padding: 20px 16px; transition: background .12s ease-out }
.affaire:hover { background: var(--fond-doux) }
.affaire .fleche { opacity: .45; transition: opacity .12s ease-out, transform .12s ease-out }
.affaire:hover .fleche { opacity: 1; transform: translateX(2px) }

/* Plus d'air AU-DESSUS d'un titre qu'en dessous : il appartient à ce qui
   suit, pas à ce qui précède. */
h2.section { margin: 52px 0 12px }

/* Une pastille d'état posée dans une ligne de liste : plus petite, sans la
   marge qu'elle porte en tête de dossier. */
.affaire .etat { margin: 0 6px 0 0; padding: 3px 9px; font-size: .76rem; vertical-align: 1px }
.affaire .quoi strong { font-size: 1.16rem }

/* Le compteur de la file, dans la navigation. Il ne paraît que s'il y a
   quelque chose : un zéro en pastille est du bruit qui apprend qu'il n'y a
   rien. */
.compteur {
  margin-left: auto; min-width: 22px; height: 22px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--or); color: #fff; border-radius: 999px;
  font-size: .78rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
@media (max-width: 900px) {
  /* En barre basse, il se pose sur l'icône plutôt que d'allonger la cellule. */
  .barre nav a { position: relative }
  .compteur { position: absolute; top: 2px; left: 50%; margin: 0;
              transform: translateX(2px); min-width: 18px; height: 18px; font-size: .68rem }
}
/* Le geste d'observation, pris ailleurs. Le contrôle reste à sa place et dit
   pourquoi il ne s'ouvre pas — un bouton qui disparaît sans rien laisse
   chercher ce qu'on a mal fait. */
.observer-pris {
  display: flex; align-items: center; gap: 10px;
  color: var(--encre-douce); font-weight: 600; cursor: not-allowed;
}
.observer-pris svg { width: 20px; height: 20px; opacity: .6 }
.observer-pris strong { color: var(--or) }

/* ─── l'écran des boutiques ─────────────────────────────────────────────────
 *
 * Le formulaire de création vivait sous la liste, visible en permanence. Deux
 * métiers sur un écran, et le plus rare occupait la moitié de la hauteur. Il
 * a le sien ; ici il ne reste qu'un bouton. */

/* Un titre et son geste principal, sur la même ligne. */
.titre-geste { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap }
/* `> :first-child` et non `> div` : la règle ne s'appliquait qu'au grand
   titre de page, et pas quand c'est un `h2` qui ouvre la ligne — le bouton
   s'étalait alors sur toute la largeur restante. */
.titre-geste > :first-child { flex: 1; min-width: 200px }
.titre-geste .compte { margin-bottom: 4px }
.titre-geste .compte-sous { margin-bottom: 0 }
.titre-geste .bouton { width: auto; margin-bottom: 6px }

/* La recherche. Un `form` en GET : pas de JavaScript, et l'URL porte l'état —
   un résultat se colle dans une conversation et s'ouvre tel quel. */
.chercher {
  display: flex; align-items: center; gap: 8px; position: relative;
  margin: 26px 0 22px;
}
.chercher-icone {
  position: absolute; left: 15px; top: 50%; transform: translateY(-50%);
  color: var(--encre-douce); display: flex; pointer-events: none;
}
.chercher-icone svg { width: 19px; height: 19px }
.chercher input {
  flex: 1; min-width: 0; height: var(--cible); padding: 0 16px 0 44px;
  border: 2px solid var(--trait); border-radius: 999px; background: #fff;
  font: inherit; font-size: 1rem; color: var(--encre);
}
.chercher input::placeholder { color: var(--encre-douce) }
.chercher input:focus { border-color: var(--vert) }
.chercher button {
  flex: none; height: var(--cible); padding: 0 22px; border: 0; border-radius: 999px;
  background: var(--encre); color: #fff; font: inherit; font-weight: 700; cursor: pointer;
}
.chercher button:hover { background: var(--vert-fonce) }
.chercher-vider { flex: none; color: var(--encre-douce); font-weight: 600; text-decoration: underline }

/* La liste, en colonnes alignées. L'ancienne rangée était un flex élastique :
   les nombres n'étaient jamais au même endroit d'une ligne à l'autre, et
   l'œil devait les chercher au lieu de les descendre. */
.tableau { border-top: 1px solid var(--trait) }
.rangee {
  display: grid; align-items: center; gap: 0 18px;
  grid-template-columns: minmax(0, 1fr) 148px 78px 78px 22px;
  padding: 16px 14px; border-bottom: 1px solid var(--trait);
  text-decoration: none; color: inherit; border-radius: 12px;
  transition: background .12s ease-out;
}
.rangee:hover { background: var(--fond-doux) }
.rangee-nom { min-width: 0 }
.rangee-nom strong { display: block; font-size: 1.08rem; font-weight: 700; letter-spacing: -.01em }
.rangee-nom > span {
  display: block; margin-top: 2px; font-size: .88rem; color: var(--encre-douce);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ② Les pastilles s'alignent à GAUCHE de leur colonne : sinon leurs points
   de couleur se décalent d'une ligne à l'autre selon la longueur du mot, et
   le repère qu'ils sont censés offrir se perd. */
.rangee .etat { margin: 0; justify-self: start }
.rangee-n { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums }
.rangee-n > span { display: block; font-size: .76rem; font-weight: 600; color: var(--encre-douce) }
.rangee .fleche { color: var(--vert); opacity: .45; transition: opacity .12s, transform .12s }
.rangee:hover .fleche { opacity: 1; transform: translateX(2px) }

.eti > span { font-weight: 600; letter-spacing: 0; text-transform: none; opacity: .7 }

.visuellement-cache {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

@media (max-width: 760px) {
  /* Deux lignes plutôt que cinq colonnes serrées : le nom et son état, puis
     les nombres. */
  .rangee { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 14px; padding: 16px 12px }
  .rangee .etat { grid-column: 2; grid-row: 1 }
  .rangee-n { grid-row: 2; text-align: left; display: flex; gap: 5px; align-items: baseline }
  .rangee-n:nth-of-type(2) { grid-column: 1 }
  .rangee-n > span { font-size: .84rem }
  .rangee .fleche { display: none }
  .chercher button { padding: 0 16px }
}

/* ─── le tiroir ──────────────────────────────────────────────────────────────
 *
 * Sans une ligne de JavaScript : `:target` fait tout. Le bouton pointe sur
 * `#creer`, le voile et la croix ramènent sur `#ferme` — une ancre posée à
 * côté du bouton, pour qu'on referme à l'endroit d'où l'on vient.
 *
 * Ce que ça achète qu'un tiroir en script n'a pas gratuitement : l'ADRESSE
 * porte l'état. Le bouton « précédent » referme, et `/boutiques#creer` ouvre.
 *
 * Ce qu'on n'a pas : la touche Échap, et le piégeage du clavier dans le
 * panneau. D'où `role="dialog"` sans `aria-modal` dans le gabarit — annoncer
 * modal alors que la tabulation en sort serait un mensonge. */
.tiroir {
  position: fixed; inset: 0; z-index: 60;
  visibility: hidden;
  /* Le délai sur `visibility` laisse la sortie se jouer avant de retirer le
     tiroir du flux ; sans lui il disparaît d'un coup et l'animation ne se
     voit qu'à l'ouverture. */
  transition: visibility 0s .22s;
}
.tiroir:target { visibility: visible; transition-delay: 0s }

.tiroir-voile {
  position: absolute; inset: 0; background: rgba(18, 16, 14, .38);
  opacity: 0; transition: opacity .22s ease-out;
  -webkit-backdrop-filter: blur(1.5px); backdrop-filter: blur(1.5px);
}
.tiroir:target .tiroir-voile { opacity: 1 }

.tiroir-panneau {
  position: absolute; inset: 0 0 0 auto; width: min(520px, 100%);
  background: #fff; display: flex; flex-direction: column;
  padding: 24px 28px calc(24px + env(safe-area-inset-bottom));
  overflow-y: auto; overscroll-behavior: contain;
  box-shadow: -24px 0 48px -24px rgba(18, 16, 14, .35);
  transform: translateX(100%);
  /* Sortie exponentielle depuis un état déjà posé : le panneau arrive vite
     puis s'arrête, au lieu de glisser à vitesse constante. */
  transition: transform .26s cubic-bezier(.22, 1, .36, 1);
}
.tiroir:target .tiroir-panneau { transform: none }

.tiroir-panneau > header {
  display: flex; align-items: center; gap: 16px; margin-bottom: 2px;
}
.tiroir-panneau h2 {
  margin: 0; flex: 1; font-size: 1.6rem; font-weight: 800; letter-spacing: -.03em;
}
.tiroir-fermer {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 9px 14px; border-radius: 999px; background: var(--fond-doux);
  color: var(--encre-douce); font-weight: 700; font-size: .9rem; text-decoration: none;
}
.tiroir-fermer:hover { background: var(--alerte-douce); color: var(--alerte) }
.tiroir-fermer svg { width: 16px; height: 16px }
.tiroir-sous { margin: 0 0 24px; color: var(--encre-douce) }

.tiroir-gestes {
  display: flex; gap: 12px; margin-top: 28px; padding-top: 22px;
  border-top: 1px solid var(--trait);
}
.tiroir-gestes .bouton { flex: 1; min-width: 0 }
.tiroir-gestes .b-neutre { flex: 0 1 120px }

@media (max-width: 560px) {
  /* Sur un téléphone, un panneau latéral de 520 px n'a pas de sens : il monte
     du bas, comme une feuille, et laisse voir d'où l'on vient. */
  .tiroir-panneau {
    inset: auto 0 0 0; width: auto; max-height: 92vh;
    border-radius: 20px 20px 0 0; transform: translateY(100%);
    box-shadow: 0 -24px 48px -24px rgba(18, 16, 14, .35);
  }
}
@media (prefers-reduced-motion: reduce) {
  .tiroir-panneau { transition: none }
}
@media (max-width: 420px) {
  /* Deux boutons côte à côte dans un tiroir étroit se réduisent sous la
     cible de 56 px de large utile : ils s'empilent. */
  .tiroir-gestes { flex-direction: column }
  .tiroir-gestes .b-neutre { flex: none }
  .tiroir-panneau { padding-left: 20px; padding-right: 20px }
}

/* ─── le dossier d'une boutique ──────────────────────────────────────────────
 *
 * Huit faits dans une grille uniforme, et le montant encaissé rangé entre
 * « forme juridique » et « dossier déposé », à la taille d'une mention
 * légale. Rien ne disait ce qui compte.
 *
 * Désormais : le chiffre d'abord, puis deux groupes nommés, puis la décision. */
.dossier-argent {
  margin: 0 0 30px; padding-bottom: 26px; border-bottom: 1px solid var(--trait);
}
.dossier-argent > span {
  display: block; font-size: .78rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--encre-douce); margin-bottom: 8px;
}
.dossier-argent > b {
  display: block; font-size: clamp(2.1rem, 6vw, 2.9rem); font-weight: 800;
  letter-spacing: -.04em; line-height: 1; white-space: nowrap;
}
.dossier-argent > b .f { font-size: .42em; font-weight: 600; color: var(--encre-douce) }
.dossier-argent > em {
  display: block; margin-top: 8px; font-style: normal; color: var(--encre-douce);
}

/* Un intertitre DANS le dossier : plus discret qu'un h2 de page, assez net
   pour séparer deux groupes de faits. */
.dossier-titre {
  margin: 0 0 14px; font-size: .78rem; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--encre-douce);
}
.faits + .dossier-titre { margin-top: 28px }
/* Une valeur absente est grise, jamais rouge : le rouge reste pour ce qui est
   cassé. Trois « non fourni » écarlates sur une boutique qui vend depuis deux
   mois, et l'alerte ne veut plus rien dire. */
.faits b.absent { color: var(--encre-douce); font-weight: 600 }

/* Les comptes, en aperçu sous le dossier. On ne juge pas une boutique sans
   savoir qui y entre ; ils étaient derrière un lien. */
.rangee-compte { grid-template-columns: auto minmax(0, 1fr) auto; cursor: default }
.rangee-compte:hover { background: none }
.rangee-compte .ini { width: 38px; height: 38px; font-size: .84rem }
/* Un intertitre et son geste, alignés sur leur ligne de base commune. Sans
   `align-items: center` ici, le bouton flottait au-dessus du titre : la règle
   `flex-end` qui convient au grand titre de page ne convient pas à un h2. */
.titre-geste:has(.section) { align-items: center; margin: 52px 0 12px }
.titre-geste .section { margin: 0 }
.titre-geste .b-neutre { flex: none; width: auto; max-width: none; padding: 0 20px;
                         height: 44px; min-height: 0; margin: 0 }
/* Une commande jamais payée n'est pas une vente : elle se lit autrement. */
.dossier-argent > em b { color: var(--or); font-weight: 700 }

/* ─── l'écran de l'argent ────────────────────────────────────────────────────
 *
 * Les écarts étaient en bas : ils sont la seule chose à FAIRE ici, le reste
 * est à regarder. Et « commission due à Sama — la règle n'est pas tranchée »
 * occupait un tiers des grands chiffres pour ne rien dire ; c'est devenu une
 * note en pied. */
.chiffres-deux { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); max-width: 620px }

/* Le montant d'une ligne : plus gros que le reste, aligné à droite, en
   chiffres tabulaires — c'est une colonne qu'on descend du regard. */
.rangee-somme {
  text-align: right; font-size: 1.14rem; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.rangee-somme > span { font-size: .72em; font-weight: 600; color: var(--encre-douce) }
.tableau .rangee:has(.rangee-somme) {
  grid-template-columns: minmax(0, 1fr) 148px 78px 120px 22px;
}

/* Celles qui n'ont rien encaissé : lisibles, mais sans prendre le pas sur
   celles qui vendent. */
.tableau-muet .rangee-nom strong { font-weight: 600; color: var(--encre-douce) }
.tableau-muet .rangee-somme { color: var(--encre-douce); font-weight: 700 }

/* Une ligne d'écart est cliquable : on va voir la boutique concernée. */
.aregler .ligne { text-decoration: none; color: inherit }
.aregler a.ligne:hover { background: var(--fond-doux) }

/* Ce qui est vrai mais ne mérite pas un grand chiffre. */
.pied-note {
  margin: 44px 0 0; padding-top: 18px; border-top: 1px solid var(--trait);
  color: var(--encre-douce); font-size: .92rem;
}

@media (max-width: 760px) {
  .tableau .rangee:has(.rangee-somme) { grid-template-columns: minmax(0, 1fr) auto }
  .rangee-somme { grid-row: 2; grid-column: 2; text-align: right }
}
