/* ===== Le tableau de bord — la colonne de droite du chat =====
   Extrait de chat.css pour tenir sous les 500 lignes par fichier, et parce que
   c'est un autre sujet : à gauche une conversation, à droite des chiffres. Les
   composants reprennent ceux de la veille (chiffres en serif sur bande à filets,
   barres arrondies, histogramme à colonne creuse). Tokens --mr-* : clair et sombre. */

/* ── Le tableau de bord ──────────────────────────────────────────────── */
/* Le defilement vit dans les panneaux, pas ici : sinon le rail des sections
   disparait des qu'on descend dans une longue liste de produits. */
.ch-bord {
    min-height: 0; overflow: hidden; padding: var(--ch-haut) 1.6rem 1.6rem;
    display: flex; flex-direction: column; gap: 1rem;
}

/* --ch-second est défini sur .ch (chat.css) : les deux colonnes partagent le
   même ton secondaire, il n'a pas à être redéclaré ici. */

.ch-bandeau {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
    /* --mr-border comme tous les autres traits de structure : --mr-border-strong
       est réservé à ce qui doit trancher (barres de citation, pointillés). */
    padding-bottom: 0.9rem; border-bottom: 1px solid var(--mr-border);
}

/* Le dossier : présent, jamais insistant. Il vaut le geste plein — c'est la
   marche de l'entonnoir juste avant le paiement — mais il ne doit pas peser
   plus que le marché dont il porte le nom, à sa gauche. D'où le contour seul.
   44 px de haut : c'est une cible tactile, l'écran sert surtout sur mobile. */
.ch-dossier {
    min-height: 44px; padding: 0 1.05rem; flex-shrink: 0;
    font-family: inherit; font-size: var(--ch-fs-sm); cursor: pointer;
    color: var(--mr-text); background: transparent;
    border: 1px solid var(--mr-border-strong); border-radius: 999px;
    transition: border-color 0.15s ease, color 0.15s ease;
}
.ch-dossier:hover:not(:disabled) { border-color: var(--mr-text); color: var(--mr-text-strong); }
.ch-dossier:disabled { opacity: 0.6; cursor: default; }

.ch-marche b { display: block; font-size: var(--ch-fs-lg); font-weight: 600; color: var(--mr-text-strong); }
.ch-marche span {
    font-size: var(--ch-fs-2xs);
    color: var(--ch-second);
}

.ch-verdict {
    display: inline-flex; align-items: center; gap: 0.5rem;
    border: 1px solid var(--mr-border-strong); border-radius: 999px;
    padding: 0.35rem 0.9rem; font-size: var(--ch-fs-xs); color: var(--mr-text-strong);
}

/* Les sections en barre d'onglets, en haut : le geste d'un navigateur, où l'on
   passe de l'un à l'autre sans jamais en fermer. L'onglet actif se raccorde au
   panneau du dessous en recouvrant le filet, ce qui dit à l'œil que le contenu
   appartient à cet onglet. */
.ch-corps {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
}

.ch-onglets {
    display: flex; flex-direction: row; gap: 2px;
    border-bottom: 1px solid var(--mr-border);
    /* Six onglets tiennent sur un écran large ; sur un plus étroit ils défilent
       plutôt que de passer à la ligne, comme une barre de navigateur. */
    overflow-x: auto; scrollbar-width: none;
    flex: none;
}
.ch-onglets::-webkit-scrollbar { display: none; }

.ch-onglet {
    font: inherit; font-size: var(--ch-fs-sm); font-weight: 500;
    text-align: left; white-space: nowrap; flex: none;
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.5rem 0.8rem; cursor: pointer;
    border-radius: var(--mr-radius-sm) var(--mr-radius-sm) 0 0;
    /* Le trait du bas de l'onglet actif est peint de la couleur du fond : il
       efface le filet de la barre juste sous lui, et l'onglet paraît ouvert
       sur son panneau. Le décalage de 1 px le fait chevaucher ce filet. */
    border: 1px solid transparent; margin-bottom: -1px;
    background: transparent; color: var(--ch-second);
    transition: background 0.15s ease, color 0.15s ease;
}

.ch-onglet:hover { background: var(--mr-surface-hover); color: var(--mr-text-strong); }

.ch-onglet[aria-selected="true"] {
    color: var(--mr-text-strong);
    background: var(--mr-surface);
    border-color: var(--mr-border);
    border-bottom-color: var(--mr-surface);
}

.ch-onglet svg { flex: none; width: 15px; height: 15px; opacity: 0.9; }
.ch-onglet[aria-selected="true"] svg { opacity: 1; }

/* La pastille suit le libellé au lieu d'être poussée au bout : en rangée, un
   `margin-left: auto` l'aurait collée au bord droit de chaque onglet, loin du
   mot qu'elle qualifie. */
.ch-onglet u {
    text-decoration: none; flex: none;
    width: 6px; height: 6px; border-radius: 50%;
    background: currentColor; opacity: 0.85;
}
.ch-onglet.est-vide u { background: transparent; border: 1px solid currentColor; opacity: 0.55; }

.ch-panneaux { min-width: 0; overflow-y: auto; flex: 1; padding-top: 1rem; }
.ch-panneau { display: none; flex-direction: column; gap: 0.9rem; }
.ch-panneau.est-actif { display: flex; }

/* Les sous-onglets ont ete retires : chaque panneau empile desormais ses
   sections. Voir `empiler()` dans chat.js — il fallait cliquer trois fois
   pour reconstituer une seule idee, et les sections en deuxieme et
   troisieme position n'etaient presque jamais ouvertes. */

/* Le filtre d'une liste : trente lignes se lisent, cent se cherchent. */
.ch-filtre { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.6rem; }

.ch-filtre-champ {
    flex: 1; min-width: 0; font: inherit; font-size: var(--ch-fs-xs);
    padding: 0.4rem 0.75rem; border-radius: 999px;
    border: 1px solid var(--mr-border); background: var(--mr-surface);
    color: var(--mr-text); outline: none;
}
.ch-filtre-champ:focus { border-color: var(--mr-border-strong); }
.ch-filtre-compte {
    flex: none; font-size: var(--ch-fs-2xs); font-variant-numeric: tabular-nums;
    color: var(--ch-second);
}

.ch-attente {
    border: 1px dashed var(--mr-border-strong); border-radius: var(--mr-radius);
    padding: 2.4rem 1.5rem; text-align: center;
    font-size: var(--ch-fs-sm); color: var(--ch-second);
}

/* Bloc, chiffres, barres, histogramme : les composants de la veille */
.ch-bloc {
    border: 1px solid var(--mr-border); border-radius: var(--mr-radius);
    background: var(--mr-surface-card); padding: 1.1rem 1.3rem;
    display: flex; flex-direction: column; gap: 0.9rem;
}

.ch-bloc-titre {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    font-size: var(--ch-fs-md); font-weight: 600;
    color: var(--mr-text-strong); margin: 0;
    padding-bottom: 0.6rem; border-bottom: 1px solid var(--mr-border);
}

.ch-bloc-note {
    font-size: var(--ch-fs-2xs); font-weight: 400;
    color: var(--ch-second);
}

.ch-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }

.ch-chiffres {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: 1px; background: var(--mr-border);
    border: 1px solid var(--mr-border); border-radius: var(--mr-radius-sm); overflow: hidden;
}

.ch-chiffre { background: var(--mr-surface-card); padding: 0.75rem 0.9rem; min-width: 0; }
.ch-chiffre span {
    display: block; margin-bottom: 0.25rem;
    font-size: var(--ch-fs-2xs);
    color: var(--ch-second);
}
.ch-chiffre b {
    font-size: var(--ch-fs-xl); font-weight: 600; line-height: 1.15;
    color: var(--mr-text-strong); font-variant-numeric: tabular-nums;
}

/* La zone du graphique : une colonne d'echelle, puis l'aire de trace. Les points
   sont en HTML par-dessus le SVG — celui-ci s'etire en largeur (sinon il se
   centre en laissant du vide), et un cercle etire devient un ovale. */
/* La hauteur de la courbe vit ICI et nulle part ailleurs : les points sont
   poses en POURCENTAGE sur `.ch-graphe-aire` et les graduations en pourcentage
   sur `.ch-echelle`. Les trois hauteurs doivent donc rester egales, sous peine
   de voir les points flotter a cote de la courbe. Elles etaient ecrites trois
   fois en dur ; une seule a ete changee et tout s'est decale. */
.ch-graphe-zone { display: flex; gap: 0.55rem; align-items: stretch; --ch-graphe-h: 150px; }
.ch-graphe-aire { position: relative; flex: 1; min-width: 0; height: var(--ch-graphe-h); }
.ch-graphe { width: 100%; height: var(--ch-graphe-h); display: block; }
.ch-graphe .grille {
    stroke: var(--mr-border); stroke-width: 1;
    vector-effect: non-scaling-stroke; stroke-dasharray: 2 4;
}

.ch-pt {
    position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
    border-radius: 50%; background: var(--mr-surface-card);
    border: 1.6px solid var(--mr-text-strong); cursor: help;
    transition: transform 0.12s ease;
}
.ch-pt.est-fort { background: var(--mr-text-strong); }
.ch-pt:hover { transform: scale(1.5); }

.ch-pt-valeur {
    position: absolute; transform: translate(-50%, -175%);
    font-size: var(--ch-fs-2xs); font-weight: 500;
    color: var(--mr-text-strong); white-space: nowrap; pointer-events: none;
}

/* Les graduations chiffrees : sans elles, deux courbes de formes identiques et
   d'ordres de grandeur opposes se ressemblent exactement. */
.ch-echelle {
    position: relative; flex: none; width: 3.2rem; height: var(--ch-graphe-h);
    font-size: var(--ch-fs-2xs); color: var(--ch-second);
    pointer-events: none;
}
.ch-echelle span { position: absolute; right: 0; transform: translateY(-50%); }
.ch-note-donnee {
    font-size: var(--ch-fs-2xs); line-height: 1.5; color: var(--ch-second);
    margin: 0.5rem 0 0; font-style: italic;
}
.ch-graphe .trace { fill: none; stroke: var(--mr-text-strong); stroke-width: 1.8; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.ch-graphe .aire { fill: var(--mr-text-strong); opacity: 0.07; stroke: none; }
.ch-axe { display: flex; justify-content: space-between; padding-left: 3.75rem; font-size: var(--ch-fs-2xs); color: var(--ch-second); font-variant-numeric: tabular-nums; }

.ch-barres { list-style: none; margin: 0; padding: 0; }
.ch-barre {
    display: grid; grid-template-columns: minmax(0, 12rem) minmax(0, 1fr) auto;
    align-items: center; gap: 0.9rem; padding: 0.35rem 0; font-size: var(--ch-fs-xs);
}
.ch-barre em { font-style: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-barre s { text-decoration: none; display: block; height: 8px; border-radius: 999px; background: var(--mr-surface-sunken); overflow: hidden; }
.ch-barre s i { display: block; height: 100%; border-radius: 999px; background: var(--mr-text-strong); opacity: 0.72; }
.ch-barre b { font-size: var(--ch-fs-2xs); font-weight: 400; color: var(--ch-second); white-space: nowrap; font-variant-numeric: tabular-nums; }

.ch-histo { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; align-items: end; gap: 0.4rem; list-style: none; margin: 0; padding: 0; }
.ch-histo li { display: grid; grid-template-rows: auto 1fr auto; gap: 0.35rem; text-align: center; }
.ch-histo-n { font-size: var(--ch-fs-2xs); color: var(--ch-second); min-height: 1em; font-variant-numeric: tabular-nums; }
.ch-histo-col { display: flex; align-items: flex-end; min-height: 96px; }
.ch-histo-col i { display: block; width: 100%; border-radius: 4px 4px 0 0; background: var(--mr-text-strong); opacity: 0.72; min-height: 2px; }
.ch-histo li.est-vide .ch-histo-col { border-bottom: 2px dashed var(--mr-border-strong); }
.ch-histo-lab { font-size: var(--ch-fs-2xs); color: var(--ch-second); font-variant-numeric: tabular-nums; }

.ch-puces { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.ch-puce { font-size: var(--ch-fs-xs); border: 1px solid var(--mr-border); border-radius: 999px; padding: 0.25rem 0.7rem; }
.ch-puce b { font-size: var(--ch-fs-xs); font-weight: 400; color: var(--ch-second); margin-left: 0.35rem; font-variant-numeric: tabular-nums; }

.ch-liste { list-style: none; margin: 0; padding: 0; }
.ch-liste li { padding: 0.5rem 0; border-bottom: 1px solid var(--mr-border); font-size: var(--ch-fs-xs); display: flex; justify-content: space-between; gap: 1rem; }
.ch-liste li:last-child { border-bottom: none; }
.ch-liste a { color: inherit; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-liste a:hover { text-decoration: underline; }
.ch-liste b { font-size: var(--ch-fs-2xs); font-weight: 400; color: var(--ch-second); white-space: nowrap; font-variant-numeric: tabular-nums; }

.ch-note { font-size: var(--ch-fs-xs); color: var(--ch-second); margin: 0; }
.ch-citation { font-size: var(--ch-fs-xs); color: var(--mr-text); border-left: 2px solid var(--mr-border-strong); padding-left: 0.8rem; margin: 0 0 0.6rem; }
.ch-citation:last-child { margin-bottom: 0; }

.ch-alerte { font-size: var(--ch-fs-xs); color: var(--ch-second); padding: 0.6rem 0.9rem; border: 1px dashed var(--mr-border-strong); border-radius: var(--mr-radius-sm); }

/* Sous 1150px la colonne des conversations sort du flux et glisse depuis la
   gauche. Elle etait un bandeau horizontal : retrouver un chat demandait de
   balayer une rangee de pastilles tronquees, et la bande coutait une ligne en
   haut de chaque ecran, y compris quand on ne cherchait rien. En panneau, les
   titres reprennent toute leur largeur et l'ecran ne paie rien tant qu'il est
   ferme. */
@media (max-width: 1150px) {
    /* La colonne quitte la grille : il ne reste qu'une seule piste. */
    .ch { grid-template-columns: minmax(0, 1fr); }

    .ch-side {
        position: fixed; z-index: 60;
        top: var(--topbar-actuelle, 64px); bottom: 0; left: 0;
        /* Meme duree que la barre : sinon le panneau saute quand elle se compacte. */
        transition: transform 0.25s ease, top 0.3s ease;
        width: min(300px, 84vw);
        border-right: 1px solid var(--mr-border);
        box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22);
        transform: translateX(-100%);
    }
    .ch.liste-ouverte .ch-side { transform: none; }

    /* Le voile ne sert pas qu'a assombrir : c'est la zone de fermeture. Au
       doigt on tape a cote pour refermer, on ne cherche pas une croix. */
    .ch-side-voile {
        /* `display` explicite, sinon la regle d'extinction du haut de fichier
           laisse le voile a `none` et il n'y a plus de zone de fermeture. Et
           la ligne `[hidden]` juste apres est obligatoire : une declaration
           `display` en CSS bat l'attribut `hidden`, que le script pilote. */
        display: block;
        position: fixed; inset: var(--topbar-actuelle, 64px) 0 0; z-index: 59;
        background: rgba(0, 0, 0, 0.45);
        opacity: 0; transition: opacity 0.25s ease;
    }
    .ch-side-voile[hidden] { display: none; }
    .ch.liste-ouverte .ch-side-voile { opacity: 1; }

    .ch-liste-bouton {
        display: flex; align-items: center; justify-content: center;
        position: fixed; z-index: 58;
        top: calc(var(--topbar-actuelle, 64px) + 0.45rem); left: 0.5rem;
        width: 38px; height: 38px; padding: 0;
        border: 1px solid var(--mr-border); border-radius: var(--mr-radius-sm);
        background: var(--mr-surface-card); color: var(--ch-second);
        cursor: pointer;
    }
    .ch-liste-bouton svg { width: 18px; height: 18px; }

    /* Le bouton laisse la place au titre du fil, qui commence au meme endroit.
       Scope a `:not(.sans-liste)` : sans conversation il n'y a pas de bouton,
       donc pas de creux a lui reserver. */
    .ch:not(.sans-liste) .ch-rail-haut { padding-left: 3.4rem; }
    .ch:not(.sans-liste) .ch-vide { padding-top: 3.6rem; }
}
/* Sous 1100px l'ecran redevient un chat, rien d'autre : la conversation prend
   toute la hauteur, la saisie est collee en bas, et le tableau de bord est
   replie derriere un bouton. Les deux colonnes empilees donnaient une page qui
   defilait sur deux ecrans, ou la saisie partait hors champ des qu'on lisait
   les chiffres et ou les chiffres partaient des qu'on ecrivait. */
@media (max-width: 1100px) {
    /* `dvh` suit la barre d'adresse des navigateurs mobiles, qui se retracte au
       defilement : avec `vh` la saisie se retrouve sous le bord de l'ecran.
       `vh` reste en repli pour les moteurs qui ignorent `dvh`. */
    .ch {
        height: calc(100vh - var(--topbar-actuelle, 64px));
        height: calc(100dvh - var(--topbar-actuelle, 64px));
        overflow: hidden;
    }

    /* `minmax(0, 1fr)` sur la rangee, sinon elle prend la hauteur de son
       contenu : le fil de conversation ne se retracte pas, la barre de saisie
       passe sous le bord de l'ecran et la page se met a defiler. */
    .ch-travail { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
    .ch-poignee { display: none; }
    .ch-rail { max-height: none; border-bottom: 0; }

    .ch-bascule {
        display: flex; align-items: center; justify-content: space-between;
        width: 100%; margin-bottom: 0.6rem;
        padding: 0.55rem 0.9rem;
        font: inherit; font-size: var(--ch-fs-xs); font-weight: 500;
        border: 1px solid var(--mr-border); border-radius: 999px;
        background: var(--mr-surface-card); color: var(--ch-second);
        cursor: pointer;
        transition: color 0.15s ease, border-color 0.15s ease;
    }
    .ch-bascule:hover { color: var(--mr-text-strong); border-color: var(--mr-border-strong); }
    .ch-bascule-fleche { width: 16px; height: 16px; flex: none; transition: transform 0.25s ease; }
    .ch.donnees-ouvertes .ch-bascule-fleche { transform: rotate(180deg); }

    /* Deplie, le bouton quitte la barre du bas et vient se caler JUSTE SOUS
       l'en-tete du fil, sans le remplacer : le titre de la conversation reste
       lisible pendant qu'on regarde les chiffres. Il passe en absolu dans
       `.ch-travail` plutot que de changer de parent, parce qu'il ne va pas
       dans un conteneur existant mais dans l'espace entre deux. */
    .ch.donnees-ouvertes .ch-bascule {
        position: absolute; z-index: 57;
        top: calc(var(--ch-haut-fil, 3.4rem) + var(--ch-creux-haut, 0px));
        left: 1rem; right: 1rem;
        /* `width: auto` : la regle de l'etat replie pose `width: 100%`, qui en
           absolu l'emporte sur la contrainte de droite. Le bouton faisait alors
           la largeur pleine ancree a gauche, debordait de 16px, et sa bordure
           arrondie sortait de l'ecran : ce qui restait visible etait un bord
           droit net, qu'on lit comme un cadre. */
        width: auto;
        margin: 0;
    }

    /* `absolute` dans `.ch-travail`, pas `fixed` sur l'ecran : `.ch-travail`
       porte un `transform` d'animation (chat-anim.css), ce qui en fait le bloc
       contenant de tout descendant `fixed`. Un `top: 64px` s'y ajoutait a la
       hauteur de la barre et le panneau demarrait a 128. Cale sur `.ch-travail`,
       qui occupe exactement la zone du chat, il ne depend plus de rien. */
    .ch-travail { position: relative; }

    /* Le panneau est TOUJOURS hors du flux, ouvert comme ferme : il ne pousse
       donc rien, et ses tableaux ne peuvent pas elargir la page. Ferme, il est
       masque par `visibility` et non par `display`, seule facon de lui donner
       une animation d'entree et de sortie (cf. chat-anim.css). `visibility`
       le retire aussi des clics et du parcours clavier. */
    .ch-bord {
        position: absolute; z-index: 55;
        /* Le panneau demarre sous le bouton, pas sous l'en-tete : c'est le
           bouton qui occupe desormais cette bande. `--ch-bascule` est mesuree
           par chat.js, sa hauteur depend de la taille de police du systeme.
           Le panneau remonte jusqu'a la MOITIE du bouton, qui le recouvre
           (z-index 57 contre 55). Cale sous lui, ses creux d'angle arrondis
           laissaient voir la conversation par-dessous. Le creux interne du
           panneau replace le contenu sous le bouton. */
        top: calc(var(--ch-haut-fil, 3.4rem) + var(--ch-creux-haut, 0px) + var(--ch-bascule, 2.5rem) / 2);
        left: 0; right: 0; bottom: var(--ch-bas, 7rem);
        /* Le creux du haut reprend le recouvrement du bouton, plus un vrai
           espace : sinon la premiere ligne du panneau passe derriere lui. */
        padding: calc(var(--ch-bascule, 2.5rem) / 2 + 0.6rem) 1rem 1rem;
        background: var(--mr-surface);
        border-bottom: 1px solid var(--mr-border);
        overflow-y: auto;
        visibility: hidden;
        /* `pointer-events` en plus de `visibility`, et pas a sa place : il ne se
           transitionne pas, donc il bascule des le clic. `visibility`, elle,
           attend la fin de l'animation de sortie ; pendant ces 0,3s le panneau
           refermé avalerait les clics destines a la conversation. */
        pointer-events: none;
    }

    /* Deplie : entre l'en-tete du fil et la barre du bas, pas par-dessus. Le
       titre de la conversation et le bouton du panneau restent en haut, donc on
       sait de quel chat ces chiffres parlent ; le bouton de repli reste en bas,
       donc on referme du meme geste qu'on a ouvert. */
    .ch.donnees-ouvertes .ch-bord { visibility: visible; pointer-events: auto; }

    /* Le nom du marche est deja dans l'en-tete du fil, juste au-dessus du
       panneau : l'ecrire deux fois a 40px d'ecart ne dit rien de plus et mange
       une ligne sur un ecran qui n'en a pas a perdre. La ligne d'etat, elle,
       n'existe nulle part ailleurs et reste. */
    .ch-marche b { display: none; }

    /* Le bandeau ne porte plus que la ligne d'etat, le nom du marche etant
       masque juste au-dessus. Or `chat.js` masque aussi cette ligne des qu'un
       onglet est rempli : il ne restait qu'un creux de 14px et un second filet
       colle a celui de l'en-tete du fil, soit une double barre pour rien.
       `:has` interroge le contenu reel plutot que de deviner l'etat.

       LE BOUTON DU DOSSIER RETIENT LE BANDEAU. Il apparait exactement quand la
       ligne d'etat s'efface — donc sans cette seconde condition, il serait
       masque sur mobile pile au moment ou il devient utile. */
    .ch-bandeau:not(:has(> .ch-marche > span:not([hidden]))):not(:has(> .ch-dossier:not([hidden]))) {
        display: none;
    }

    .ch-duo { grid-template-columns: 1fr; }
    .ch-chiffres { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: 1fr 1fr; }
}

/* Les fiches expliquees : le chiffre dans son encadre, la phrase dessous. Une
   liste de lignes se parcourt du regard sans que rien n'accroche ; un encadre par
   mesure donne un objet a saisir, et la phrase repond a « et alors ? ». */
.ch-fiches {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 0.7rem;
}

.ch-fiche {
    display: flex; flex-direction: column; gap: 0.35rem;
    padding: 0.9rem 1rem 1rem;
    border: 1px solid var(--mr-border); border-radius: var(--mr-radius-sm);
    background: var(--mr-surface);
}

.ch-fiche-nom {
    font-size: var(--ch-fs-2xs); font-weight: 500;
    color: var(--ch-second);
}

.ch-fiche-valeur {
    font-size: var(--ch-fs-xl); line-height: 1.1;
    font-weight: 500; color: var(--mr-text-strong);
}

.ch-fiche-phrase {
    margin: 0; font-size: var(--ch-fs-xs); line-height: 1.55;
    color: var(--ch-second);
    padding-top: 0.35rem; border-top: 1px solid var(--mr-border);
}

/* Le tableau des pistes : on vient ici pour COMPARER, pas pour lire une liste.
   « La place » est la colonne qu'on regarde en premier — la seule question a
   laquelle le volume de recherche ne repond pas. */
.ch-tableau-zone { overflow-x: auto; }

/* `separate` et non `collapse` : une cellule collante perd ses bordures en mode
   fusionné pendant le défilement. Avec un espacement nul et des bordures posées
   sur les cellules, le rendu est identique. */
.ch-tableau { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--ch-fs-xs); }

/* Le nom de la niche NE DOIT JAMAIS partir. Huit colonnes dans un panneau
   étroit, ça défile — et la première colonne, celle qui dit ce QU'EST chaque
   ligne, était la première à disparaître : il restait un tableau de nombres
   sans sujet. Elle reste donc collée à gauche, et l'ombre marque la césure. */
.ch-tableau th:first-child,
.ch-tableau td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--mr-surface-card);
    box-shadow: 1px 0 0 var(--mr-border);
}
.ch-tableau thead th:first-child { z-index: 2; }
.ch-tableau tbody tr:hover td:first-child { background: var(--mr-surface-hover); }
/* L'en-tête se distingue par sa graisse, pas par un trait plus épais — sinon
   il y aurait deux forces de filet pour un même rôle. (font-weight était
   déclaré deux fois ici : le 400 qui suivait annulait le 500.) */
.ch-tableau th {
    text-align: left; padding: 0.5rem 0.6rem; white-space: nowrap;
    font-size: var(--ch-fs-2xs); font-weight: 600;
    color: var(--ch-second);
    border-bottom: 1px solid var(--mr-border);
}
.ch-tableau td {
    padding: 0.55rem 0.6rem; white-space: nowrap;
    border-bottom: 1px solid var(--mr-border); color: var(--ch-second);
}
.ch-tableau tr:last-child td { border-bottom: 0; }
.ch-tableau tbody tr:hover td { background: var(--mr-surface-hover); }
.ch-td-mot { color: var(--mr-text-strong); font-weight: 500; white-space: normal; }
/* ── L'offre d'un marché logiciel ────────────────────────────────────────────
   Des lignes riches, pas le tableau serré des produits : ici chaque concurrent
   porte un nom, un tarif, une provenance et souvent un extrait. Le prix relevé
   est mis en avant, l'absence de prix est expliquée en gris — « — » se lirait
   « gratuit », ce qui est faux et coûterait cher à qui débute. */
.ch-liste .ch-ligne { padding: 0.6rem 0; border-bottom: 1px solid var(--mr-border); }
.ch-liste .ch-ligne:last-child { border-bottom: none; }
.ch-ligne-titre { display: block; font-size: var(--ch-fs-sm); font-weight: 600; color: inherit; text-decoration: none; }
.ch-ligne-titre:hover { text-decoration: underline; }
.ch-ligne-detail { font-size: var(--ch-fs-xs); margin-top: 0.15rem; line-height: 1.45; }
.ch-ligne-meta { display: block; font-size: var(--ch-fs-2xs); color: var(--ch-second); margin-top: 0.2rem; text-decoration: none; font-variant-numeric: tabular-nums; }
a.ch-ligne-meta:hover { text-decoration: underline; }
.ch-offre-prix { font-size: var(--ch-fs-sm); font-variant-numeric: tabular-nums; }
.ch-offre-muet { color: var(--ch-second); font-size: var(--ch-fs-xs); font-style: italic; }

/* La provenance, quand le prix ne vient pas de la page de l'éditeur. Elle suit
   le montant sur la même ligne et en plus petit : c'est une réserve sur le
   chiffre, pas une information de même rang que lui. */
.ch-offre-source {
    margin-left: 0.45rem; color: var(--ch-second);
    font-size: var(--ch-fs-2xs); font-style: italic;
}
.ch-rang { display: inline-block; margin-left: 0.5rem; padding: 0.05rem 0.4rem; border: 1px solid var(--mr-border); border-radius: 3px; font-size: var(--ch-fs-xs); color: var(--ch-second); vertical-align: middle; font-variant-numeric: tabular-nums; }

/* Le vocabulaire du marché : des mots à parcourir, pas une liste à lire.
   Le multiplicateur dit combien de créateurs ont choisi le même terme. */
.ch-nuage { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.6rem; }
.ch-mot { display: inline-flex; align-items: baseline; gap: 0.25rem; padding: 0.18rem 0.5rem; border: 1px solid var(--mr-border); border-radius: 3px; font-size: var(--ch-fs-xs); }
.ch-mot b { font-size: var(--ch-fs-xs); font-weight: 400; color: var(--ch-second); font-variant-numeric: tabular-nums; }

/* Les avis réels : la note du client se lit d'un coup d'œil avant son texte. */
.ch-note-avis { display: inline-block; min-width: 2.4rem; font-size: var(--ch-fs-2xs); color: var(--ch-second); font-variant-numeric: tabular-nums; }
.ch-sous-titre { margin: 0.9rem 0 0.3rem; font-size: var(--ch-fs-xs); font-weight: 600; }


/* ── Ranger l'analyse dans un projet ─────────────────────────────────────
   Sous les panneaux, donc APRES les chiffres : c'est une suite, pas une
   offre. Propose au-dessus, ce bloc demanderait de decider avant d'avoir lu.

   Un cadre discret et non un encadre colore : ce n'est pas une promotion,
   c'est la marche suivante du produit. Ce qui doit attirer l'oeil ici, c'est
   le bouton, pas la boite. */
.ch-ranger {
    margin: 1.5rem 0 0;
    padding: 1.1rem 1.2rem;
    border: 1px solid var(--mr-border);
    border-radius: 12px;
    background: var(--mr-surface-sunken, transparent);
}

.ch-ranger-titre {
    margin: 0 0 0.35rem;
    font-size: var(--ch-fs-sm);
    font-weight: 600;
    color: var(--mr-text-strong);
}

.ch-ranger-texte {
    margin: 0 0 0.9rem;
    font-size: var(--ch-fs-2xs);
    line-height: 1.5;
    color: var(--ch-second);
    max-width: 46ch;
}

/* `wrap` et non une grille fixe : le panneau du dossier se retrecit avec la
   fenetre, et un champ plus un bouton cote a cote y passent sous 360 px. */
.ch-ranger-ligne {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.6rem;
}

.ch-ranger-champ {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    /* `min-width: 0` : sans lui un champ dans un conteneur flex refuse de
       descendre sous sa largeur par defaut et deborde au lieu de se plier. */
    flex: 1 1 12rem;
    min-width: 0;
}

.ch-ranger-etiquette {
    font-size: var(--ch-fs-2xs);
    color: var(--ch-second);
}

.ch-ranger-champ input {
    min-height: 40px;
    padding: 0 0.75rem;
    font-family: inherit;
    font-size: var(--ch-fs-sm);
    color: var(--mr-text);
    background: var(--mr-surface);
    border: 1px solid var(--mr-border-strong);
    border-radius: 8px;
}

.ch-ranger-champ input:focus-visible {
    outline: 2px solid var(--mr-text-strong);
    outline-offset: 1px;
}

.ch-ranger-bouton {
    min-height: 40px;
    padding: 0 1.1rem;
    flex-shrink: 0;
    font-family: inherit;
    font-size: var(--ch-fs-sm);
    font-weight: 600;
    cursor: pointer;
    color: var(--mr-surface);
    background: var(--mr-text-strong);
    border: 1px solid var(--mr-text-strong);
    border-radius: 8px;
}

.ch-ranger-bouton:hover { opacity: 0.88; }
