/* ==========================================================================
   perrin-charte.css — charte d'interface du Groupe Perrin
   --------------------------------------------------------------------------
   Feuille UNIQUE. Remplace ao-base.css, ao-ui.css, ao-one.css et le :root
   inline de devis/templates/v3/base.html.

   Intégration (backend/templates/base_ao.html) :
     <link rel="stylesheet" href="{{ url_for('static', filename='css/perrin-charte.css') }}?v={{ mtime }}">
   et retirer les trois <link> des anciennes couches.

   Le scoping body:not(.v3-scope) / .v3-scope n'est plus nécessaire : aucun
   sélecteur ici ne dépend de la page. La classe .v3-scope reste posée sur
   l'éditeur de devis pour Bootstrap, elle est simplement ignorée.

   Aucun !important. Aucune couleur hors rampe. Police embarquée en woff2.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Police
   Fichiers à déposer dans backend/static/fonts/.
   -------------------------------------------------------------------------- */
@font-face { font-family: 'Qanelas'; src: url('../fonts/Qanelas-Regular.woff2')    format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Qanelas'; src: url('../fonts/Qanelas-Medium.woff2')     format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Qanelas'; src: url('../fonts/Qanelas-SemiBold.woff2')   format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Qanelas'; src: url('../fonts/Qanelas-Bold.woff2')       format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Qanelas'; src: url('../fonts/Qanelas-ExtraBold.woff2')  format('woff2'); font-weight: 800; font-style: normal; font-display: swap; }

/* --------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------- */
:root {

  /* — Couleurs de marque ————————————————————————————————— */
  --bleu:            #1B2A44;   /* Bleu de Prusse — texte, rail, boutons primaires */
  --orange:          #C45727;   /* Orange épicée — signal, aplats et boutons pleins */
  --cuivre:          #B67F3E;   /* accent secondaire — décor, data-viz. JAMAIS en texte */
  --lin:             #F1EADD;   /* fond d'application */
  --blanc:           #FFFFFF;   /* cartes et surfaces surélevées uniquement */

  /* — Rampe Bleu (tous les gris de l'application : aucun gris neutre) —— */
  --bleu-900:        #101B2E;   /* rail de navigation */
  --bleu-800:        #1B2A44;   /* = --bleu */
  --bleu-700:        #2A3D5C;   /* survol sur fond sombre, texte dense */
  --bleu-600:        #3D5477;   /* texte secondaire — 7,2:1 sur Lin 100 */
  --bleu-300:        #8695AC;   /* icônes inactives, bordures. PAS de texte */
  --bleu-100:        #D6DCE5;   /* bordures de contrôle */
  --bleu-50:         #EDF0F4;   /* filets, fonds de pastille neutre */

  /* — Rampe Orange ——————————————————————————————————— */
  --orange-700:      #8F3D1B;   /* actif, texte sur Orange 100 */
  --orange-600:      #A3461D;   /* TEXTE et LIENS — 6,1:1 sur blanc */
  --orange-500:      #C45727;   /* = --orange. Aplats à texte blanc uniquement */
  --orange-400:      #D97845;
  --orange-100:      #F7E2D6;   /* fond de badge, filtre retirable */

  /* — Rampe Cuivre ——————————————————————————————————— */
  --cuivre-600:      #92662F;
  --cuivre-500:      #B67F3E;
  --cuivre-100:      #F0E3D0;

  /* — Rampe Lin ————————————————————————————————————— */
  --lin-100:         #FAF7F2;   /* surfaces calmes, en-têtes de tableau */
  --lin-200:         #F1EADD;   /* fond d'application */
  --lin-300:         #E2D7C4;   /* bordure quand la surface voisine est déjà Lin */

  /* — Sémantiques : teinte pleine, fond pâle, encre sur fond pâle ——— */
  --succes:          #2E7D5B;  --succes-100:  #E6F1EC;  --succes-700:  #1F5D43;
  --alerte:          #C9931F;  --alerte-100:  #FAF0DA;  --alerte-700:  #7A5A0E;
  --erreur:          #B3332B;  --erreur-100:  #F7E4E2;  --erreur-700:  #8C2822;
  --info:            #2A5C8A;  --info-100:    #E3EBF3;  --info-700:    #224C72;

  /* — Rôles ————————————————————————————————————————— */
  --fond:            var(--lin-200);
  --surface:         var(--blanc);
  --surface-calme:   var(--lin-100);
  --encre:           var(--bleu-800);
  --encre-douce:     var(--bleu-600);
  --encre-inverse:   var(--blanc);
  --bordure:         var(--bleu-100);
  --bordure-lin:     var(--lin-300);
  --filet:           var(--bleu-50);
  --lien:            var(--orange-600);
  --lien-survol:     var(--orange-700);

  /* — Typographie ————————————————————————————————————
     Une seule famille, une seule unité (px), plancher à 11px.        */
  --police:          'Qanelas', system-ui, -apple-system, sans-serif;
  --police-chiffres: 'Qanelas', ui-monospace, monospace;

  --t-display:       32px;  --lh-display:      36px;  --g-display:  800;
  --t-titre:         24px;  --lh-titre:        30px;  --g-titre:    700;
  --t-carte:         16px;  --lh-carte:        22px;  --g-carte:    600;
  --t-corps:         14px;  --lh-corps:        21px;  --g-corps:    400;
  --t-dense:         13px;  --lh-dense:        19px;
  --t-libelle:       13px;  --lh-libelle:      16px;  --g-libelle:  500;
  --t-colonne:       11px;  --lh-colonne:      14px;  --g-colonne:  700;
  --t-micro:         11px;  --lh-micro:        14px;  /* plancher absolu */

  --ls-display:      -.02em;
  --ls-titre:        -.015em;
  --ls-section:      .16em;   /* titres de section en capitales */
  --ls-colonne:      .10em;   /* en-têtes de colonne en capitales */

  /* — Espacement : base 4, rien entre les paliers ——————————— */
  --e-1:  4px;   /* icône ↔ libellé */
  --e-2:  8px;   /* intérieur de badge, gap de boutons */
  --e-3:  12px;  /* cellule de tableau, vertical */
  --e-4:  16px;  /* cellule horizontal, gap de grille */
  --e-5:  20px;  /* intérieur de carte */
  --e-6:  24px;  /* intérieur de panneau, marge de page */
  --e-7:  32px;  /* entre deux blocs */
  --e-8:  48px;  /* entre deux sections */

  /* — Rayons : trois valeurs, contre onze auparavant ——————————— */
  --r-1:  4px;   /* contrôles denses */
  --r-2:  6px;   /* boutons, champs, badges */
  --r-3:  8px;   /* cartes, panneaux, modales */
  /* border-radius:999px est proscrit : rien n'est en gélule. */

  /* Deux rayons de rôle, posés par la charte du 16/09 : ils ne rouvrent pas
     la rampe, ils nomment les deux tailles que les gabarits emploient. */
  --r-action: 10px;  /* boutons et champs de la bande d'actions (46 px) */
  --r-carte:  12px;  /* carte blanche de contenu */

  /* — Ombres : teintées bleu, jamais noires —————————————— */
  --ombre-1:     0 1px 2px rgba(27,42,68,.06);
  --ombre-2:     0 1px 3px rgba(27,42,68,.08), 0 3px 10px rgba(27,42,68,.05);
  --ombre-3:     0 10px 28px rgba(27,42,68,.14);
  --focus:       0 0 0 3px rgba(196,87,39,.35);

  /* Ombre à deux couches de la carte : un filet net posé sur une ombre large
     et très diffuse. C'est elle qui remplace la bordure. */
  --ombre-carte:        0 1px 2px rgba(27,42,68,.07), 0 10px 24px -18px rgba(27,42,68,.4);
  --ombre-carte-survol: 0 1px 2px rgba(27,42,68,.09), 0 16px 32px -20px rgba(27,42,68,.5);

  /* — Densité : « confort » par défaut, « compact » par data-densite — */
  --ligne-h:     40px;
  --ligne-py:    12px;
  --ligne-px:    16px;
  --controle-h:  40px;   /* 32 compact · 44 tactile */
  --tactile-min: 44px;

  --transition:  140ms ease;
}

[data-densite="compact"] {
  --ligne-h:    32px;
  --ligne-py:   8px;
  --ligne-px:   12px;
  --controle-h: 32px;
}

@media (pointer: coarse) {
  :root { --controle-h: var(--tactile-min); }
}

@media (prefers-reduced-motion: reduce) {
  :root { --transition: 0ms; }
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
}

/* --------------------------------------------------------------------------
   3. Alias de compatibilité
   Les gabarits Jinja existants continuent de fonctionner sans retouche :
   ces noms viennent de ao-base / ao-ui / ao-one et du :root de devis v3.
   À supprimer une fois les templates migrés vers les tokens ci-dessus.
   -------------------------------------------------------------------------- */
:root {
  --primary:         var(--bleu);
  --primary-dark:    var(--bleu-900);
  --blue:            var(--bleu);
  --perrin-cyan:     var(--bleu);          /* l'ancien cyan devient le bleu */
  --perrin-cyan-dark:var(--bleu-900);
  --orange-accent:   var(--orange);
  --accent:          var(--orange);
  --muted:           var(--encre-douce);
  --border:          var(--bordure);
  --bg:              var(--fond);
  --card:            var(--surface);
  --text:            var(--encre);
  --status-ok:       var(--succes);
  --status-warn:     var(--alerte);
  --status-err:      var(--erreur);
  --status-info:     var(--info);
  --nego:            var(--alerte-700);    /* corrige un contraste sous AA */
  --radius:          var(--r-3);
  --shadow:          var(--ombre-1);

  /* rampe d'avancement : sept paliers ramenés à trois crans chartés */
  --prog-0: var(--cuivre-500);  --prog-1: var(--cuivre-500);  --prog-2: var(--orange-500);
  --prog-3: var(--orange-500);  --prog-4: var(--orange-500);  --prog-5: var(--succes);
  --prog-6: var(--succes);
}

/* --------------------------------------------------------------------------
   4. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--police);
  font-size: var(--t-dense);
  line-height: var(--lh-dense);
  -webkit-font-smoothing: antialiased;
}

a        { color: var(--lien); text-decoration: none; }
a:hover  { color: var(--lien-survol); text-decoration: underline; }

:focus-visible {
  outline: none;
  box-shadow: var(--focus);
  border-radius: var(--r-2);
}

h1 { font-size: var(--t-display); line-height: var(--lh-display); font-weight: var(--g-display); letter-spacing: var(--ls-display); color: var(--encre); margin: 0; }
h2 { font-size: var(--t-titre);   line-height: var(--lh-titre);   font-weight: var(--g-titre);   letter-spacing: var(--ls-titre);   color: var(--encre); margin: 0; }
h3 { font-size: var(--t-carte);   line-height: var(--lh-carte);   font-weight: var(--g-carte);   color: var(--encre); margin: 0; }

/* Titre de section : capitales, interlettrage élargi */
.section-t {
  font-size: var(--t-colonne); line-height: var(--lh-colonne);
  font-weight: 700; letter-spacing: var(--ls-section);
  text-transform: uppercase; color: var(--encre);
}

/* Chiffres : toujours tabulaires, alignés à droite en colonne */
.n, td.n, .montant { font-variant-numeric: tabular-nums; text-align: right; }

/* --------------------------------------------------------------------------
   5. Composants
   Les noms de classe sont ceux du dépôt : aucun gabarit à renommer.
   -------------------------------------------------------------------------- */

/* Boutons — cinq variantes, contre dix-sept -------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
  min-height: var(--controle-h); padding: 0 var(--e-4);
  border: 1px solid transparent; border-radius: var(--r-2);
  background: var(--bleu); color: var(--encre-inverse);
  font-family: inherit; font-size: var(--t-dense); font-weight: 600;
  cursor: pointer; transition: background var(--transition), border-color var(--transition);
}
.btn:hover              { background: var(--bleu-700); color: var(--encre-inverse); text-decoration: none; }
.btn:active             { background: var(--bleu-900); }
.btn[disabled]          { background: var(--bleu-50); color: var(--bleu-300); cursor: not-allowed; }

.btn.accent             { background: var(--orange); }
.btn.accent:hover       { background: var(--orange-600); }
.btn.accent:active      { background: var(--orange-700); }

.btn.ghost              { background: var(--surface); border-color: var(--bordure); color: var(--encre); }
.btn.ghost:hover        { background: var(--bleu-50); border-color: var(--bleu-300); color: var(--encre); }
.btn.ghost:active       { background: var(--bleu-100); }

.btn.danger             { background: var(--surface); border-color: var(--erreur); color: var(--erreur-700); }
.btn.danger:hover       { background: var(--erreur); color: var(--encre-inverse); }

.btn.sm                 { min-height: 32px; padding: 0 var(--e-3); font-size: 12px; }
.btn.lg                 { min-height: var(--tactile-min); padding: 0 var(--e-5); font-size: var(--t-corps); }
.btn.icone              { width: var(--controle-h); padding: 0; }

/* Champs -------------------------------------------------------------------- */
.champ, input[type="text"], input[type="date"], input[type="time"],
input[type="number"], input[type="search"], select, textarea {
  min-height: var(--controle-h); padding: 0 var(--e-3);
  border: 1px solid var(--bordure); border-radius: var(--r-2);
  background: var(--surface); color: var(--encre);
  font-family: inherit; font-size: var(--t-dense);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.champ:hover, input:hover, select:hover                     { border-color: var(--bleu-300); }
.champ:focus, input:focus, select:focus, textarea:focus     { outline: none; border-color: var(--orange); box-shadow: var(--focus); }
.champ[readonly], input[readonly]                           { background: var(--lin-100); border-color: var(--filet); color: var(--encre-douce); }
.champ[disabled], input[disabled], select[disabled]         { background: var(--bleu-50); border-color: var(--filet); color: var(--bleu-300); cursor: not-allowed; }
.champ.erreur, input.erreur                                 { border-color: var(--erreur); background: #FDF8F8; }
textarea                                                    { padding: var(--e-3); line-height: var(--lh-corps); }
.aide-erreur { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 12px; font-weight: 500; color: var(--erreur-700); }

/* Cartes et panneaux -------------------------------------------------------- */
.card, .panel {
  background: var(--surface);
  border: 1px solid var(--bordure-lin);
  border-radius: var(--r-3);
  box-shadow: var(--ombre-1);
  padding: var(--e-5);
}
.card:hover   { box-shadow: var(--ombre-2); }
.card-header  { display: flex; align-items: center; gap: var(--e-3); padding-bottom: var(--e-3); border-bottom: 1px solid var(--filet); margin-bottom: var(--e-4); }

/* En-tête d'écran : date, titre, recherche, action principale ---------------
   La bande du haut de chaque écran de liste. Le titre est DATÉ : l'application
   se lit le matin, et « à rendre < 7 j » ne veut rien dire sans savoir quel jour
   on est. La recherche et le bouton d'action sont à droite, empilés. */
.ecran-tete      { display: flex; align-items: flex-start; gap: var(--e-5); flex-wrap: wrap; margin-bottom: var(--e-6); }
.ecran-tete-txt  { flex: 1 1 320px; min-width: 0; }
.ecran-date      { display: block; font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-colonne); text-transform: uppercase; color: var(--orange-600); }
.ecran-date::before { content: "— "; }
.ecran-titre     { margin: 5px 0 0; font-size: clamp(25px, 2.6vw, 33px); font-weight: 800; letter-spacing: -.025em; line-height: 1.1; color: var(--encre); }
.ecran-tete-act  { flex: 0 1 auto; display: flex; flex-direction: column; align-items: flex-end; gap: var(--e-3); min-width: 0; }
.ecran-tete-act .btn { white-space: nowrap; }

/* Champ de recherche de l'en-tête. Le rappel du raccourci « / » est POSÉ À CÔTÉ
   du texte et non dans le placeholder : dans le placeholder il disparaît dès la
   première lettre tapée, c'est-à-dire au moment où on peut encore en douter. */
/* `flex: none` et pas une base : `.ecran-tete-act` est une colonne, où
   `flex-basis` fixe la HAUTEUR. Une base de 300 px y étirait le champ sur
   300 px de haut, et la loupe — positionnée sur ce conteneur — se retrouvait
   cent pixels sous le texte. */
.rech            { position: relative; flex: none; width: min(300px, 46vw); }
.rech input      { width: 100%; box-sizing: border-box; min-height: var(--tactile-min); padding: 0 34px 0 36px; border: 1px solid var(--bordure); border-radius: var(--r-3); background: var(--surface); color: var(--encre); font-family: inherit; font-size: 13px; font-weight: 500; }
.rech input::placeholder { color: var(--bleu-300); }
.rech input:focus { outline: none; border-color: var(--bleu-600); box-shadow: 0 0 0 3px rgba(61, 84, 119, .16); }
.rech svg        { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--bleu-300); pointer-events: none; }
.rech-kbd        { position: absolute; right: 9px; top: 50%; transform: translateY(-50%); padding: 1px 6px; border: 1px solid var(--bordure); border-radius: var(--r-1); background: var(--lin-100); color: var(--encre-douce); font-family: var(--police-chiffres); font-size: var(--t-micro); font-weight: 700; cursor: help; }
.rech input:focus ~ .rech-kbd { opacity: 0; }

/* Bandeau d'indicateurs : une bande posée sur le fond, séparée par des filets.
   Pas de cartes : quatre surfaces blanches bordées pour quatre nombres pesaient
   plus lourd, à l'écran, que la liste qu'elles résument. */
.kpi-bande       { display: flex; flex-wrap: wrap; gap: var(--e-4) 0; margin-bottom: var(--e-6); }
.kpi-bloc        { flex: 1 1 190px; min-width: 0; padding: 0 var(--e-5); border-left: 1px solid var(--bordure-lin); }
.kpi-bloc:first-child { padding-left: 0; border-left: 0; }
.kpi-bloc .kpi-lab  { display: block; font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-colonne); text-transform: uppercase; color: var(--encre-douce); }
.kpi-bloc .kpi-val  { display: block; margin: 7px 0 4px; font-size: clamp(26px, 2.3vw, 31px); font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--encre); font-variant-numeric: tabular-nums; }
.kpi-bloc .kpi-val.alerte { color: var(--orange-600); }
.kpi-bloc .kpi-val small  { font-size: .52em; font-weight: 700; letter-spacing: 0; }
.kpi-bloc .kpi-note { display: block; font-size: 11.5px; font-weight: 500; color: var(--encre-douce); }

/* Rangée de filtres : sur le fond, pas dans une carte. Elle reste COLLANTE —
   c'est elle qui porte la recherche active et le décompte, et on la perdait au
   premier défilement. */
.fbar            { position: sticky; top: var(--fbar-top, 0px); z-index: 900; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; padding: var(--e-3) 0; margin-bottom: var(--e-3); background: var(--fond); }
.fbar .chip      { flex: 0 0 auto; }
.fbar-select     { flex: 0 0 auto; min-height: 32px; max-width: 190px; padding: 0 9px; border: 1px solid var(--bordure); border-radius: 999px; background: var(--surface); color: var(--encre-douce); font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.fbar-select:focus { outline: none; border-color: var(--bleu-600); }
.fbar-select.on  { background: var(--bleu-800); border-color: var(--bleu-800); color: var(--encre-inverse); }
.fbar-res        { margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--encre-douce); white-space: nowrap; }
.fbar .segments  { flex: 0 0 auto; }

/* Sous 760 px, l'empilement en lignes inégales (flex-wrap) laisse des blancs
   à droite de chaque rangée : bande scrollable plutôt que grille de secours,
   même idiome que `.pnav-links` (cf. section 7). */
@media (max-width: 760px) {
  .fbar        { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
                 scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .fbar::-webkit-scrollbar { display: none; }
  .fbar-res    { margin-left: 0; }
}

/* En-tête de section repliable (agenda et vue compacte) --------------------
   Le libellé, le compte, le résumé de ce que la section contient, puis
   « Déplier ». Le résumé est ce qui rend le repli acceptable : une section
   fermée dit encore combien elle pèse. */
.grp-resume      { font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
.grp-plier       { margin-left: auto; font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--lien); white-space: nowrap; }
.grp-row.collapsed .grp-plier::after { content: "Déplier"; }
/* Le résumé ne s'affiche que sur une section FERMÉE : ouverte, les lignes le
   disent déjà, et le répéter en en-tête ne ferait que charger la ligne. */
.grp-row:not(.collapsed) .grp-resume { display: none; }

/* Vue compacte : une ligne par marché, qu'on balaie ------------------------ */
/* `table-layout: fixed` est ce qui fait tenir les six colonnes dans la largeur
   de l'écran : en disposition automatique, l'objet — souvent long — poussait
   « Montant HT » et « À faire » hors du cadre, et elles ne se voyaient plus. */
.tbl-compact                 { table-layout: fixed; }
.tbl-compact tbody td        { vertical-align: middle; }
.tbl-compact .th-sub         { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--encre-douce); }
.tbl-compact .c-num          { text-align: right; }
.tbl-compact .c-num .mnt     { font-size: 13.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tbl-compact .vide           { color: var(--bleu-300); }
.tbl-compact .objet-lien     { display: block; font-size: 13.5px; font-weight: 600; color: var(--encre); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tbl-compact .objet-lien:hover { color: var(--lien); }
.tbl-compact .objet-tete     { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tbl-compact .objet-tete .objet-lien { min-width: 0; }
.tbl-compact .objet-tete .eti.visite { flex: none; }
.tbl-compact .objet-sous     { display: block; margin-top: 2px; font-size: 11.5px; font-weight: 500; color: var(--encre-douce); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tbl-compact .c-lots         { line-height: 1.5; }
.lot-ligne                   { display: block; font-size: 11.5px; font-weight: 500; color: var(--encre-douce); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lot-ligne b                 { font-weight: 700; letter-spacing: .04em; color: var(--bleu-700); }
.lot-ligne:hover             { color: var(--lien); }
.tbl-compact .grp-row td     { padding-top: 9px; padding-bottom: 9px; }
.grp-tete                    { display: flex; align-items: center; gap: 10px; }
.sig-rien                    { color: var(--bleu-300); font-weight: 700; }

/* Indicateurs --------------------------------------------------------------- */
.kpi        { background: var(--surface); border: 1px solid var(--bordure-lin); border-left: 3px solid var(--bleu); border-radius: var(--r-3); padding: var(--e-4) var(--e-5); }
.kpi.accent { border-left-color: var(--orange); }
.kpi.cuivre { border-left-color: var(--cuivre); }
.kpi.ok     { border-left-color: var(--succes); }
.kpi.warn   { border-left-color: var(--alerte); }
.kpi.err    { border-left-color: var(--erreur); }
.kpi-lab    { font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-colonne); text-transform: uppercase; color: var(--encre-douce); }
.kpi-val    { font-size: var(--t-display); font-weight: 800; letter-spacing: var(--ls-display); line-height: 1; font-variant-numeric: tabular-nums; margin-top: 6px; }

/* Tableaux — un seul système, contre quatre --------------------------------- */
.tbl-wrap { overflow-x: auto; border-radius: var(--r-3); border: 1px solid var(--bordure-lin); background: var(--surface); }
table.ds  { width: 100%; border-collapse: collapse; font-size: var(--t-dense); }
table.ds thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--lin-200); color: var(--bleu-700);
  text-align: left; white-space: nowrap;
  padding: 10px var(--ligne-px);
  font-size: var(--t-colonne); line-height: var(--lh-colonne);
  font-weight: var(--g-colonne); letter-spacing: var(--ls-colonne); text-transform: uppercase;
  border-bottom: 1px solid var(--bordure-lin);
}
table.ds tbody td      { padding: var(--ligne-py) var(--ligne-px); height: var(--ligne-h); border-bottom: 1px solid var(--filet); }
table.ds tbody tr:hover{ background: var(--lin-100); }
/* Sans ces trois règles, `style.css` zèbre une ligne sur deux en #f8fafc et
   `perrin-ui.css` écrit les liens de tableau en 700 sur l'ancien encre : la
   charte ne les redéclarait pas, donc les feuilles historiques gouvernaient
   l'apparence de tous les tableaux de l'application. */
table.ds tbody tr                { background: var(--surface); }
/* `:not(.btn)` : sans lui, ce sélecteur (0,1,3) bat `.btn` (0,1,0) et repeint
   en encre sombre le texte d'un bouton posé dans une cellule — sur son propre
   fond sombre. Un bouton dans un tableau reste un bouton. */
table.ds td a:not(.btn)          { color: var(--encre); font-weight: 600; }
table.ds td a:not(.btn):hover    { color: var(--lien); }
table.ds tbody tr.selection      { background: var(--orange-100); }
table.ds tbody tr.visite-manquante,
table.ds tbody tr.demande-retard { background: var(--erreur-100); }
table.ds tbody tr.demande-recue  { background: var(--succes-100); }
table.ds tr.grp-row td { background: var(--bleu-50); font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-colonne); text-transform: uppercase; color: var(--bleu-700); }
table.ds tr.grp-row.danger td { background: var(--erreur-100); color: var(--erreur-700); }
table.ds tr.grp-row.warn   td { background: var(--alerte-100); color: var(--alerte-700); }

/* Badges d'état — un état, une couleur, partout ----------------------------- */
.etat {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: var(--r-2);
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--bleu-50); color: var(--bleu-700);
}
.etat.repondu     { background: var(--info-100);   color: var(--info-700); }
.etat.negociation { background: var(--alerte-100); color: var(--alerte-700); }
.etat.gagne       { background: var(--succes-100); color: var(--succes-700); }
.etat.perdu       { background: var(--erreur-100); color: var(--erreur-700); }
.etat.favori      { background: var(--cuivre-100); color: var(--encre); }
/* Seul aplat plein : le signal à ne jamais noyer dans un tableau de 30 lignes */
.etat.visite      { background: var(--erreur); color: var(--encre-inverse); }
/* Les six variantes ci-dessus nomment des états de MARCHÉ. Tout autre état —
   celui d'un lot, d'une tâche — se dit par sa gravité, avec les mêmes noms que
   `.sig` et `.signal` pour qu'un seul vocabulaire serve partout. `critique` est
   l'aplat plein : le seul lisible sur une ligne déjà peinte en clair. */
.etat.info        { background: var(--info-100);   color: var(--info-700); }
.etat.ok          { background: var(--succes-100); color: var(--succes-700); }
.etat.warn        { background: var(--alerte-100); color: var(--alerte-700); }
.etat.err         { background: var(--erreur-100); color: var(--erreur-700); }
.etat.critique    { background: var(--erreur);     color: var(--encre-inverse); }

/* Échéance — escalade en cinq crans ----------------------------------------- */
.badge-j { display: inline-block; min-width: 62px; text-align: center; padding: 4px 10px; border-radius: var(--r-2); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; background: var(--bleu-50); color: var(--bleu-700); }
.badge-j.j30 { background: var(--cuivre-100); color: var(--encre); }        /* 30 à 15 j */
.badge-j.j14 { background: var(--orange-100); color: var(--orange-700); }   /* 14 à 7 j  */
.badge-j.j7  { background: var(--orange);     color: var(--encre-inverse); }/* < 7 j     */
.badge-j.depasse { background: var(--erreur); color: var(--encre-inverse); }

/* Puces de filtre ----------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 32px; padding: 0 14px;
  border: 1px solid var(--bordure); border-radius: var(--r-2);
  background: var(--surface); color: var(--bleu-700);
  font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
}
.chip:hover      { background: var(--bleu-50); border-color: var(--bleu-300); }
.chip.on         { background: var(--bleu); border-color: var(--bleu); color: var(--encre-inverse); }
.chip.retirable  { background: var(--orange-100); border-color: var(--orange); color: var(--orange-700); }
.chip .cpt       { min-width: 19px; padding: 0 4px; border-radius: var(--r-1); background: var(--bleu-50); font-size: var(--t-micro); font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.chip.on .cpt    { background: rgba(255,255,255,.22); }

/* Onglets — un seul système, contre trois ----------------------------------- */
.tabs  { display: flex; gap: 2px; border-bottom: 1px solid var(--bordure); flex-wrap: wrap; }
.tab   { padding: 10px 14px; margin-bottom: -1px; font-size: var(--t-dense); font-weight: 500; color: var(--encre-douce); cursor: pointer; }
.tab:hover  { color: var(--encre); }
.tab.actif  { font-weight: 600; color: var(--encre); border-bottom: 2px solid var(--orange); }
.tab[disabled], .tab.inactif { color: var(--bleu-300); cursor: not-allowed; }

/* Avancement — trois crans, piste de largeur fixe --------------------------- */
.bar-track { display: block; height: 7px; border-radius: 4px; background: var(--bleu-50); overflow: hidden; }
/* `min-width:0` neutralise le `min-width:3px` de `perrin-ui.css` : sans lui, un
   remplissage à 0 % peint quand même trois pixels de couleur et affirme un
   avancement qui n'existe pas. */
.bar-fill  { display: block; height: 100%; min-width: 0; border-radius: 4px; background: var(--cuivre); }
.bar-fill.presse { background: var(--orange); }
.bar-fill.fini   { background: var(--succes); }
.bar-fill.info   { background: var(--info); }
/* Légende d'une barre : un chiffre qu'on lit, pas un état qu'on signale — d'où
   la casse normale, là où `.lot-etat` est en capitales et se teinte. */
.bar-cap   { display: block; margin-top: 5px; font-size: 11.5px; font-weight: 700;
             color: var(--encre-douce); font-variant-numeric: tabular-nums; }

/* Modale ---------------------------------------------------------------------
   Fermée par défaut, ouverte par `.active` — c'est le contrat des gabarits du
   dépôt, et le JS qui les pilote ne pose que cette classe. La feuille livrée
   déclarait `display:flex` sans condition : toutes les modales de la page
   s'ouvraient en même temps dès qu'elle était chargée.                        */
.etat-modal      { position: fixed; inset: 0; z-index: 9999; display: none; align-items: center; justify-content: center; padding: var(--e-4); background: rgba(16,27,46,.5); }
.etat-modal.active,
.etat-modal[open] { display: flex; }
.etat-modal-card { width: 100%; max-width: 560px; background: var(--surface); border-radius: var(--r-3); box-shadow: var(--ombre-3); overflow: hidden; }
.etat-modal-header { display: flex; align-items: center; gap: var(--e-3); padding: var(--e-4) var(--e-5); border-bottom: 1px solid var(--filet); font-size: var(--t-carte); font-weight: 600; }
.etat-modal-body   { padding: var(--e-5); }
.etat-modal-footer { display: flex; gap: var(--e-2); justify-content: flex-end; padding: var(--e-4) var(--e-5); background: var(--lin-100); border-top: 1px solid var(--filet); }

/* Notifications — n'existaient pas : les retours passaient par alert() ------- */
.toast        { display: flex; align-items: flex-start; gap: var(--e-2); padding: var(--e-3) var(--e-4); border-radius: var(--r-2); background: var(--surface); border: 1px solid var(--bordure); border-left: 3px solid var(--info); box-shadow: var(--ombre-2); font-size: var(--t-dense); }
.toast.ok     { border-color: #BFD9CC; border-left-color: var(--succes); }
.toast.warn   { border-color: #F0E3C8; border-left-color: var(--alerte); }
.toast.err    { border-color: #F0D6D3; border-left-color: var(--erreur); }

/* Pile flottante (ui-dialogs.js) : `.toast`/`.toasts` ci-dessus sont pensées
   pour un flux EN LIGNE (haut de formulaire) ; `toast()` empile ses messages
   par-dessus la page, en bas à droite, chacun se retirant seul. */
.ui-toasts { position: fixed; right: 16px; bottom: 16px; z-index: 2000;
             display: flex; flex-direction: column; gap: var(--e-2);
             max-width: min(360px, calc(100vw - 32px)); }
/* `white-space:pre-line` : plusieurs messages convertis depuis alert() portent
   des \n\n (ex. devis.html — erreur + détail) que le texte en flux normal
   effondrerait en une seule ligne. */
.ui-toasts .toast { opacity: 0; transform: translateY(8px); white-space: pre-line;
                     transition: opacity 160ms ease, transform 160ms ease; }
.ui-toasts .toast.on { opacity: 1; transform: none; }

/* États vides et chargement -------------------------------------------------- */
.empty { display: flex; flex-direction: column; align-items: center; gap: var(--e-2); padding: 28px var(--e-5); border: 1px dashed var(--bordure-lin); border-radius: var(--r-2); background: var(--lin-100); text-align: center; color: var(--encre-douce); }
.empty b { font-size: var(--t-corps); font-weight: 600; color: var(--encre); }

.skel { height: 12px; border-radius: 3px; background: linear-gradient(90deg, var(--bleu-50) 8%, #F6F8FA 18%, var(--bleu-50) 33%); background-size: 420px 100%; animation: skel 1.4s linear infinite; }
@keyframes skel { 0% { background-position: -420px 0; } 100% { background-position: 420px 0; } }

.spin { width: 14px; height: 14px; border: 2px solid var(--bleu-100); border-top-color: var(--bleu-600); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Rail de navigation ---------------------------------------------------------- */
/* `border-bottom` et `box-shadow` sont remis à zéro EXPRÈS : `perrin-one.css`
   pose encore le liseré orange de 3 px et l'ombre cyan de l'ancien bandeau
   horizontal. Sur un rail vertical, ce liseré devenait un trait orange en bas
   de la colonne, sans rien signifier. */
.pnav          { display: flex; flex-wrap: wrap; align-content: flex-start; background: var(--bleu-900); border-bottom: 0; box-shadow: none; }
.pnav-links a  { display: flex; align-items: center; gap: 12px; min-height: var(--tactile-min); padding: 0 14px; border-radius: var(--r-3); color: var(--bleu-100); font-size: 13.5px; font-weight: 500; text-decoration: none; }
.pnav-links a:hover  { background: var(--bleu); color: var(--encre-inverse); text-decoration: none; }
.pnav-links a.actif  { background: var(--lin-200); color: var(--bleu-900); font-weight: 600; }
.pnav-sect     { font-size: var(--t-colonne); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--lin-300); padding: 22px 14px 8px; }

/* Le repli du rail est en fin de section 7 : il doit passer APRÈS les règles
   .pnav-* de la coquille, sinon celles-ci le recouvrent. */

/* --------------------------------------------------------------------------
   7. Coquille — classes employées par base_ao.html
   Le rail est un frère du contenu dans un parent en flex-wrap : sous ~920px
   il passe seul en pleine largeur et devient un bandeau (cf. section 5).
   -------------------------------------------------------------------------- */
.app   { display: flex; flex-wrap: wrap; align-items: flex-start; align-content: flex-start;
         min-height: 100vh; background: var(--fond); }
/* `align-content` n'est pas décoratif : sans lui, sur une page COURTE repliée
   en deux rangées (sous 920 px), les rangées se partagent les 100vh et le
   bandeau de navigation enfle jusqu'à 300 px. */
.page  { flex: 999 1 660px; min-width: 0; max-width: 100%; box-sizing: border-box; padding: var(--e-6) clamp(16px, 3vw, 40px) 64px; }

.pnav  { flex: 1 1 248px; max-width: 100%; box-sizing: border-box; align-self: stretch; align-content: flex-start; padding-bottom: var(--e-3); }
/* `flex-direction: row` est EXPLICITE : `perrin-one.css` pose encore
   `flex-direction: column` sur cette même classe, et sans cette ligne le
   chevron se retrouvait empilé au-dessus du nom, centré. Idem pour
   `text-transform` : la feuille historique met le nom en capitales. */
/* Le retrait horizontal n'est PAS cosmétique : sans lui le chevron tombe à x=0,
   collé au bord du rail — et s'y fait rogner — alors que les icônes de navigation
   commencent à 26 px (`.pnav-links` s'encart de --e-3 = 12, et chaque lien de 14
   de plus). Mesuré au banc sur le rail réel : marque à 0, navigation à 26.
   Ces 26 px l'alignent exactement sur elles. Le défaut et sa mesure viennent de
   `veille-ao`, qui partage cette feuille et l'avait corrigé de son côté par un
   style en ligne ; il est réglé ici, à la source, pour les deux. */
.pnav-brand { flex: 1 1 100%; box-sizing: border-box; display: flex; flex-direction: row; align-items: center; gap: 13px; padding: 24px 14px 20px 26px; border-bottom: 1px solid var(--bleu-700); }
.pnav-brand img { flex: none; }
.pnav-brand [data-wordmark] { min-width: 0; }
.pnav-brand b { display: block; font-size: 17px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; text-transform: none; color: var(--encre-inverse); }
.pnav-brand i { display: block; margin-top: 2px; font-style: normal; font-size: 11px; font-weight: 600; letter-spacing: .16em; white-space: nowrap; text-transform: uppercase; color: var(--lin-300); }

.pnav-links { flex: 1 1 100%; box-sizing: border-box; display: flex; flex-wrap: wrap; gap: 3px; padding: var(--e-4) var(--e-3) 0; }
.pnav-links a { flex: 1 1 176px; box-sizing: border-box; }
.pnav-links a svg { flex: none; }
.pnav-compte { margin-left: auto; font-size: 11.5px; font-weight: 700; color: var(--bleu-100); font-variant-numeric: tabular-nums; }
.pnav-links a.actif .pnav-compte { color: var(--bleu-700); }
.pnav-alerte { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-2); background: var(--orange); color: var(--encre-inverse); font-size: var(--t-micro); font-weight: 700; }
/* Entrée qui MÈNE DEHORS (une autre application du groupe, nouvel onglet). Le
   chevron sortant se lit avant le clic ; la pastille reste effacée tant qu'on
   ne survole pas, pour ne pas peser autant qu'un compte ou qu'une alerte. */
.pnav-externe { margin-left: auto; flex: none; color: var(--bleu-300); }
.pnav-links a:hover .pnav-externe { color: var(--encre-inverse); }
/* Le libellé de section et un filet qui court jusqu'au bord : c'est le filet
   qui sépare les blocs du rail, pas un écart vertical de plus. */
.pnav-sect  { flex: 1 1 100%; box-sizing: border-box; display: flex; align-items: center; gap: 11px; }
.pnav-sect::after { content: ""; flex: 1; height: 1px; background: var(--bleu-700); }

.pnav-user  { flex: 1 1 100%; box-sizing: border-box; display: flex; align-items: center; gap: 11px; margin: 20px var(--e-3) 0; padding: var(--e-3) 14px; border-radius: var(--r-3); background: var(--bleu-800); }
.pnav-user .av { flex: none; display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: var(--r-3); background: var(--orange); color: var(--encre-inverse); font-size: 12px; font-weight: 700; letter-spacing: .04em; }
.pnav-user > span[data-usermeta] { flex: 1; min-width: 0; line-height: 1.3; }
.pnav-user b { display: block; font-size: 12.5px; font-weight: 600; color: var(--encre-inverse); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pnav-user i { display: block; font-style: normal; font-size: var(--t-micro); color: var(--bleu-100); }
.pnav-logout { flex: none; display: flex; align-items: center; justify-content: center; width: var(--tactile-min); height: var(--tactile-min); border-radius: var(--r-3); color: var(--bleu-100); }
.pnav-logout:hover { background: var(--bleu-700); color: var(--encre-inverse); text-decoration: none; }

/* En-tête de page : surtitre cuivre à filet, titre, sous-titre */
.page-sur   { display: inline-flex; align-items: center; gap: 9px; font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-section); text-transform: uppercase; color: var(--orange-600); margin-bottom: 9px; }
.page-sur::before { content: ""; width: 18px; height: 2px; background: var(--cuivre); }
.page-title { margin: 0; font-size: clamp(24px, 3vw, 34px); line-height: 1.1; font-weight: 800; letter-spacing: -.028em; color: var(--encre); text-wrap: pretty; }
.page-sub   { display: block; margin-top: 6px; font-size: 13.5px; line-height: 1.5; color: var(--encre-douce); text-wrap: pretty; }

/* Bande de chiffres : colonnes figées, trait entre les blocs, jamais orphelin */
.kpis   { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(14px, 2vw, 28px); padding: 0 4px var(--e-6); }
/* Beaucoup d'écrans n'ont que TROIS chiffres honnêtes à montrer : une vue qui ne
   reçoit que les marchés de son état ne peut pas compter les autres. Sans cette
   variante, la bande s'arrêtait aux trois quarts de sa largeur. */
.kpis.trois                       { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpis.trois > div:nth-child(3n+1) { padding-left: 0; border-left: 0; }
.kpis > div { min-width: 0; padding-left: clamp(14px, 2vw, 28px); border-left: 1px solid var(--bordure-lin); }
.kpis > div:nth-child(4n+1) { padding-left: 0; border-left: 0; }
.kpis .lab { display: block; font-size: var(--t-colonne); font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--encre-douce); margin-bottom: 7px; }
.kpis .val { display: block; font-size: clamp(24px, 2.8vw, 30px); font-weight: 800; letter-spacing: -.025em; line-height: 1; font-variant-numeric: tabular-nums; }
.kpis .sub { display: block; font-size: 12px; font-weight: 500; color: var(--encre-douce); margin-top: 5px; }

.toasts { display: flex; flex-direction: column; gap: var(--e-2); margin-bottom: var(--e-5); }

/* Repli du rail — bandeau horizontal collant sous 920 px, navigation sur sa
   propre rangée sous 580 px. Posé ici, et pas en section 5 : à spécificité
   égale, c'est la dernière règle qui gagne, et les règles de coquille
   ci-dessus reposent la disposition en colonne. */
@media (max-width: 920px) {
  .pnav        { flex-wrap: nowrap; align-items: center; align-content: center;
                 position: sticky; top: 0; z-index: 1000; padding: 0;
                 box-shadow: 0 1px 3px rgba(16, 27, 46, .3); }
  .pnav-brand  { flex: 0 0 auto; padding: 9px 4px 9px 14px; border-bottom: 0; }
  .pnav-brand [data-wordmark] { display: none; }
  .pnav-links  { flex: 1 1 0%; min-width: 0; order: 2; flex-wrap: nowrap;
                 overflow-x: auto; overflow-y: hidden; padding: 0 6px; gap: 2px;
                 scrollbar-width: none; }
  .pnav-links::-webkit-scrollbar { display: none; }
  .pnav-links a { flex: 0 0 auto; padding: 0 12px; }
  .pnav-sect   { display: none; }
  .pnav-user   { flex: 0 0 auto; order: 3; margin: 0; padding: 9px 12px;
                 background: transparent; border-radius: 0; }
  .pnav-user [data-usermeta] { display: none; }
}
@media (max-width: 580px) {
  .pnav        { flex-wrap: wrap; }
  .pnav-links  { flex: 1 1 100%; order: 2; padding: 0 8px 8px; }
  .pnav-user   { order: 1; margin-left: auto; }
}

/* Au-dessus de 920 px, le rail colle au bord haut et occupe toute la hauteur
   de la fenêtre. Sans cette règle, `align-content: flex-start` sur `.app` borne
   chaque rangée à la hauteur de son contenu : `align-self: stretch` n'étire le
   rail que jusqu'au bas de SA rangée, et le fond bleu s'arrête au dernier lien
   sur les pages courtes. `height` (et non `min-height`) pour que le rail défile
   dans son propre cadre quand ses entrées dépassent la fenêtre. */
@media (min-width: 921px) {
  .pnav { position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto; }
  /* Une entrée par rangée, quelle que soit la largeur du rail : la base de
     176 px de `.pnav-links a` autorisait deux colonnes dès que le rail
     dépassait ~370 px (libellé long, zoom, police plus grande). */
  .pnav-links a { flex: 1 1 100%; }
}

@media (max-width: 920px) {
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-2); padding: 0 0 22px; }
  .kpis > div, .kpis > div:nth-child(4n+1) { box-sizing: border-box; padding: 13px var(--e-4); background: var(--surface); border-radius: 10px; box-shadow: var(--ombre-1); border-left: 0; }
}
@media (max-width: 430px) {
  .kpis { grid-template-columns: minmax(0, 1fr); }
}

/* `.kpi-bande` (bandeau à liseré, cf. section 5) reprend le même repli carte
   que `.kpis` : même geste sous 920 px pour les deux systèmes de bandeau. */
@media (max-width: 920px) {
  .kpi-bande { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-2); }
  .kpi-bloc, .kpi-bloc:first-child { box-sizing: border-box; padding: 13px var(--e-4); background: var(--surface); border-radius: 10px; box-shadow: var(--ombre-1); border-left: 0; }
}
@media (max-width: 430px) {
  .kpi-bande { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   8. Gabarits
   Ce que la livraison ne portait pas : les classes des écrans eux-mêmes.
   Trame commune à toute page — en-tête à surtitre, bande de chiffres, cartes
   blanches sans bordure, groupes d'onglets en segments. Aucune couleur hors
   rampe, aucun !important : tout passe par les tokens de la section 2.
   -------------------------------------------------------------------------- */

/* En-tête de page : titre à gauche, recherche et actions à droite ----------- */
.page-tete       { display: flex; align-items: flex-end; gap: var(--e-5); flex-wrap: wrap; margin-bottom: var(--e-6); }
.page-tete-txt   { flex: 1 1 280px; min-width: 0; }
.page-tete-act   { flex: 0 1 auto; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }

/* Recherche : la loupe est dans le champ, pas à côté */
.recherche       { position: relative; flex: 1 1 240px; min-width: 200px; display: block; }
.recherche svg   { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: var(--encre-douce); pointer-events: none; }
.recherche input { width: 100%; min-height: 46px; padding: 0 18px 0 42px; border: 0; border-radius: var(--r-action); background: var(--surface); box-shadow: var(--ombre-1); font-size: 13.5px; font-weight: 500; }
.recherche input:focus { border-color: transparent; }

/* Boutons de la bande d'actions : 46 px, rayon 10 (charte du 16/09) */
.actions         { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding-bottom: var(--e-6); }
.actions .btn,
.page-tete-act .btn { min-height: 46px; border-radius: var(--r-action); padding: 0 var(--e-5); font-size: 13.5px; }
.btn.calme       { background: var(--surface-calme); color: var(--bleu-700); }
.btn.calme:hover { background: var(--surface); color: var(--encre); box-shadow: var(--ombre-1); }
.btn.ok          { background: var(--succes-100); color: var(--succes-700); }
.btn.ok:hover    { background: var(--succes); color: var(--encre-inverse); }

/* Retour : le fil d'Ariane de l'application se résume à un bouton */
.retour          { display: inline-flex; align-items: center; gap: var(--e-2); min-height: 36px; padding: 0 13px 0 10px; border-radius: 9px; background: var(--surface-calme); color: var(--bleu-700); font-size: 12.5px; font-weight: 600; }
.retour:hover    { background: var(--surface); color: var(--encre); box-shadow: var(--ombre-1); text-decoration: none; }

/* Barre de filtres --------------------------------------------------------- */
.filtres         { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; padding-bottom: 22px; }
.filtres-sep     { flex: none; width: 1px; height: 22px; background: var(--bordure-lin); margin: 0 3px; }
.filtres-fin     { margin-left: auto; display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; }
.filtres-cpt     { font-size: 12.5px; font-weight: 600; color: var(--encre-douce); white-space: nowrap; }

/* Segments : bascule de vue et groupes d'onglets --------------------------- */
.segments        { display: inline-flex; align-items: center; gap: 3px; padding: 3px; border-radius: 11px; background: var(--lin-300); max-width: 100%; flex-wrap: wrap; }
.segment         { display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2); min-height: 34px; padding: 0 13px; border: 0; border-radius: var(--r-3); background: transparent; color: var(--bleu-700); font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.segment:hover   { color: var(--encre); text-decoration: none; }
.segment.actif   { background: var(--surface); color: var(--encre); box-shadow: 0 1px 2px rgba(27, 42, 68, .12); }
.segments.onglets           { margin-bottom: var(--e-6); }
.segments.onglets .segment  { min-height: 38px; padding: 0 15px; }
.segments.onglets .segment:hover:not(.actif) { background: var(--surface-calme); }

/* Titre de bloc : libellé, compteur, filet jusqu'au bord ------------------- */
.bloc            { display: block; }
.bloc-tete       { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: 13px; }
.bloc-t          { display: inline-flex; align-items: center; gap: var(--e-2); font-size: var(--t-colonne); line-height: var(--lh-colonne); font-weight: 700; letter-spacing: var(--ls-section); text-transform: uppercase; color: var(--bleu-700); }
.bloc-t.urgent   { color: var(--erreur-700); }
.bloc-t.calme    { color: var(--encre); }
.bloc-cpt        { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-2); background: var(--lin-300); color: var(--encre); font-size: var(--t-micro); font-weight: 700; font-variant-numeric: tabular-nums; }
.bloc-cpt.urgent { background: var(--erreur); color: var(--encre-inverse); }
.bloc-cpt.fort   { background: var(--bleu); color: var(--encre-inverse); }
.bloc-filet      { flex: 1; min-width: 20px; height: 1px; background: var(--bordure-lin); }
.bloc-note       { font-size: 11.5px; font-weight: 500; color: var(--encre-douce); }

/* Carte de la charte : blanche, rayon 12, SANS bordure, ombre à deux couches
   (.card de la section 5 garde sa bordure pour les gabarits non repris)      */
.carte           { background: var(--surface); border-radius: var(--r-carte); box-shadow: var(--ombre-carte); }
.carte.pad       { padding: var(--e-5) clamp(16px, 1.8vw, 22px); }
a.carte:hover,
.carte.cliquable:hover { box-shadow: var(--ombre-carte-survol); text-decoration: none; }

/* --------------------------------------------------------------------------
   Agenda de cartes — accueil Marchés
   Le tableau de onze colonnes devient une pile de cartes groupée par échéance.
   -------------------------------------------------------------------------- */
.agenda          { display: flex; flex-direction: column; gap: var(--e-3); }

/* En-tête de groupe de l'agenda. C'est le même élément que la ligne `.grp-row`
   du tableau — mêmes classes, même comportement de repli — mais hors table :
   il lui faut sa propre mise en forme. */
.agenda-grp      { display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
                   margin: var(--e-5) 0 2px; padding: 0 2px; cursor: pointer;
                   font-size: var(--t-colonne); line-height: var(--lh-colonne);
                   font-weight: 700; letter-spacing: var(--ls-section);
                   text-transform: uppercase; color: var(--encre); }
.agenda-grp:first-child       { margin-top: 0; }
.agenda-grp.danger            { color: var(--erreur-700); }
.agenda-grp.warn              { color: var(--orange-700); }
.agenda-grp .grp-caret        { transition: transform var(--transition); }
.agenda-grp.collapsed .grp-caret { transform: rotate(-90deg); }
/* Un groupe replié garde son en-tête : c'est lui qui dit combien il cache. */
.agenda-grp.collapsed         { opacity: .75; }
.cartes          { display: flex; flex-direction: column; gap: var(--e-3); }

.mcarte          { display: flex; flex-wrap: wrap; overflow: hidden; background: var(--surface); border-radius: var(--r-carte); box-shadow: var(--ombre-carte); }
.mcarte:hover    { box-shadow: var(--ombre-carte-survol); }

/* Pavé d'échéance : la seule couleur de la carte, elle dit le temps restant */
.mcarte-ech      { flex: 0 0 auto; min-width: 92px; padding: var(--e-5) 18px; display: flex; flex-direction: column; gap: 3px; background: var(--bleu-50); }
.mcarte-ech b    { font-size: 24px; font-weight: 800; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--bleu-700); }
.mcarte-ech span { font-size: 12.5px; font-weight: 600; color: var(--bleu-700); font-variant-numeric: tabular-nums; }
.mcarte-ech i    { font-style: normal; font-size: 11.5px; font-weight: 500; color: var(--bleu-600); font-variant-numeric: tabular-nums; }
.mcarte-ech.depasse                  { background: var(--erreur-100); }
.mcarte-ech.depasse b,
.mcarte-ech.depasse span,
.mcarte-ech.depasse i                { color: var(--erreur-700); }
.mcarte-ech.depasse b                { color: var(--erreur); }
.mcarte-ech.j7                       { background: var(--orange-100); }
.mcarte-ech.j7 b                     { color: var(--orange-500); }
.mcarte-ech.j7 span,
.mcarte-ech.j7 i                     { color: var(--orange-700); }
.mcarte-ech.j14                      { background: var(--cuivre-100); }
.mcarte-ech.j14 b                    { color: var(--cuivre-600); }
.mcarte-ech.j14 span                 { color: var(--encre); }
.mcarte-ech.j14 i                    { color: var(--bleu-700); }

.mcarte-corps    { flex: 1 1 300px; min-width: 0; padding: var(--e-5) clamp(16px, 1.8vw, 22px); }
.mcarte-hdr      { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 7px; }
.mcarte-titre    { display: block; font-size: clamp(15.5px, 1.35vw, 17.5px); font-weight: 600; line-height: 1.3; letter-spacing: -.012em; color: var(--encre); text-wrap: pretty; }
.mcarte-titre:hover { color: var(--encre); text-decoration: underline; }
.mcarte-meta     { display: flex; align-items: center; gap: 7px 16px; flex-wrap: wrap; margin-top: var(--e-2); font-size: 12.5px; font-weight: 500; color: var(--encre-douce); }
.mcarte-meta span{ display: inline-flex; align-items: center; gap: 6px; }

/* Note : un filet cuivre, jamais une bordure complète */
.note-bloc       { display: flex; align-items: flex-start; gap: 11px; margin-top: 13px; padding: 11px 14px; border-radius: var(--r-3); background: var(--lin-100); }
.note-bloc::before { content: ""; flex: none; width: 2px; align-self: stretch; border-radius: 2px; background: var(--cuivre); }
.note-bloc p     { flex: 1; min-width: 0; margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--bleu-700); white-space: pre-wrap; text-wrap: pretty; }

/* Une carte sans note ne montre que le bouton « Ajouter » : pas de bloc vide,
   pas de « Pas de note. » répété sur chaque ligne de la page. */
/* Carte sans note : RIEN, pas même un bouton « Ajouter ». Sur vingt cartes,
   vingt boutons pour un geste qu'on fait trois fois par semaine faisaient du
   bruit ; le crayon revient au survol de la carte, là où on va le chercher. */
.note-bloc.note-vide            { background: transparent; padding: 0; margin-top: 0; }
.note-bloc.note-vide::before,
.note-bloc.note-vide .marche-note { display: none; }
.note-bloc.note-vide .note-btn  { opacity: 0; margin-top: 9px; transition: opacity var(--transition); }
.mcarte:hover .note-bloc.note-vide .note-btn,
.note-bloc.note-vide .note-btn:focus-visible { opacity: 1; }

/* Le crayon seul. `.note-btn-lbl` reste dans le DOM — c'est lui que le script
   met à jour après enregistrement — mais il ne s'affiche plus. */
.note-btn        { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 28px; height: 28px; padding: 0; border: 1px solid var(--bordure); border-radius: var(--r-2); background: var(--surface); color: var(--encre-douce); cursor: pointer; }
.note-btn:hover  { border-color: var(--bleu-600); color: var(--encre); }
.note-btn .note-btn-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* `.lot-pill` est un lien (clic = ouvrir le devis du lot) : on neutralise
   l'ancienne pastille — largeur fixe (elle débordait de la colonne), coins arrondis
   (ils incurvaient le filet de séparation entre deux lots) et fonds `ddp-fait` /
   `ddp-attente`, survol compris : dans la carte, le lot est une ligne, pas un jeton.
   Le survol de `.lot-pill` est plus spécifique dans `perrin-ui.css` — d'où `:hover`
   ici aussi, sans quoi le gris de l'ancienne pastille revient au passage de souris. */
.mcarte-lots .lot-pill,
.mcarte-lots .lot-pill:hover    { width: auto; box-sizing: border-box; background: transparent;
                                  border: 0; border-radius: 0; padding: 0; cursor: pointer; }
.mcarte-lots .lot-pill:hover .lot-nom > span:first-child { color: var(--lien); }

/* Vue compacte : là, `.lot-pill` reste un jeton — c'est voulu, le tableau est dense.
   Seule sa palette héritée est ramenée sur celle de la charte : elle sortait du
   nuancier (vert #1f9d57, gris #5c6470) et jurait à côté de la jauge. La teinte
   garde son sens : demande de prix faite (`ddp-fait`) ou non (`ddp-attente`). */
.lots-flex .lot-pill.ddp-fait          { background: var(--succes-100); color: var(--succes-700); border-color: var(--succes); }
.lots-flex .lot-pill.ddp-fait:hover    { background: var(--succes-100); filter: brightness(.98); }
.lots-flex .lot-pill.ddp-attente       { background: var(--bleu-50); color: var(--encre-douce); border-color: transparent; }
.lots-flex .lot-pill.ddp-attente:hover { background: var(--bleu-50); filter: brightness(.98); }

/* Colonne des lots : sur fond Lin, elle se détache sans trait de séparation */
.mcarte-lots     { flex: 1 1 236px; min-width: 0; max-width: 300px; padding: var(--e-5) clamp(16px, 1.8vw, 22px); background: var(--lin-100); display: flex; flex-direction: column; gap: 11px; }
.lots-tete       { display: flex; align-items: baseline; gap: var(--e-2); flex-wrap: wrap; font-size: var(--t-colonne); font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--encre-douce); }
.lots-tete .mnt  { margin-left: auto; font-size: 13px; font-weight: 800; letter-spacing: 0; text-transform: none; color: var(--encre); font-variant-numeric: tabular-nums; }
.lots-tete .vide { margin-left: auto; font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--encre-douce); }
.lot             { display: flex; flex-direction: column; gap: 7px; }
.lot + .lot      { padding-top: 9px; border-top: 1px solid var(--bordure-lin); }
.lot-nom         { display: flex; align-items: center; gap: var(--e-2); font-size: 11.5px; font-weight: 700; color: var(--encre); }
.lot-nom > span:first-child { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lot-nom .mnt    { margin-left: auto; flex: none; font-variant-numeric: tabular-nums; }
.lot-nom .prix   { margin-left: auto; flex: none; display: inline-flex; align-items: center; justify-content: center;
                   padding: 1px 7px; border-radius: 5px; background: var(--orange-100); color: var(--orange-700); font-size: var(--t-micro); }
/* Rien à lancer : l'attente n'est pas une action, elle ne prend pas la couleur d'appel. */
.lot-nom .prix.attente { background: var(--bleu-50); color: var(--bleu-700); }

/* Ligne d'état : le compte à gauche, le détail des prix poussé à droite. */
.lot-etat        { display: flex; align-items: center; gap: var(--e-2); font-size: var(--t-micro); font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--encre-douce); }
.lot-etat.encours{ color: var(--orange-700); }
.lot-etat.fini   { color: var(--succes-700); }
.lot-etat.vide   { color: var(--encre-douce); }
.lot-etat .ddp-mini { margin-left: auto; flex: none; }

/* Jauge d'avancement en six crans : lisible sans survol, imprimable */
.jauge           { display: flex; gap: 3px; }
.jauge span      { flex: 1; height: 4px; border-radius: 2px; background: var(--lin-300); }
.jauge span.on   { background: var(--cuivre); }
.jauge.presse span.on { background: var(--orange); }
.jauge.fini span.on   { background: var(--succes); }
/* Les crans allumés prennent la rampe d'avancement `--prog-0..6`, la même que la
   barre qu'ils remplacent : la couleur ne change donc pas de sens d'un écran à
   l'autre. `.lot-step-N` est la classe déjà posée par `_ouv_step()`. */
.jauge.lot-step-0 span.on { background: var(--prog-0); }
.jauge.lot-step-1 span.on { background: var(--prog-1); }
.jauge.lot-step-2 span.on { background: var(--prog-2); }
.jauge.lot-step-3 span.on { background: var(--prog-3); }
.jauge.lot-step-4 span.on { background: var(--prog-4); }
.jauge.lot-step-5 span.on { background: var(--prog-5); }
.jauge.lot-step-6 span.on { background: var(--prog-6); }

/* Pastilles de signal : DCE, étude administrative, lien de consultation */
.sigs            { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: 11px; }
.sig             { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 7px; background: var(--bleu-50); color: var(--encre-douce); }
.sig.ok          { background: var(--succes-100); color: var(--succes-700); }
.sig.warn        { background: var(--alerte-100); color: var(--alerte-700); }
.sig.err         { background: var(--erreur-100); color: var(--erreur-700); }
.sig.nu          { background: transparent; color: var(--cuivre-600); }
.ouvrir          { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--lien); }

/* Colonne « À faire » d'un tableau : les pastilles à droite, sur une rangée. */
/* Le tableau présenté en CARTE (maquette, écrans 7 et 8) : pas de bordure, le
   rayon des cartes, l'ombre à deux couches, le pied de liste à l'intérieur.
   `.tbl-carte` ENVELOPPE un `.tbl-wrap`, à qui il ne reste que le défilement.
   Le fond de la carte prend la couleur de l'EN-TÊTE et `tbody` porte le blanc :
   l'en-tête est un rectangle à angles droits dans un conteneur à rayon 12, et
   un croissant blanc dépassait dans chaque coin haut — arrondir les cellules
   d'extrémité n'y fait rien, `border-collapse:collapse` ignore leur rayon.
   Sous 760 px le tableau devient une pile de cartes, qui portent déjà la leur :
   le conteneur s'efface, sinon il fait une carte dans une carte. */
.tbl-carte                       { border-radius: var(--r-carte); background: var(--lin-200);
                                   box-shadow: var(--ombre-carte); overflow: hidden; }
.tbl-carte .tbl-wrap             { border: 0; border-radius: 0; background: transparent; }
.tbl-carte table.ds tbody        { background: var(--surface); }
@media (max-width: 760px) {
  .tbl-carte                     { background: transparent; box-shadow: none; overflow: visible; }
  .tbl-carte table.ds tbody      { background: transparent; }
  .tbl-carte .tbl-pied           { border-radius: var(--r-carte); }
}

/* `.empty` est un encadré pleine largeur ; `.sans` est son équivalent EN LIGNE,
   pour une donnée absente au milieu d'une phrase ou d'une cellule. */
.sans               { font-size: 12.5px; color: var(--encre-douce); }

td.sigs-cell        { text-align: right; }
td.sigs-cell .sigs  { margin: 0; padding: 0; flex-wrap: nowrap; justify-content: flex-end; }

/* Étiquettes de carte ------------------------------------------------------ */
.eti             { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: var(--r-2); background: var(--bleu-50); color: var(--bleu-700); font-size: var(--t-micro); font-weight: 700; }
.eti.agence      { font-weight: 800; letter-spacing: .06em; padding: 3px var(--e-2); }
.eti.agence.pmb  { background: var(--orange-100); color: var(--orange-700); }
.eti.agence.pbe  { background: var(--info-100);   color: var(--info-700); }
.eti.ref         { font-family: var(--police-chiffres); background: transparent; color: var(--encre-douce); padding: 3px 0; }
.eti.favori      { background: var(--cuivre-100); color: var(--encre); }
.eti.warn        { background: var(--alerte-100); color: var(--alerte-700); }
.eti.err         { background: var(--erreur-100); color: var(--erreur-700); }
.eti.ok          { background: var(--succes-100); color: var(--succes-700); }
.eti.visite      { background: var(--erreur); color: var(--encre-inverse); text-transform: uppercase; letter-spacing: .04em; }

/* Groupes repliés : <details>, donc dépliables sans JavaScript -------------- */
.pli             { background: var(--surface); border-radius: var(--r-carte); box-shadow: var(--ombre-1); }
.pli:hover       { box-shadow: var(--ombre-carte); }
.pli > summary   { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; padding: var(--e-4) var(--e-5); cursor: pointer; list-style: none; }
.pli > summary::-webkit-details-marker { display: none; }
.pli > summary .lib  { font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-section); text-transform: uppercase; color: var(--encre); }
.pli > summary .det  { font-size: 12.5px; font-weight: 500; color: var(--encre-douce); }
.pli > summary .plus { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--lien); }
.pli > summary .plus::after        { content: "Déplier"; }
.pli[open] > summary .plus::after  { content: "Replier"; }
.pli[open] > summary .plus svg     { transform: rotate(180deg); }
.pli-corps       { padding: 0 var(--e-5) var(--e-5); }

/* --------------------------------------------------------------------------
   Tableau dense → liste de cartes sous 760 px
   On pose data-col sur chaque cellule ; sous le seuil, l'en-tête de colonne
   revient en libellé devant la valeur et la ligne devient une carte.
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
  .tbl-wrap.cartes-mobile                     { border: 0; background: transparent; overflow: visible; }
  table.ds.cartes-mobile,
  table.ds.cartes-mobile tbody                { display: block; width: 100%; }
  /* Une largeur minimale posée pour le mode tableau (et qui l'empêche de
     s'écraser à côté du rail) clipperait la carte : en pile, elle n'a plus
     lieu d'être. */
  table.ds.cartes-mobile                      { min-width: 0; }
  table.ds.cartes-mobile thead                { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  table.ds.cartes-mobile tbody tr             { display: block; margin-bottom: var(--e-3); padding: var(--e-4); border-radius: var(--r-carte); background: var(--surface); box-shadow: var(--ombre-carte); }
  table.ds.cartes-mobile tbody tr:hover       { background: var(--surface); }
  table.ds.cartes-mobile tbody td             { display: block; height: auto; padding: 9px 0; border-bottom: 1px solid var(--filet); text-align: left; }
  table.ds.cartes-mobile tbody td:last-child  { border-bottom: 0; padding-bottom: 0; }
  table.ds.cartes-mobile tbody td::before     { content: attr(data-col); display: block; margin-bottom: 4px; font-size: var(--t-colonne); line-height: var(--lh-colonne); font-weight: var(--g-colonne); letter-spacing: var(--ls-colonne); text-transform: uppercase; color: var(--encre-douce); }
  table.ds.cartes-mobile tbody td[data-col=""]::before { content: none; }
  /* Les colonnes de chiffres reviennent à gauche : en carte, elles ne sont
     plus alignées sur une colonne voisine. */
  table.ds.cartes-mobile tbody td.n           { text-align: left; }
  table.ds.cartes-mobile td.total-lab          { text-align: left; }
  /* En carte, plus rien ne justifie de tronquer : la largeur n'est plus
     contrainte par une colonne voisine. */
  table.ds.cartes-mobile tbody td,
  table.ds.cartes-mobile tbody td * { white-space: normal; overflow: visible;
                                      text-overflow: clip; max-width: none; }
  table.ds.cartes-mobile tbody td .lot-pill,
  table.ds.cartes-mobile tbody td .lots-flex { width: auto; }
  table.ds.cartes-mobile tbody td.sigs-cell,
  table.ds.cartes-mobile tbody td.sigs-cell .sigs { justify-content: flex-start; text-align: left; }
  /* La ligne de tête de groupe reste une bande pleine largeur */
  table.ds.cartes-mobile tbody tr.grp-row     { padding: 0; background: transparent; box-shadow: none; }
  table.ds.cartes-mobile tbody tr.grp-row td  { display: block; min-height: 0; padding: var(--e-3) var(--e-4); border: 0; border-radius: var(--r-2); }
  table.ds.cartes-mobile tbody tr.grp-row td::before { content: none; }
}

/* --------------------------------------------------------------------------
   Détail marché — bandeau d'échéance et fiches
   -------------------------------------------------------------------------- */
.chiffres        { flex: 1 1 300px; min-width: 0; display: flex; align-items: stretch; gap: var(--e-3); flex-wrap: wrap; }
.chiffre         { flex: 1 1 124px; min-width: 118px; padding: var(--e-4) 18px; border-radius: var(--r-carte); background: var(--lin-100); }
.chiffre .lab    { display: block; font-size: var(--t-colonne); font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--encre-douce); margin-bottom: 6px; }
.chiffre .val    { display: block; font-size: 24px; font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--encre); font-variant-numeric: tabular-nums; }
.chiffre .val u  { font-size: .58em; font-weight: 700; color: var(--encre-douce); text-decoration: none; }
.chiffre .sub    { display: block; font-size: 12.5px; font-weight: 500; color: var(--encre-douce); margin-top: 5px; font-variant-numeric: tabular-nums; }
.chiffre.presse            { background: var(--orange-100); }
.chiffre.presse .lab,
.chiffre.presse .sub       { color: var(--orange-700); font-weight: 600; }
.chiffre.presse .val       { color: var(--orange-500); }
.chiffre.depasse           { background: var(--erreur-100); }
.chiffre.depasse .lab,
.chiffre.depasse .sub      { color: var(--erreur-700); font-weight: 600; }
.chiffre.depasse .val      { color: var(--erreur); }

/* Fiche : paires libellé / valeur, sans tableau */
.fiche           { display: flex; flex-direction: column; }
.fiche-l         { display: flex; align-items: baseline; gap: var(--e-3); flex-wrap: wrap; padding: 9px 0; border-bottom: 1px solid var(--lin-200); }
.fiche-l:last-child { border-bottom: 0; }
.fiche-lab       { flex: 0 0 150px; font-size: var(--t-colonne); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--encre-douce); }
.fiche-lab.court { flex-basis: 128px; }
.fiche-val       { flex: 1 1 150px; min-width: 0; font-size: 13px; color: var(--encre); }
.fiche-val.vide  { color: var(--encre-douce); font-style: italic; }
.fiche-val.alerte{ color: var(--erreur-700); font-weight: 600; }
.fiche-src       { font-weight: 700; letter-spacing: .04em; padding: 2px 6px; border-radius: 5px; background: var(--info-100); color: var(--info-700); }
.fiche-src.ccap  { background: var(--orange-100); color: var(--orange-700); }
.fiche-src.ae    { background: var(--erreur-100); color: var(--erreur-700); }
.fiche-src.optim { background: var(--succes-100); color: var(--succes-700); }
.grille          { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); gap: var(--e-6) var(--e-7); align-items: start; }
.grille.large    { grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap: var(--e-3); }
.grille.lots     { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--e-3); }

/* Carte de lot du détail marché */
.lcarte          { display: block; padding: 18px var(--e-5); color: var(--encre); }
.lcarte-tete     { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 11px; }
.lcarte-nom      { flex: 1; min-width: 0; font-size: 15.5px; font-weight: 600; letter-spacing: -.012em; }
.lcarte-mnt      { font-size: 14px; font-weight: 800; white-space: nowrap; font-variant-numeric: tabular-nums; }
.lcarte-mnt.vide { font-size: 12.5px; font-weight: 600; color: var(--encre-douce); }
.lcarte-pied     { display: flex; align-items: center; gap: var(--e-2) var(--e-4); flex-wrap: wrap; font-size: 12px; font-weight: 600; color: var(--encre-douce); }
.lcarte-pied .ddp{ margin-left: auto; display: inline-flex; align-items: center; gap: 5px; }
.lcarte .bar-track { height: 7px; margin-bottom: 9px; }

/* Dépôt de fichiers : zone d'accueil, pas un bouton déguisé */
.depot           { display: flex; flex-direction: column; align-items: center; gap: 9px; margin-top: var(--e-4); padding: 22px; border-radius: 9px; background: var(--lin-100); text-align: center; }

/* --------------------------------------------------------------------------
   Détail lot — frise des étapes et bandeau de signaux
   -------------------------------------------------------------------------- */
.lot-tete        { position: sticky; top: 0; z-index: 900; margin: calc(var(--e-6) * -1) calc(clamp(16px, 3vw, 40px) * -1) 0; padding: var(--e-4) clamp(16px, 3vw, 40px) 0; background: var(--fond); box-shadow: 0 1px 0 var(--bordure-lin); }
.lot-tete-l      { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; }
.lot-tete-t      { flex: none; display: inline-flex; align-items: baseline; gap: 9px; font-size: clamp(15px, 1.8vw, 18px); font-weight: 800; letter-spacing: -.02em; color: var(--encre); white-space: nowrap; }
.lot-tete-t span { font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--encre-douce); }
.pousse          { flex: 1; min-width: 12px; }

.signaux         { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; padding-top: 10px; }
.signal          { display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--r-3); background: var(--bleu-50); color: var(--bleu-700); font-family: inherit; font-size: 11.5px; font-weight: 700; }
button.signal    { cursor: pointer; }
.signal.warn     { background: var(--alerte-100); color: var(--alerte-700); }
.signal.info     { background: var(--info-100);   color: var(--info-700); }
.signal.accent   { background: var(--orange);     color: var(--encre-inverse); }
.signal.accent:hover { background: var(--orange-600); }
.signal.doux     { background: var(--orange-100); color: var(--orange-700); }
.signal.ok       { background: var(--succes-100); color: var(--succes-700); }

/* Frise : quatorze étapes en escalier de couleur, sur autant de rangées qu'il
   faut. La charte livrée tenait la rangée unique (`nowrap` + `overflow-x:auto`)
   avec la barre de défilement masquée — mesuré au banc sur quatorze étapes :
   924 px hors cadre à 390, 436 à 900, 172 à 1440, et aucun indice qu'il reste
   quelque chose à droite. « Tableau des portes » et « Consultations » n'étaient
   atteignables à aucune largeur. La maquette (écran 3) replie : `flex-wrap:wrap`. */
.frise           { display: flex; gap: 4px; flex-wrap: wrap; padding: var(--e-3) 0 var(--e-4); }
.frise .etape    { flex: 1 1 auto; min-width: 0; min-height: 34px; padding: 0 10px; border: 0; border-radius: var(--r-3); background: var(--bleu-50); color: var(--encre-douce); font-family: inherit; font-size: 11.5px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 5px; white-space: nowrap; overflow: hidden; cursor: pointer; }
.frise .etape.faite    { background: var(--succes-100); color: var(--succes-700); }
.frise .etape.encours  { background: var(--orange);     color: var(--encre-inverse); }
.frise .etape.afaire   { background: var(--bleu-50);    color: var(--encre-douce); }
.frise .etape.consult  { background: var(--cuivre-100); color: var(--cuivre-600); }
.frise .etape.inconnu  { background: var(--lin-100);    color: var(--encre-douce); border: 1px dashed var(--bleu-100); }
.frise .etape.actif    { background: var(--orange-100); color: var(--orange-700); outline: 2px solid var(--orange); outline-offset: -2px; }
.frise .etape:hover:not(.actif) { color: var(--encre); }

/* Bandeau de totaux au-dessus du bordereau */
.tbl-tete        { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; padding: 15px clamp(14px, 1.8vw, 20px); background: var(--lin-100); }
.tbl-tete .lib   { font-size: var(--t-colonne); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--bleu-700); }
.tbl-tete .cpt   { margin-left: auto; font-size: 12.5px; font-weight: 500; color: var(--encre-douce); }
.tbl-tete .mnt   { font-size: 15px; font-weight: 800; color: var(--encre); font-variant-numeric: tabular-nums; }
.tbl-pied        { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; padding: var(--e-4); background: var(--lin-100); font-size: 12px; font-weight: 500; color: var(--encre-douce); }
.tbl-pied a      { margin-left: auto; font-weight: 600; }
table.ds tbody tr.attente td { background: var(--alerte-100); }
table.ds tbody tr.capture td { background: var(--orange-100); }
table.ds tbody tr.total  td  { background: var(--lin-100); font-weight: 700; }
table.ds td.total-lab        { text-align: right; font-size: var(--t-colonne); letter-spacing: var(--ls-colonne); text-transform: uppercase; }

/* --------------------------------------------------------------------------
   Aujourd'hui — une ligne = une action, la couleur dit l'urgence
   -------------------------------------------------------------------------- */
.jour-sect       { display: block; }
.jour-sect-tete  { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: var(--e-4); padding-bottom: var(--e-2); border-bottom: 2px solid var(--encre); }
.jour-sect-tete.calme { border-bottom-color: var(--bleu-100); }
.jour-sect-t     { font-size: 13px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--encre); }
.jour-sect-tete.calme .jour-sect-t { font-weight: 600; color: var(--encre-douce); }
.jour-sect-cpt   { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
.jour-lab        { font-size: var(--t-colonne); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--encre-douce); margin: 0 0 9px; }
.jour-liste      { display: flex; flex-direction: column; gap: 9px; margin-bottom: 22px; }
.jour-liste:last-child { margin-bottom: 0; }

.tache           { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--e-3); padding: var(--e-4) clamp(14px, 1.6vw, 18px); border-radius: 10px; background: var(--surface); border-left: 5px solid var(--bleu-300); box-shadow: var(--ombre-1); }
.tache-txt       { flex: 1 1 380px; min-width: 0; }
.tache-t         { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; font-size: 15px; line-height: 1.4; color: var(--encre); text-wrap: pretty; }
.tache-t b       { font-weight: 700; color: var(--succes-700); }
.tache-det       { font-size: 12.5px; line-height: 1.5; color: var(--encre-douce); margin-top: 4px; }
.tache-det a     { font-weight: 600; color: var(--bleu-700); border-bottom: 1px solid var(--bleu-100); }
.tache-det a:hover { color: var(--encre); text-decoration: none; }
.tache-det .lot  { display: inline-block; margin-left: 7px; padding: 1px 7px; border-radius: 5px; background: var(--bleu-50); color: var(--bleu-700); font-size: var(--t-micro); font-weight: 700; vertical-align: 1px; }
.tache-act       { flex: 0 1 auto; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-left: auto; }
.tache-note      { width: 190px; max-width: 44vw; min-height: 38px; border: 0; border-radius: var(--r-3); background: var(--lin-100); font-size: 12.5px; }
.tache-note:focus{ background: var(--surface); }
.tache-quand     { flex: none; font-size: var(--t-micro); font-weight: 800; letter-spacing: .07em; text-transform: uppercase; padding: 3px var(--e-2); border-radius: 5px; background: var(--bleu-50); color: var(--bleu-700); }

/* Trois crans d'urgence : à venir, aujourd'hui, en retard */
.tache.presse    { background: #FFFAF3; border-left-color: var(--orange); }
.tache.presse .tache-quand { background: var(--orange-100); color: var(--orange-700); }
.tache.jour      { background: #FDF8F8; border-left-color: var(--erreur); }
.tache.jour .tache-t       { color: var(--erreur-700); }
.tache.jour .tache-quand   { background: var(--erreur); color: var(--encre-inverse); }
.tache.retard    { background: var(--erreur-700); border-left-color: var(--erreur-700); }
.tache.retard .tache-t,
.tache.retard .tache-det a { color: var(--encre-inverse); }
.tache.retard .tache-det   { color: var(--erreur-100); }
.tache.retard .tache-det a { border-bottom-color: rgba(255, 255, 255, .45); }
.tache.retard .tache-det .lot { background: rgba(255, 255, 255, .22); color: var(--encre-inverse); }
.tache.retard .tache-quand { background: var(--encre-inverse); color: var(--erreur-700); }
.tache.retard .tache-note  { background: var(--surface); }
.tache.faite     { border-left-color: var(--succes); }
.tache.relance   { border-left-color: var(--bleu-300); }

.deborde         { margin-top: var(--e-3); }
.deborde > summary { cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--bleu-700); padding: 9px var(--e-3); border-radius: var(--r-3); background: var(--lin-100); }
.deborde ul      { margin: var(--e-2) 0 0; padding-left: var(--e-5); font-size: 12.5px; line-height: 1.6; color: var(--encre-douce); }

/* --------------------------------------------------------------------------
   Connexion — panneau de marque à gauche, carte à droite
   -------------------------------------------------------------------------- */
.connexion       { min-height: 100vh; display: flex; flex-wrap: wrap; align-items: stretch; background: var(--bleu-900); }
.connexion-marque{ flex: 1 1 380px; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; gap: 40px; padding: clamp(28px, 5vw, 64px); }
.connexion-marque img { height: clamp(34px, 4vw, 44px); width: auto; align-self: flex-start; }
.connexion-marque h1  { max-width: 30ch; font-size: clamp(28px, 4vw, 42px); line-height: 1.08; color: var(--encre-inverse); }
.connexion-marque p   { max-width: 30ch; margin: var(--e-4) 0 0; font-size: var(--t-corps); line-height: 1.6; color: var(--bleu-100); text-wrap: pretty; }
.connexion-sur   { display: inline-flex; align-items: center; gap: 10px; font-size: var(--t-colonne); font-weight: 700; letter-spacing: var(--ls-section); text-transform: uppercase; color: var(--lin-300); margin-bottom: var(--e-4); }
.connexion-sur::before { content: ""; width: 20px; height: 2px; background: var(--cuivre); }
.connexion-pied  { font-size: 11.5px; font-weight: 500; color: var(--bleu-300); }
.connexion-panneau { flex: 1 1 440px; min-width: 0; display: flex; align-items: center; justify-content: center; padding: clamp(20px, 4vw, 48px); background: var(--fond); }
.connexion-carte { width: 100%; max-width: 410px; padding: clamp(24px, 3vw, 34px); }
.connexion-carte img  { height: 40px; width: auto; display: block; margin-bottom: 22px; }
.connexion-carte h2   { font-size: 21px; line-height: 1.2; }
.connexion-carte p    { margin: 6px 0 22px; font-size: 13px; line-height: 1.55; color: var(--encre-douce); }
.connexion-carte .btn { width: 100%; min-height: 48px; border-radius: var(--r-action); font-size: var(--t-corps); }
.ou              { display: flex; align-items: center; gap: var(--e-3); margin: 22px 0; }
.ou::before, .ou::after { content: ""; flex: 1; height: 1px; background: var(--filet); }
.ou span         { font-size: var(--t-colonne); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--encre-douce); }
.encart          { display: flex; align-items: flex-start; gap: 10px; padding: var(--e-3) 14px; border-radius: 9px; background: var(--lin-100); font-size: 12.5px; line-height: 1.55; color: var(--bleu-700); text-wrap: pretty; }
.encart svg      { flex: none; margin-top: 1px; color: var(--encre-douce); }
.encart.err      { background: #FDF8F8; box-shadow: 0 0 0 1px #F0D6D3 inset; color: var(--erreur-700); }
.encart.err svg  { color: var(--erreur); }
.encart.info     { background: var(--info-100); color: var(--info-700); }
.encart.info svg { color: var(--info-700); }

/* --------------------------------------------------------------------------
   Replis communs
   -------------------------------------------------------------------------- */
@media (max-width: 920px) {
  /* La carte de marché devient une pile ; l'échéance passe en barre */
  .mcarte          { flex-direction: column; flex-wrap: nowrap; border-radius: 10px; }
  .mcarte-ech      { flex: 0 0 auto; width: 100%; min-width: 0; flex-direction: row; align-items: baseline; gap: 10px; padding: 11px var(--e-4); }
  .mcarte-ech b    { font-size: 19px; }
  .mcarte-ech i    { margin-left: auto; }
  .mcarte-corps    { flex: 0 0 auto; width: 100%; padding: var(--e-4); }
  .mcarte-lots     { flex: 0 0 auto; width: 100%; max-width: none; padding: var(--e-4); border-top: 1px solid var(--bordure-lin); }
  .lot-tete        { margin-inline: calc(clamp(16px, 3vw, 40px) * -1); }
}

@media (max-width: 580px) {
  .page-tete-act   { width: 100%; }
  .filtres-fin     { margin-left: 0; width: 100%; }
  .tache-act       { margin-left: 0; width: 100%; }
  .tache-note      { flex: 1; width: auto; max-width: none; }
  .fiche-lab,
  .fiche-lab.court { flex-basis: 100%; }
}

/* --------------------------------------------------------------------------
   6. Impression
   Les e-mails et exports PDF ne chargent pas cette feuille : ils gardent
   leurs styles inline. Cette section ne vaut que pour l'impression écran.
   -------------------------------------------------------------------------- */
@media print {
  body { background: var(--blanc); }
  .pnav, .btn, .chip, .toast, .segments, .recherche, .actions, .tache-act { display: none; }
  .card, .panel, .tbl-wrap { box-shadow: none; border-color: var(--bleu-100); }
  .carte, .mcarte, .pli, .tache { box-shadow: none; border: 1px solid var(--bleu-100); }
  .lot-tete { position: static; box-shadow: none; }
  .pli[open] > summary .plus, .pli > summary .plus { display: none; }
  table.ds thead th { position: static; }
  /* Un groupe replié ne s'imprime pas vide : on le déplie à l'impression. */
  .pli-corps { display: block; }
}

/* --------------------------------------------------------------------------
   9. Composants hérités — dernières classes de ao-base/ao-ui/ao-one et de
   style/perrin-ui/perrin-one (suivi) qui n'ont pas d'équivalent nommé dans
   les sections précédentes. Les six feuilles sont supprimées ; ces noms de
   classe restent dans les gabarits (et, pour les onglets, dans le JS qui les
   sélectionne) — les retoucher n'apportait rien que ce fichier ne fasse déjà
   en les habillant des tokens de la section 2. Aucune couleur hors rampe.
   À supprimer classe par classe à mesure que les gabarits qui la portent
   passent aux composants natifs de la charte (section 8).
   -------------------------------------------------------------------------- */

/* Onglets « tablink/tabcontent » — apercu_marche.html et marche_detail.html.
   Ce dernier pose déjà `.segment` À CÔTÉ de `.tablink` (même bouton, classes
   cumulées) : `:not(.segment)` laisse `.segment` gouverner seul cet écran-là,
   et ne dessine le bouton nu que pour apercu_marche.html, qui n'a pas
   `.segment`. `.tabcontent{display:none}` reste réel : c'est lui qui masque
   les panneaux inactifs avant que le JS (openTab / initOnglets) ne les montre. */
.tablink:not(.segment) {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--controle-h); padding: 0 var(--e-4);
  border: 1px solid var(--bordure); border-radius: var(--r-2);
  background: var(--lin-100); color: var(--bleu-700);
  font-family: inherit; font-size: var(--t-dense); font-weight: 600;
  cursor: pointer; white-space: nowrap; text-decoration: none;
}
.tablink:not(.segment):hover  { background: var(--bleu-50); color: var(--bleu-700); text-decoration: none; }
.tablink:not(.segment).active { background: var(--bleu); border-color: var(--bleu-900); color: var(--encre-inverse); }
.tabcontent { display: none; padding: var(--e-3) 0; }

/* Favoris nominatifs — apercu_marche.html (bandeau de fiche). */
.favori-p1      { color: var(--succes-700); font-size: 1.1em; font-weight: 700; }
.favori-p2      { color: var(--alerte-700); font-size: 1.1em; font-weight: 700; }
.favori-p3      { color: var(--encre);      font-size: 1.1em; font-weight: 700; }
.favori-sylvain { color: var(--orange-600); font-size: 1.1em; font-weight: 700; }
.favori-anthony { color: var(--cuivre-600); font-size: 1.1em; font-weight: 700; }

/* Texte d'alerte hors pastille (échéance en tête de fiche). */
.red { color: var(--erreur); font-size: 1.1em; font-weight: 700; }

/* Tableau des demandes de prix — apercu_marche.html, marche_detail.html. */
.demande-table { width: 100%; border-collapse: collapse; font-size: var(--t-dense); margin-top: var(--e-3); }
.demande-table th, .demande-table td { border: 1px solid var(--bordure-lin); padding: var(--e-3) var(--e-4); vertical-align: top; }
.demande-table thead { background: var(--bleu-900); color: var(--encre-inverse); }
.demande-actions { white-space: nowrap; }
.demande-actions .btn { padding: 4px 8px; font-size: .85em; margin-right: 6px; }

/* Recherche pleine largeur — apercu_marches.html (le champ `.rech` de la
   section 5 est calibré pour l'en-tête d'écran, plus étroit). */
.search { position: relative; width: 100%; max-width: 460px; }
.search input { width: 100%; box-sizing: border-box; min-height: var(--controle-h); padding: 0 16px 0 42px; border: 1px solid var(--bordure); border-radius: var(--r-3); font-family: inherit; font-size: 14px; font-weight: 600; color: var(--encre); background: var(--surface); outline: none; box-shadow: var(--ombre-1); transition: var(--transition); }
.search input::placeholder { color: var(--bleu-300); font-weight: 500; }
.search input:focus { border-color: var(--bleu-600); box-shadow: var(--focus); }
.search svg { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--bleu-300); pointer-events: none; }
.search:focus-within svg { color: var(--orange); }

/* Puces de filtre groupées — apercu_marches.html (`.chip` seul existe déjà). */
.chips        { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.chip-grp-lab { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--encre-douce); margin-right: 2px; }

/* Légende des pastilles de demande de prix — apercu_marches.html. */
.ddp-legende   { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; font-size: 11px; font-weight: 600; color: var(--encre-douce); margin: 0 0 var(--e-4); }
.ddp-legende b { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.ddp-legende .dot   { width: 13px; height: 13px; border-radius: 4px; }
.ddp-legende .dot.g { background: var(--bleu-50); }
.ddp-legende .dot.v { background: var(--succes-100); }

/* Bande de KPI en grille libre — apercu_marches.html. `.kpi` (section 5) fait
   déjà la carte ; il ne manque que le conteneur et le contenu en `.lab`/`.val`,
   qu'il redéclarait lui-même en `.kpi-lab`/`.kpi-val`. */
.grid-kpi      { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--e-4); }
.kpi .lab      { font-size: var(--t-colonne); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--encre-douce); }
.kpi .val      { font-weight: 800; font-size: 27px; letter-spacing: -.02em; margin-top: 6px; color: var(--encre); }
.kpi .val small{ font-size: 14px; font-weight: 700; color: var(--encre-douce); }
.kpi .note     { font-size: 11.5px; color: var(--encre-douce); margin-top: 4px; font-weight: 500; }
.kpi.hero      { border-left-color: var(--orange); }
.kpi.hero .val { color: var(--orange); }
.kpi.info      { border-left-color: var(--info); }
.kpi.info .val { color: var(--info); }

/* Pastille de lot : libellé tronqué, montant. */
.lot-pill-lbl { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lot-montant  { font-size: 10.5px; font-weight: 800; color: var(--bleu-900); white-space: nowrap; }

/* Pastille d'état ponctuelle — marches.html (seule survivante : VISITE
   obligatoire ; `.eti`/`.etat` de la section 5 couvrent tout le reste). */
.st-pill        { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: var(--r-2); font-size: var(--t-micro); font-weight: 700; letter-spacing: .03em; text-transform: uppercase; background: var(--bleu-50); color: var(--bleu-700); }
.st-pill.visite { background: var(--erreur); color: var(--encre-inverse); }

/* Étiquette compacte — marches.html (pastille de favori posée en JS, couleur
   fournie en style inline par le serveur). */
.ty { display: inline-block; font-size: 9.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 1px 6px; border-radius: var(--r-1); background: var(--bleu-50); color: var(--bleu-700); vertical-align: middle; }

/* Chiffres alignés — marches.html, lot_detail.html. */
.num { font-variant-numeric: tabular-nums; }

/* Modale d'état : le contenu (tableau + actions), la coquille est en section 5. */
.etat-modal-table            { width: 100%; border-collapse: collapse; font-size: var(--t-dense); }
.etat-modal-table th,
.etat-modal-table td          { border: 1px solid var(--bordure-lin); padding: var(--e-3) var(--e-4); }
.etat-modal-table thead        { background: var(--bleu); color: var(--encre-inverse); }
.etat-modal-actions .btn      { margin-right: 6px; }

/* Groupe de boutons d'action — marches_gagnes/negociation/perdus/repondus.html. */
.action-group { display: flex; gap: 6px; flex-wrap: wrap; }

/* Champ de cellule éditable, masqué jusqu'au clic — marche_detail.html. */
.cell-input { width: 100%; box-sizing: border-box; }

/* Dépôt d'un e-mail de réponse — marche_detail.html (le gabarit resserre déjà
   `td .email-dropzone` en `display:flex` ; il ne manque que le décor). */
.email-dropzone           { border: 2px dashed var(--succes); padding: var(--e-3); border-radius: var(--r-2); text-align: center; cursor: pointer; background: var(--succes-100); transition: background var(--transition); }
.email-dropzone.dragover  { background: #E3FFE3; border-color: var(--bleu); }
.email-status             { font-size: .85em; color: var(--encre-douce); margin-top: 6px; }

/* Compteurs de demandes de prix d'un lot — _lot_avancement.html. */
.ddp-lbl  { font-size: 9px; font-weight: 800; letter-spacing: .04em; color: var(--encre-douce); text-transform: uppercase; }
.ddp-chip { display: inline-flex; align-items: center; justify-content: center; min-width: 15px; height: 15px; padding: 0 3px; border-radius: 4px; font-size: 9.5px; font-weight: 800; color: var(--encre-inverse); }
.ddp-chip.c-lancer  { background: var(--orange); }
.ddp-chip.c-attente { background: var(--info); }
.ddp-chip.c-recu    { background: var(--succes); }
.ddp-chip.zero      { background: var(--bleu-50); color: var(--encre-douce); }
.lot-pill .ddp-chip { height: 12px; min-width: 14px; }

/* Texte de visite obligatoire, sauts de ligne conservés — visites_obligatoires.html. */
.text-visite { white-space: pre-wrap; }

/* En-tête de filtres sur `<tr>` — visites_obligatoires.html (le conteneur
   `.filtres` de la section 8 vise un `<div>` de page, pas cette ligne-là). */
tr.filters th { background: var(--lin-100); padding: var(--e-1) var(--e-2); }

/* Zone de texte du prompt DCE (lecture, copie) — marches.html. */
.prompt-box { width: 100%; height: 220px; margin: 6px 0 var(--e-4); font-family: var(--police-chiffres); }
