/* =============================================================================================
   Feuille de style — outil de veille commerciale.

   Réécrite le 2026-09-01 en THÈME CLAIR. Le sombre avait été choisi par habitude de terminal, pas
   d'après la scène d'usage : cet outil se lit toute la journée, dans un bureau éclairé, à côté de
   documents budgétaires et de tableurs. Le clair est ce que fait le reste du poste de travail, et
   c'est ce que montre la référence donnée par l'utilisateur. La palette sombre reste vivante sous
   `prefers-color-scheme: dark` — mêmes jetons, valeurs échangées, aucune règle dupliquée.

   Sommaire
     1. Jetons          — couleurs (clair puis sombre), espacements, rayons, ombres
     2. Base            — corps, titres, liens, formulaires, surfaces du navigateur
     3. Ossature        — barre latérale, zone principale
     4. Composants      — cartes, tableaux, badges, filtres, panneaux
     5. Tableau de bord — bandeau, anneau, calendrier
     6. Adaptatif       — sous 1 100 px
   ============================================================================================= */

/* --- 1. Jetons ------------------------------------------------------------------------------ */

:root {
    /* Quatre profondeurs : le fond de page, les surfaces posées dessus, le survol, et les champs
       creusés dedans. Le fond est un blanc légèrement bleuté — sur un blanc pur, une carte blanche
       n'existe pas. */
    --fond: #f2f5fa;
    --surface: #ffffff;
    --surface-haute: #f6f9fd;
    --creux: #f4f7fb;

    --bordure: #e3e9f2;
    --bordure-forte: #c4cfe0;

    --texte: #101725;
    /* Trois niveaux de gris, tous mesurés au-dessus de 4,5:1 sur blanc — le seuil AA du texte
       courant. Le plus clair du premier jet (#7d889d) tombait à 3,6:1, et c'est précisément lui
       qui porte les titres de groupe du menu, les en-têtes de colonnes et les libellés de champs :
       les petits textes, ceux qui pardonnent le moins. */
    --texte-doux: #4a5568;
    --texte-faible: #6b7688;

    --accent: #1f57d3;
    --accent-fort: #17429f;
    --accent-doux: #e8f0ff;
    --sur-accent: #ffffff;

    /* Signaux. Retenus pour un fond clair : les teintes vives de l'ancienne palette sombre
       (#35c07a, #e0a72d) tombent à 2:1 sur du blanc — lisibles sur noir, illisibles ici. */
    --haut: #0f7f57;
    --moyen: #9c5f08;
    --bas: #6b7688;
    --urgent: #c62b3c;
    --sur-signal: #ffffff;

    --haut-doux: #e4f6ee;
    --moyen-doux: #fdf1dd;
    --urgent-doux: #fdeaec;

    /* Surbrillance des occurrences trouvées. Déclarée dans les deux thèmes : un jaune clair figé
       porterait du texte clair sur fond clair en mode sombre — illisible. */
    --surbrillance: #fff2a8;

    /* Le bandeau d'accueil, seul aplat saturé de l'application. */
    --heros-de: #1a49c4;
    --heros-vers: #2f7ae0;

    /* Élévation déclarée UNE fois : en clair une ombre porte les cartes et la bordure disparaît ;
       en sombre l'inverse — une ombre ne se voit pas sur un fond noir, une bordure oui. */
    --carte-bordure: 1px solid transparent;
    --carte-ombre: 0 1px 2px rgba(16, 23, 37, 0.05), 0 6px 16px -8px rgba(16, 23, 37, 0.14);
    --carte-ombre-survol: 0 2px 4px rgba(16, 23, 37, 0.06), 0 12px 26px -10px rgba(16, 23, 37, 0.2);
    --ombre-haute: 0 10px 30px -12px rgba(16, 23, 37, 0.28);

    --anneau-focus: rgba(31, 87, 211, 0.22);
    --selection: #cfe0ff;

    /* Échelle d'espacement. Cinq valeurs : à la main, on écrivait 0.4rem ici et 0.45rem là. */
    --e1: 0.35rem;
    --e2: 0.75rem;
    --e3: 1.25rem;
    --e4: 2rem;
    --e5: 3rem;

    --rayon: 14px;
    --rayon-petit: 9px;
    --rayon-grand: 20px;

    --largeur-laterale: 248px;

    font-family: "Segoe UI Variable Text", "Segoe UI", -apple-system, Roboto,
                 "Helvetica Neue", Arial, sans-serif;
    /* Chiffres à chasse fixe partout : c'est ce qui aligne scores et montants d'une ligne à
       l'autre, donc ce qui rend une colonne de nombres comparable d'un coup d'œil. */
    font-variant-numeric: tabular-nums;

    color-scheme: light;

    /* Alias conservés : quelques gabarits les utilisent encore en style en ligne. */
    --bg: var(--fond);
    --panel: var(--surface);
    --border: var(--bordure);
    --text: var(--texte);
    --muted: var(--texte-doux);
    --survol: var(--surface-haute);
    --high: var(--haut);
    --mid: var(--moyen);
    --low: var(--bas);
    --ombre: var(--carte-ombre);
}

/* Variante sombre. Seuls les jetons changent : aucune règle de composant n'est réécrite. */
@media (prefers-color-scheme: dark) {
    :root {
        --fond: #0d1017;
        --surface: #161a22;
        --surface-haute: #1d222c;
        --creux: #0a0d13;

        --bordure: #262c38;
        --bordure-forte: #3a4252;

        --texte: #e9ecf2;
        --texte-doux: #a2abba;
        --texte-faible: #7c8697;

        --accent: #6d9bff;
        --accent-fort: #8ab0ff;
        --accent-doux: #1b2740;
        --sur-accent: #0b0f18;

        --haut: #3ecb87;
        --moyen: #e6b13c;
        --bas: #7d8798;
        --urgent: #f0616f;
        --sur-signal: #0b0f18;

        --haut-doux: #10281f;
        --moyen-doux: #2a2113;
        --urgent-doux: #2c1418;

        --surbrillance: #4d3f10;

        --heros-de: #17307a;
        --heros-vers: #1d5399;

        --carte-bordure: 1px solid var(--bordure);
        --carte-ombre: none;
        --carte-ombre-survol: none;
        --ombre-haute: 0 10px 30px -12px rgba(0, 0, 0, 0.7);

        --anneau-focus: rgba(109, 155, 255, 0.28);
        --selection: #1e3763;

        color-scheme: dark;
    }
}

* { box-sizing: border-box; }

/* --- 2. Base -------------------------------------------------------------------------------- */

body {
    margin: 0;
    background: var(--fond);
    color: var(--texte);
    line-height: 1.55;
    font-size: 15px;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Les surfaces que le navigateur dessine à notre place appartiennent quand même à la page. */
::selection { background: var(--selection); color: var(--texte); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
* { scrollbar-color: var(--bordure-forte) transparent; scrollbar-width: thin; }
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--bordure-forte);
    border: 3px solid var(--fond);
    border-radius: 999px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--texte-faible); }

a { color: var(--accent); text-decoration: none; text-underline-offset: 0.18em; }
a:hover { text-decoration: underline; }

h1 { margin: 0 0 var(--e1); font-size: 1.6rem; font-weight: 680; letter-spacing: -0.025em; }
h2 {
    margin: var(--e5) 0 var(--e2);
    font-size: 1.02rem;
    font-weight: 680;
    letter-spacing: -0.012em;
}
h3 { margin: var(--e3) 0 var(--e2); font-size: 0.94rem; font-weight: 660; }

button {
    background: var(--accent);
    color: var(--sur-accent);
    border: 1px solid transparent;
    padding: 0.48rem 1.05rem;
    border-radius: var(--rayon-petit);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 570;
    transition: background 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
button:hover { background: var(--accent-fort); }
button:active { transform: translateY(1px); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

input, select, textarea {
    background: var(--creux);
    border: 1px solid var(--bordure);
    color: var(--texte);
    caret-color: var(--accent);
    padding: 0.48rem 0.65rem;
    border-radius: var(--rayon-petit);
    font-family: inherit;
    font-size: 0.9rem;
    transition: border-color 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
}
input::placeholder, textarea::placeholder { color: var(--texte-faible); }
input:hover, select:hover, textarea:hover { border-color: var(--bordure-forte); }
input:focus, select:focus, textarea:focus {
    outline: none;
    background: var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--anneau-focus);
}

/* Icônes : jeu dessiné (sprite en tête de `base.html`), même grille et même graisse de trait
   partout. Aucun caractère Unicode détourné en pictogramme. */
.ico {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.empty { color: var(--texte-doux); font-style: italic; }
.lien-discret { color: var(--texte-doux); font-size: 0.85rem; }
.lien-discret:hover { color: var(--accent); }

/* --- 3. Ossature ---------------------------------------------------------------------------- */

.app { display: grid; grid-template-columns: var(--largeur-laterale) 1fr; min-height: 100vh; }

.barre-laterale {
    display: flex;
    flex-direction: column;
    gap: var(--e4);
    padding: var(--e3) var(--e2) var(--e2);
    background: var(--surface);
    border-right: 1px solid var(--bordure);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.marque { display: flex; align-items: center; gap: var(--e2); padding: 0 var(--e2); color: inherit; }
.marque:hover { text-decoration: none; }
.marque-sceau {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: 10px;
    background: linear-gradient(140deg, var(--heros-vers), var(--heros-de));
    color: #fff;
    display: grid;
    place-items: center;
    box-shadow: 0 4px 10px -4px rgba(26, 73, 196, 0.6);
}
.marque-sceau .ico { width: 19px; height: 19px; stroke-width: 1.9; }
.marque-nom { display: block; font-weight: 700; font-size: 0.92rem; line-height: 1.2; letter-spacing: -0.015em; }
.marque-sous { display: block; color: var(--texte-faible); font-size: 0.73rem; margin-top: 1px; }

nav { display: flex; flex-direction: column; gap: var(--e3); flex: 1; }
.nav-groupe { display: flex; flex-direction: column; gap: 2px; }
.nav-groupe-titre {
    color: var(--texte-faible);
    font-size: 0.67rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 0 var(--e2) var(--e1);
}
.nav-lien {
    display: flex;
    align-items: center;
    gap: 0.62rem;
    color: var(--texte-doux);
    padding: 0.45rem var(--e2);
    border-radius: var(--rayon-petit);
    font-size: 0.885rem;
    font-weight: 500;
    transition: background 0.13s ease, color 0.13s ease;
}
.nav-lien .ico { color: var(--texte-faible); transition: color 0.13s ease; }
.nav-lien:hover { background: var(--surface-haute); color: var(--texte); text-decoration: none; }
.nav-lien:hover .ico { color: var(--texte-doux); }
/* La page courante est marquée par une barre ET une couleur : le repère reste lisible pour un œil
   qui distingue mal les nuances de bleu. */
.nav-lien-actif, .nav-lien-actif:hover {
    background: var(--accent-doux);
    color: var(--accent-fort);
    font-weight: 620;
    box-shadow: inset 2.5px 0 0 var(--accent);
}
.nav-lien-actif .ico, .nav-lien-actif:hover .ico { color: var(--accent); }

.barre-laterale-pied {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-top: var(--e2);
    border-top: 1px solid var(--bordure);
}
.compte {
    display: flex;
    align-items: center;
    gap: 0.62rem;
    padding: 0.45rem var(--e2);
    border-radius: var(--rayon-petit);
    color: inherit;
}
.compte:hover { background: var(--surface-haute); text-decoration: none; }
.compte-pastille {
    width: 28px;
    height: 28px;
    flex: none;
    border-radius: 999px;
    background: var(--accent-doux);
    color: var(--accent-fort);
    display: grid;
    place-items: center;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.compte-nom { display: block; font-size: 0.865rem; font-weight: 600; line-height: 1.2; }
.compte-role { display: block; color: var(--texte-faible); font-size: 0.71rem; text-transform: capitalize; }
.pied-liens { display: flex; align-items: center; gap: var(--e2); padding: var(--e1) var(--e2) 0; }
.pied-liens a { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.79rem; }
.pied-liens .ico { width: 0.95em; height: 0.95em; }

.zone-principale { padding: var(--e4) var(--e4) var(--e5); max-width: 1560px; }
/* `.container` sert aux pages hors application (connexion, MFA, confidentialité). */
.container { max-width: 1100px; margin: 0 auto; padding: var(--e4); }

.sous-titre { color: var(--texte-doux); margin: 0 0 var(--e3); max-width: 68ch; }

/* --- 4. Composants -------------------------------------------------------------------------- */

/* Bloc de contenu générique : c'est lui qui porte l'élévation, une seule fois. */
.panneau {
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
    padding: var(--e3);
}
.panneau-titre {
    display: flex;
    align-items: center;
    gap: var(--e2);
    margin: 0 0 var(--e3);
    font-size: 0.95rem;
    font-weight: 680;
    letter-spacing: -0.01em;
}
.panneau-titre .ico { color: var(--texte-faible); }
.panneau-lien { margin-left: auto; font-size: 0.82rem; font-weight: 500; }

/* Cartes de synthèse. Deux niveaux : ce qui appelle une action, et ce qui décrit un état. Sept
   cartes de poids identique ne hiérarchisaient rien. */
.stat-grid {
    display: grid;
    /* Colonnes par défaut : sans elles, une grille sans modificateur empilait ses cartes sur
       toute la largeur, une par ligne (constaté sur /bi). */
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--e2);
    margin-bottom: var(--e2);
}
.stat-grid-action { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.stat-grid-etat { grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); margin-bottom: var(--e4); }
.stat-card {
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
    padding: var(--e3);
    display: block;
    color: inherit;
}

/* Carte d'action : icône teintée, nombre, libellé, et une flèche qui n'apparaît qu'au survol —
   l'affordance sans le bruit permanent. La teinte distingue les quatre files de travail les unes
   des autres ; c'est le seul endroit où la couleur sert d'identité et non de niveau. */
.stat-card-action {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-rows: auto auto;
    column-gap: var(--e2);
    align-items: center;
    transition: box-shadow 0.16s ease, transform 0.16s ease;
}
.stat-card-action:hover {
    text-decoration: none;
    box-shadow: var(--carte-ombre-survol);
    transform: translateY(-2px);
}
.stat-jeton {
    grid-row: 1 / 3;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    display: grid;
    place-items: center;
    background: var(--accent-doux);
    color: var(--accent);
}
.stat-jeton .ico { width: 20px; height: 20px; }
.stat-card-action .stat-value { font-size: 1.85rem; }
.stat-fleche {
    grid-row: 1 / 3;
    color: var(--texte-faible);
    opacity: 0;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
.stat-card-action:hover .stat-fleche { opacity: 1; transform: translateX(2px); }

.teinte-bleu .stat-jeton { background: var(--accent-doux); color: var(--accent); }
.teinte-vert .stat-jeton { background: var(--haut-doux); color: var(--haut); }
.teinte-ambre .stat-jeton { background: var(--moyen-doux); color: var(--moyen); }
.teinte-rouge .stat-jeton { background: var(--urgent-doux); color: var(--urgent); }

.stat-card-discret {
    padding: var(--e2) var(--e3);
    box-shadow: none;
    border: 1px solid var(--bordure);
    background: transparent;
}
.stat-card-discret .stat-value { font-size: 1.25rem; color: var(--texte-doux); }
.stat-card-discret:hover { border-color: var(--bordure-forte); text-decoration: none; }
.stat-card-urgent .stat-value { color: var(--urgent); }
.stat-value { display: block; font-weight: 700; line-height: 1.12; letter-spacing: -0.03em; }
.stat-label { color: var(--texte-doux); font-size: 0.82rem; }

/* Tableaux. Aucun ne fait défiler la page : le débordement reste chez lui. */
/* Le débordement horizontal n'est confiné qu'en dessous de la largeur où il peut arriver.
   `overflow-x: auto` fait aussi de l'élément un conteneur de défilement VERTICAL (la spec force
   `overflow-y: visible` à `auto` dès que l'autre axe ne l'est pas) : les `th` collants s'y
   ancreraient alors sur un conteneur qui ne défile jamais, et cesseraient de suivre la page.
   Au-dessus de 1 100 px les tableaux tiennent dans la colonne — l'ancrage reste la fenêtre. */
.table-scroll {
    max-width: 100%;
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
}
.opportunities-table { width: 100%; border-collapse: collapse; }
.opportunities-table th, .opportunities-table td {
    text-align: left;
    padding: 0.62rem 0.85rem;
    border-bottom: 1px solid var(--bordure);
    vertical-align: top;
}
.opportunities-table th {
    color: var(--texte-faible);
    font-weight: 660;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
    /* En-tête collant : sur mille lignes, savoir quelle colonne on lit ne doit pas obliger à
       remonter en haut de la page. */
    position: sticky;
    top: 0;
    background: var(--surface);
    z-index: 1;
    border-bottom: none;
    box-shadow: inset 0 -1px 0 var(--bordure);
}
.opportunities-table td { font-size: 0.885rem; }
.opportunities-table tbody tr { transition: background 0.1s ease; }
.opportunities-table tbody tr:hover { background: var(--surface-haute); }
.opportunities-table tbody tr:last-child td { border-bottom: none; }
.opportunities-table td a { font-weight: 520; color: var(--texte); }
.opportunities-table td a:hover { color: var(--accent); }

/* La flèche n'apparaît que sur la colonne active : un indicateur neutre sur chaque colonne ferait
   sept signaux concurrents pour une seule information. */
.th-triable a { color: inherit; font-weight: inherit; display: inline-flex; gap: var(--e1); }
.th-triable a:hover { color: var(--texte); text-decoration: none; }
.th-actif a { color: var(--accent); }
.tri-fleche { font-size: 0.7rem; }

/* Montants alignés à droite : c'est ce qui permet de comparer deux ordres de grandeur d'un coup
   d'œil, au lieu de lire chaque chiffre. */
.cell-montant { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.score-badge {
    display: inline-block;
    min-width: 2.15rem;
    text-align: center;
    padding: 0.16rem 0.5rem;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.8rem;
    color: var(--sur-signal);
}
.score-high { background: var(--haut); }
.score-mid { background: var(--moyen); }
.score-low { background: var(--bas); }

.badge {
    display: inline-block;
    padding: 0.13rem 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 999px;
    font-size: 0.77rem;
    color: var(--texte-doux);
    background: var(--creux);
}
/* Compteur d'avis regroupés : il qualifie le titre sans lui disputer l'attention. */
.badge-avis { font-size: 0.71rem; white-space: nowrap; margin-left: var(--e1); }

/* Échéances : trois niveaux, pas un dégradé. Si le rouge servait aussi à quinze jours, il
   cesserait d'alerter. */
.echeance {
    display: inline-block;
    padding: 0.13rem 0.55rem;
    border-radius: 999px;
    font-size: 0.77rem;
    font-weight: 660;
    white-space: nowrap;
    border: 1px solid transparent;
}
.echeance-critique { background: var(--urgent); color: var(--sur-signal); }
.echeance-proche { background: var(--moyen-doux); color: var(--moyen); border-color: var(--moyen); }
.echeance-a_venir { color: var(--texte-doux); border-color: var(--bordure); }

.bar-chart {
    /* `display: block` explicite : la barre est parfois portée par un `<span>` dans une cellule,
       où l'affichage en ligne lui ôtait toute hauteur. */
    display: block;
    background: var(--creux);
    border: 1px solid var(--bordure);
    border-radius: 999px;
    height: 0.6rem;
    overflow: hidden;
}
.bar-fill { display: block; background: var(--accent); height: 100%; border-radius: 999px; }

/* Une valeur et sa barre côte à côte : le chiffre reste vérifiable, la barre rend l'ordre lisible
   sans avoir à comparer les chiffres deux à deux. */
.mesure { display: flex; align-items: center; gap: var(--e2); }
.mesure-valeur { min-width: 1.7rem; font-weight: 640; font-variant-numeric: tabular-nums; }
.mesure .bar-chart { flex: 1; max-width: 11rem; }

/* Vues rapides : la question posée en arrivant est « qu'est-ce que je traite aujourd'hui ? », pas
   « quels filtres dois-je composer ? ». */
.filtres-rapides { display: flex; align-items: center; flex-wrap: wrap; gap: var(--e1); margin-bottom: var(--e2); }
.filtres-rapides-libelle {
    color: var(--texte-faible);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-right: var(--e1);
}
.chip {
    padding: 0.32rem 0.85rem;
    border: 1px solid var(--bordure);
    background: var(--surface);
    border-radius: 999px;
    font-size: 0.845rem;
    color: var(--texte-doux);
    white-space: nowrap;
    transition: border-color 0.13s ease, color 0.13s ease;
}
.chip:hover { color: var(--texte); border-color: var(--bordure-forte); text-decoration: none; }
.chip-actif, .chip-actif:hover {
    color: var(--sur-accent);
    background: var(--accent);
    border-color: var(--accent);
    font-weight: 600;
}

/* Chaque champ porte son libellé : les seuls repères étaient les textes indicatifs, et deux champs
   de date affichaient « jj/mm/aaaa » à l'identique. */
.filtres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--e2) var(--e3);
    padding: var(--e3);
    margin-bottom: var(--e3);
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
}
.champ { display: flex; flex-direction: column; gap: var(--e1); }
.champ-large { grid-column: span 2; }
.champ > span {
    color: var(--texte-faible);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 600;
}
.champ input, .champ select { width: 100%; }
.filtres-actions { display: flex; align-items: flex-end; gap: var(--e2); }

.barre-resultats {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--e3);
    margin-bottom: var(--e2);
    flex-wrap: wrap;
}
.resultats-total { font-weight: 660; }
.results-count { color: var(--texte-doux); font-size: 0.85rem; }

.pagination { display: flex; gap: var(--e2); align-items: center; margin-top: var(--e2); }
.pagination button { background: var(--surface); color: var(--texte); border-color: var(--bordure); }
.pagination button:hover { background: var(--surface-haute); border-color: var(--bordure-forte); }
.pagination span { color: var(--texte-doux); font-size: 0.87rem; }

.saved-searches { display: flex; align-items: center; gap: var(--e2); margin-bottom: var(--e3); flex-wrap: wrap; }
.saved-searches form { display: flex; gap: var(--e1); }
.saved-list { display: flex; gap: var(--e1); flex-wrap: wrap; }
.saved-chip {
    background: var(--surface);
    border: 1px solid var(--bordure);
    padding: 0.26rem 0.7rem;
    border-radius: 999px;
    font-size: 0.845rem;
}

.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: var(--e3);
    margin: var(--e3) 0 var(--e4);
    padding: var(--e3);
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
}
/* Chaque couple libellé/valeur est un bloc : posés à plat dans la grille, ils devenaient des
   cases indépendantes et une valeur se retrouvait sous le libellé voisin. */
.detail-champ dt {
    color: var(--texte-faible);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 600;
}
.detail-champ dd { margin: var(--e1) 0 0; font-size: 0.95rem; }

.objet-text { white-space: pre-wrap; line-height: 1.65; max-width: 72ch; }
.score-details {
    background: var(--creux);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    padding: var(--e3);
    white-space: pre-wrap;
    font-size: 0.82rem;
    color: var(--texte-doux);
    overflow-x: auto;
}
.sources-list { line-height: 1.9; }

.crm-panel {
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
    padding: var(--e3);
    margin: var(--e3) 0;
}
.crm-panel h2 { margin-top: 0; }
.crm-panel h3 { margin-bottom: var(--e1); }
.crm-panel label { display: block; color: var(--texte-doux); font-size: 0.85rem; margin-bottom: var(--e1); }
.crm-panel select { width: 100%; margin-bottom: var(--e3); }
.next-action-form { display: flex; gap: var(--e1); align-items: flex-end; margin-bottom: var(--e3); flex-wrap: wrap; }
.next-action-form input[name="prochaine_action"] { flex: 1; min-width: 200px; }
.note-form { display: flex; gap: var(--e1); align-items: flex-start; margin-bottom: var(--e2); }
.note-form textarea { flex: 1; min-height: 2.6rem; resize: vertical; }
.notes-list { list-style: none; margin: 0; padding: 0; }
.notes-list li { border-top: 1px solid var(--bordure); padding: var(--e2) 0; }
.notes-list li:first-child { border-top: none; }
.notes-list p { margin: var(--e1) 0 0; white-space: pre-wrap; }
.note-date { color: var(--texte-faible); font-size: 0.78rem; }

/* Actions dans une cellule de tableau : compactes, sur une seule colonne. */
.row-actions { display: flex; gap: var(--e1); align-items: center; margin-top: var(--e1); }
.row-actions input { width: 11rem; padding: 0.3rem 0.5rem; }

/* --- 5. Tableau de bord --------------------------------------------------------------------- */

/* Bandeau d'accueil : le seul aplat saturé de l'application, et le seul endroit où la recherche
   est offerte sans qu'on l'ait demandée. Ailleurs, un bleu plein toute la journée fatiguerait la
   lecture des tableaux, qui est le vrai travail. */
.heros {
    position: relative;
    overflow: hidden;
    border-radius: var(--rayon-grand);
    background: linear-gradient(118deg, var(--heros-de) 0%, var(--heros-vers) 100%);
    color: #fff;
    padding: var(--e4);
    margin-bottom: var(--e4);
    box-shadow: var(--ombre-haute);
}
/* Géométrie, pas illustration : des arcs concentriques et un aplat diagonal, purement décoratifs
   et masqués aux lecteurs d'écran. */
.heros-motif { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.heros-contenu { position: relative; max-width: 46rem; }
.heros-date {
    display: block;
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.11em;
    font-weight: 620;
    color: rgba(255, 255, 255, 0.72);
}
.heros h1 { color: #fff; font-size: 1.9rem; margin: var(--e1) 0; letter-spacing: -0.03em; }
.heros-phrase { color: rgba(255, 255, 255, 0.86); margin: 0 0 var(--e3); max-width: 52ch; }
.heros-recherche { display: flex; gap: var(--e2); max-width: 38rem; }
.heros-champ { position: relative; flex: 1; }
.heros-champ .ico {
    position: absolute;
    left: 0.85rem;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: #6b7688;
}
.heros-recherche input {
    width: 100%;
    background: #fff;
    border-color: transparent;
    color: #101725;
    caret-color: #1a49c4;
    padding: 0.72rem 0.9rem 0.72rem 2.6rem;
    font-size: 0.95rem;
}
.heros-recherche input::placeholder { color: #6b7688; }
.heros-recherche input:focus { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.45); border-color: transparent; }
.heros-recherche button {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(255, 255, 255, 0.45);
    color: #fff;
    padding-inline: 1.3rem;
}
.heros-recherche button:hover { background: rgba(255, 255, 255, 0.28); }

/* Deux panneaux de tête : la composition de la file, et sa répartition dans le temps. */
.tableau-duo {
    display: grid;
    grid-template-columns: minmax(19rem, 0.85fr) minmax(24rem, 1.15fr);
    gap: var(--e2);
    align-items: start;
    margin-bottom: var(--e2);
}

/* Anneau de composition. Dessiné en SVG (`stroke-dasharray` sur des cercles) : trois valeurs
   n'ont pas besoin d'une bibliothèque de graphes, et chaque part est un lien vers la recherche
   filtrée correspondante — sinon ce ne serait qu'une décoration. */
.anneau-bloc { display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap; }
.anneau { position: relative; width: 146px; height: 146px; flex: none; }
.anneau svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.anneau-piste { stroke: var(--creux); }
/* `stroke-width` est une propriété SVG, pas une propriété de mise en page : elle repeint
   l'anneau de 146 px, elle ne relance pas le calcul de la page. Le détecteur de motifs la
   signale par ressemblance de nom avec `width` — c'est un faux positif, noté ici pour ne pas
   le réexaminer à chaque passage. */
.anneau-part { transition: stroke-width 0.16s ease; }
.anneau-part:hover { stroke-width: 20; }
.anneau-centre { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; line-height: 1.15; }
.anneau-total { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.03em; }
.anneau-sous { font-size: 0.72rem; color: var(--texte-faible); text-transform: uppercase; letter-spacing: 0.07em; }
.anneau-legende { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 11rem; }
.legende-ligne {
    display: grid;
    grid-template-columns: 0.65rem 1fr auto;
    align-items: center;
    gap: var(--e2);
    padding: 0.34rem var(--e2);
    border-radius: var(--rayon-petit);
    color: var(--texte-doux);
    font-size: 0.865rem;
}
.legende-ligne:hover { background: var(--surface-haute); color: var(--texte); text-decoration: none; }
.legende-marque { width: 0.65rem; height: 0.65rem; border-radius: 3px; }
.legende-nombre { font-weight: 660; color: var(--texte); font-variant-numeric: tabular-nums; }

/* Calendrier des dépôts. La liste des échéances dit *quoi* ; la grille dit *quand* — qu'une
   semaine soit vide et la suivante chargée est une information de charge de travail. */
.calendrier-bloc { display: grid; grid-template-columns: auto 1fr; gap: var(--e3); align-items: start; }
.calendrier { border-collapse: collapse; }
.calendrier th {
    color: var(--texte-faible);
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding-bottom: var(--e1);
    text-align: center;
}
.calendrier td { padding: 1px; }
.jour {
    width: 2.15rem;
    height: 2.15rem;
    display: grid;
    place-items: center;
    border-radius: 9px;
    font-size: 0.8rem;
    color: var(--texte-doux);
    position: relative;
}
.jour-vide { visibility: hidden; }
.jour-aujourdhui { outline: 1.5px solid var(--accent); color: var(--accent); font-weight: 700; }
/* Un jour porteur d'échéance est un aplat, pas une pastille sous le chiffre : à cette taille, un
   point de 4 px se confond avec le crénage du chiffre au-dessus. */
.jour-charge { background: var(--moyen-doux); color: var(--moyen); font-weight: 700; }
.jour-charge:hover { background: var(--moyen); color: var(--sur-signal); text-decoration: none; }
.jour-compte {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 0.2rem;
    border-radius: 999px;
    background: var(--urgent);
    color: var(--sur-signal);
    font-size: 0.62rem;
    font-weight: 700;
    display: grid;
    place-items: center;
    border: 1.5px solid var(--surface);
}
.calendrier-liste { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.calendrier-ligne {
    display: grid;
    grid-template-columns: 3.6rem 1fr auto;
    align-items: baseline;
    gap: var(--e2);
    padding: 0.4rem var(--e2);
    border-radius: var(--rayon-petit);
    color: inherit;
    font-size: 0.86rem;
    min-width: 0;
}
.calendrier-ligne:hover { background: var(--surface-haute); text-decoration: none; }
.calendrier-jour {
    color: var(--texte-faible);
    font-size: 0.75rem;
    font-weight: 660;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.calendrier-titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Deux colonnes de listes courtes en bas de tableau de bord. */
.tableau-colonnes { display: grid; grid-template-columns: repeat(auto-fit, minmax(23rem, 1fr)); gap: var(--e2); }
.liste-simple { display: flex; flex-direction: column; }
.liste-ligne {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--e2);
    padding: 0.5rem var(--e2);
    border-radius: var(--rayon-petit);
    color: inherit;
    min-width: 0;
}
.liste-ligne:hover { background: var(--surface-haute); text-decoration: none; }
.liste-titre { font-size: 0.885rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.liste-meta { color: var(--texte-faible); font-size: 0.77rem; white-space: nowrap; }

/* --- Explication d'un score ------------------------------------------------------------------ */

/* La décomposition était affichée en dictionnaire Python brut. C'est l'information la plus utile
   du produit — pourquoi ce dossier est classé là — et c'était la moins lisible de la page. */
.explication {
    display: grid;
    grid-template-columns: 1fr minmax(15rem, 20rem);
    gap: var(--e3) var(--e4);
    align-items: start;
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
    padding: var(--e3);
}
.explication-signaux { display: flex; flex-direction: column; gap: var(--e3); }
.signal-groupe { display: flex; flex-direction: column; gap: var(--e1); }
.signal-titre {
    color: var(--texte-faible);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 600;
}
.signal-liste { display: flex; flex-wrap: wrap; gap: var(--e1); }
.signal {
    padding: 0.16rem 0.62rem;
    border-radius: 999px;
    font-size: 0.815rem;
    border: 1px solid var(--bordure);
    color: var(--texte-doux);
    background: var(--creux);
}
/* Un signal fort porte la couleur de l'accent, un signal contraire celle de l'alerte : la teinte
   dit le rôle, la lecture ne dépend pas de l'ordre des groupes. */
.signal-fort { color: var(--accent-fort); border-color: var(--accent); background: var(--accent-doux); font-weight: 560; }
.signal-cpv { border-style: dashed; }
.signal-negatif { color: var(--urgent); border-color: var(--urgent); background: var(--urgent-doux); }

.explication-raisons { margin: 0; padding-left: 1.1rem; color: var(--texte-doux); }
.explication-raisons li { margin-bottom: var(--e1); }

.explication-points { border-collapse: collapse; width: 100%; align-self: start; }
.explication-points td { padding: 0.32rem 0; border-bottom: 1px solid var(--bordure); font-size: 0.875rem; }
.explication-points td:first-child { color: var(--texte-doux); }
.explication-valeur { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.explication-negative { color: var(--urgent); }
.explication-total td {
    border-bottom: none;
    border-top: 1px solid var(--bordure-forte);
    padding-top: var(--e2);
    font-weight: 700;
    color: var(--texte) !important;
}

.explication-note { grid-column: 1 / -1; margin: 0; color: var(--texte-faible); font-size: 0.815rem; }

/* Retour visuel pendant une recherche. Cliquer sur « Rechercher » ne produisait aucun signe : sur
   1 300 marchés la requête prend une fraction de seconde, assez pour douter d'avoir cliqué. htmx
   pose la classe `htmx-request` sur l'élément désigné par `hx-indicator` pendant la requête. */
.chargement {
    opacity: 0;
    transition: opacity 0.15s ease;
    color: var(--texte-doux);
    font-size: 0.85rem;
    padding: var(--e1) 0;
}
.chargement.htmx-request { opacity: 1; }

/* État vide : il doit dire quoi faire, pas seulement constater. */
.etat-vide {
    text-align: center;
    padding: var(--e5) var(--e3);
    background: var(--surface);
    border: 1px dashed var(--bordure-forte);
    border-radius: var(--rayon);
    color: var(--texte-doux);
}
.etat-vide-titre { display: block; color: var(--texte); font-weight: 620; margin-bottom: var(--e1); font-size: 1rem; }
.etat-vide-actions { display: flex; gap: var(--e2); justify-content: center; margin-top: var(--e3); flex-wrap: wrap; }

/* Requête refusée. Fond teinté plutôt qu'un trait d'accent : la distinction avec l'état vide
   ordinaire doit se voir d'un coup d'œil, parce que les deux messages ne veulent pas dire du tout
   la même chose — « rien ne correspond » contre « rien n'a été cherché ». */
.etat-vide-refus { background: var(--urgent-doux); border-style: solid; border-color: var(--urgent); color: var(--texte); }
.aide-syntaxe { display: flex; gap: var(--e2); justify-content: center; margin-top: var(--e3); flex-wrap: wrap; }
.aide-syntaxe code {
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: calc(var(--rayon) / 2);
    padding: 0.2em 0.55em;
    font-size: 0.79rem;
    color: var(--texte-doux);
}

/* Légende des scores : « 91/100 » ne dit rien tant qu'on ignore où sont les seuils. */
.legende { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; color: var(--texte-faible); font-size: 0.79rem; }
.legende-item { display: inline-flex; align-items: center; gap: var(--e1); }
.legende-pastille { width: 0.65rem; height: 0.65rem; border-radius: 3px; display: inline-block; }

/* Juger depuis la liste. Deux boutons par ligne plutôt qu'une sélection multiple : sur des dossiers
   qu'il faut lire pour juger, un clic par ligne est plus rapide qu'une sélection puis une action
   groupée. Le vert retient, le rouge écarte, comme partout ailleurs. */
.cell-verdict { white-space: nowrap; }
.bouton-verdict {
    background: var(--surface);
    border: 1px solid var(--bordure);
    color: var(--texte-doux);
    padding: 0.22rem 0.62rem;
    font-size: 0.79rem;
    font-weight: 600;
}
.bouton-retenir:hover { background: var(--haut); border-color: var(--haut); color: var(--sur-signal); }
.bouton-ecarter:hover { background: var(--urgent); border-color: var(--urgent); color: var(--sur-signal); }
.bouton-verdict + .bouton-verdict { margin-left: var(--e1); }

/* --- Fiche marché ---------------------------------------------------------------------------- */

/* Elle n'affichait que six champs dans une grille de définitions, dont plusieurs vides. Trois
   colonnes, dans l'ordre des questions qu'on se pose devant un appel d'offres : à qui ai-je
   affaire, combien de temps me reste-t-il, qu'est-ce que c'est exactement. */
.fiche-entete { margin-bottom: var(--e3); }
.fiche-entete h1 { max-width: 55ch; }
.fiche-badges { display: flex; flex-wrap: wrap; gap: var(--e1); align-items: center; margin-top: var(--e2); }
.badge-fort { color: var(--accent-fort); border-color: var(--accent); background: var(--accent-doux); font-weight: 600; }
.badge-alerte { color: var(--urgent); border-color: var(--urgent); background: var(--urgent-doux); font-weight: 650; }
.badge-reference { font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }

.fiche-colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: var(--e2);
    align-items: start;
    margin-bottom: var(--e4);
}
.fiche-colonnes .panneau h3 { margin: var(--e3) 0 var(--e1); }

.fiche-acheteur-nom { margin: 0 0 var(--e2); font-size: 1.02rem; font-weight: 640; }
.fiche-acheteur-nom a { color: var(--texte); }
.fiche-acheteur-nom a:hover { color: var(--accent); }

/* Couples libellé/valeur en lignes, pas en grille : sur une colonne étroite, deux colonnes de
   définitions cassent les paires dès qu'une valeur passe à la ligne. */
.fiche-champs { margin: 0; display: flex; flex-direction: column; }
.fiche-champs > div {
    display: grid;
    grid-template-columns: 10rem 1fr;
    gap: var(--e2);
    padding: 0.38rem 0;
    border-top: 1px solid var(--bordure);
}
.fiche-champs > div:first-child { border-top: none; padding-top: 0; }
.fiche-champs dt { color: var(--texte-faible); font-size: 0.78rem; }
.fiche-champs dd { margin: 0; font-size: 0.9rem; }

.fiche-tension {
    display: flex;
    align-items: center;
    gap: var(--e2);
    margin-top: var(--e3);
    padding: var(--e2);
    border-radius: var(--rayon-petit);
    background: var(--creux);
    color: var(--texte-doux);
    font-size: 0.85rem;
}
.fiche-tension:hover { background: var(--surface-haute); color: var(--texte); text-decoration: none; }

.liste-ligne-simple { grid-template-columns: 1fr auto; }

/* Compte à rebours. La part de l'anneau est calculée sur la fenêtre RÉELLE de réponse
   (parution -> remise) : trois jours restants sur quinze n'est pas la même urgence que sur cent. */
.compte-a-rebours { display: flex; align-items: center; gap: var(--e3); }
.anneau-jours { width: 92px; height: 92px; }
.anneau-jours .anneau-total { font-size: 1.5rem; }
.anneau-jauge { stroke: var(--haut); stroke-linecap: round; }
.anneau-proche .anneau-jauge { stroke: var(--moyen); }
.anneau-critique .anneau-jauge { stroke: var(--urgent); }
.anneau-critique .anneau-total { color: var(--urgent); }

/* Frise des dates. Un marché est une séquence, pas un formulaire : la ligne verticale porte
   l'ordre, et ce qui est passé s'efface sans disparaître. */
.frise { list-style: none; margin: var(--e3) 0 0; padding: 0 0 0 var(--e2); }
.frise-etape {
    display: grid;
    grid-template-columns: 5.4rem 1fr;
    gap: var(--e2);
    align-items: baseline;
    position: relative;
    padding: 0.42rem 0 0.42rem var(--e3);
    border-left: 2px solid var(--bordure);
}
.frise-etape:last-child { border-left-color: transparent; }
.frise-etape::before {
    content: "";
    position: absolute;
    left: -6px;
    top: 0.85rem;
    width: 10px;
    height: 10px;
    border-radius: 999px;
    background: var(--accent);
    box-shadow: 0 0 0 3px var(--surface);
}
.frise-passee { color: var(--texte-faible); }
.frise-passee::before { background: var(--bordure-forte); }
.frise-estimee::before { background: var(--surface); border: 2px solid var(--bordure-forte); }
.frise-date { font-size: 0.8rem; font-weight: 640; white-space: nowrap; }
.frise-heure { color: var(--texte-faible); font-weight: 500; }
.frise-libelle { font-size: 0.88rem; }

/* Un chiffre isolé qui mérite d'être lu comme une phrase : le nombre de concurrents qui ont
   réellement répondu. */
.indicateur {
    display: flex;
    align-items: center;
    gap: var(--e3);
    margin-top: var(--e3);
    padding: var(--e2) var(--e3);
    border-radius: var(--rayon-petit);
    background: var(--accent-doux);
    color: var(--accent-fort);
}
.indicateur-valeur { font-size: 2rem; font-weight: 700; line-height: 1; letter-spacing: -0.03em; }
.indicateur-libelle { font-size: 0.84rem; }

/* Cartes d'indicateurs. Le détail sous chaque chiffre n'est pas une note de bas de page : c'est
   ce qui rend le chiffre utilisable. Un « 5 candidats habituels » sans son assiette ne se discute
   pas avec un associé. */
.indicateurs-grille {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--e2);
    margin-bottom: var(--e4);
}
.carte-indicateur {
    display: flex;
    flex-direction: column;
    gap: var(--e1);
    padding: var(--e3);
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon);
    box-shadow: var(--carte-ombre);
}
.carte-indicateur-libelle { color: var(--texte-faible); font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
.carte-indicateur-valeur { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.025em; line-height: 1.15; }
.carte-indicateur-detail { color: var(--texte-doux); font-size: 0.8rem; line-height: 1.45; }
/* La vigilance se marque sur la valeur, pas sur toute la carte : quatre cartes rouges côte à côte
   ne signalent plus rien. */
.carte-indicateur-vigilance .carte-indicateur-valeur { color: var(--urgent); }

/* Accès au dossier de consultation. Seul bouton plein de la fiche : c'est la seule action qui
   sort de la plateforme, et celle qu'on cherche quand on a décidé de répondre. Le nom d'hôte est
   affiché parce que le lien quitte l'application — savoir où l'on va avant de cliquer. */
.bouton-dossier {
    display: inline-flex;
    align-items: center;
    gap: var(--e2);
    margin-top: var(--e3);
    padding: 0.6rem 1.1rem;
    border-radius: var(--rayon-petit);
    background: var(--accent);
    color: var(--sur-accent);
    font-size: 0.92rem;
    font-weight: 570;
    box-shadow: var(--carte-ombre);
    transition: background 0.14s ease;
}
.bouton-dossier:hover { background: var(--accent-fort); text-decoration: none; }
.bouton-dossier-hote {
    padding-left: var(--e2);
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    font-size: 0.78rem;
    font-weight: 500;
    opacity: 0.85;
    font-variant-numeric: tabular-nums;
}

/* Avis du modèle. Présenté comme un avis, pas comme un verdict : il n'entre dans aucun tri, et le
   cas qui mérite l'œil est le désaccord — tout ce qui est analysé a passé le seuil déterministe,
   donc un « écarté » contredit les mots-clés. */
.avis-ia-entete { display: flex; align-items: center; gap: var(--e2); margin-bottom: var(--e2); }
.avis-ia-verdict { font-weight: 620; }
/* Le désaccord se marque par un fond teinté et la couleur du verdict, pas par une barre latérale
   colorée : l'élévation est déjà déclarée une fois par `.panneau`. */
.avis-ia-desaccord { background: var(--moyen-doux); }
.avis-ia-desaccord .avis-ia-verdict { color: var(--moyen); }
.avis-ia-desaccord .avis-ia-note { color: var(--moyen); opacity: 0.85; }
.avis-ia-raison { margin: 0 0 var(--e3); max-width: 72ch; line-height: 1.6; }
.avis-ia-note { margin: 0; color: var(--texte-faible); font-size: 0.82rem; max-width: 72ch; }
.avis-ia-note code { font-size: 0.95em; }

/* Désaccord du modèle, marqué dans la liste. Teinte d'attention, pas d'alerte : ce n'est pas une
   erreur, c'est un avis à trancher — et il se trompe une fois sur cinq environ. */
.badge-conteste {
    color: var(--moyen);
    border-color: var(--moyen);
    background: var(--moyen-doux);
    font-size: 0.71rem;
    font-weight: 640;
    margin-left: var(--e1);
    white-space: nowrap;
}

/* Nom d'acheteur non rapproché : lisible, mais visiblement pas un lien vers une fiche. */
.acheteur-non-resolu { color: var(--texte-doux); font-style: italic; }

/* --- Pages de connexion --------------------------------------------------------------------- */

/* Premier écran du produit, et le seul qui n'avait aucun style à lui : deux champs sans libellé
   posés dans une grille de filtres détournée. Une carte centrée, la marque, des libellés — ce que
   voit d'abord quelqu'un à qui on ouvre l'accès. */
.auth {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--e3);
    padding: var(--e4) var(--e3);
}
.auth-carte {
    width: 100%;
    max-width: 27rem;
    background: var(--surface);
    border: var(--carte-bordure);
    border-radius: var(--rayon-grand);
    box-shadow: var(--ombre-haute);
    padding: var(--e4);
}
.auth-marque { display: flex; align-items: center; gap: var(--e2); margin-bottom: var(--e4); }
.auth h1 { font-size: 1.35rem; }
.auth-phrase { color: var(--texte-doux); margin: 0 0 var(--e3); font-size: 0.9rem; }
.auth-form { display: flex; flex-direction: column; gap: var(--e3); }
.auth-form .champ input { width: 100%; padding-block: 0.55rem; }
.auth-form button { width: 100%; padding-block: 0.62rem; font-size: 0.95rem; }
/* Un code à usage unique se relit chiffre par chiffre : chasse fixe et lettrage espacé. */
.champ-code {
    font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
    font-size: 1.35rem;
    letter-spacing: 0.35em;
    text-align: center;
}

/* Message d'échec. Le gris italique de `.empty` servait aussi bien à « aucun résultat » qu'à
   « connexion refusée » : le second doit se voir, et nommer sa cause. */
.alerte {
    background: var(--urgent-doux);
    border: 1px solid var(--urgent);
    color: var(--urgent);
    border-radius: var(--rayon-petit);
    padding: 0.6rem 0.85rem;
    font-size: 0.86rem;
    margin: 0 0 var(--e3);
}

/* Bandeau « la veille ne tourne plus », affiché sur toutes les pages tant que la collecte n'a pas
   abouti depuis 36 h. Plus appuyé que `.alerte` parce qu'il conteste la validité de TOUT ce que la
   page affiche — mais sans aplat saturé : un bandeau rouge vif présent en permanence devient un
   décor qu'on cesse de voir en trois jours, ce qui est exactement le défaut qu'il corrige. */
.bandeau-veille {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    background: var(--urgent-doux);
    border: 1px solid var(--urgent);
    border-left-width: 4px;
    color: var(--urgent);
    border-radius: var(--rayon-petit);
    padding: 0.7rem 0.9rem;
    font-size: 0.88rem;
    line-height: 1.45;
    margin: 0 0 var(--e3);
}

.bandeau-veille .ico { flex: none; width: 1.05rem; height: 1.05rem; margin-top: 0.12rem; }
.bandeau-veille strong { display: block; }
.bandeau-veille a { color: inherit; text-decoration: underline; }

/* --- 6. Adaptatif --------------------------------------------------------------------------- */

@media (max-width: 1180px) {
    .tableau-duo { grid-template-columns: 1fr; }
    .calendrier-bloc { grid-template-columns: 1fr; }
}

/* Sous 1 100 px la colonne latérale mange trop de largeur : elle repasse en bandeau horizontal
   défilant, ce qui garde tous les liens accessibles sans replier la page sur trois lignes. */
@media (max-width: 1100px) {
    .app { grid-template-columns: 1fr; }
    .barre-laterale {
        position: sticky;
        top: 0;
        z-index: 20;
        height: auto;
        flex-direction: row;
        align-items: center;
        gap: var(--e3);
        overflow-x: auto;
        border-right: none;
        border-bottom: 1px solid var(--bordure);
        padding: var(--e2);
    }
    .barre-laterale nav { flex-direction: row; gap: var(--e2); flex: 0 0 auto; }
    .nav-groupe { flex-direction: row; gap: var(--e1); }
    .nav-groupe-titre { display: none; }
    .marque-texte { display: none; }
    .barre-laterale-pied { flex-direction: row; align-items: center; gap: var(--e2); border-top: none; padding-top: 0; }
    .compte-role { display: none; }
    .pied-liens { padding: 0; }
    .pied-liens .libelle-pied { display: none; }
    .zone-principale { padding: var(--e3); }
    .table-scroll { overflow-x: auto; }
    .champ-large { grid-column: span 1; }
    .heros { padding: var(--e3); }
    .heros h1 { font-size: 1.5rem; }
    .heros-recherche { flex-direction: column; }
    .explication { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
    .stat-card-action:hover { transform: none; }
}

/* Synthèse des mots-clés : où le score a trouvé ce qu'il a compté.
   Fond teinté par force plutôt que trait d'accent — la distinction fort/faible/contraire doit se
   lire d'un coup d'œil sans ajouter de bordure à une page qui en a déjà beaucoup. */
.synthese-mots { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e3); }
.synthese-entete { display: flex; align-items: baseline; gap: var(--e2); flex-wrap: wrap; margin-bottom: var(--e1); }
.synthese-expression {
    font-weight: 620;
    color: var(--texte);
    background: var(--fond);
    border: 1px solid var(--bordure);
    border-radius: calc(var(--rayon) / 2);
    padding: 0.15em 0.5em;
}
.synthese-fort .synthese-expression { background: var(--haut-doux, var(--fond)); border-color: var(--haut); }
.synthese-negatif .synthese-expression { background: var(--urgent-doux); border-color: var(--urgent); }
.synthese-compte { color: var(--texte-faible); font-size: 0.79rem; }
.synthese-extraits { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35em; }
.synthese-extraits li { display: flex; gap: var(--e2); align-items: baseline; }
.synthese-champ {
    flex: 0 0 auto;
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    color: var(--texte-faible);
    min-width: 3.4rem;
}
.synthese-extrait { color: var(--texte-doux); font-size: 0.88rem; line-height: 1.55; }
.synthese-extrait mark { background: var(--surbrillance); color: var(--texte); padding: 0 0.15em; border-radius: 2px; }
.synthese-reste { color: var(--texte-faible); font-size: 0.82rem; font-style: italic; }
.synthese-note { color: var(--texte-faible); font-size: 0.82rem; margin: var(--e3) 0 0; }
