/* CABIGEST — design system partagé */

:root {
  --ink-900: #101828;
  --ink-700: #344054;
  --ink-500: #667085;
  --ink-300: #98a2b3;
  --line: #e4e7ec;
  --line-soft: #eef1f5;
  --surface: #ffffff;
  --canvas: #f7f8fa;

  --brand-50:  #eef2ff;
  --brand-100: #e0e7ff;
  --brand-500: #4f46e5;
  --brand-600: #4338ca;
  --brand-700: #3730a3;

  --teal-50:  #ecfdf5;
  --teal-500: #10b981;
  --teal-600: #059669;

  --amber-50:  #fffbeb;
  --amber-500: #f59e0b;
  --amber-600: #d97706;

  --rose-50:  #fef2f2;
  --rose-500: #ef4444;
  --rose-600: #dc2626;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);

  --font: "Inter", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
}

* { box-sizing: border-box; }

/* Garantit que [hidden] masque toujours l'élément, même si une règle (ou un style inline)
   lui donne par ailleurs "display: flex/grid/block" pour son état visible — sans ce
   !important, un sélecteur plus spécifique que l'attribut (ID, style inline) l'emporte et
   l'élément reste affiché malgré l'attribut "hidden" posé par le JS. Bug réel trouvé sur
   "#pageWrap"/"#consultWrap" (constantes/bio/rx/documents/numerisation/ordonnances/
   vaccinations/consultations) : la fiche restait visible et modifiable (champs mémo compris)
   même quand le message "Aucun patient sélectionné" s'affichait. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--canvas);
  color: var(--ink-900);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* ---------- Nav shell ---------- */

.app-shell {
  display: flex;
  min-height: 100vh;
}

.app-nav {
  width: 220px;
  flex: none;
  background: linear-gradient(180deg, var(--brand-700), var(--brand-600));
  color: #fff;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.app-nav .brand {
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.02em;
  padding: 0 10px 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.app-nav .brand .dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--teal-500);
  box-shadow: 0 0 0 4px rgba(16,185,129,0.25);
}

.app-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  color: rgba(255,255,255,0.78);
  transition: background 0.15s ease, color 0.15s ease;
  flex: none;
}

.nav-divider {
  height: 2px; margin: 3px -14px; flex: none;
  background: rgba(255,255,255,0.22);
}
/* Entrées masquées (modules éteints, menu allégé d'une personne) : deux séparateurs qui se suivent sans entrée entre
   eux n'en font qu'un (30/09/2026, demandé : « ne pas trouver 3 ou 4 séparateurs superposés »). */
.nav-divider + .nav-divider { display: none; }

/* Navigateur de consultations : la consultation affichée n'est PAS celle du jour. Le bandeau qui
   l'annonçait en toutes lettres sur chaque page (« Consultation antérieure n° … Revenir à
   aujourd'hui pour … ») a été retiré à la demande — il prenait une ligne entière pour redire la
   date déjà affichée ici. La couleur seule porte l'information. Spécificité supérieure à la règle
   `.cs-navigator .nav-label` répétée dans chaque page, donc l'ordre de chargement est sans effet. */
.cs-navigator .nav-label.historique {
  color: #b45309; font-weight: 800;
  background: #fef3c7; border-radius: 5px; padding: 1px 8px;
}

/* Rappel d'abonnement, trois niveaux (cf. partials/nav.php) : discret tant qu'il reste plus d'un
   mois, orange dans le dernier mois, rouge pendant la période de grâce. Deux lignes au maximum,
   sinon le menu se met à défiler. */
/* Marges négatives : le bandeau déborde sur le rembourrage de la barre pour gagner 16 px de
   largeur utile — c'est ce qui permet à « Abonnement encore valide 11 jours » de tenir sur UNE
   ligne, et donc au bloc entier de tenir sur deux. */
.nav-licence {
  margin: 3px -8px 1px; padding: 4px 4px; border-radius: 6px; flex: none;
  font-size: 10.5px; line-height: 1.25; text-align: center; font-weight: 650;
}
/* Adresse de renouvellement : plus petite et insécable, pour que la deuxième ligne reste UNE
   ligne dans une barre de 220 px (le numéro international revenait à la ligne, d'où trois lignes
   et un menu qui se mettait à défiler). */
.nav-licence .contact { display: block; font-weight: 500; font-size: 9.5px; white-space: nowrap; }
.nav-licence.calme { background: none; padding: 2px 4px; font-size: 11px; font-weight: 500; color: rgba(255,255,255,0.6); }
.nav-licence.orange { background: #f59e0b; color: #1f2937; }
.nav-licence.rouge { background: #dc2626; color: #fff; }

/* Pas de barre de défilement verticale dans le menu (demandé explicitement : elle apparaissait
   quand la fenêtre est peu haute, portable / mode application). D'abord on resserre les
   espaces entre les entrées selon la hauteur disponible ; en dernier recours le menu reste
   défilable à la molette mais la barre est masquée. */
.app-nav { scrollbar-width: none; }
.app-nav::-webkit-scrollbar { width: 0; height: 0; }

/* Quatre NIVEAUX de resserrement, décrits une seule fois par des variables, et déclenchés à des
   hauteurs différentes selon le menu : celui du cabinet de l'éditeur porte une entrée de plus
   (« Licences ») et doit donc se resserrer ~100 px plus tôt — sans cela il se mettait à défiler
   entre 900 et 1000 px de hauteur de fenêtre, et le nom du praticien sortait par le haut. */
.app-nav {
  --nav-pad-v: 12px; --nav-gap: 2px; --nav-item-pad: 7px; --nav-font: 13.5px;
  --nav-ic: 19px; --nav-ic-w: 22px; --nav-div: 3px; --nav-logo: 180px; --nav-logo-pad: 6px;
  --nav-nom-pad: 10px; --nav-nom-font: 13.5px; --nav-ver-pad: 10px; --nav-ver-font: 12px;
  --nav-lic-font: 11px; --nav-lic-pad: 4px;
  padding-top: var(--nav-pad-v); padding-bottom: var(--nav-pad-v); gap: var(--nav-gap);
}
.app-nav a { padding: var(--nav-item-pad) 12px; font-size: var(--nav-font); }
.app-nav a .ic { font-size: var(--nav-ic); width: var(--nav-ic-w); }
.nav-divider { margin: var(--nav-div) -14px; }
.nav-top-logo { padding: 2px 6px var(--nav-logo-pad); }
.nav-top-logo img { max-width: var(--nav-logo); }
.nav-licence { font-size: var(--nav-lic-font); padding: var(--nav-lic-pad) 4px; }
/* Bandeau du cabinet de DÉMONSTRATION : deux lignes de plus dans la barre, dimensionnées par les
   mêmes variables pour qu'il se resserre avec le reste au lieu de faire défiler le menu. */
.nav-demo {
  margin: 3px -8px 1px; padding: var(--nav-lic-pad) 4px; border-radius: 6px; flex: none;
  background: #fbbf24; color: #1f2937; text-align: center; font-weight: 600;
  font-size: var(--nav-lic-font); line-height: 1.25;
}
.nav-demo span { display: block; font-weight: 500; font-size: calc(var(--nav-lic-font) - 0.5px); }

/* Resserrement du menu selon la hauteur de l'écran (recalé le 26/09/2026, 23 entrées avec
   « Courrier reçu »). Hauteur naturelle MESURÉE du menu de la démonstration (le plus long : bandeau
   jaune de 40 px ; un cabinet ordinaire fait 40 px de moins, l'éditeur une entrée de plus) :
   niveau 0 = 1208 px, 1 = 1113, 2 = 988, 3 = 876, 4 = 839, 5 = 785, 6 = 713. Chaque écran prend le
   niveau le plus aéré qui tient ; les règles sont cumulatives (la dernière qui s'applique l'emporte). */
/* Niveau 1 : léger. */
@media (max-height: 1211px) { .app-nav { --nav-pad-v: 9px; --nav-gap: 1px; --nav-item-pad: 6px; --nav-div: 2px; --nav-logo: 150px; --nav-logo-pad: 4px; } }
/* Niveau 2 : moyen. */
@media (max-height: 1116px) { .app-nav { --nav-pad-v: 8px; --nav-gap: 0; --nav-item-pad: 4px; --nav-logo: 120px; --nav-logo-pad: 3px; --nav-nom-pad: 5px; --nav-lic-font: 10.5px; --nav-lic-pad: 3px; } }
/* Niveau 3 : serré (1366×900). */
@media (max-height: 991px) { .app-nav { --nav-item-pad: 2px; --nav-font: 13px; --nav-ic: 18px; --nav-div: 1px; --nav-logo: 96px; --nav-ver-pad: 5px; --nav-ver-font: 11px; --nav-nom-pad: 4px; --nav-nom-font: 12.5px; } }
/* Niveau 4 : très serré. */
@media (max-height: 879px) { .app-nav { --nav-pad-v: 6px; --nav-item-pad: 2px; --nav-font: 12.5px; --nav-ic: 16px; --nav-ic-w: 20px; --nav-logo: 70px; --nav-ver-pad: 3px; --nav-ver-font: 10.5px; --nav-lic-font: 10px; --nav-lic-pad: 2px; --nav-nom-font: 12px; --nav-nom-pad: 3px; } }
/* Niveau 5 : portable (1366×768 en mode application). */
@media (max-height: 842px) { .app-nav { --nav-item-pad: 1px; --nav-logo: 60px; --nav-nom-pad: 2px; } }
/* Niveau 6 : petit écran (1280×720). */
@media (max-height: 788px) { .app-nav { --nav-item-pad: 0px; --nav-logo: 48px; --nav-div: 0px; --nav-font: 12px; --nav-ic: 15px; } }
/* Menu plus long que prévu (modules d'activité, « Licences ») : hauteur des entrées calculée par
   partials/nav.php (classe .ajuste, variable --nav-a-h), 26/09/2026. */
.app-nav.ajuste > a { height: var(--nav-a-h); min-height: 0; }
.app-nav a:hover { background: rgba(255,255,255,0.08); color: #fff; }
.app-nav a.active { background: rgba(255,255,255,0.16); color: #fff; }
.app-nav a .ic { font-size: 19px; width: 22px; text-align: center; }
.app-nav a .ic svg { width: 18px; height: 18px; vertical-align: middle; }
/* Icône image (SVG servi en fichier, ex. assets/icon-scanner.svg) : même gabarit que les émojis. */
.app-nav a .ic img { width: 19px; height: 19px; vertical-align: -4px; }
/* Seringue penchée, aiguille pointant vers le bas (demandé explicitement — "garde la inclinée
   mais seringue incliné vers le bas") : aucun émoji Unicode dédié pour une orientation
   différente, rotation CSS du glyphe 💉 (par défaut dessiné aiguille en haut à gauche, piston en
   bas à droite) — angle choisi pour rester penché (pas vertical pur) tout en pointant vers le
   bas plutôt que vers le haut. */
.ic-rotate-down { display: inline-block; transform: rotate(165deg); }
/* Stéthoscope 🩺 recoloré du bleu d'origine vers rouge/corail (demandé explicitement — "stetho
   mai pas bleu") : aucune variante de couleur native pour cet émoji en Unicode, filtre CSS
   hue-rotate (+ saturate pour compenser le ternissement que hue-rotate cause souvent). */
.ic-recolor-coral { display: inline-block; filter: hue-rotate(160deg) saturate(1.6); }

/* Nouveau logo : fond dégradé bleu foncé déjà intégré à l'image, trop proche du violet
   de la nav pour se détacher tout seul ("bleu sur bleu"). Au lieu de retoucher les
   couleurs de marque du logo ou le thème violet de toute l'appli, un liseré clair
   (anneau) autour de la carte suffit à créer une séparation nette. (Un essai de fondu/
   vignette sans cadre a été fait puis annulé — "remets ça" — retour à ce style d'origine.) */
/* 25/09/2026 : l'essai « bord à bord » a été annulé (« non, reviens »), puis demandé « sans liseré
   blanc » : taille d'origine (110 px, centré), mais la carte épouse l'image (inline-block) et n'a
   plus de bordure claire — seule une ombre détache le logo du fond de la barre. */
/* Bandeau bord à bord (demandé le 25/09/2026 : « largeur identique au panneau gauche, cette
   hauteur, recréé sans perte ») : fichier logo-clicgest-bandeau.png (recadré 1,9:1 depuis
   l'original, 880 px de large), qui déborde des marges de la barre pour en prendre toute la
   largeur — 220 px au poste, soit 96 px de haut (recadrage resserré à 2,3:1 pour que « Mentions
   de l'éditeur » reste visible en bas du menu). Sur un écran bas, la hauteur est plafonnée
   (--nav-logo) et l'image est recadrée au centre plutôt que rétrécie. */
.nav-top-logo { padding: 0 0 4px; margin: calc(-1 * var(--nav-pad-v)) -14px 0; text-align: center; flex: none; line-height: 0; }
.nav-top-logo .card { display: block; border-radius: 0; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.3); border: 0; }
.nav-top-logo img { width: 100%; max-width: none; height: auto; max-height: var(--nav-logo); object-fit: cover; object-position: center; display: block; }
.nav-wordmark { display: none; }   /* mot-symbole du téléphone (css/mobile.css) */

/* Praticien connecté + déconnexion (réplique lbCurrentUser/BtnDeconnect côté Delphi) : la
   déconnexion est un lien de nav comme les autres (icône + libellé), pas un bouton à part,
   pour rester cohérente visuellement avec le reste de la barre latérale. */
/* flex:none — comme toutes les autres entrées de la barre. Sans lui, la barre étant une colonne
   flex, le nom du praticien était le seul élément à se laisser ÉCRASER quand la place manquait :
   mesuré à 10 px de haut pour une police de 12 px entre 900 et 1000 px de fenêtre, c'est-à-dire
   un nom rogné jusqu'à disparaître (signalé). */
.nav-user-name {
  font-size: 12px; font-weight: 650; color: rgba(255,255,255,0.7);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: 6px 12px 0; flex: none;
}
.nav-user-name-top { text-align: center; padding: var(--nav-nom-pad) 8px 0; font-size: var(--nav-nom-font); }
/* Nom + icône de déconnexion (nav.php) : l'enveloppe ne compte pas au poste, l'icône n'y apparaît pas. */
.nav-user-ligne { display: contents; }
.nav-logout-mobile { display: none; }

/* Critère HAS LAPv A8 : immatriculation de version affichable depuis le LAP. Mise en évidence
   demandée explicitement ("mettre en évidence... gras") : plus discrète à l'origine, elle
   passait inaperçue au pied d'une longue barre de nav. */
.nav-version {
  font-size: var(--nav-ver-font); font-weight: 500; color: rgba(255,255,255,0.85);
  text-align: center; padding: var(--nav-ver-pad) 8px 4px; margin-top: auto; flex: none;
}

.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.app-topbar {
  padding: 16px 28px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.app-topbar h1 { font-size: 18px; margin: 0; font-weight: 650; color: var(--ink-900); }

/* Bande "patient" centrée DANS la barre de titre plutôt qu'une bande séparée en dessous
   (demandé explicitement — "supprimer la bande ou il y a le nom du patient... deplace le nom
   vers la bande de tout en haut en centrant le nom") : Constantes, Bio/Rx, Ordonnance,
   Documents, Numérisation, Vaccinations, Consultations. Modificateur (.app-topbar-patient),
   pas .app-topbar directement : les pages sans contexte patient (Patients, Statistiques,
   Comptabilité...) gardent le flex/space-between à 2 enfants d'origine, inchangé.
   grid-column EXPLICITE (pas l'ordre naturel des 3 zones) sur chacune des 3 zones : quand
   .patient-header est "hidden" (aucun patient sélectionné), la grille garde son 1fr/auto/1fr
   (titre à gauche, actions à droite) au lieu d'un repli à 2 colonnes qui aurait recollé les
   actions au centre. */
.app-topbar-patient { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px; }
.app-topbar-patient .topbar-title { grid-column: 1; min-width: 0; }
.app-topbar-patient .patient-header { grid-column: 2; margin: 0; background: none; border: none; border-radius: 0; padding: 0; box-shadow: none; }
.app-topbar-patient .topbar-actions { grid-column: 3; justify-self: end; display: flex; gap: 8px; }
.app-topbar .sub { font-size: 12.5px; color: var(--ink-500); margin-top: 2px; }

.app-content { flex: 1; padding: 24px 28px; min-height: 0; }

/* ---------- Primitives ---------- */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

input, select, textarea {
  font: inherit;
  font-size: 13.5px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  width: 100%;
  background: #fff;
  color: var(--ink-900);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px var(--brand-100);
}
input:disabled, select:disabled { background: var(--line-soft); color: var(--ink-500); }
textarea { resize: vertical; min-height: 64px; }
/* Choix coché (bouton radio ou case à cocher) : son libellé passe en ROUGE gras, partout dans
   l'application, comme les groupes de Biologie/Radiologie (demandé). Les pastilles (.chip,
   .radio-chip à fond plein), qui se colorent par le fond, gardent leur propre style. */
:root { --coche: #cc0033; }

/* Groupe de boutons radio (24/09/2026) : la présentation des modes de règlement de la
   comptabilité, mise en commun — un seul choix, et le choix retenu se voit (gras, couleur de
   coche). Remplace les pastilles-boutons là où l'on choisit UNE valeur parmi quelques-unes. */
.radio-group { display: flex; flex-wrap: wrap; gap: 5px 14px; }
.radio-group label { display: flex; align-items: center; gap: 5px; margin: 0; font-size: 12px; font-weight: 600; color: var(--ink-700); cursor: pointer; white-space: nowrap; }
.radio-group input[type="radio"] { width: 14px; height: 14px; margin: 0; flex: none; accent-color: var(--brand-600); cursor: pointer; }
.radio-group label:has(input:checked) { color: var(--coche); font-weight: 800; }
label:not(.chip):not(.radio-chip):has(input[type="radio"]:checked),
label:not(.chip):not(.radio-chip):has(input[type="checkbox"]:checked) { color: var(--coche); font-weight: 800; }

/* « case à cocher + libellé sur une ligne ». La règle vivait dans certaines pages seulement
   (agenda, consultations, fiche patient) : ailleurs la case héritait du width:100% des champs
   de saisie et s'étalait en grand rectangle vide qui poussait le libellé hors de la ligne
   (constaté le 23/09/2026 sur Constantes/Documents/Bio-Rx). Posée ici, elle vaut partout. */
label.checkbox-row { display: inline-flex; align-items: center; gap: 7px; }
label.checkbox-row input[type="checkbox"], label.checkbox-row input[type="radio"] {
  width: auto; flex: none; margin: 0;
}
/* Champs de recherche principaux (médicaments, examens bio/radio, modèles de documents) mis en
   évidence (demandé) : fond ambre clair, bordure indigo renforcée par une ombre (même hauteur
   qu'un champ ordinaire), loupe à gauche, texte en gras. */
input.search-hl {
  background: #fffbeb url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234338ca' stroke-width='2.6' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") no-repeat 9px center;
  padding-left: 32px;
  border-color: var(--brand-500);
  box-shadow: inset 0 0 0 1px var(--brand-500);
  font-weight: 650;
}
input.search-hl::placeholder { color: #92400e; font-weight: 600; opacity: .8; }
input.search-hl:focus { background-color: #fff; box-shadow: inset 0 0 0 1px var(--brand-600), 0 0 0 3px var(--brand-100); }

label.field-label {
  display: block;
  font-size: 12px;
  font-weight: 750;
  color: var(--ink-700);
  margin-bottom: 5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

button {
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  padding: 8px 16px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--brand-500);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.05s ease, box-shadow 0.15s ease;
}
button:hover { background: var(--brand-600); }
button:active { transform: translateY(1px); }
button.secondary { background: var(--line-soft); color: var(--ink-700); }
button.secondary:hover { background: var(--line); }
/* 01/10/2026 (demandé : « partout, mets en évidence le bouton Retour ») : tout « ← Retour … » est ambre et gras,
   même couleur que la barre du cadre PDF (js/pdf_cadre.js) ; les pages d'impression, sans cette feuille, reçoivent
   le même style en ligne par js/actions.js. */
button.btn-retour, a.btn-retour, button.secondary.btn-retour { background: #f59e0b; color: #1f2937; font-weight: 800; border: none; border-radius: 6px; text-decoration: none; }
button.btn-retour:hover, a.btn-retour:hover, button.secondary.btn-retour:hover { background: #d97706; color: #111827; }
button.ghost { background: transparent; color: var(--brand-600); padding: 8px 10px; }
button.ghost:hover { background: var(--brand-50); }
button.danger { background: var(--rose-50); color: var(--rose-600); }
button.danger:hover { background: #fee2e2; }
button:disabled { opacity: 0.5; cursor: not-allowed; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
}

.toast {
  font-size: 13px;
  font-weight: 600;
  padding: 4px 0;
}
.toast.ok { color: var(--teal-600); }
.toast.err { color: var(--rose-600); }

/* ---------- Segmented toggle (PEC, filtres...) ---------- */

.segmented { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; background: #fff; }
.segmented button { border-radius: 0; background: #fff; color: var(--ink-700); box-shadow: none; padding: 8px 18px; }
.segmented button:hover { background: var(--canvas); }
.segmented button.active { background: var(--brand-500); color: #fff; }
.segmented button.active:hover { background: var(--brand-600); }

/* ---------- Chip radio: <label class="chip"><input type=radio>Texte</label> ---------- */

label.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 999px; border: 1.5px solid var(--line);
  font-size: 12.5px; font-weight: 600; color: var(--ink-700); cursor: pointer;
  background: #fff; transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
label.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
label.chip:hover { border-color: var(--brand-500); }
label.chip:has(input:checked) { background: #fff5f6; border-color: var(--coche); color: var(--coche); font-weight: 800; }

/* ---------- Card section (remplace fieldset/legend) ---------- */

.card-section { border: 1px solid var(--line); border-radius: var(--radius-md); margin-bottom: 16px; overflow: hidden; background: #fff; }
.card-section-head {
  display: flex; align-items: center; gap: 8px; padding: 11px 18px;
  background: linear-gradient(90deg, var(--brand-50), #fff); border-left: 4px solid var(--brand-500); border-bottom: 1px solid var(--line);
  font-size: 11.5px; font-weight: 800; color: var(--brand-700);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.card-section-head .ic { font-size: 13px; }
.card-section-body { padding: 18px; }

/* ---------- Avatar ---------- */

.avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; color: #fff;
}
.avatar.sm { width: 30px; height: 30px; font-size: 11.5px; }

/* ---------- Autocomplétion (ville, médecin traitant, patient...) ---------- */

.autocomplete { position: relative; }
.autocomplete-list {
  position: absolute; top: 100%; left: 0; right: 0; margin-top: 2px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md); max-height: 220px; overflow-y: auto; z-index: 30;
}
.autocomplete-list div { padding: 7px 10px; font-size: 13px; cursor: pointer; }
.autocomplete-list div:hover { background: var(--brand-50); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-300); }

/* ---------- Éditeur de texte enrichi (Documents / Ordonnances) — public/js/richtext.js ---------- */

/* flex:1/min-height:0 (demandé explicitement — "verifie si ca depasse hauteur" sur le mémo
   Ordonnance/Document) : .rte-wrap n'était qu'un bloc normal dans son parent flex-colonne
   (.ordo-editor/.doc-editor, déjà correctement flex:1/min-height:0), donc sans hauteur bornée
   propre — un texte long agrandissait toute la carte au lieu de faire défiler .rte-editor
   (qui a pourtant dejà overflow-y:auto, mais ça ne sert à rien sans hauteur bornée). */
.rte-wrap { border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; background: #fff; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.rte-toolbar {
  display: flex; align-items: center; gap: 3px; flex-wrap: wrap; flex: none;
  padding: 5px 6px; background: var(--line-soft); border-bottom: 1px solid var(--line);
}
.rte-btn {
  width: 28px; height: 26px; padding: 0; font-size: 12.5px; font-weight: 600;
  background: #fff; color: var(--ink-700); border: 1px solid transparent; border-radius: 5px;
}
.rte-btn:hover { background: var(--brand-50); }
.rte-btn.active { background: var(--brand-100); border-color: var(--brand-500); color: var(--brand-700); }
.rte-sep { width: 1px; align-self: stretch; background: var(--line); margin: 2px 3px; }
.rte-toolbar select.rte-font { max-width: 130px; }
.rte-toolbar select.rte-size { max-width: 78px; }
.rte-toolbar select { height: 26px; font-size: 12px; padding: 0 4px; }
.rte-toolbar input[type=color] { width: 28px; height: 26px; padding: 1px; border: 1px solid var(--line); border-radius: 5px; background: #fff; }
.rte-editor {
  flex: 1; min-height: 160px; padding: 10px 12px; font-size: 13px; line-height: 1.6;
  outline: none; overflow-y: auto;
}
.rte-editor:empty::before { content: attr(data-placeholder); color: var(--ink-300); }

/* ---------------- Changer de patient depuis n'importe quelle page clinique (demandé
   explicitement — "changer de patient sans revenir à la queue") : un petit ▾ injecté à côté du
   nom dans .patient-header (cf. public/js/patient-switcher.js, chargé sur chaque page clinique)
   ouvre la liste des patients actuellement en salle d'attente (même source que index.php) ;
   cliquer en choisit un autre et recharge la MÊME page pour lui. Styles centralisés ici (plutôt
   que dupliqués par page comme .patient-header lui-même) car injectés par un seul script
   partagé, pas par du HTML par page. ---------------- */
.patient-switch-wrap { position: relative; display: inline-block; margin-left: 4px; }
.patient-switch-btn {
  background: none; border: none; box-shadow: none; padding: 2px 5px; margin: 0;
  color: var(--brand-600); font-size: 11px; cursor: pointer; border-radius: var(--radius-sm);
}
.patient-switch-btn:hover { background: var(--brand-50); }
.patient-switch-panel {
  position: absolute; top: 100%; left: 0; z-index: 60; width: 300px; max-height: 340px;
  overflow-y: auto; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); padding: 6px; margin-top: 4px;
}
.patient-switch-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: var(--radius-sm);
  cursor: pointer; font-size: 12.5px; color: var(--ink-900);
}
.patient-switch-row:hover { background: var(--brand-50); }
.patient-switch-row.current { background: var(--brand-100); font-weight: 650; }
.patient-switch-row .psw-wait { margin-left: auto; flex: none; font-size: 10.5px; color: var(--ink-500); }
.patient-switch-empty { padding: 12px; text-align: center; color: var(--ink-500); font-size: 12px; }

/* Boîte « une consultation du jour va être ouverte » (js/cs_du_jour.js, 24/09/2026) : centrée,
   voile léger, boutons Annuler / Ouvrir. Au-dessus de tout (grilles, formulaires VIDAL). */
.cs-jour-fond {
  position: fixed; inset: 0; z-index: 10000;
  background: rgba(16, 24, 40, 0.35);
  display: flex; align-items: center; justify-content: center;
}
.cs-jour-boite {
  background: #fff; border-radius: 10px; padding: 18px 22px; max-width: 440px; width: calc(100% - 32px);
  box-shadow: 0 12px 40px rgba(16, 24, 40, 0.28); font-size: 14px; color: var(--ink-900);
}
.cs-jour-titre { font-weight: 700; font-size: 16px; margin-bottom: 8px; }
.cs-jour-texte { color: var(--ink-700); margin-bottom: 16px; line-height: 1.4; }
.cs-jour-boutons { display: flex; justify-content: flex-end; gap: 10px; }
.cs-jour-boutons button { font-size: 13.5px; padding: 6px 14px; border-radius: 6px; cursor: pointer; }
.cs-jour-boutons .btn-secondaire { background: #fff; border: 1px solid var(--ink-300); color: var(--ink-700); }
.cs-jour-boutons .btn-primaire { background: var(--teal-600); border: 1px solid var(--teal-600); color: #fff; font-weight: 600; }

/* Bandeau d'information « … créé dans la consultation du jour » (annoncerCs, js/cs_du_jour.js). */
.cs-jour-toast {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 10000;
  background: var(--ink-900); color: #fff; padding: 10px 18px; border-radius: 8px;
  font-size: 14px; font-weight: 600; max-width: min(90vw, 560px); text-align: center;
  box-shadow: 0 8px 28px rgba(16, 24, 40, 0.3);
}

/* ---- « Ajouter un patient à la file d'attente » : Cabinet / Secrétariat en boutons radio
   (25/09/2026, demandé : comme au téléphone, cf. mobile.css). Même mécanique (classe .active
   posée par queue.js), seul l'aspect change ; sur poste les deux choix restent côte à côte. ---- */
#checkinPec { display: flex; gap: 28px; border: 0; border-radius: 0; background: none; overflow: visible; }
#checkinPec button { display: flex; align-items: center; gap: 10px; background: none; color: var(--ink-900); border: 0; box-shadow: none; padding: 4px 0; font-size: 15px; font-weight: 600; text-transform: none; cursor: pointer; }
#checkinPec button:hover { background: none; color: var(--brand-600); }
#checkinPec button::before { content: ""; flex: none; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--ink-500); background: #fff; box-sizing: border-box; }
#checkinPec button:hover::before { border-color: var(--brand-500); }
#checkinPec button.active, #checkinPec button.active:hover { background: none; color: var(--brand-600); }
#checkinPec button.active::before { border-color: var(--brand-500); background: radial-gradient(var(--brand-500) 40%, #fff 46%); }

/* ---- Phrases types (26/09/2026, js/phrases.js) : bouton 💬 sur le champ actif + fenêtre ---- */
.phr-bouton { position: fixed; z-index: 1001; width: 26px; height: 24px; padding: 0; border-radius: 6px; background: #fff; color: var(--ink-700); border: 1px solid var(--line); box-shadow: 0 1px 3px rgba(16,24,40,.12); font-size: 13px; line-height: 1; cursor: pointer; }
.phr-bouton:hover { background: var(--brand-50); border-color: var(--brand-500); }
.phr-bouton[hidden] { display: none; }
.phr-fenetre { position: fixed; z-index: 1002; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 32px rgba(16,24,40,.22); overflow: hidden; font-size: 13px; }
.phr-fenetre.phr-mobile { left: 8px !important; right: 8px; bottom: 8px; top: auto !important; width: auto !important; max-height: 70vh; }
.phr-tete { display: flex; align-items: center; gap: 4px; padding: 8px 10px; background: var(--brand-50); border-bottom: 1px solid var(--line); }
.phr-tete .phr-champ { color: var(--ink-500); font-size: 12px; flex: 1; }
.phr-fermer { padding: 2px 8px; background: none; color: var(--ink-700); font-size: 14px; box-shadow: none; }
.phr-fermer:hover { background: var(--line-soft); }
.phr-corps { display: flex; flex-direction: column; min-height: 0; padding: 8px 10px; gap: 8px; overflow: hidden; }
.phr-recherche { width: 100%; }
.phr-liste { overflow-y: auto; min-height: 40px; max-height: 320px; border: 1px solid var(--line-soft); border-radius: 8px; }
.phr-item { display: flex; align-items: flex-start; gap: 6px; padding: 7px 9px; cursor: pointer; border-bottom: 1px solid var(--line-soft); }
.phr-item:last-child { border-bottom: none; }
.phr-item.survol, .phr-item:hover { background: var(--brand-50); }
.phr-item-txt { flex: 1; min-width: 0; }
.phr-lib { font-weight: 700; color: var(--ink-900); }
.phr-badge { margin-left: 6px; padding: 0 6px; border-radius: 999px; background: #ecfdf3; color: #067647; font-size: 10.5px; font-weight: 700; }
.phr-apercu { color: var(--ink-500); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
.phr-modif { flex: none; padding: 2px 6px; background: none; box-shadow: none; font-size: 12px; }
.phr-modif:hover { background: #fff; }
.phr-vide { padding: 14px; text-align: center; color: var(--ink-500); }
.phr-pied { display: flex; gap: 8px; flex-wrap: wrap; }
.phr-pied button { padding: 6px 12px; font-size: 12.5px; }
.phr-form { display: flex; flex-direction: column; gap: 5px; }
.phr-form label { font-size: 12px; font-weight: 700; color: var(--ink-700); }
.phr-form .phr-aide { font-weight: 400; color: var(--ink-500); }
.phr-form textarea { width: 100%; min-height: 90px; }
.phr-f-partage { display: flex; align-items: center; gap: 6px; font-weight: 600 !important; }
.phr-f-statut { color: var(--rose-600); font-size: 12px; min-height: 1em; }
.phr-alerte { position: fixed; z-index: 1003; max-width: 360px; padding: 6px 10px; border-radius: 8px; background: #fffaeb; border: 1px solid #fedf89; color: #93370d; font-size: 12.5px; box-shadow: 0 4px 12px rgba(16,24,40,.12); }

/* ---- Certificats structurés (26/09/2026, js/certificats.js) — page Documents ---- */
.cert-modal { width: min(1080px, 96vw); max-height: calc(100vh - 32px); display: flex; flex-direction: column; gap: 10px; }
.cert-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cert-tete h2 { margin: 0; }
.cert-types { align-self: flex-start; flex-wrap: wrap; }
/* 01/10/2026 : raccourcis vers la création de modèles (fenêtre Certificats, liste des courriers). */
.cert-types .cert-creer { align-self: center; margin-left: 6px; padding: 4px 10px; border: 1px dashed #6366f1; border-radius: 6px; color: #4338ca; font-size: 12.5px; font-weight: 700; text-decoration: none; background: #eef2ff; }
.cert-types .cert-creer:hover { background: #e0e7ff; }
.tpl-creer { display: block; width: calc(100% - 8px); margin: 6px 4px; padding: 5px 8px; border: 1px dashed #6366f1; border-radius: 6px; background: #eef2ff; color: #4338ca; font-weight: 700; font-size: 12.5px; text-align: left; }
.tpl-creer:hover { background: #e0e7ff; }
.cert-grille { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; min-height: 0; flex: 1 1 auto; overflow: hidden; }
.cert-form { overflow-y: auto; padding-right: 4px; display: flex; flex-direction: column; gap: 8px; }
.cert-form .field { margin-bottom: 0; }
.cert-form textarea { width: 100%; }
.cert-ligne { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cert-ligne.cert-ligne3 { grid-template-columns: 1fr 110px 1fr; }
.cert-case { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; }
.cert-case[hidden], .cert-form [hidden] { display: none !important; }
.cert-radios { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 13px; }
.cert-radios label { display: inline-flex; align-items: center; gap: 5px; }
.cert-court { width: 190px; }
.cert-aide { font-weight: 400; color: var(--ink-500); font-size: 11.5px; }
.cert-droite { display: flex; flex-direction: column; gap: 6px; min-height: 0; overflow: hidden; }
.cert-libelle { font-size: 12px; font-weight: 700; color: var(--ink-700); }
.cert-apercu { flex: 1 1 auto; min-height: 140px; overflow-y: auto; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; font-family: Georgia, 'Times New Roman', serif; font-size: 14px; line-height: 1.55; color: var(--ink-900); }
.cert-registre { max-height: 140px; overflow-y: auto; border: 1px solid var(--line-soft); border-radius: 8px; padding: 4px 8px; font-size: 12.5px; }
.cert-reg-ligne { display: flex; gap: 10px; padding: 3px 0; border-bottom: 1px solid var(--line-soft); }
.cert-reg-ligne:last-child { border-bottom: none; }
.cert-reg-date { flex: none; width: 76px; color: var(--ink-500); font-variant-numeric: tabular-nums; }
.cert-reg-type { font-weight: 650; }
.cert-reg-detail { margin-left: auto; color: var(--ink-700); white-space: nowrap; }
.cert-actions { justify-content: flex-end; align-items: center; }
.cert-statut { margin-right: auto; color: var(--rose-600); font-size: 12.5px; }
@media (max-width: 760px) {
  .cert-grille { grid-template-columns: 1fr; overflow-y: auto; }
  .cert-ligne, .cert-ligne.cert-ligne3 { grid-template-columns: 1fr; }
}
.cert-form .cert-case input, .cert-form .cert-radios input[type="radio"], .cert-form .cert-radios input[type="checkbox"] { width: auto; flex: none; margin: 0; }
.cert-form .cert-radios .cert-court { width: 190px; flex: none; }

/* ---- Coût estimé de la biologie (26/09/2026, bio_rx.js renderCoutBio) ---- */
.cout-bio { flex: none; margin-top: 8px; padding: 7px 12px; border-radius: 8px; background: #f0fdf4; border: 1px solid #bbf7d0; color: #14532d; font-size: 13px; }
.cout-bio .cout-aide { color: var(--ink-500); font-size: 12px; }

/* ---- Rappels au patient (26/09/2026, fiche RDV de l'agenda) ---- */
.rappels-bloc { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; margin-bottom: 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--canvas); }
.rappels-ligne { display: flex; align-items: center; gap: 10px 16px; flex-wrap: wrap; }
.rappels-case { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-900); }
.rappels-case input { width: auto; margin: 0; }
.rappels-ligne select { width: auto; padding: 3px 8px; font-size: 12.5px; }
.rappels-bientot .rappels-case { color: var(--ink-500); font-weight: 500; }
.rappels-bientot em { font-style: normal; font-size: 11.5px; }
.rappels-aide { font-size: 11.5px; color: var(--ink-500); }
.rappels-historique { font-size: 12px; border-top: 1px dashed var(--line); padding-top: 6px; display: flex; flex-direction: column; gap: 2px; }
.rappels-historique .env-ok { color: #067647; }
.rappels-historique .env-ko { color: var(--rose-600); }
.rappel-bandeau { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 10000; padding: 9px 16px; border-radius: 8px; background: #ecfdf3; border: 1px solid #abefc6; color: #067647; font-size: 13.5px; font-weight: 600; box-shadow: 0 8px 24px rgba(16,24,40,.18); }
