/* Feuille de style unique — microbiologie
   Assemblée depuis les trois pages. Le tronc commun vaut partout ; les règles
   propres à une page sont portées par la classe de son <body> (.p-crh,
   .p-synthese), ce qui évite qu elles débordent sur les autres pages.
   Les classes des modules sont préfixées : tl- (frise), prt- (portage),
   cmp- (comparateur), bil- (bilan). Ne pas croiser ces préfixes. */

/* ===================== TRONC COMMUN ET FRISE ===================== */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: #d8dfe3;
    min-height: 100vh;
    padding: 20px;
}
.container {
    max-width: 1600px;
    margin: 0 auto;
    background: white;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    overflow: hidden;
}
.header {
    background: #435663;
    color: white;
    padding: 30px;
    text-align: center;
    position: relative;
}
.header h1 {
    font-size: 28px;
    font-weight: 600;
}
/* « Microbio.icu » est un nom de domaine autant qu'un nom : le suffixe rendu
   de la même graisse que le reste le fait lire comme une adresse qu'on
   aurait oublié d'habiller. Allégé, il devient une partie du nom. */
.header h1 .nom-tld {
    font-weight: 400;
    opacity: 0.62;
}
/* L'écart est porté par le sous-titre et non par le titre : les pages qui n'en
   ont pas laisseraient sinon un blanc mort sous leur titre. */
.header p {
    font-size: 14px;
    opacity: 0.95;
    margin-top: 8px;
}
.header .liens {
    position: absolute;
    top: 20px;
    right: 24px;
    display: flex;
    gap: 8px;
}
.header .liens a {
    color: white;
    opacity: 0.8;
    font-size: 13px;
    text-decoration: none;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 6px;
    padding: 5px 11px;
}
.header .liens a:hover {
    opacity: 1;
    background: rgba(255, 255, 255, 0.12);
}
.zone {
    padding: 24px 30px;
}
.zone + .zone {
    padding-top: 0;
}
.zone h2 {
    font-size: 15px;
    color: #2c3942;
    font-weight: 600;
    margin-bottom: 10px;
}
textarea {
    width: 100%;
    height: 150px;
    padding: 14px;
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    font-family: 'Courier New', monospace;
    font-size: 12.5px;
    resize: vertical;
    transition: border-color 0.2s;
}
textarea:focus {
    outline: none;
    border-color: #435663;
}
.button-group {
    display: flex;
    gap: 10px;
    margin-top: 12px;
}
button {
    padding: 11px 22px;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    gap: 8px;
}
.btn-primary {
    background: #435663;
    color: white;
}
.btn-primary:hover {
    background: #354451;
}
.btn-secondary {
    background: #eceff1;
    color: #546e7a;
}
.btn-secondary:hover {
    background: #cfd8dc;
}
/* ---- Modules ----
   Chacun des trois blocs (portage, frise, comparaison) est encadré : on voit
   d'un coup d'œil où commence et où finit chaque outil. */
.module {
    border: 2px solid #b8c5cd;
    border-radius: 10px;
    background: #fff;
    padding: 15px 17px;
}
.module > h2 {
    margin-bottom: 12px;
}
.bandeau-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 20px;
    font-size: 13px;
    color: #435663;
    padding: 9px 14px;
    border: 1.5px solid #dde3e7;
    border-radius: 8px;
    background: #f5f7f8;
}
.bandeau-l {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6b7f8c;
}
.bandeau-box label {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
}
.bandeau-box input[type="checkbox"] {
    accent-color: #435663; cursor: pointer;
}
/* ---- Sélection ---- */
.selection {
    display: none;
}
.selection.visible {
    display: block;
    margin-bottom: 14px;
}
.sel-box {
    border: 1.5px solid #dde3e7;
    border-radius: 8px;
    padding: 14px 16px;
    background: #f5f7f8;
}
.sel-row + .sel-row {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid #dde3e7;
}
.sel-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6b7f8c;
    margin-bottom: 9px;
}
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 11px;
    background: white;
    border: 1.5px solid #cfd8dc;
    border-radius: 20px;
    font-size: 12.5px;
    color: #2c3942;
    cursor: pointer;
    user-select: none;
}
.chip:hover {
    border-color: #8fa3b0;
}
.chip.on {
    background: #e3ecf1; border-color: #435663;
}
.chip input {
    cursor: pointer; accent-color: #435663;
}
.chip .count {
    color: #7a8c98; font-size: 11px;
}
.sel-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px;
    font-size: 13px;
    color: #435663;
}
.sel-actions label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}
.sel-actions input[type="checkbox"] {
    accent-color: #435663; cursor: pointer;
}
.sel-actions select {
    padding: 4px 7px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    color: #2c3942;
    background: white;
    cursor: pointer;
}
/* Filtre de période : les trois champs sont posés d'un bloc par le parseur,
   dans un <span>. « display: contents » l'efface de la mise en page, si bien
   que « Toute la période », « Du … » et « au … » deviennent des éléments de la
   ligne comme les autres — même écart, même alignement. Sans lui, le groupe
   ne comptait que pour un et « Du » se collait à la case précédente. */
#friPeriode {
    display: contents;
}
/* « Tout cocher / Tout décocher », propres à une famille de filtres, posés au
   fil du titre de la famille. Le titre est en petites capitales : ces deux
   boutons n'en sont pas et reprennent la casse ordinaire. */
.sel-tout {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
    margin-left: 14px;
}
.sel-tout .link-btn {
    font-size: 12px;
}
.sel-tout .link-btn + .link-btn {
    margin-left: 12px;
}
/* display: inline annule le « display: flex » posé sur tous les boutons :
   dans une phrase, ce bouton doit rester au fil du texte et non passer à
   la ligne (bilan d'analyse). */
.link-btn {
    display: inline;
    background: none;
    border: none;
    padding: 0;
    color: #435663;
    font-size: 13px;
    font-weight: 500;
    text-decoration: underline;
    cursor: pointer;
}
.link-btn:hover {
    color: #1f2b33;
}
/* ---- Portage BMR / BHRe ----
   Tableau de bord en tête de page : le statut de portage conditionne
   l'isolement du patient, il se lit avant tout le reste. */
.portage {
    display: none;
}
.portage.visible {
    display: block;
}
/* align-items: start — une carte dépliée ne doit pas étirer ses voisines */
.prt-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
    align-items: start;
    gap: 8px;
}
/* Carte repliée : le nom et le statut, rien de plus. Le détail se déplie au
   clic — un tableau de bord de portage se lit d'abord d'un coup d'œil. */
.prt-carte {
    border: 1.5px solid #dde3e7;
    border-radius: 8px;
    padding: 8px 11px;
    background: #f7f9fa;
    font-size: 12px;
    color: #6b7f8c;
    min-width: 0;
}
.prt-carte > summary {
    cursor: pointer;
    list-style: none;
    user-select: none;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 7px;
}
.prt-carte > summary::-webkit-details-marker {
    display: none;
}
.prt-nom {
    font-size: 12.5px;
    font-weight: 700;
    color: #2c3942;
    flex: 1 1 100%;
}
.prt-etat {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.01em;
}
.prt-aide {
    font-size: 12px;
    color: #6b7f8c;
    margin-bottom: 11px;
}
/* Date du dernier événement, visible sans déplier */
.prt-quand {
    font-size: 11.5px;
}
/* Recontrôles négatifs : visible sans déplier, c'est ce qui dit si le portage
   a été redépisté et combien de fois. */
.prt-neg {
    flex: 1 1 100%;
    font-size: 11.5px;
    color: #2e7d32;
}
.prt-carte[open] > summary {
    margin-bottom: 5px;
}
.prt-carte .l {
    margin-top: 2px; overflow-wrap: anywhere;
}
.prt-carte .l.type {
    color: #4c5f6c; font-weight: 600;
}
/* Un dépistage négatif postérieur au dernier positif ne lève pas le portage,
   mais c'est une information que le clinicien doit voir sans la chercher. */
.prt-carte .l.apres {
    color: #2e7d32;
}
.prt-carte.pos {
    border-color: #ef9a9a; background: #fdecea;
}
.prt-carte.pos .prt-etat {
    color: #c62828;
}
/* Les molécules suivies d'une souche, sous la carte dépliée : UNE LIGNE PAR
   ANTIBIOTIQUE, le nom à gauche, la catégorie à droite. Les catégories
   s'alignent donc en colonne et se comptent d'un coup d'œil — sur plusieurs
   colonnes, il fallait les chercher une par une. */
.prt-atb {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2px;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px dashed #dde3e7;
}
.prt-atb .a {
    display: flex;
    justify-content: space-between;
    gap: 5px;
    font-size: 11px;
    white-space: nowrap;
}
.prt-atb .a b {
    color: #55697a; font-weight: 600;
}
/* Le nom entier plutôt que le code : la carte a la largeur d'une ligne, et
   « Ceftolozane/Tazobactam » se lit sans avoir à traduire « C/T ». */
.prt-atb .a .n {
    overflow: hidden; text-overflow: ellipsis;
}
.prt-atb .a i {
    font-style: normal; font-weight: 700;
}
.prt-atb .r-S { color: #2e7d32; }
.prt-atb .r-R { color: #c62828; }
.prt-atb .r-SFP, .prt-atb .r-I, .prt-atb .r-ZIT, .prt-atb .r-BNR { color: #b26a00; }
/* Non testée : le point gris ne doit surtout pas se lire comme un sensible */
.prt-atb .r-NT, .prt-atb .r-V { color: #b0bec5; }

/* Positif, mais pas au même titre : un Pseudomonas résistant impose des
   précautions sans relever des mesures d'une BHRe. Le rouge est réservé à
   celles-ci ; l'orange dit « à signaler » sans dire « alerte maximale ».
   Le contraste reste au-dessus de 4,5:1 sur le fond de la carte. */
.prt-carte.pos.ton-orange {
    border-color: #ffcc80; background: #fff6e9;
}
.prt-carte.pos.ton-orange .prt-etat {
    color: #b35c00;
}
.prt-carte.neg {
    border-color: #c3e0c5; background: #f2f8f3;
}
.prt-carte.neg .prt-etat {
    color: #2e7d32;
}
/* ND : ni positif ni négatif — le laboratoire n'a rien cherché. Le contour
   pointillé dit l'absence d'information, il ne rassure pas. */
.prt-carte.nd {
    border-style: dashed; background: #fff;
}
.prt-carte.nd .prt-etat {
    color: #90a4ae;
}
.prt-detail {
    margin-top: 12px; font-size: 12px; color: #4c5f6c;
}
/* Vert sensible, rouge résistant, jusque dans les preuves : c'est là qu'on
   vérifie sur quoi le statut repose. */
.prt-detail .r-S { color: #2e7d32; font-weight: 600; }
.prt-detail .r-R { color: #c62828; font-weight: 700; }
.prt-detail .r-SFP, .prt-detail .r-I,
.prt-detail .r-ZIT, .prt-detail .r-BNR { color: #b26a00; font-weight: 600; }
.prt-detail .r-V { color: #78909c; }
.prt-detail summary {
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    color: #435663;
    user-select: none;
}
.prt-detail summary::-webkit-details-marker {
    display: none;
}
.prt-detail summary::before {
    content: '▸ ';
}
.prt-detail details[open] summary::before {
    content: '▾ ';
}
.prt-detail .m {
    font-weight: 700; color: #2c3942; margin: 9px 0 2px 0;
}
.prt-detail ul {
    margin: 0; padding-left: 18px;
}
.prt-detail li {
    margin-bottom: 1px;
}
.prt-detail .p {
    color: #c62828; font-weight: 700;
}
.prt-detail .n {
    color: #2e7d32; font-weight: 700;
}
/* ---- Bilan d'analyse ----
   Compte ce qui est entré, ce qui est affiché et ce qui ne l'est pas : un
   examen que le parseur n'a pas su lire ne doit jamais disparaître en
   silence d'un dossier de microbiologie. */
.bilan, .bandeau {
    display: none;
}
.bilan.visible, .bandeau.visible {
    display: block;
}
.bilan-box {
    border: 1.5px solid #dde3e7;
    border-radius: 8px;
    background: #f5f7f8;
    padding: 10px 14px;
    font-size: 12.5px;
    color: #4c5f6c;
}
.bilan-box.alerte {
    border-color: #ecc98a; background: #fff9ef;
}
.bilan-l + .bilan-l {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid #e4eaed;
}
.bilan-l.attention {
    color: #8a5a00;
}
.bilan-l b {
    color: #2c3942;
}
.bilan-l.attention b {
    color: #7a4f00;
}
.bilan details {
    margin-top: 4px;
}
.bilan summary {
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    user-select: none;
}
.bilan summary::-webkit-details-marker {
    display: none;
}
.bilan summary::before {
    content: '▸ ';
}
.bilan details[open] summary::before {
    content: '▾ ';
}
.bilan .inc {
    margin-top: 7px;
}
.bilan .inc .src {
    color: #8fa3b0;
}
.bilan .inc ul {
    margin: 2px 0 0 0; padding-left: 18px;
}
.bilan .inc li {
    font-family: 'Courier New', Courier, monospace;
    font-size: 11.5px;
    color: #55707f;
}
/* ---- Frise ---- */
.frise {
    display: none;
}
.frise.visible {
    display: block;
}
/* Pas de marge horizontale ici : « position: sticky » se cale sur le bord
   intérieur de la bordure, et le contenu défilerait visiblement sous cette
   marge, à gauche de la colonne figée. La marge est reportée dans la colonne.
   Pas de bordure non plus : celle du module encadre déjà l'ensemble. */
.tl-scroll {
    overflow-x: auto;
    padding: 4px 0 6px 0;
    background: white;
}
/* --cw : largeur d'une colonne-jour, --mk : taille d'une pastille.
   Toutes deux recalculées par ajusterZoom() selon le zoom et la place. */
.tl-grid {
    display: grid;
    align-items: center;
    min-width: min-content;
    padding-right: 14px;
    --cw: 28px;
    --mk: 25px;
}
/* La colonne des libellés reste visible quand on fait défiler les mois :
   sans elle, les pastilles ne sont plus rattachables à un prélèvement. */
.tl-corner {
    height: 100%;
    position: sticky;
    left: 0;
    z-index: 3;
    background: #fff;
    padding-left: 14px;
}
.tl-month {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #6b7f8c;
    font-weight: 600;
    height: 20px;
    display: flex;
    align-items: center;
    padding-left: 5px;
    border-left: 1px solid #cfd8dc;
    white-space: nowrap;
    overflow: hidden;
}
.tl-day {
    font-size: 9px;
    color: #b0bec5;
    text-align: center;
    height: 18px;
    line-height: 18px;
    overflow: hidden;
}
.tl-day.on {
    color: #435663; font-weight: 700;
}
.tl-rowlabel {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: #2c3942;
    height: 36px;
    padding-left: 14px;
    padding-right: 12px;
    border-top: 1px solid #eceff1;
    white-space: nowrap;
    position: sticky;
    left: 0;
    z-index: 2;
    background: #fff;
    box-shadow: 1px 0 0 #dde4e8;
}
.tl-rowlabel svg {
    width: 17px; height: 17px; flex: none; color: #607d8b; fill: currentColor;
}
.tl-rowlabel .an {
    color: #78909c;
    font-size: 11.5px;
}
.tl-rowlabel .n {
    color: #90a4ae;
    font-size: 11px;
}
.tl-cell {
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-top: 1px solid #eceff1;
}
.tl-cell.we {
    background: #fafbfc;
}
.tl-mark {
    width: var(--mk);
    height: var(--mk);
    border-radius: 7px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    cursor: default;
}
/* fill: currentColor est indispensable : sans lui les icônes pleines
   restent noires et le code couleur ne porte que sur les icônes en trait */
.tl-mark svg {
    width: calc(var(--mk) * 0.6); height: calc(var(--mk) * 0.6); fill: currentColor;
}
/* Zoom serré : le compteur ne tient plus dans la pastille */
.tl-grid.mini .tl-mark .n {
    display: none;
}
.tl-mark.pos {
    color: #c62828;
    background: #fdecea;
    box-shadow: inset 0 0 0 1.5px #ef9a9a;
}
.tl-mark.pending {
    color: #b26a00;
    background: #fff6e5;
    box-shadow: inset 0 0 0 1.5px #ecc98a;
}
.tl-mark.neg {
    color: #7d99a8;
    background: #eef3f5;
    box-shadow: inset 0 0 0 1.5px #dde6ea;
}
/* Dossier clos sans résultat : contour pointillé et fond vide, pour qu'on ne
   le confonde ni avec un négatif rendu ni avec une culture en cours. */
.tl-mark.annule {
    color: #b0bec5;
    background: #fff;
    border: 1.5px dashed #cfd8dc;
}
.tl-mark {
    cursor: pointer;
}
.tl-pop {
    position: absolute;
    z-index: 60;
    display: none;
    width: max-content;
    min-width: 360px;
    max-width: min(96vw, 1080px);
    max-height: 66vh;
    overflow: auto;
    background: #fff;
    border: 1px solid #b8c5cd;
    border-radius: 10px;
    box-shadow: 0 10px 32px rgba(31, 43, 51, 0.22);
    padding: 16px 18px;
    font-size: 12.5px;
    line-height: 1.5;
    color: #1f2b33;
}
.tl-pop.on {
    display: block;
}
.tl-pop .fermer {
    position: absolute;
    top: 8px;
    right: 8px;
    background: none;
    border: none;
    color: #90a4ae;
    font-size: 20px;
    line-height: 1;
    padding: 2px 6px;
    cursor: pointer;
}
.tl-pop .fermer:hover {
    color: #435663;
}
.tl-pop .sec {
    margin-top: 14px; padding-top: 12px; border-top: 1px solid #e4eaed;
}
.tl-pop .sec:first-of-type {
    margin-top: 0; padding-top: 0; border-top: none;
}
.tl-pop h4 {
    font-size: 13.5px; font-weight: 700; color: #2c3942; padding-right: 22px;
}
.tl-pop .an {
    color: #78909c; font-size: 11.5px; margin-bottom: 8px;
}
.tl-pop .k {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    color: #8fa3b0;
    margin: 9px 0 2px 0;
}
.tl-pop ul {
    margin: 0; padding-left: 17px;
}
.tl-pop li {
    margin-bottom: 1px;
}
/* Germes et marqueurs positifs en rouge : c'est ce qu'on cherche dans une
   infobulle. La graisse dit ensuite la significativité — gras au seuil de
   pathogénicité, normale en dessous. Deux informations, deux signaux
   distincts, aucun des deux ne masque l'autre. */
.tl-pop .res-fort {
    color: #c62828;
    font-weight: 700;
}
.tl-pop .res-pending {
    color: #b26a00; font-weight: 600;
}
.tl-pop .res-neg {
    color: #55707f;
}
.tl-pop .res-annule {
    color: #90a4ae; font-style: italic;
}
.tl-pop .cmt {
    color: #6b7f8c;
}
/* Sections repliées par défaut : l'antibiogramme complet et les commentaires
   du laboratoire noieraient le résultat s'ils étaient toujours déroulés */
.tl-pop details {
    margin-top: 10px;
}
.tl-pop summary {
    cursor: pointer;
    list-style: none;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    color: #8fa3b0;
    user-select: none;
}
.tl-pop summary::-webkit-details-marker {
    display: none;
}
.tl-pop summary::before {
    content: '▸ ';
}
.tl-pop details[open] summary::before {
    content: '▾ ';
}
.tl-pop summary:hover {
    color: #435663;
}
/* Un germe par colonne, trois de front au plus */
.tl-pop .atbg-grid {
    display: grid; gap: 12px 28px; margin-top: 6px;
}
.tl-pop .atbg-col > b {
    display: block; color: #2c3942; margin-bottom: 4px;
}
/* Deux colonnes : les catégories s'alignent quelle que soit la longueur
   du nom de molécule */
.tl-pop .atbg-list {
    display: grid;
    grid-template-columns: max-content max-content;
    column-gap: 18px;
    row-gap: 1px;
}
.tl-pop .atbg-list .nom {
    white-space: nowrap;
}
.tl-pop .ss {
    font-weight: 400; font-size: 11.5px; color: #8d6e63;
}
/* Ce qui a été cherché, avant ce qui a été trouvé */
.tl-pop .cherche {
    color: #6b7f8c; margin-bottom: 3px;
}
/* Panel testé : liste longue, coulée en colonnes. La largeur maximale évite
   qu'un groupe de trois cibles ne s'étale sur toute la largeur de l'infobulle,
   que le plus long commentaire du laboratoire peut rendre très large. */
.tl-pop .panel {
    columns: 3 190px; column-gap: 26px; margin-top: 5px; max-width: 760px;
}
/* Nom du panel ou du virus dont relève le bloc de cibles qui suit */
.tl-pop .p-tete {
    font-weight: 700;
    color: #4c5f6c;
    margin-top: 7px;
}
.tl-pop details > .p-tete:first-of-type {
    margin-top: 4px;
}
/* Pas de nowrap ici : certains libellés de panel dépassent la largeur de
   colonne et déborderaient sur la suivante */
.tl-pop .panel .l {
    break-inside: avoid;
}
.tl-pop .p-pos {
    color: #c62828; font-weight: 700;
}
.tl-pop .p-neg {
    color: #78909c;
}
.tl-pop .p-nd {
    color: #b0bec5; font-style: italic;
}
.tl-pop .r-S {
    color: #2e7d32; font-weight: 700;
}
.tl-pop .r-R {
    color: #c62828; font-weight: 700;
}
/* SFP (sensible à forte posologie) reste utilisable mais sous condition :
   il ne se lit pas comme un S franc */
.tl-pop .r-SFP, .tl-pop .r-I, .tl-pop .r-ZIT, .tl-pop .r-BNR {
    color: #b26a00; font-weight: 700;
}
.tl-pop .r-V {
    color: #78909c; font-weight: 700;
}
.tl-mark .n {
    position: absolute;
    top: -5px;
    right: -5px;
    font-size: 8.5px;
    font-style: normal;
    font-weight: 700;
    background: #435663;
    color: #fff;
    border-radius: 7px;
    padding: 0 3.5px;
    line-height: 12px;
}
.tl-legend {
    margin-top: 14px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    font-size: 12px;
    color: #4c5f6c;
    align-items: center;
}
.tl-legend .item {
    display: inline-flex; align-items: center; gap: 6px;
}
.tl-legend .item svg {
    width: 15px; height: 15px; color: #607d8b; fill: currentColor;
}
.tl-legend .sep {
    width: 1px;
    height: 16px;
    background: #cfd8dc;
}
.tl-swatch {
    width: 15px;
    height: 15px;
    border-radius: 5px;
}
.tl-swatch.pos {
    background: #fdecea; box-shadow: inset 0 0 0 1.5px #ef9a9a;
}
.tl-swatch.pending {
    background: #fff6e5; box-shadow: inset 0 0 0 1.5px #ecc98a;
}
.tl-swatch.neg {
    background: #eef3f5; box-shadow: inset 0 0 0 1.5px #dde6ea;
}
.tl-swatch.annule {
    background: #fff; border: 1.5px dashed #cfd8dc;
}
.vide {
    color: #90a4ae;
    font-style: italic;
    font-size: 13px;
}
/* ---- Comparaison d'antibiogrammes ----
   Sous la frise : on repère d'abord quand le germe est apparu, on compare
   ensuite ses antibiogrammes d'un prélèvement à l'autre. */
.compa {
    display: none;
}
.compa.visible {
    display: block;
}
.compa-actions select {
    padding: 4px 7px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    color: #2c3942;
    background: white;
    cursor: pointer;
}
.compa-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px;
    font-size: 13px;
    color: #435663;
    margin-bottom: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid #eceff1;
}
.compa-actions label {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
}
.compa-actions input[type="checkbox"] {
    accent-color: #435663; cursor: pointer;
}
/* Nom d'espèce en italique, capitale au seul genre : la convention
   microbiologique, pas des capitales. */
/* Un groupe par espèce (ou par prélèvement), REPLIÉ par défaut : sur un
   dossier fourni, on vient d'abord savoir quels germes ont poussé. Déplier
   les vingt prélèvements de chacun obligeait à faire défiler pour lire une
   liste d'espèces qui tient en six lignes. */
.compa-groupe {
    border-bottom: 1px solid #f0f3f5;
}
.compa-groupe:last-child {
    border-bottom: 0;
}
.compa-groupe > summary {
    cursor: pointer;
    list-style: none;
    user-select: none;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 6px;
    padding: 7px 0;
}
.compa-groupe > summary::-webkit-details-marker {
    display: none;
}
/* Le chevron dit que la ligne s'ouvre, sans coûter un mot */
.compa-groupe > summary::before {
    content: '\25B8';
    color: #90a4ae;
    font-size: 10px;
    flex: 0 0 auto;
}
.compa-groupe[open] > summary::before {
    content: '\25BE';
}
.compa-espece {
    font-size: 13px;
    font-style: italic;
    color: #2c3942;
    font-weight: 700;
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}
/* En présentation « par prélèvement », l'intertitre n'est pas un nom d'espèce */
.compa-espece.prel {
    font-style: normal;
}
/* Le nombre de prélèvements du groupe : c'est lui qui dit si le groupe vaut
   la peine d'être ouvert. */
.compa-nb {
    font-size: 11px;
    color: #55697a;
    background: #eceff1;
    border-radius: 9px;
    padding: 1px 6px;
    flex: 0 0 auto;
}
/* Ce qui est retenu doit rester lisible GROUPE FERMÉ : sans ce repère, on ne
   sait plus d'où vient le tableau de droite après avoir replié. */
.compa-retenu {
    font-size: 11px;
    color: #1d6a3a;
    font-weight: 600;
    flex: 0 0 auto;
}
/* Sur sa propre ligne : accolé au nom, il repoussait le compte hors du cadre
   dès que l'espèce portait un nom long. Aligné à gauche sur le nom qu'il
   complète — `display: inline` le laissait suivre l'alignement du bloc. */
.compa-groupe > summary .link-btn {
    font-size: 11.5px;
    font-style: normal;
    flex: 1 1 100%;
    display: block;
    text-align: left;
    padding-left: 14px;
}
/* Léger retrait : les prélèvements dépendent du germe qui les coiffe */
.compa-groupe > .chips {
    padding: 0 0 9px 14px;
}
/* Isolat sans antibiogramme : montré pour qu'on sache qu'il existe, mais
   hors de portée de la sélection. */
.compa .chip.off {
    cursor: default;
    border-style: dashed;
    color: #90a4ae;
    background: #fafbfc;
}
.compa .chip .sans {
    color: #b0bec5; font-size: 11px; font-style: italic;
}
/* Sélection à gauche, comparaison à droite : on coche et on voit le tableau
   changer sans quitter la liste des yeux. La colonne de gauche est collante,
   elle reste à portée quand le tableau est long. */
.compa-corps {
    display: grid;
    grid-template-columns: minmax(205px, 275px) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-top: 14px;
}
.compa-choix {
    border-right: 1px solid #eceff1;
    padding-right: 16px;
    position: sticky;
    top: 12px;
    max-height: calc(100vh - 60px);
    overflow-y: auto;
}
/* En colonne étroite, une puce par ligne se lit mieux qu'un pavé enroulé */
.compa-choix .chips {
    flex-direction: column; align-items: stretch; gap: 5px;
}
.compa-choix .chip {
    justify-content: flex-start;
}
.compa-choix .chip .count, .compa-choix .chip .sans {
    margin-left: auto; padding-left: 8px;
}
.compa-table {
    overflow-x: auto;
}
/* border-collapse: separate est nécessaire pour que la colonne des molécules
   reste figée : en mode collapse, les bordures des cellules « sticky »
   disparaissent au défilement. */
table.cmp {
    border-collapse: separate; border-spacing: 0; font-size: 12.5px;
}
table.cmp th, table.cmp td {
    padding: 5px 13px;
    border-bottom: 1px solid #eceff1;
    text-align: center;
    white-space: nowrap;
    background: #fff;
}
table.cmp thead th {
    vertical-align: bottom; border-bottom: 2px solid #cfd8dc;
}
table.cmp .mol {
    text-align: left;
    position: sticky;
    left: 0;
    z-index: 1;
    box-shadow: 1px 0 0 #dde4e8;
}
table.cmp thead th .germe {
    display: block; font-weight: 700; font-style: italic; color: #2c3942;
}
table.cmp thead th .meca {
    display: block; font-weight: 600; font-size: 11px; color: #c62828;
}
table.cmp thead th .prel {
    display: block; font-weight: 400; font-size: 11px; color: #78909c;
}
/* Deux lectures selon ce qu'on cherche : les molécules sur lesquelles les
   antibiogrammes divergent (mêmes souches ou non ?), ou celles sur lesquelles
   ils s'accordent (une antibiothérapie unique est-elle possible ?). */
table.cmp tr.diff th, table.cmp tr.diff td {
    background: #fffaf0;
}
table.cmp tr.conc th, table.cmp tr.conc td {
    background: #f2f8f3;
}
/* Antibiothérapie la plus ciblée : la surbrillance porte sur les cellules
   couvertes, pas sur la ligne — les souches laissées de côté restent en clair,
   c'est précisément ce qu'il faut voir. */
table.cmp td.cbl {
    background: #d7ecd9;
    box-shadow: inset 0 0 0 1px #a9d3ac;
}
table.cmp td.mol.cible {
    font-weight: 700; color: #1b5e20;
}
table.cmp td.nt {
    color: #cfd8dc;
}
table.cmp .r-S {
    color: #2e7d32; font-weight: 700;
}
table.cmp .r-R {
    color: #c62828; font-weight: 700;
}
table.cmp .r-SFP, table.cmp .r-I, table.cmp .r-ZIT, table.cmp .r-BNR {
    color: #b26a00; font-weight: 700;
}
table.cmp .r-V {
    color: #78909c; font-weight: 700;
}
.compa-resume {
    margin-top: 9px; font-size: 12px; color: #6b7f8c;
}
.compa-resume .cible-l {
    margin-top: 7px; color: #1b5e20;
}
.compa-resume .cible-u {
    margin: 2px 0 0 0; padding-left: 18px; color: #4c5f6c;
}

@media (max-width: 950px) {
    .compa-corps { grid-template-columns: 1fr; }
    .compa-choix {
        position: static;
        max-height: none;
        border-right: none;
        border-bottom: 1px solid #eceff1;
        padding-right: 0;
        padding-bottom: 12px;
    }
    .compa-choix .chips { flex-direction: row; align-items: center; gap: 7px; }
    .compa-choix .chip .count, .compa-choix .chip .sans { margin-left: 0; padding-left: 0; }
}

/* ===================== RENDU CHRONOLOGIQUE (microbio.php) ===================== */

/* ---- Panneau de sélection ---- */
.p-crh .selection {
    display: none;
    padding: 20px 30px 0 30px;
}
.p-crh .selection.visible {
    display: block;
}
.p-crh .sel-box {
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    padding: 16px 18px;
    background: #f5f7f8;
}
.p-crh .sel-row + .sel-row {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid #dde3e7;
}
.p-crh .sel-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6b7f8c;
    margin-bottom: 10px;
}
.p-crh .chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.p-crh .chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    background: white;
    border: 1.5px solid #cfd8dc;
    border-radius: 20px;
    font-size: 13px;
    color: #2c3942;
    cursor: pointer;
    user-select: none;
    transition: all 0.15s;
}
.p-crh .chip.on .count {
    color: #546e7a;
}
.p-crh .sel-actions select {
    padding: 5px 8px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    color: #2c3942;
    background: white;
    cursor: pointer;
}
.p-crh .link-btn {
    background: none;
    border: none;
    padding: 0;
    color: #435663;
    font-size: 13px;
    font-weight: 500;
    text-decoration: underline;
    cursor: pointer;
}
/* ---- Contenu ---- */
.p-crh .content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    padding: 30px;
}
.p-crh .panel {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.p-crh .panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
}
.p-crh .panel-header h2 {
    font-size: 18px;
    color: #2c3942;
    font-weight: 600;
}
.p-crh textarea {
    width: 100%;
    height: 560px;
    padding: 15px;
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    font-family: 'Courier New', monospace;
    font-size: 13px;
    resize: vertical;
    transition: border-color 0.2s;
}
.p-crh #output {
    height: 560px;
    overflow: auto;
    padding: 15px;
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    background-color: #f5f7f8;
    font-size: 13.5px;
    line-height: 1.55;
    color: #1f2b33;
}
.p-crh #output .placeholder {
    color: #90a4ae;
    font-style: italic;
}
/* ---- Rendu formaté ---- */
/* Pas de bordure CSS ici : le trait est fait de « _ » dans le texte lui-même,
   pour qu'il survive au copier-coller (voir REGLE). */
.p-crh #output .day-h {
    font-weight: 700;
    font-size: 14px;
    color: #2c3942;
    margin: 16px 0 5px 0;
}
.p-crh #output .day-h:first-child {
    margin-top: 0;
}
.p-crh #output .line {
    margin: 0 0 3px 0;
    padding-left: 14px;
}
.p-crh #output .line .meta {
    color: #4c5f6c;
}
.p-crh #output .germ {
    margin: 0 0 2px 18px;
}
.p-crh #output .neg {
    color: #55707f;
}
.p-crh #output .flag {
    color: #7a8c98;
    font-size: 12px;
}
.p-crh #output .legende {
    margin-top: 14px;
    font-size: 12px;
    color: #4c5f6c;
}
.p-crh #output .note {
    color: #7a8c98;
    font-size: 12px;
    margin: 1px 0 3px 18px;
}
/* Pseudo-tableau ASCII : Orbis n'accepte pas de vrai tableau dans les CRH.
   La police monospace est aussi posée en style inline (voir atbgHtml) car
   cette feuille de style n'accompagne pas le texte dans le presse-papier. */
.p-crh #output pre.atbg {
    font-family: 'Courier New', Courier, monospace;
    font-size: 11.5px;
    line-height: 1.35;
    margin: 4px 0 8px 18px;
    overflow-x: auto;
}
.p-crh .button-group {
    display: flex;
    gap: 10px;
    margin-top: 15px;
}
.p-crh button {
    padding: 12px 24px;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    gap: 8px;
}
.p-crh .btn-primary {
    background: #435663;
    color: white;
    flex: 1;
}
.p-crh .btn-success {
    background: #81c784;
    color: white;
    flex: 1;
}
.p-crh .btn-success:hover {
    background: #66bb6a;
}

@media (max-width: 1100px) {
    .p-crh .content {
        grid-template-columns: 1fr;
    }
}

/* ===================== SYNTHÈSE PAR GERME (synthese.php) ===================== */

/* ---- Options ---- */
.p-synthese .selection {
    display: none;
    padding: 20px 30px 0 30px;
}
.p-synthese .selection.visible {
    display: block;
}
.p-synthese .sel-box {
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    padding: 16px 18px;
    background: #f5f7f8;
}
.p-synthese .sel-actions select {
    padding: 5px 8px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    color: #2c3942;
    background: white;
    cursor: pointer;
}
/* ---- Contenu ---- */
.p-synthese .content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    padding: 30px;
}
.p-synthese .panel {
    display: flex; flex-direction: column; min-width: 0;
}
.p-synthese .panel-header {
    margin-bottom: 12px;
}
.p-synthese .panel-header h2 {
    font-size: 18px;
    color: #2c3942;
    font-weight: 600;
}
.p-synthese textarea {
    width: 100%;
    height: 620px;
    padding: 15px;
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    font-family: 'Courier New', monospace;
    font-size: 13px;
    resize: vertical;
}
.p-synthese #output {
    height: 620px;
    overflow: auto;
    padding: 18px 20px;
    border: 2px solid #b8c5cd;
    border-radius: 8px;
    background-color: #fff;
    font-size: 13.5px;
    line-height: 1.6;
    color: #1f2b33;
}
.p-synthese #output .placeholder {
    color: #90a4ae; font-style: italic;
}
/* ---- Rendu ----
   La hiérarchie est portée par le rendu lui-même et non par la feuille de
   style : titres en capitales, tirets, indentation. Elle survit donc au
   collage en texte brut dans Orbis, où aucun style ne passe. */
.p-synthese #output .sec {
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 0.08em;
    color: #435663;
    margin: 20px 0 8px 0;
}
.p-synthese #output .sec:first-child {
    margin-top: 0;
}
.p-synthese #output .germe {
    font-weight: 700;
    font-size: 14.5px;
    color: #1f2b33;
    margin-top: 12px;
}
.p-synthese #output .germe:first-of-type {
    margin-top: 0;
}
.p-synthese #output .meca {
    color: #c62828;
}
.p-synthese #output .l {
    margin: 1px 0 0 20px;
    color: #37474f;
}
.p-synthese #output .l.sensible {
    color: #1b5e20;
}
.p-synthese #output .l.resistant {
    color: #8a3a3a;
}
.p-synthese #output .l.evol {
    color: #8a5a00;
}
.p-synthese #output .l.ou {
    color: #4c5f6c;
}
.p-synthese #output .simple {
    margin: 2px 0 0 0; color: #37474f;
}
.p-synthese #output .rien {
    color: #90a4ae; font-style: italic;
}
.p-synthese .button-group {
    display: flex; gap: 10px; margin-top: 15px;
}
.p-synthese button {
    padding: 12px 24px;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
}
.p-synthese .btn-primary {
    background: #435663; color: white; flex: 1;
}
.p-synthese .btn-success {
    background: #81c784; color: white; flex: 1;
}
.p-synthese .btn-success:hover {
    background: #66bb6a;
}

@media (max-width: 1100px) {
    .p-synthese .content {
        grid-template-columns: 1fr;
    }
}

/* ===================== ADMINISTRATION (admin.php) ===================== */

.p-admin .adm-porte form {
    display: flex;
    gap: 10px;
    align-items: center;
}

.p-admin .adm-porte input {
    padding: 10px 12px;
    border: 1.5px solid #cfd8dc;
    border-radius: 6px;
    font-size: 14px;
    font-family: inherit;
    min-width: 240px;
}

.p-admin .adm-err {
    color: #c62828;
    font-size: 13px;
    margin-bottom: 10px;
}

.p-admin .adm-ok {
    background: #f2f8f3;
    border: 1.5px solid #c3e0c5;
    border-radius: 8px;
    padding: 9px 14px;
    font-size: 13px;
    color: #1b5e20;
    margin-bottom: 14px;
}

/* ---- Diagnostic de fermeture des données -------------------------------- */
/* Trois états, trois couleurs, et la même largeur de liseré : on doit pouvoir
   compter les alertes sans lire. `info` n'est pas une alerte — un dossier de
   données sous la racine web est le cas ordinaire, pas un défaut. */
.p-admin .adm-secu { list-style: none; margin: 0; padding: 0; }
.p-admin .adm-secu li {
    border-left: 4px solid #cfd8dc;
    background: #fafbfc;
    border-radius: 0 6px 6px 0;
    padding: 9px 13px;
    margin-bottom: 7px;
    font-size: 13px;
    line-height: 1.5;
}
.p-admin .adm-secu li b { display: block; color: #37474f; }
.p-admin .adm-secu li span {
    display: block;
    margin-top: 3px;
    font-size: 12.5px;
    color: #6b7f8c;
    overflow-wrap: anywhere;
}
/* ⚠️ Le « li. » n'est pas décoratif : sans lui, la règle générique ci-dessus
   — deux classes ET un élément — l'emporte sur celles-ci, qui n'ont que deux
   classes. Les cinq lignes sortaient alors du même gris, et le diagnostic ne
   se lisait plus d'un coup d'œil, ce qui est tout son objet. */
.p-admin .adm-secu li.adm-secu-ok     { border-left-color: #66a06a; background: #f4f9f4; }
.p-admin .adm-secu li.adm-secu-ok b   { color: #1b5e20; }
.p-admin .adm-secu li.adm-secu-info   { border-left-color: #8fa6b2; }
.p-admin .adm-secu li.adm-secu-alerte { border-left-color: #c62828; background: #fdf5f5; }
.p-admin .adm-secu li.adm-secu-alerte b { color: #c62828; }

.p-admin .adm-secu-liens { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.p-admin .adm-secu-liens li { margin-bottom: 5px; }
.p-admin .adm-secu-liens a { color: #435663; font-weight: 600; }
.p-admin .adm-secu-liens span { color: #90a4ae; font-size: 12.5px; }

.p-admin .adm-aide {
    font-size: 12.5px;
    color: #6b7f8c;
    margin-bottom: 12px;
}

.p-admin textarea {
    height: 130px;
}

.p-admin .adm-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
    margin-top: 14px;
}

.p-admin .adm-table th,
.p-admin .adm-table td {
    padding: 6px 10px;
    border-bottom: 1px solid #eceff1;
    text-align: left;
}

.p-admin .adm-table th {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #6b7f8c;
    border-bottom: 2px solid #cfd8dc;
}

.p-admin .adm-table td.adm-n { color: #90a4ae; }

/* Compteur d'usage : des nombres se lisent alignés à droite, la colonne de
   semaine et celle des pages restent du texte. Le total se détache. */
.p-admin .adm-usage td:nth-child(n+2):nth-child(-n+5),
.p-admin .adm-usage th:nth-child(n+2):nth-child(-n+5) { text-align: right; }
.p-admin .adm-usage td:last-child,
.p-admin .adm-usage th:last-child { text-align: left; color: #6b7f8c; }
.p-admin .adm-usage tfoot th {
    border-top: 2px solid #cfd8dc;
    border-bottom: none;
    color: #435663;
    font-size: 13px;
    text-transform: none;
    letter-spacing: 0;
}

.p-admin .adm-table input,
.p-admin .adm-table select {
    padding: 4px 7px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    width: 100%;
}

.p-admin .adm-table .adm-ordre { width: 80px; }

/* Prélèvement encore sans règle : c'est lui qu'on vient chercher ici */
.p-admin tr.adm-nc td { background: #fff9ef; }

.p-admin .adm-badge {
    font-size: 11px;
    font-weight: 700;
    color: #8a5a00;
    background: #ffe9c4;
    border-radius: 10px;
    padding: 1px 7px;
    margin-left: 6px;
}

.p-admin .adm-journal { margin-top: 8px; }

.p-admin .adm-journal summary {
    cursor: pointer;
    font-weight: 600;
    color: #2c3942;
    padding: 6px 0;
    list-style: none;
}

.p-admin .adm-journal summary::-webkit-details-marker { display: none; }
.p-admin .adm-journal summary::before { content: '▸ '; }
.p-admin .adm-journal[open] summary::before { content: '▾ '; }

.p-admin .adm-taille {
    font-weight: 400;
    color: #90a4ae;
    font-size: 12px;
    margin-left: 8px;
}

.p-admin .adm-log {
    max-height: 420px;
    overflow: auto;
    background: #f5f7f8;
    border: 1px solid #dde3e7;
    border-radius: 6px;
    padding: 10px 12px;
    font-family: 'Courier New', Courier, monospace;
    font-size: 11.5px;
    line-height: 1.4;
    white-space: pre-wrap;
    word-break: break-word;
}

.p-admin .adm-purge { margin: 4px 0 8px 0; }

/* Conteneur d'un module posé par le socle */
.mod-hote { display: none; }
.mod-hote.visible { display: block; }

/* Contenu du kit multiplex : une liste écrite par le laboratoire, dont les
   retours à la ligne font le sens — d'où le <pre>, mais en police de texte :
   ce sont des noms de germes, pas des colonnes à aligner. */
.tl-pop details.panel-kit pre {
    max-height: 260px;
    overflow: auto;
    margin-top: 6px;
    padding: 8px 11px;
    background: #f7f9fa;
    border: 1px solid #dde3e7;
    border-radius: 6px;
    font-family: inherit;
    font-size: 12px;
    line-height: 1.5;
    color: #37474f;
    white-space: pre-wrap;
}

/* Texte brut d'Orbis, en fin d'infobulle : la source, telle quelle */
.tl-pop details.brut pre {
    max-height: 340px;
    overflow: auto;
    margin-top: 6px;
    padding: 9px 11px;
    background: #f5f7f8;
    border: 1px solid #dde3e7;
    border-radius: 6px;
    font-family: 'Courier New', Courier, monospace;
    font-size: 11px;
    line-height: 1.45;
    color: #37474f;
    white-space: pre;
}

/* Aperçu de l'icône choisie, à côté de la liste déroulante */
.p-admin .adm-apercu { width: 28px; }
.p-admin .adm-apercu svg { width: 20px; height: 20px; color: #607d8b; fill: currentColor; }
.p-admin .adm-table .adm-orbis { min-width: 200px; }
.p-admin .adm-inconnus td { font-size: 13px; }

/* Journal des prélèvements : le texte brut d'Orbis se lit en chasse fixe —
   c'est une chaîne à recopier, pas une phrase. Le tableau peut être large :
   il défile sur lui-même plutôt que de pousser la page. */
.p-admin .adm-prelevements { font-size: 13px; }
.p-admin .adm-prelevements code {
    font-family: 'SF Mono', Menlo, 'Courier New', monospace;
    font-size: 12px;
    color: #263238;
    background: #eceff1;
    border-radius: 3px;
    padding: 1px 5px;
    word-break: break-word;
}
.p-admin .adm-prelevements .src { color: #78909c; font-size: 11.5px; }
.p-admin .adm-prelevements i { color: #90a4ae; }

.p-admin .adm-liste { margin: 0 0 12px 18px; }
.p-admin .adm-liste li { margin-bottom: 5px; }
.p-admin .adm-table .adm-cat { min-width: 150px; }
.p-admin .adm-table .adm-orbis { min-width: 170px; }
.p-admin .adm-table .adm-orbis::placeholder { color: #b0bec5; font-style: italic; }

.p-admin .adm-attention {
    background: #fff9ef;
    border: 1.5px solid #ecc98a;
    border-radius: 8px;
    padding: 9px 13px;
    color: #8a5a00;
}
.p-admin code {
    background: #eceff1;
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 12px;
}

/* Conclusion du laboratoire, sous le titre de l'infobulle */
.tl-pop .concl {
    margin: 2px 0 8px 0;
    color: #37474f;
    font-style: italic;
}


/* Les paires de boutons du pied de page dépassent 320 px mises bout à bout.
   Cantonné à l'administration : les autres pages ont leurs propres largeurs. */
.p-admin .button-group { flex-wrap: wrap; }

/* ---------- Barre d'onglets de l'administration ----------
   Six pages plutôt qu'une. Les pastilles portent ce qui attend une action,
   et rien d'autre : un nombre qui ne descend jamais à zéro cesse d'être lu. */
.p-admin .adm-onglets {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 0 30px;
    background: #37474f;
    border-bottom: 1px solid #cfd8dc;
}
.p-admin .adm-onglets a {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 12px 16px;
    color: #cfd8dc;
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 500;
    border-bottom: 3px solid transparent;
    transition: background 0.15s, color 0.15s;
}
.p-admin .adm-onglets a:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.p-admin .adm-onglets a.adm-o-actif {
    background: #fff;
    color: #263238;
    border-bottom-color: #435663;
}
.p-admin .adm-o-i { font-size: 15px; }
.p-admin .adm-o-n {
    background: #c62828;
    color: #fff;
    border-radius: 9px;
    padding: 1px 7px;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.5;
}
@media (max-width: 700px) {
    .p-admin .adm-onglets { padding: 0 10px; }
    .p-admin .adm-onglets a { padding: 10px 10px; font-size: 12.5px; }
}

/* ---------- Un tableau large défile dans son cadre ----------
   ⚠️ .container porte overflow:hidden : un tableau qui déborde y est rogné
   EN SILENCE, sans barre de défilement pour le dire. Un huit-colonnes ne
   tient pas sur un portable, et le tronquer sans le signaler serait pire que
   de le faire défiler. */
.p-admin .adm-scroll {
    overflow-x: auto;
    max-width: 100%;
}
.p-admin .adm-scroll > .adm-table { margin-bottom: 0; }

/* ---------- Sous-onglets (genres d'anomalie) ---------- */
.p-admin .adm-sous-onglets {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 16px;
    border-bottom: 1px solid #eceff1;
    padding-bottom: 8px;
}
.p-admin .adm-sous-onglets a {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid #cfd8dc;
    border-radius: 20px;
    color: #455a64;
    text-decoration: none;
    font-size: 12.5px;
}
.p-admin .adm-sous-onglets a:hover { background: #eceff1; }
.p-admin .adm-sous-onglets a.sso-actif {
    background: #435663;
    border-color: #435663;
    color: #fff;
}
.p-admin .adm-sous-onglets .adm-o-n { background: #b71c1c; }
.p-admin .adm-sous-onglets a.sso-actif .adm-o-n { background: rgba(255, 255, 255, 0.25); }

/* ---------- Tuiles de chiffres ----------
   Le plancher est en minmax(min(...), 1fr) et non minmax(150px, 1fr) :
   .container porte overflow:hidden, un débordement y serait rogné en silence. */
.p-admin .adm-tuiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
    gap: 12px;
}
.p-admin .adm-tuile {
    background: #435663;
    color: #fff;
    border-radius: 10px;
    padding: 18px 16px;
}
.p-admin .adm-tuile-2 { background: #eceff1; color: #263238; }
.p-admin .adm-t-n {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.1;
}
.p-admin .adm-t-u { font-size: 18px; font-weight: 600; opacity: 0.7; }
.p-admin .adm-t-l {
    margin-top: 6px;
    font-size: 12.5px;
    line-height: 1.35;
    opacity: 0.85;
}
.p-admin .adm-source { margin-top: 12px; }

/* ---------- Deux modules côte à côte ---------- */
.p-admin .adm-duo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
    gap: 14px;
    align-items: start;
}
.p-admin .adm-duo .module { margin: 0; }

/* ---------- Histogrammes ----------
   Dessinés en pixels, sans viewBox : un viewBox ferait grossir ou maigrir les
   étiquettes avec la largeur de la fenêtre. Le conteneur défile plutôt. */
.p-admin .adm-graph-boite {
    overflow-x: auto;
    padding-top: 4px;
}
.p-admin .adm-graph { display: block; }
.p-admin .adm-graph-v { font-size: 11px; font-weight: 600; fill: #455a64; }
.p-admin .adm-graph-l { font-size: 10.5px; fill: #90a4ae; }

/* ---------- Deux sources dans un même tableau ----------
   Elles ne se croisent pas : la teinte le dit sans qu'on ait à le relire. */
.p-admin .adm-hebdo th.adm-src-auth,
.p-admin .adm-hebdo td.adm-src-auth { background: #f4f7f8; }
.p-admin .adm-hebdo thead th.adm-src-auth,
.p-admin .adm-hebdo thead th.adm-src-usage { text-align: center; font-size: 11.5px; }
.p-admin .adm-taux {
    display: inline-block;
    background: #eceff1;
    border-radius: 10px;
    padding: 1px 9px;
    font-weight: 600;
    font-size: 12px;
}
.p-admin tr.adm-inactif td { opacity: 0.6; }

/* ---------- Ce qui attend une action (tableau de bord) ---------- */
.p-admin .adm-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 12px;
}
.p-admin .adm-action {
    display: block;
    padding: 16px;
    border: 1.5px solid #ecc98a;
    background: #fff9ef;
    border-radius: 10px;
    text-decoration: none;
    color: #263238;
}
.p-admin .adm-action:hover { border-color: #d9a94e; }
.p-admin .adm-action-ko { border-color: #ef9a9a; background: #fdf2f2; }
.p-admin .adm-action-n {
    display: block;
    font-size: 26px;
    font-weight: 700;
    color: #8a5a00;
}
.p-admin .adm-action-ko .adm-action-n { color: #b71c1c; }
.p-admin .adm-action-t { display: block; font-weight: 600; margin-bottom: 5px; }
.p-admin .adm-action-d { display: block; font-size: 12.5px; color: #546e7a; line-height: 1.45; }

.p-admin .adm-vide {
    background: #f1f8f2;
    border: 1.5px solid #a5d6a7;
    border-radius: 8px;
    padding: 11px 14px;
    color: #2e5b32;
}
.p-admin .adm-sommaire-liste { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.65; }
.p-admin .adm-sommaire-liste li { margin-bottom: 6px; color: #546e7a; }
.p-admin .adm-sommaire-liste a { color: #435663; font-weight: 600; }
.p-admin summary.adm-sommaire { cursor: pointer; }
.p-admin summary.adm-sommaire h2 { display: inline-block; }

/* ---------- Anomalies, une carte par cause ---------- */
.p-admin .adm-causes { display: flex; flex-direction: column; gap: 12px; }
.p-admin .adm-cause {
    border: 1px solid #cfd8dc;
    border-left: 4px solid #90a4ae;
    border-radius: 8px;
    padding: 14px 16px;
    background: #fff;
}
/* Le liseré dit le coût du défaut : un résultat qui n'apparaît pas se lit
   comme un examen jamais fait, un prélèvement mal nommé se lit quand même. */
.p-admin .adm-cause.adm-p4 { border-left-color: #c62828; }
.p-admin .adm-cause.adm-p2 { border-left-color: #ef9a3d; }
.p-admin .adm-cause.adm-p1 { border-left-color: #90a4ae; }
.p-admin .adm-cause-ok { background: #fafafa; border-left-color: #a5d6a7; }
.p-admin .adm-cause-h {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-start;
    justify-content: space-between;
}
/* Le plancher est explicite : sans lui, la colonne des chiffres écrase le
   libellé Orbis jusqu'à huit pixels sur un écran de téléphone. */
.p-admin .adm-cause-quoi { min-width: 0; flex: 1 1 200px; }
.p-admin .adm-cause-titre {
    font-size: 14px;
    word-break: break-word;
}
.p-admin code.adm-cause-titre { background: #eceff1; padding: 3px 7px; }
.p-admin .adm-cause-aff { margin-top: 4px; }
.p-admin .adm-cause-chiffres { text-align: right; flex: 0 0 auto; }
.p-admin .adm-cause-n { font-size: 24px; font-weight: 700; color: #435663; line-height: 1; }
.p-admin .adm-cause .src { color: #78909c; font-size: 11.5px; }
.p-admin .adm-etat {
    margin-top: 10px;
    padding: 7px 11px;
    border-radius: 6px;
    font-size: 12.5px;
}
.p-admin .adm-etat-ok { background: #f1f8f2; color: #2e5b32; }
.p-admin .adm-etat-ko { background: #fdf2f2; color: #b71c1c; }
.p-admin .adm-repli { margin-top: 10px; }
.p-admin .adm-repli > summary {
    cursor: pointer;
    font-size: 12.5px;
    color: #546e7a;
    padding: 3px 0;
}
.p-admin .adm-cause-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    align-items: center;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid #eceff1;
}
.p-admin .adm-inline { display: inline; }
.p-admin .adm-cause-pages { margin-left: auto; }
.p-admin .btn-mini {
    padding: 5px 11px;
    font-size: 12.5px;
    border-radius: 6px;
}

/* ---------- Filtres de la liste des comptes ---------- */
.p-admin .usr-filtres {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-end;
    margin-bottom: 14px;
    padding: 12px 14px;
    background: #f4f7f8;
    border-radius: 8px;
}
/* ⚠️ min-width:0 sur le label ET sur le champ : un <select> a pour largeur
   minimale celle de sa plus longue option — « Maladies infectieuses et
   tropicales » débordait de l'écran d'un téléphone, en silence. */
.p-admin .usr-filtres label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 160px;
    min-width: 0;
    font-size: 11.5px;
    color: #607d8b;
    font-weight: 600;
}
.p-admin .usr-filtres select,
.p-admin .usr-filtres input {
    font-size: 13px;
    padding: 6px 9px;
    border: 1px solid #cfd8dc;
    border-radius: 6px;
    background: #fff;
    font-family: inherit;
    width: 100%;
    min-width: 0;
    max-width: 100%;
}
.p-admin .usr-f-chercher { flex: 1 1 220px; }
.p-admin .usr-f-chercher input { width: 100%; }
.p-admin .usr-f-compte { font-size: 12.5px; color: #546e7a; padding-bottom: 7px; }

/* ===================== AVERTISSEMENT ET PIED DE PAGE ===================== */

/* Un outil qui reformate des résultats médicaux doit dire ce qu'il est et ce
   qu'il n'est pas. Le bandeau est sobre mais toujours visible : le masquer
   derrière un repli reviendrait à ne pas l'afficher. */
.avert {
    margin: 0 30px;
    padding: 12px 16px;
    border: 1.5px solid #ecc98a;
    border-left-width: 4px;
    border-radius: 8px;
    background: #fff9ef;
    font-size: 12.5px;
    line-height: 1.5;
    color: #6b5326;
}

.avert p + p { margin-top: 6px; }
.avert b { color: #4a3813; }

/* Avertissement « ce n'est pas de la microbiologie » (alerteHorsMicrobio,
   dans le parseur). Deux tons, et l'écart entre eux est voulu : rien n'a été
   reconnu — la page va rester vide, il faut refaire la sélection — ou bien de
   la biologie a seulement été laissée de côté à côté d'examens bien rendus.
   Rendre le second du même rouge que le premier ferait douter d'une page
   pourtant juste. */
.hors-micro {
    margin: 12px 30px 0 30px;
    padding: 12px 16px;
    border: 1.5px solid;
    border-left-width: 4px;
    border-radius: 8px;
    font-size: 12.5px;
    line-height: 1.5;
}
.hors-micro b { display: block; margin-bottom: 3px; }
.hors-micro.alerte {
    border-color: #e0a2a2;
    background: #fdf4f3;
    color: #7b3131;
}
.hors-micro.alerte b { color: #5d1f1f; font-size: 13.5px; }
.hors-micro.note {
    border-color: #cdd8de;
    background: #f5f7f8;
    color: #4c5f6c;
}
.hors-micro.note b { color: #2c3942; }

.pied {
    max-width: 1600px;
    margin: 14px auto 0 auto;
    padding: 0 10px 4px 10px;
    font-size: 12px;
    color: #6b7f8c;
    text-align: center;
}

@media (max-width: 700px) {
    .avert { margin: 0 20px; }
    .hors-micro { margin-left: 20px; margin-right: 20px; }
}

/* Invite d'aide : présente tant que rien n'est collé, effacée dès que
   l'utilisateur a trouvé ses données — l'invite n'a plus d'objet. */
.btn-aide {
    text-decoration: none;
    justify-content: center;
}

body.avec-donnees .btn-aide { display: none; }

.pied p + p { margin-top: 5px; }
.pied a { color: #435663; }

/* Avis de responsabilité. Détaché du reste du pied par un filet et rendu un
   peu plus lisible que les mentions qui l'entourent : c'est une clause, pas
   une note de bas de page. Aligné à gauche — un paragraphe de six lignes
   centré ne se lit pas. */
.pied-avis {
    max-width: 900px;
    margin: 0 auto 12px auto;
    padding: 12px 16px;
    border: 1px solid #e0e5e8;
    border-radius: 6px;
    background: #fafbfc;
    color: #5a6d7a;
    text-align: left;
    line-height: 1.55;
}
.pied-avis b { color: #435663; }

/* ---- Page d'aide ---- */
.p-aide .module h3 {
    font-size: 15px;
    color: #2c3942;
    margin: 18px 0 6px 0;
}

.p-aide .module h3:first-child { margin-top: 0; }
.p-aide .module p { margin-bottom: 8px; line-height: 1.6; }
.p-aide .module ol, .p-aide .module ul { margin: 0 0 10px 22px; }
.p-aide .module li { margin-bottom: 5px; }
.p-aide .module img { max-width: 100%; border: 1px solid #cfd8dc; border-radius: 6px; }

.btn-aide-retour { text-decoration: none; justify-content: center; }

/* Panel court : une seule colonne, sur toute la largeur — le libellé et son
   statut tiennent alors sur la même ligne. */
.tl-pop .panel.court {
    columns: 1;
    max-width: none;
}

/* La cible et son statut ne se séparent pas au fil du texte */
.tl-pop .panel .l { break-inside: avoid; }

/* Filtre de période : les champs de date suivent le style des autres réglages */
.sel-actions input[type="date"],
.compa-actions input[type="date"] {
    padding: 4px 7px;
    border: 1.5px solid #cfd8dc;
    border-radius: 5px;
    font-size: 13px;
    font-family: inherit;
    color: #2c3942;
    background: white;
}

.sel-actions input[type="date"]:disabled {
    background: #f0f3f5;
    color: #b0bec5;
}

/* Texte brut d'un prélèvement signalé, déplié sous sa ligne */
.p-admin .adm-actions-cell { white-space: nowrap; }
.p-admin .adm-actions-cell .link-btn + .link-btn { margin-left: 12px; }
.p-admin .adm-brut-ligne td { background: #f5f7f8; padding: 0 10px 10px 10px; }
.p-admin .adm-brut-ligne .adm-log { max-height: 300px; margin: 0; }

/* =========================================================================
   MODULE SUIVI QUANTITATIF DES PCR

   Sélection à gauche (colonne collante réutilisée du comparateur), graphique
   et lecture chiffrée à droite. Le SVG est dessiné en pixels par le module :
   la feuille ne fixe donc ni sa largeur ni sa hauteur, seulement ses textes.
   ========================================================================= */
.quanti-aide {
    font-size: 12px;
    color: #6b7f8c;
    margin-bottom: 11px;
}
.quanti-corps {
    display: grid;
    grid-template-columns: minmax(205px, 275px) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-top: 14px;
}
.quanti-droite {
    min-width: 0;
}
/* Le graphique déborde dans son propre cadre : la page, elle, ne défile
   jamais horizontalement. */
.quanti-graphe {
    overflow-x: auto;
}
.quanti-svg {
    display: block;
}
.quanti-svg .quanti-ax {
    font-size: 10.5px;
    fill: #7a8c98;
    font-family: inherit;
}
.quanti-svg .quanti-val {
    font-size: 10px;
    font-family: inherit;
    font-weight: 700;
}
.quanti-svg .quanti-pt {
    cursor: help;
}
/* Nombre de séries dont le marqueur tombe exactement au même endroit. Les
   décaler mentirait sur la date : on les compte. */
.quanti-svg .quanti-empile {
    font-size: 9.5px;
    font-family: inherit;
    font-weight: 700;
    fill: #6b7f8c;
}
.quanti-vide {
    font-size: 12.5px;
    color: #90a4ae;
    font-style: italic;
    padding: 26px 0;
}
/* Rond de couleur de la série : le même dans la liste de sélection, dans la
   lecture chiffrée et sur la courbe. */
.quanti-corps .pastille {
    display: inline-block;
    width: 9px; height: 9px;
    border-radius: 50%;
    flex: 0 0 auto;
}
.quanti-corps .chip .ou {
    color: #7a8c98; font-size: 11px;
}
/* Deux unités sur un même axe : ça se dit, ça ne se devine pas. */
.quanti-avert {
    font-size: 12px;
    color: #8a5a00;
    background: #fff8e6;
    border: 1px solid #f0dca8;
    border-radius: 6px;
    padding: 8px 11px;
    margin: 14px 0 0 0;
}
/* Rappel discret, en mode « valeur rendue » : l'axe reste logarithmique.
   Ce n'est pas un avertissement — rien n'est en défaut — seulement ce qu'il
   faut savoir pour lire l'espacement des points. */
.quanti-note {
    font-size: 12px;
    color: #667;
    margin: 12px 0 0 0;
}

/* La suite des valeurs, en toutes lettres : un graphique ne se colle pas dans
   un CRH, une phrase si. */
.quanti-liste {
    list-style: none;
    margin: 14px 0 0 0;
    padding: 0;
    font-size: 12.5px;
    color: #2c3942;
}
.quanti-liste li {
    padding: 9px 0;
    border-top: 1px solid #eceff1;
    line-height: 1.7;
}
.quanti-liste li:first-child {
    border-top: none;
}
.quanti-liste .ou {
    color: #7a8c98; font-size: 11.5px;
}
.quanti-liste .v {
    font-weight: 700;
}
/* Valeur bornée : le laboratoire n'a pas mesuré ce nombre, il a dit
   « au-delà » ou « en deçà ». Graisse normale, pour ne pas la lire comme une
   mesure. */
.quanti-liste .v.borne {
    font-weight: 400; color: #6b7f8c;
}
.quanti-liste .q {
    color: #90a4ae; font-size: 11px;
}
.quanti-liste .fl {
    color: #b0bec5; padding: 0 2px;
}
.quanti-liste .note {
    color: #90a4ae; font-size: 11px; font-style: italic;
}
/* Sous 950 px, la sélection repasse au-dessus du graphique : la même bascule
   que le comparateur. */
@media (max-width: 950px) {
    .quanti-corps {
        grid-template-columns: 1fr;
    }
    .quanti-corps .compa-choix {
        border-right: none;
        border-bottom: 1px solid #eceff1;
        padding-right: 0;
        padding-bottom: 12px;
        position: static;
        max-height: none;
    }
}

/* -------------------------------------------------------------------------
   Signalement d'un examen mal rendu
   ------------------------------------------------------------------------- */

/* Discret dans l'infobulle : on le cherche quand on en a besoin, il ne doit
   pas concurrencer le résultat. */
.tl-pop .link-btn.signal {
    display: inline-block;
    margin: 10px 0 2px;
    padding: 3px 9px;
    border: 1px solid #e0c9c9;
    border-radius: 999px;
    background: #fdf6f6;
    color: #a04747;
    font-size: 11.5px;
}
.tl-pop .link-btn.signal:hover { background: #f9ecec; border-color: #d4b0b0; }

.p-signal textarea,
.p-signal input[type="email"] {
    width: 100%;
    padding: 9px 11px;
    border: 1.5px solid #cfd8dc;
    border-radius: 6px;
    font-family: inherit;
    font-size: 13.5px;
    color: #263238;
    background: #fff;
}
.p-signal textarea[readonly] {
    background: #f5f7f8;
    color: #546e7a;
    font-family: 'Courier New', Courier, monospace;
    font-size: 11.5px;
    line-height: 1.45;
}
.p-signal h2 { margin-top: 18px; }
.p-signal h2:first-of-type { margin-top: 0; }

/* Consentement à la transmission du compte rendu. Encadré et non posé nu :
   c'est la seule case de la page, et elle décide si des résultats de patient
   quittent le poste. Elle doit se voir sans se confondre avec le reste. */
.p-signal .signal-consent {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1.5px solid #b8c5cd;
    border-radius: 8px;
    background: #f4f7f8;
    cursor: pointer;
    line-height: 1.45;
}
.p-signal .signal-consent input { margin-top: 3px; flex: none; }
.p-signal .signal-consent:has(input:checked) {
    border-color: #435663;
    background: #e3ebef;
}

/* Ce qui ne sera pas transmis s'affiche en retrait : on doit voir, avant
   d'envoyer, ce que l'on garde pour soi. */
.p-signal textarea.signal-exclu { opacity: 0.45; }

/* ===================== AUTHENTIFICATION ET DÉMONSTRATION =====================
   Préfixes : bu- (barre d'identité), cnx- (connexion), pres- (présentation),
   usr- (gestion des utilisateurs). Ne pas les croiser avec ceux des modules. */

/* Les boutons du tronc commun sont des <button> ; plusieurs actions sont ici
   des liens (déconnexion, démonstration). Ils doivent en avoir l'aspect sans
   que la règle « button { display:flex } » puisse s'y appliquer. */
a.btn-primary,
a.btn-secondary {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 22px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    transition: all 0.2s;
}

/* ---- Barre d'identité -------------------------------------------------
   Au-dessus du titre, discrète mais toujours là : sur un poste partagé, la
   question « sous quel compte suis-je en train de lire ? » doit se régler
   d'un coup d'œil, sans cliquer. */
.barre-user {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 8px 18px;
    background: #eceff1;
    border-bottom: 1px solid #cfd8dc;
    font-size: 12.5px;
    color: #546e7a;
}
.bu-qui { font-weight: 600; color: #2c3942; }
.bu-statut {
    padding: 2px 9px;
    border-radius: 20px;
    font-size: 11.5px;
    font-weight: 600;
    border: 1px solid transparent;
}
.bu-actif   { background: #e8f5e9; color: #2e7d32; border-color: #a5d6a7; }
.bu-avance  { background: #e0f2f1; color: #00695c; border-color: #80cbc4; }
.bu-admin   { background: #e8eaf6; color: #303f9f; border-color: #9fa8da; }
.bu-attente { background: #fff8e1; color: #8d6e00; border-color: #ffe082; }
.bu-ancien  { background: #eceff1; color: #78909c; border-color: #cfd8dc; }

.bu-liens { margin-left: auto; display: flex; gap: 14px; }
.bu-liens a { color: #435663; text-decoration: none; font-weight: 500; }
.bu-liens a:hover { text-decoration: underline; }

/* ---- Mode démonstration ----------------------------------------------- */

/* Le bandeau de démonstration ne réutilise PAS l'ambre de l'avertissement
   d'usage : ce n'est pas une mise en garde mais un état de la page, et les
   confondre ferait passer l'un pour l'autre. */
.avert-demo {
    border-color: #90a4ae;
    background: #eef3f6;
    color: #37474f;
}
.avert-demo b { color: #263238; }

/* Choix du dossier de démonstration, au-dessus de la zone de collage.
   Trois cartes plutôt qu'une liste déroulante : le résumé de chaque dossier
   est ce qui permet de choisir, et une liste déroulante le cacherait. */
.demo-choix { margin-bottom: 12px; }
.dc-titre {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #78909c;
    margin-bottom: 7px;
}
.dc-liste {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 9px;
}
.dc-item {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: 'r n' '. s';
    gap: 2px 8px;
    align-items: start;
    padding: 10px 12px;
    border: 1.5px solid #cfd8dc;
    border-radius: 8px;
    background: #fbfcfc;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.dc-item:hover { border-color: #90a4ae; background: #f4f6f7; }
.dc-item.on {
    border-color: #435663;
    background: #eef3f6;
    box-shadow: inset 0 0 0 1px #435663;
}
.dc-item input { grid-area: r; margin-top: 2px; accent-color: #435663; }
.dc-nom {
    grid-area: n;
    font-size: 13px;
    font-weight: 600;
    color: #2c3942;
    line-height: 1.3;
}
.dc-resume {
    grid-area: s;
    font-size: 11.5px;
    line-height: 1.45;
    color: #6b7f8c;
}

textarea.verrouille {
    background: #f4f6f7;
    color: #546e7a;
    border-style: dashed;
    cursor: default;
}

/* Le refus de collage se dit, il ne se devine pas : sans message, un Ctrl+V
   sans effet se lit comme une panne. */
.demo-refus {
    margin-top: 8px;
    padding: 8px 12px;
    border-radius: 6px;
    background: #fbe9e7;
    border: 1px solid #ffab91;
    color: #8d3b23;
    font-size: 12.5px;
    display: none;
}
.demo-refus.on { display: block; }

/* ---- Page de connexion ------------------------------------------------- */
/* Hors de la grille du haut (page d'erreur, écran étroit), le formulaire
   reste centré et borné : un champ de saisie large de 1 200 px ne se lit pas. */
.p-connexion .cnx-module {
    max-width: 560px;
    margin: 0 auto;
}
/* Dans la grille, il occupe sa colonne, dont la largeur fait déjà la mesure. */
.cnx-haut .cnx-module { max-width: none; margin: 0; }
.cnx-onglets {
    display: flex;
    gap: 4px;
    border-bottom: 2px solid #e0e5e8;
    margin-bottom: 18px;
}
.cnx-onglet {
    background: none;
    color: #78909c;
    padding: 9px 16px;
    border-radius: 6px 6px 0 0;
    font-weight: 600;
    font-size: 14px;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
}
.cnx-onglet.on { color: #435663; border-bottom-color: #435663; }
.cnx-onglet:hover { background: #f4f6f7; }

/* L'onglet actif est posé par le serveur : sans JavaScript, la page reste
   utilisable — on y voit la vue que le serveur a choisie, et une erreur de
   saisie ramène sur le bon formulaire. */
.cnx-vue { display: none; }
.cnx-vue.on { display: block; }

/* Titre d'une vue qui n'a pas d'onglet — « Mot de passe oublié », et la pose
   d'un mot de passe neuf, atteinte par le lien d'un courriel. Même trait que
   la barre d'onglets, pour que l'écran garde sa charpente là où la barre
   disparaît. */
.cnx-titre {
    font-size: 15px;
    font-weight: 700;
    color: #435663;
    padding-bottom: 9px;
    border-bottom: 2px solid #e0e5e8;
    margin-bottom: 16px;
}
/* Discret et à droite, sous le champ : c'est un dépannage, pas une des deux
   actions de la page. */
.cnx-oubli-lien {
    margin-top: 6px;
    text-align: right;
    font-size: 12.5px;
}

.cnx-l {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: #546e7a;
    margin: 12px 0 4px 0;
}

/* « Rester connecté ». La mise en garde est sous la case, en petit mais en
   ambre : ce n'est pas un réglage de confort, c'est ce qui décide si le poste
   rouvre les résultats tout seul demain matin. */
.cnx-memoire {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 14px 0 4px 0;
    font-size: 12.5px;
    line-height: 1.45;
    color: #455a64;
    cursor: pointer;
}
.cnx-memoire input { margin-top: 2px; flex: none; }
.cnx-memoire small {
    display: block;
    margin-top: 2px;
    color: #8a6d3b;
}
.p-connexion input[type="text"],
.p-connexion input[type="email"],
.p-connexion input[type="password"],
.p-connexion select,
.p-users input[type="text"],
.p-users input[type="email"],
.p-users input[type="password"],
.p-users .usr-form select {
    width: 100%;
    padding: 10px 12px;
    border: 2px solid #b8c5cd;
    border-radius: 6px;
    font-size: 14px;
    font-family: inherit;
    background: #fff;
    color: #2c3942;
}
.p-connexion input:focus,
.p-connexion select:focus,
.p-users input:focus { outline: none; border-color: #435663; }

/* Deux champs de même nature sur une ligne — prénom/nom, mot de passe et sa
   confirmation. Ils se replient l'un sous l'autre sur écran étroit. */
.p-connexion .button-group { flex-wrap: wrap; }
.cnx-duo { display: flex; gap: 12px; }
.cnx-duo > div { flex: 1; min-width: 0; }

.cnx-autre { display: none; }
.cnx-autre.on { display: block; }

.cnx-note { font-size: 11.5px; color: #90a4ae; margin-top: 4px; }
.cnx-aide { font-size: 12.5px; color: #607d8b; margin-top: 14px; line-height: 1.55; }
.cnx-aide a { color: #435663; }

.cnx-err {
    padding: 10px 12px;
    border-radius: 6px;
    background: #fbe9e7;
    border: 1px solid #ffab91;
    color: #8d3b23;
    font-size: 13px;
}
.cnx-info {
    padding: 11px 14px;
    border-radius: 8px;
    background: #e8f5e9;
    border: 1px solid #a5d6a7;
    color: #2e7d32;
    font-size: 13px;
    line-height: 1.5;
}
/* Le même bandeau, quand ce qu'il annonce n'a PAS marché — un lien de
   réinitialisation périmé, par exemple. Rendu en vert de réussite, un tel
   message se lit à l'envers : on croit l'opération faite. */
.cnx-info.avert {
    background: #fff8e6;
    border-color: #ecc98a;
    color: #8d6e00;
}

/* ---- Haut de page : le pitch et l'accès côte à côte ---------------------
   Deux colonnes, et la large est celle du pitch : c'est lui qui parle au
   plus grand nombre. Le formulaire tient la colonne étroite, ce qui suffit
   à quatre champs et le garde lisible.

   `align-items: start` et non `stretch` : le module d'accès ne doit pas
   s'étirer sur toute la hauteur du pitch, il deviendrait une colonne vide
   surmontée de deux champs. */
.cnx-haut {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 40px;
    align-items: start;
    padding-top: 8px;
}
.cnx-pitch h2 {
    font-size: 31px;
    line-height: 1.22;
    font-weight: 700;
    color: #2c3942;
    margin-bottom: 16px;
}
/* Le chapô du haut est aligné à gauche et non centré comme celui d'un
   encadré : c'est un paragraphe qu'on lit, pas une accroche qu'on survole. */
.cnx-pitch .pres-chapo { margin: 0; max-width: 640px; }
.cnx-pitch .pres-chapo + .pres-chapo { margin-top: 12px; }

.cnx-cta {
    margin-top: 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}
.cnx-cta .pres-cta-note { line-height: 1.45; }

/* ---- Présentation du produit -------------------------------------------
   Une page de présentation, pas un article : ce sont les captures qui
   convainquent, le texte les explique. D'où l'alternance texte / image, qui
   donne un rythme de lecture et laisse chaque copie d'écran respirer. */

.pres-oeil {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #78909c;
    margin-bottom: 12px;
}
.pres-chapo {
    max-width: 680px;
    margin: 0 auto;
    font-size: 14.5px;
    line-height: 1.7;
    color: #45535c;
}
.pres-chapo i { color: #607d8b; }

.pres-cta {
    margin-top: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    flex-wrap: wrap;
}
.pres-cta-note { font-size: 12.5px; color: #78909c; }

/* Une fonction, une capture. L'ordre s'inverse une ligne sur deux : sans cela
   la page devient une colonne de texte doublée d'une colonne d'images, et
   l'œil cesse de faire le lien entre les deux. */
.pres-feature {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 32px;
    align-items: center;
    padding: 34px 0;
}
.pres-feature + .pres-feature { border-top: 1px solid #e6ebee; }
/* En inversant l'ordre il faut inverser les largeurs avec lui : sans cela la
   capture se retrouve dans la colonne étroite une ligne sur deux, et un
   tableau d'antibiogramme y devient illisible. */
.pres-feature.inverse { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.pres-feature.inverse .pres-txt { order: 2; }
.pres-feature.inverse .pres-shot { order: 1; }

.pres-num {
    display: block;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: #b8c5cd;
    margin-bottom: 6px;
}
.pres-txt h3 {
    font-size: 20px;
    line-height: 1.3;
    color: #2c3942;
    margin-bottom: 12px;
}
.pres-txt p {
    font-size: 13.5px;
    line-height: 1.65;
    color: #45535c;
}
.pres-txt p + p { margin-top: 10px; }
.pres-txt code {
    font-family: 'Courier New', monospace;
    background: #eceff1;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 12.5px;
}
/* Les quatre statuts, dans le texte, avec la couleur qu'ils ont à l'écran :
   c'est plus court qu'une phrase, et cela apprend la légende au passage. */
.t-pos { color: #c62828; }
.t-enc { color: #b26a00; }
.t-neg { color: #607d8b; }
.t-ann { color: #90a4ae; }

.pres-shot { margin: 0; }
.pres-shot a {
    display: block;
    border: 1px solid #cfd8dc;
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
    box-shadow: 0 6px 22px rgba(44, 57, 66, 0.10);
    transition: box-shadow 0.2s, transform 0.2s;
}
.pres-shot a:hover {
    box-shadow: 0 10px 30px rgba(44, 57, 66, 0.17);
    transform: translateY(-2px);
}
.pres-shot img { display: block; width: 100%; height: auto; }
.pres-shot figcaption {
    margin-top: 8px;
    font-size: 11.5px;
    color: #90a4ae;
    text-align: center;
}

.pres-duo-cartes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    gap: 14px;
}
.pres-carte {
    border: 1px solid #dbe2e6;
    border-radius: 8px;
    padding: 14px 16px;
    background: #fbfcfc;
}
.pres-carte h3 { font-size: 14.5px; color: #435663; margin-bottom: 7px; }
.pres-carte p { font-size: 12.5px; line-height: 1.6; color: #45535c; }

/* Trois temps, numérotés : c'est un mode d'emploi, il se lit dans l'ordre. */
.pres-etapes { list-style: none; counter-reset: etape; margin: 0; }
.pres-etapes li {
    counter-increment: etape;
    position: relative;
    padding-left: 42px;
    min-height: 30px;
    font-size: 13.5px;
    line-height: 1.6;
    color: #45535c;
}
.pres-etapes li + li { margin-top: 14px; }
.pres-etapes li::before {
    content: counter(etape);
    position: absolute;
    left: 0;
    top: -1px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #435663;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.pres-etapes a { color: #435663; }

.pres-garde { border-color: #ecc98a; background: #fffdf9; }
.pres-h-avert { color: #8d6e00; }
.pres-liste { margin: 8px 0 0 20px; }
.pres-liste li {
    font-size: 13px;
    line-height: 1.6;
    color: #45535c;
    margin-bottom: 8px;
}

@media (max-width: 860px) {
    .pres-feature,
    .pres-feature.inverse { grid-template-columns: 1fr; gap: 18px; padding: 26px 0; }
    /* Sur une colonne, l'inversion n'a plus de sens : le texte doit toujours
       précéder sa capture, sinon on regarde une image sans savoir quoi y voir. */
    .pres-feature.inverse .pres-txt { order: 0; }
    .pres-feature.inverse .pres-shot { order: 0; }
    .cnx-pitch h2 { font-size: 23px; }
}

/* Le pliage du haut de page se fait plus tôt que celui des captures : à
   deux colonnes, le formulaire devient trop étroit bien avant que la
   présentation ne gêne. Sur une colonne, le pitch reste EN PREMIER — il est
   court, et l'accès arrive dans le même écran ou juste après. */
@media (max-width: 1020px) {
    .cnx-haut { grid-template-columns: minmax(0, 1fr); gap: 26px; }
    .cnx-haut .cnx-module { max-width: 560px; margin: 0 auto; width: 100%; }
    .cnx-pitch .pres-chapo { max-width: none; }
}

/* ---- Gestion des utilisateurs ------------------------------------------ */
.usr-table td { vertical-align: top; }
.usr-table code {
    font-family: 'Courier New', monospace;
    background: #eceff1;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 12px;
}
.usr-table .src { color: #78909c; font-size: 11.5px; margin-top: 2px; }
.usr-table .src a { color: #78909c; }
.usr-bloque { color: #c62828 !important; font-weight: 600; }

/* Une demande en attente est ce qu'on vient traiter : elle doit se voir sans
   être cherchée. Le fond reprend celui des prélèvements non catégorisés. */
.p-users tr.usr-attente td { background: #fff9ef; }
.p-users tr.usr-ancien td { color: #90a4ae; }

.usr-statut select {
    width: 100%;
    min-width: 150px;
    padding: 6px 8px;
    border: 1px solid #b8c5cd;
    border-radius: 5px;
    font-size: 12.5px;
    font-family: inherit;
    background: #fff;
}
.usr-inline { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.usr-inline .link-btn { margin: 0; }
.usr-sup { color: #c62828 !important; }

.usr-mdp { border-color: #a5d6a7; }
.usr-code {
    font-family: 'Courier New', monospace;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 2px;
    color: #2c3942;
    background: #f4f6f7;
    border: 2px dashed #b8c5cd;
    border-radius: 8px;
    padding: 14px 18px;
    text-align: center;
    user-select: all;
}
.usr-form { max-width: 520px; }

@media (max-width: 700px) {
    .cnx-duo { flex-direction: column; gap: 0; }
    .barre-user { font-size: 12px; }
    .bu-liens { margin-left: 0; width: 100%; }
}

/* ---- Tutoriel d'aide (aide.php) ----------------------------------------
   Une liste numérotée qui reprend les repères entourés sur les copies
   d'écran : le numéro à l'écran et le numéro dans le texte doivent être le
   même, sinon le lecteur cherche. */
.tuto { list-style: none; counter-reset: tuto var(--depart, 0); margin: 16px 0 0 0; }
.tuto li {
    counter-increment: tuto;
    position: relative;
    padding-left: 46px;
    margin-bottom: 16px;
}
.tuto li::before {
    content: counter(tuto);
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #c62828;          /* le rouge des repères de la capture */
    color: #fff;
    font-size: 14px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.tuto h4 {
    font-size: 14.5px;
    color: #2c3942;
    margin: 4px 0 5px 0;
    line-height: 1.35;
}
.tuto p { font-size: 13px; line-height: 1.6; color: #45535c; }
.tuto p + p { margin-top: 5px; }
.tuto-note { color: #78909c !important; font-size: 12.5px !important; }

.tuto-fig { margin: 4px 0 26px 0; }
.tuto-fig a {
    display: block;
    border: 1px solid #cfd8dc;
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
    box-shadow: 0 4px 16px rgba(44, 57, 66, 0.10);
    transition: box-shadow 0.2s;
}
.tuto-fig a:hover { box-shadow: 0 8px 24px rgba(44, 57, 66, 0.16); }
.tuto-fig img { display: block; width: 100%; height: auto; }
.tuto-fig figcaption {
    margin-top: 8px;
    font-size: 12px;
    line-height: 1.5;
    color: #78909c;
}

.tuto-bilan {
    margin: 18px 0 6px 0;
    padding: 12px 16px;
    border-left: 4px solid #435663;
    border-radius: 0 8px 8px 0;
    background: #eef3f6;
}
.tuto-bilan p { font-size: 13px; line-height: 1.7; color: #2c3942; }
.tuto-bilan code {
    font-family: 'Courier New', monospace;
    background: #fff;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 12px;
}

/* Un compte ouvert dont le titulaire n'a jamais été prévenu : il attend sans
   le savoir. C'est une anomalie à voir sans la chercher. */
.usr-muet { color: #b26a00 !important; font-weight: 600; }

/* Créer un compte : replié par défaut. C'est le geste rare — on vient d'abord
   ici pour valider des demandes, pas pour créer des comptes à la main. */
.usr-creer > summary {
    cursor: pointer;
    font-size: 14px;
    color: #435663;
    list-style: none;
    padding: 2px 0;
}
.usr-creer > summary::-webkit-details-marker { display: none; }
.usr-creer > summary::before { content: '▸ '; color: #90a4ae; }
.usr-creer[open] > summary::before { content: '▾ '; }
.usr-creer[open] > summary { margin-bottom: 12px; }
.usr-creer > summary:hover { color: #2c3942; }

.usr-case {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 16px;
    font-size: 13px;
    color: #45535c;
    cursor: pointer;
}
.usr-case input { accent-color: #435663; }
.usr-case .cnx-note { margin-top: 0; }

/* ---- Aperçu par statut --------------------------------------------------
   Voyante à dessein : un administrateur qui oublie qu'il est en aperçu perd
   l'administration et le bouton de signalement, et croirait l'outil cassé. */
.barre-apercu {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 9px 18px;
    background: #fff3e0;
    border-bottom: 1px solid #ffcc80;
    font-size: 12.5px;
    color: #7a4f00;
}
.ba-l {
    padding: 2px 9px;
    border-radius: 20px;
    background: #ef6c00;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.ba-txt { flex: 1; min-width: 220px; line-height: 1.45; }
.ba-txt b { color: #5d3a00; }
.ba-fin {
    color: #7a4f00;
    text-decoration: none;
    font-weight: 600;
    border: 1px solid #ffb74d;
    border-radius: 6px;
    padding: 4px 11px;
    background: #fff;
    white-space: nowrap;
}
.ba-fin:hover { background: #ffe0b2; }

/* Le lanceur, dans la gestion des utilisateurs. */
.usr-apercu { margin-top: 4px; }
.usr-apercu .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.usr-apercu .chips a {
    display: inline-block;
    padding: 7px 14px;
    border: 1.5px solid #cfd8dc;
    border-radius: 20px;
    background: #fbfcfc;
    color: #435663;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
}
.usr-apercu .chips a:hover { border-color: #435663; background: #eef3f6; }

/* ---- Engagement d'usage, à la demande de compte ------------------------
   Encadré et détaché du reste du formulaire : ce n'est pas un champ de plus,
   c'est ce qu'on accepte. Le fond ambré est celui des avertissements. */
.cnx-engagement {
    margin-top: 20px;
    padding: 14px 16px;
    border: 1.5px solid #ecc98a;
    border-left-width: 4px;
    border-radius: 8px;
    background: #fff9ef;
}
.cnx-eng-titre {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #8d6e00;
    margin-bottom: 8px;
}
.cnx-engagement ul { margin: 0 0 0 18px; }
.cnx-engagement li {
    font-size: 12.5px;
    line-height: 1.55;
    color: #5c4a1e;
    margin-bottom: 6px;
}
.cnx-engagement li b { color: #4a3813; }

.cnx-eng-case {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin-top: 12px;
    padding-top: 11px;
    border-top: 1px solid #f0dcb4;
    font-size: 13px;
    font-weight: 600;
    color: #4a3813;
    cursor: pointer;
}
.cnx-eng-case input { accent-color: #8d6e00; }
