/* LithoExpert · composants
   Vocabulaire commun à tous les écrans : une carte, un bouton, une pastille,
   un tableau, un onglet, un champ. Posé ici une fois, pour qu'un même état
   porte la même couleur partout et qu'aucun gabarit n'ait de couleur en dur.

   Ardoise et cuivre. Une seule élévation, focus clavier toujours visible,
   aucun dégradé. Le clair est le mode par défaut ; le sombre ne s'applique
   que si l'utilisateur le demande, par la classe .dark-mode sur <body>.
   ------------------------------------------------------------------------
   Les teintes de marque sont données en canaux RVB séparés par des espaces :
   c'est la forme qu'attend Tailwind pour y appliquer ensuite une opacité
   (bg-brand-600/15). Un code hexadécimal ne le permettrait pas. */

:root {
  --brand-50:  252 243 235;   --brand-100: 246 228 212;  --brand-200: 237 210 188;
  --brand-500: 196 121  63;   --brand-600: 168  85  31;  --brand-700: 138  69  24;
  --brand-800: 107  52  19;   --brand-900:  74  36  12;

  /* Les neutres sont tirés vers le cuivre, comme PemaTrack tire les siens vers
     le teal et Mobikisi vers le rouge. Un gris pur à côté d'un accent chaud se
     voit : il fait lire la couleur comme posée après coup. */
  --canvas:  247 243 240;     /* fond de page, aplat légèrement teinté */
  --surface: 255 255 255;     /* carte, barre supérieure */
  --surface-2: 250 246 242;   /* en-tête de tableau, survol de ligne, zone creuse */
  --surface-3: 243 237 231;
  --ink:      31  23  20;     /* encre, presque noire mais chaude */
  --ink-2:    74  62  56;     /* texte courant */
  --muted:   111  97  88;     /* libellé secondaire */
  --line:    236 227 220;     /* filet */
  --line-2:  217 203 192;     /* filet appuyé */

  --succes: 47 122  79;       --succes-fond: 237 246 240;  --succes-trait: 190 219 201;
  --attente:154 107  20;      --attente-fond:250 244 230;  --attente-trait:229 213 178;
  --danger: 164  69  58;      --danger-fond: 250 238 236;  --danger-trait: 226 194 189;
  --info:    42 107 138;      --info-fond:   234 243 247;  --info-trait:   186 211 223;

  --ombre: 107 52 19;         /* ombres portées, teintées de cuivre */

  /* Coque de la barre latérale : un gris foncé à plat, neutre. Le cuivre y est
     réservé au lien actif, qui se détache donc sans concurrence. Une coque
     teintée de marque mettait l'accent partout, et l'accent nulle part. */
  --coque:       #1F2426;
  --coque-rgb:    31  36  38;   /* la même, en canaux, pour les opacités */
  --coque-clair: #C4793F;     /* accent du lien actif */
  --coque-encre: #FFFFFF;     /* texte posé sur l'accent */
  --coque-nav:   #C9D1D3;     /* libellé de lien inactif */
  --coque-ico:   #8C989B;
}

/* Le sombre ne redéfinit que des jetons : aucune règle de composant à réécrire. */
body.dark-mode, :root[data-theme="dark"] {
  --brand-50:   45  32  22;   --brand-100:  62  44  30;   --brand-200:  80  57  39;
  --brand-500: 197 118  57;   --brand-600: 217 137  77;   --brand-700: 231 166 115;
  --brand-800: 240 205 176;   --brand-900: 246 227 210;

  --canvas:   23  18  15;
  --surface:  32  26  22;
  --surface-2:41  33  28;
  --surface-3:52  42  35;
  --ink:     242 235 230;
  --ink-2:   196 182 172;
  --muted:   148 132 120;
  --line:     56  46  39;
  --line-2:   78  65  56;

  --succes:  95 180 135;      --succes-fond:  22  39  31;  --succes-trait:  38  66  52;
  --attente:214 165  70;      --attente-fond: 43  34  14;  --attente-trait: 72  57  24;
  --danger: 214 124 112;      --danger-fond:  44  26  24;  --danger-trait:  74  44  40;
  --info:   122 178 207;      --info-fond:    20  36  45;  --info-trait:    34  60  74;

  --ombre: 0 0 0;
  --coque:       #16191B;
  --coque-clair: #D9894D;
  --coque-nav:   #BCC5C7;
  --coque-ico:   #7E8A8D;
}

/* ─────────────────────────────────────────────────── base */
html { scroll-behavior: smooth; }
body {
  background: rgb(var(--canvas));
  color: rgb(var(--ink));
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.tnum, table, .mono, .kpi-value { font-variant-numeric: tabular-nums; }
.mono { font-family: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace; }
.text-muted  { color: rgb(var(--muted)); }
.text-ink    { color: rgb(var(--ink)); }
.text-2xs    { font-size: .6875rem; line-height: 1rem; }
.bg-canvas   { background: rgb(var(--canvas)); }
.bg-surface  { background: rgb(var(--surface)); }
.border-line { border-color: rgb(var(--line)); }
.divide-line > * + * { border-color: rgb(var(--line)); }

/* Le focus clavier reste visible partout : un écran médical se parcourt
   souvent au clavier, gants aux mains, sans quitter le champ des yeux. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid rgb(var(--brand-600));
  outline-offset: 2px;
  border-radius: 4px;
}

/* ─────────────────────────────────────────────────── carte */
.card {
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  border-radius: .875rem;
  /* Pas de marge interne : c'est l'usage qui la pose (p-4, p-5), ou aucune
     quand la carte enveloppe un tableau qui doit toucher ses bords. L'ancienne
     feuille en imposait vingt-quatre pixels, ce qui gonflait les cartes dont
     le contenu porte deja sa propre marge. */
  padding: 0;
  box-shadow: 0 1px 2px 0 rgb(var(--ombre) / .05), 0 1px 3px 0 rgb(var(--ombre) / .04);
}
.card-hover { transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease; }
.card-hover:hover {
  box-shadow: 0 8px 24px -6px rgb(var(--ombre) / .14);
  border-color: rgb(var(--brand-200));
}

/* ─────────────────────────────────────────────────── bouton
   Un bouton est un bouton : une action se clique, elle ne se lit pas comme
   un lien. L'état désactivé se voit, sinon un clic sans effet passe pour
   une panne. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .55rem .9rem; border: 1px solid transparent; border-radius: .625rem;
  font-size: .875rem; font-weight: 600; line-height: 1.2; cursor: pointer;
  text-decoration: none; white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn-primary  { background: rgb(var(--brand-600)); color: #fff;
                box-shadow: 0 1px 2px rgb(var(--brand-600) / .25); }
.btn-primary:hover  { background: rgb(var(--brand-700)); }
.btn-outline  { background: rgb(var(--surface)); color: rgb(var(--ink));
                border-color: rgb(var(--line)); }
.btn-outline:hover  { background: rgb(var(--surface-2)); border-color: rgb(var(--line-2)); }
.btn-ghost    { background: transparent; color: rgb(var(--muted)); }
.btn-ghost:hover    { background: rgb(var(--surface-2)); color: rgb(var(--ink)); }
.btn-danger   { background: rgb(var(--danger)); color: #fff; }
.btn-danger:hover   { filter: brightness(.92); }
.btn-succes   { background: rgb(var(--succes)); color: #fff; }
.btn-succes:hover   { filter: brightness(.92); }
.btn-sm { padding: .4rem .65rem; font-size: .8125rem; border-radius: .5rem; }
.btn-lg { padding: .7rem 1.1rem; font-size: .9375rem; }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; box-shadow: none; filter: none;
}

/* ─────────────────────────────────────────────────── pastille
   Les couleurs de sens ne bougent jamais : vert = acquis, ambre = en attente,
   rouge = défavorable, bleu = informatif, gris = non renseigné. Le médecin
   qui change d'écran ne doit pas relire la légende. */
.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .18rem .55rem; border: 1px solid transparent; border-radius: 999px;
  font-size: .75rem; font-weight: 600; line-height: 1.4; white-space: nowrap;
}
.pill svg { width: 13px; height: 13px; }
.pill-dot::before {
  content: ""; width: 7px; height: 7px; border-radius: 999px;
  background: currentColor; display: inline-block; flex: none;
}
.pill-succes  { background: rgb(var(--succes-fond));  color: rgb(var(--succes));
                border-color: rgb(var(--succes-trait)); }
.pill-attente { background: rgb(var(--attente-fond)); color: rgb(var(--attente));
                border-color: rgb(var(--attente-trait)); }
.pill-danger  { background: rgb(var(--danger-fond));  color: rgb(var(--danger));
                border-color: rgb(var(--danger-trait)); }
.pill-info    { background: rgb(var(--info-fond));    color: rgb(var(--info));
                border-color: rgb(var(--info-trait)); }
.pill-neutre  { background: rgb(var(--surface-2));    color: rgb(var(--ink-2));
                border-color: rgb(var(--line)); }
.pill-marque  { background: rgb(var(--brand-50));     color: rgb(var(--brand-700));
                border-color: rgb(var(--brand-200)); }

/* ─────────────────────────────────────────────────── champ */
.field-label {
  display: block; font-size: .8125rem; font-weight: 600;
  color: rgb(var(--ink-2)); margin-bottom: .35rem;
}
.field-req::after { content: " *"; color: rgb(var(--danger)); }
.field-help { font-size: .75rem; color: rgb(var(--muted)); margin-top: .3rem; }
.input, .select, .textarea {
  width: 100%; background: rgb(var(--surface)); color: rgb(var(--ink));
  border: 1px solid rgb(var(--line)); border-radius: .625rem;
  padding: .6rem .8rem; font-size: .875rem; min-height: 44px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input::placeholder, .textarea::placeholder { color: rgb(var(--muted)); }
.input:focus, .select:focus, .textarea:focus {
  border-color: rgb(var(--brand-600));
  box-shadow: 0 0 0 3px rgb(var(--brand-600) / .14);
  outline: none;
}
.input.has-error, .select.has-error { border-color: rgb(var(--danger)); }
/* Champ précédé d'une icône : le décalage se déclare ici et non dans le
   gabarit, parce que .input pose un `padding` raccourci et réécrirait sans
   bruit une classe pl-9 posée sur le champ. */
.input.avec-icone, .select.avec-icone { padding-left: 2.25rem; }
.textarea { min-height: 5rem; resize: vertical; }

/* Choix segmenté : des options peu nombreuses se montrent, elles ne se
   déroulent pas. */
.seg {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .55rem .85rem; border: 1px solid rgb(var(--line));
  border-radius: .625rem; font-size: .875rem; font-weight: 600;
  color: rgb(var(--ink-2)); cursor: pointer; background: rgb(var(--surface));
  transition: .15s ease;
}
.seg:hover  { border-color: rgb(var(--line-2)); }
.seg.is-on  { border-color: rgb(var(--brand-600)); background: rgb(var(--brand-50));
              color: rgb(var(--brand-700)); box-shadow: inset 0 0 0 1px rgb(var(--brand-600)); }

/* ─────────────────────────────────────────────────── tableau */
.tbl { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .875rem; }
.tbl thead th {
  position: sticky; top: 0; z-index: 1; background: rgb(var(--surface-2));
  text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: rgb(var(--muted));
  padding: .7rem .9rem; border-bottom: 1px solid rgb(var(--line));
}
.tbl tbody td {
  padding: .8rem .9rem; border-bottom: 1px solid rgb(var(--line) / .6);
  color: rgb(var(--ink-2)); vertical-align: middle;
}
.tbl td.mono, .tbl td.tnum { white-space: nowrap; }
.tbl tbody tr { transition: background-color .12s ease; }
.tbl tbody tr:hover { background: rgb(var(--surface-2)); }
.tbl-compact thead th, .tbl-compact tbody td { padding-left: .55rem; padding-right: .55rem; }

/* ─────────────────────────────────────────────────── onglets
   Les onglets sont des liens portant un paramètre d'adresse : un écran
   filtré se transmet par lien, revient par le bouton Précédent et
   s'ajoute aux favoris. */
.tabs { display: flex; gap: .25rem; border-bottom: 1px solid rgb(var(--line));
        overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab {
  padding: .6rem .2rem; margin: 0 .8rem -1px; font-size: .875rem; font-weight: 600;
  color: rgb(var(--muted)); cursor: pointer; text-decoration: none;
  border-bottom: 2px solid transparent; white-space: nowrap;
  transition: color .15s ease, border-color .15s ease;
}
.tab:first-child { margin-left: 0; }
.tab:hover { color: rgb(var(--ink)); }
.tab.is-on { color: rgb(var(--brand-600)); border-bottom-color: rgb(var(--brand-600)); }

/* ─────────────────────────────────────────────────── jauge
   Un indice chiffré se lit mieux posé sur son échelle : le médecin voit où
   tombe la valeur sans avoir à retenir les seuils. */
.bar { height: 8px; border-radius: 999px; background: rgb(var(--surface-2));
       border: 1px solid rgb(var(--line)); overflow: hidden; }
.bar > span { display: block; height: 100%; border-radius: 999px; }
.jauge { display: grid; gap: .3rem; }
.jauge-tete { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.jauge-val { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-weight: 600;
             font-variant-numeric: tabular-nums; }
.jauge-seuils { display: flex; justify-content: space-between;
                font-size: .6875rem; color: rgb(var(--muted)); }

/* ─────────────────────────────────────────────────── barre latérale */
.sidebar-bg { background: var(--coque); }
.nav-groupe { padding: 1rem .75rem .25rem; font-size: .6875rem; font-weight: 700;
              letter-spacing: .06em; text-transform: uppercase; color: rgb(255 255 255 / .42); }
.nav-link {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem .75rem; border-radius: .5rem; font-size: .875rem; font-weight: 500;
  color: var(--coque-nav); text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.nav-link:hover { background: rgb(255 255 255 / .07); color: #fff; }
.nav-link.is-active {
  background: var(--coque-clair); color: var(--coque-encre); font-weight: 600;
  box-shadow: 0 2px 8px -2px rgb(var(--brand-600) / .6);
}
.nav-ico { width: 18px; height: 18px; flex: none; color: var(--coque-ico); }
.nav-link:hover .nav-ico { color: #fff; }
.nav-link.is-active .nav-ico { color: var(--coque-encre); }
.nav-badge { margin-left: auto; font-size: .6875rem; font-weight: 700;
             background: rgb(255 255 255 / .14); color: #fff;
             padding: .05rem .4rem; border-radius: 999px; }
/* Le pavé de marque. La marque elle-même est un calcul en coupe : noyau,
   couches concentriques et interfaces de clivage, soit exactement ce que
   l'application lit sur un scanner. Le pavé garde une coque ardoise, qui la
   tient lisible sur la barre latérale sombre comme sur le blanc du formulaire
   de connexion. */
.marque-pave { display: grid; place-items: center; border-radius: .625rem; flex: none;
               background: rgb(var(--coque-rgb, 31 36 38));
               box-shadow: 0 2px 8px rgb(var(--ombre) / .28); }
.marque-pave img { display: block; }

/* ─────────────────────────────────────────────────── vignette d'indicateur */
.kpi-ico { width: 44px; height: 44px; border-radius: 999px;
           display: grid; place-items: center; flex: none; }
.kpi-value { font-size: 1.5rem; font-weight: 800; line-height: 1.15; color: rgb(var(--ink)); }

/* ─────────────────────────────────────────────────── boîte de dialogue
   Réservée à ce qui est court : créer une ligne, confirmer une suppression.
   Tout ce qui se consulte ou se remplit longuement est une page, avec son
   adresse, son bouton Précédent et son impression. */
.modale {
  width: min(620px, calc(100vw - 2rem)); max-height: calc(100dvh - 3rem);
  border: 0; border-radius: .875rem; padding: 0; overflow: auto;
  background: rgb(var(--surface)); color: rgb(var(--ink));
  box-shadow: 0 24px 64px -16px rgb(var(--ombre) / .35);
}
.modale::backdrop { background: rgb(var(--ombre) / .45); }
.modale-tete { position: sticky; top: 0; background: rgb(var(--surface));
               border-bottom: 1px solid rgb(var(--line)); padding: 1rem 1.25rem;
               display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.modale-corps { padding: 1.25rem; }
.modale-pied { position: sticky; bottom: 0; background: rgb(var(--surface));
               border-top: 1px solid rgb(var(--line)); padding: .85rem 1.25rem;
               display: flex; justify-content: flex-end; gap: .5rem; }
/* Au téléphone, la boîte occupe le bas de l'écran sur toute la largeur :
   le pouce atteint les boutons sans traverser l'écran. */
@media (max-width: 640px) {
  .modale { width: 100vw; max-width: 100vw; max-height: 92dvh;
            margin: auto 0 0; border-radius: 1rem 1rem 0 0; }
}

/* ─────────────────────────────────────────────────── divers */
.page-titre { font-size: 1.125rem; font-weight: 700; color: rgb(var(--ink)); line-height: 1.3; }
.page-sous  { font-size: .875rem; color: rgb(var(--muted)); margin-top: .1rem; }
/* Toute cible tactile atteint 44 px : un écran de consultation se manipule
   debout, d'une main. */
@media (hover: none) {
  .btn, .nav-link, .tab { min-height: 44px; }
  .btn-sm { min-height: 38px; }
}
@media print {
  .no-print, aside, .modale { display: none !important; }
  .card { box-shadow: none; border-color: #ccc; }
  body { background: #fff; }
}

/* ─────────────────────────────────────────────────── teintes nommées
   Employées par les macros : une vignette, une jauge et une pastille qui
   parlent de la même chose portent la même teinte, parce qu'elles la
   demandent par son nom et non par un code. */
.teinte-marque { background: rgb(var(--brand-50));     color: rgb(var(--brand-600)); }
.teinte-succes { background: rgb(var(--succes-fond));  color: rgb(var(--succes)); }
.teinte-attente{ background: rgb(var(--attente-fond)); color: rgb(var(--attente)); }
.teinte-danger { background: rgb(var(--danger-fond));  color: rgb(var(--danger)); }
.teinte-info   { background: rgb(var(--info-fond));    color: rgb(var(--info)); }
.teinte-neutre { background: rgb(var(--surface-2));    color: rgb(var(--ink-2)); }

.teinte-texte-marque { color: rgb(var(--brand-600)); }
.teinte-texte-succes { color: rgb(var(--succes)); }
.teinte-texte-attente{ color: rgb(var(--attente)); }
.teinte-texte-danger { color: rgb(var(--danger)); }
.teinte-texte-info   { color: rgb(var(--info)); }
.teinte-texte-neutre { color: rgb(var(--ink-2)); }

.teinte-fond-marque { background: rgb(var(--brand-600)); }
.teinte-fond-succes { background: rgb(var(--succes)); }
.teinte-fond-attente{ background: rgb(var(--attente)); }
.teinte-fond-danger { background: rgb(var(--danger)); }
.teinte-fond-info   { background: rgb(var(--info)); }
.teinte-fond-neutre { background: rgb(var(--line-2)); }

/* ─────────────────────────────────────────────────── barre de défilement
   Sobre et teintée : une barre système grise sur un fond chaud se voit. */
* { scrollbar-width: thin; scrollbar-color: rgb(var(--line-2)) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgb(var(--line-2)); border-radius: 999px;
                             border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: rgb(var(--muted)); background-clip: content-box; }

/* ─────────────────────────────────────────────────── apparition douce
   Une seule animation, à l'arrivée du contenu. Rien ne bouge en continu :
   un écran clinique se lit, il ne se regarde pas. */
@keyframes monte { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.monte { animation: monte .4s ease both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─────────────────────────────────────────────────── sélecteur de langue */
.lang-switch { display: inline-flex; border: 1px solid rgb(var(--line)); border-radius: .5rem;
               overflow: hidden; background: rgb(var(--surface)); }
.lang-btn { padding: .3rem .55rem; font-size: .72rem; font-weight: 700; line-height: 1;
            color: rgb(var(--muted)); cursor: pointer; background: transparent; border: none;
            text-decoration: none; transition: background-color .15s ease, color .15s ease; }
.lang-btn:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); }
.lang-btn.is-on { background: rgb(var(--brand-600)); color: #fff; }

/* ─────────────────────────────────────────────────── liste à puces
   La puce est un point de la couleur du propos, pas un tiret ni un disque
   noir : elle doit se lire comme un repère, pas comme du texte. */
.liste-puces { display: grid; gap: .5rem; }
.liste-puces > li { display: flex; align-items: flex-start; gap: .625rem; line-height: 1.55; }
.liste-puces > li::before {
  content: ""; width: 5px; height: 5px; border-radius: 999px; flex: none;
  margin-top: .55rem; background: rgb(var(--brand-600));
}
.liste-puces.puces-succes > li::before { background: rgb(var(--succes)); }
.liste-puces.puces-neutre > li::before { background: rgb(var(--muted)); }

/* ─────────────────────────────────────────────────── bloc à filet de gauche
   Un encadré de sens : le filet dit la nature du propos, le fond reste
   presque blanc pour que le texte garde son contraste. */
.encart { border: 1px solid rgb(var(--line)); border-left-width: 3px;
          border-radius: .75rem; padding: .9rem 1.1rem; background: rgb(var(--surface)); }
.encart-marque  { border-left-color: rgb(var(--brand-600)); }
.encart-succes  { border-left-color: rgb(var(--succes));  background: rgb(var(--succes-fond)); }
.encart-attente { border-left-color: rgb(var(--attente)); background: rgb(var(--attente-fond)); }
.encart-danger  { border-left-color: rgb(var(--danger));  background: rgb(var(--danger-fond)); }
.encart-info    { border-left-color: rgb(var(--info));    background: rgb(var(--info-fond)); }
.encart-titre { font-size: .6875rem; font-weight: 700; letter-spacing: .04em;
                text-transform: uppercase; color: rgb(var(--muted)); margin-bottom: .25rem; }

/* ─────────────────────────────────────────────────── chronologie
   Les événements d'un dossier, reliés par un filet continu : on voit d'un
   coup s'ils se suivent de près ou s'espacent. */
.fil { position: relative; padding-left: 1.5rem; }
.fil::before { content: ""; position: absolute; left: 5px; top: .4rem; bottom: .4rem;
               width: 2px; background: rgb(var(--line)); border-radius: 999px; }
.fil-item { position: relative; padding-bottom: .9rem; }
.fil-item:last-child { padding-bottom: 0; }
.fil-item::before {
  content: ""; position: absolute; left: -1.5rem; top: .35rem;
  width: 12px; height: 12px; border-radius: 999px;
  background: rgb(var(--surface)); border: 2px solid rgb(var(--brand-600));
}
.fil-item.est-vide::before { border-color: rgb(var(--line-2)); }

/* ─────────────────────────────────────────────────── petit bouton d'action
   Les actions d'une ligne de tableau : discrètes au repos, nettes au survol,
   et assez grandes pour le doigt. */
.btn-icone {
  display: inline-grid; place-items: center; width: 32px; height: 32px;
  border-radius: .5rem; border: 1px solid transparent; background: transparent;
  color: rgb(var(--muted)); cursor: pointer; flex: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.btn-icone svg { width: 16px; height: 16px; }
.btn-icone:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink));
                   border-color: rgb(var(--line)); }
.btn-icone.est-danger:hover { background: rgb(var(--danger-fond)); color: rgb(var(--danger));
                              border-color: rgb(var(--danger-trait)); }
@media (hover: none) { .btn-icone { width: 44px; height: 44px; } }

/* ─────────────────────────────────────────────────── pastille de compte
   Le nombre qui accompagne un libellé d'onglet ou de menu. */
.compte { display: inline-grid; place-items: center; min-width: 1.25rem; height: 1.25rem;
          padding: 0 .35rem; border-radius: 999px; font-size: .6875rem; font-weight: 700;
          font-variant-numeric: tabular-nums;
          background: rgb(var(--surface-2)); color: rgb(var(--muted)); }
.tab.is-on .compte { background: rgb(var(--brand-50)); color: rgb(var(--brand-700)); }

/* ─────────────────────────────────────────────────── bandeau de salutation
   Il porte le contexte : qui est connecté, pour quel établissement, quel jour
   et quelle heure. Sur un poste partagé entre plusieurs praticiens, c'est la
   première chose à vérifier avant de saisir quoi que ce soit. */
.bandeau {
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  border-left: 4px solid rgb(var(--brand-600));
  border-radius: .875rem;
  padding: 1.1rem 1.35rem;
  box-shadow: 0 1px 2px 0 rgb(var(--ombre) / .05);
}

/* ─────────────────────────────────────────────────── histogramme sobre
   Des colonnes dessinées en CSS, sans bibliothèque : six valeurs ne méritent
   pas trois cents kilo-octets de JavaScript, et celui-ci suit le mode sombre
   parce qu'il lit les mêmes jetons que le reste. */
.histo { display: flex; align-items: flex-end; gap: .35rem; height: 72px; }
.histo-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
             height: 100%; min-width: 0; }
.histo-barre { border-radius: .25rem .25rem 0 0; background: rgb(var(--brand-600));
               min-height: 3px; transition: background-color .15s ease; }
.histo-col:hover .histo-barre { background: rgb(var(--brand-700)); }
.histo-col.est-courant .histo-barre { background: rgb(var(--brand-500)); }
.histo-pieds { display: flex; gap: .35rem; margin-top: .4rem; }
.histo-pied { flex: 1; text-align: center; font-size: .625rem; font-weight: 600;
              color: rgb(var(--muted)); min-width: 0; }
.histo-col.est-courant + .histo-pied,
.histo-pied.est-courant { color: rgb(var(--brand-600)); }

/* ─────────────────────────────────────────────────── barre de répartition
   Une liste de parts, chacune avec son libellé, son compte et sa longueur.
   Préférée à un camembert : on compare des longueurs bien mieux que des
   angles, et les libellés tiennent sans légende. */
.repartition { display: grid; gap: .55rem; }
.repartition-ligne { display: grid; grid-template-columns: minmax(0, 7.5rem) 1fr auto;
                     align-items: center; gap: .6rem; font-size: .8125rem; }
.repartition-libelle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                       color: rgb(var(--ink-2)); }
.repartition-piste { height: 7px; border-radius: 999px; background: rgb(var(--surface-2));
                     border: 1px solid rgb(var(--line)); overflow: hidden; }
.repartition-part { display: block; height: 100%; border-radius: 999px;
                    background: rgb(var(--brand-600)); min-width: 2px; }
.repartition-compte { font-family: 'IBM Plex Mono', ui-monospace, monospace;
                      font-variant-numeric: tabular-nums; font-weight: 600;
                      color: rgb(var(--ink)); font-size: .75rem; }

/* ─────────────────────────────────────────────────── action rapide
   Une tuile large, atteignable au pouce, qui dit le geste et son effet. */
.action-rapide {
  display: flex; align-items: center; gap: .75rem; padding: .85rem 1rem;
  background: rgb(var(--surface)); border: 1px solid rgb(var(--line));
  border-radius: .75rem; text-decoration: none; min-height: 60px;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.action-rapide:hover { border-color: rgb(var(--brand-200));
                       box-shadow: 0 6px 18px -8px rgb(var(--ombre) / .18); }
.action-rapide:active { transform: translateY(1px); }
.action-rapide .kpi-ico { width: 38px; height: 38px; border-radius: .625rem; }

/* ─────────────────────────────────────────────────── rail de sections
   Pour les formulaires longs. Il dit où l'on est, ce qui est fait, et permet
   de revenir en arrière sans faire défiler à l'aveugle. */
.rail-lien {
  display: flex; align-items: center; gap: .6rem;
  padding: .45rem .55rem; border-radius: .5rem;
  font-size: .8125rem; font-weight: 500; color: rgb(var(--ink-2));
  text-decoration: none; transition: background-color .15s ease, color .15s ease;
}
.rail-lien:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); }
.rail-lien.est-courant { background: rgb(var(--brand-50)); color: rgb(var(--brand-700));
                         font-weight: 600; }
.rail-num {
  display: grid; place-items: center; width: 1.3rem; height: 1.3rem; flex: none;
  border-radius: 999px; font-size: .6875rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: rgb(var(--surface-2)); color: rgb(var(--muted));
  border: 1px solid rgb(var(--line));
}
.rail-lien.est-courant .rail-num { background: rgb(var(--brand-600)); color: #fff;
                                   border-color: rgb(var(--brand-600)); }
.rail-lien.est-remplie .rail-num { background: rgb(var(--succes-fond));
                                   color: rgb(var(--succes));
                                   border-color: rgb(var(--succes-trait)); }
/* La coche ne parait que lorsque la section porte une valeur : une coche
   toujours visible ne distingue plus le rempli du vide. */
.rail-coche { opacity: 0; color: rgb(var(--succes)); transition: opacity .15s ease; }
.rail-lien.est-remplie .rail-coche { opacity: 1; }

/* ── Squelette de chargement ───────────────────────────────────────────────
   Une liste qui se charge affichait « Chargement… » centré sur du vide : la
   page sautait d'une ligne de texte à six cartes, et rien ne disait combien
   de place allait être prise. Le squelette occupe d'avance la forme du
   contenu attendu, ce qui supprime le saut et fait paraître l'attente plus
   courte. Il ne remplace jamais un état vide : quand il n'y a rien à montrer,
   c'est l'état vide nommé qui s'affiche, pas un squelette qui tourne.
   ------------------------------------------------------------------------ */
.sq {
  background: rgb(var(--surface-2));
  border-radius: .5rem;
  position: relative;
  overflow: hidden;
}
.sq::after {
  content: ''; position: absolute; inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg,
              rgb(var(--surface-2) / 0) 0%,
              rgb(var(--surface) / .85) 50%,
              rgb(var(--surface-2) / 0) 100%);
  animation: sq-balaye 1.4s ease-in-out infinite;
}
@keyframes sq-balaye { to { transform: translateX(100%); } }

.sq-ligne  { height: .75rem; }
.sq-titre  { height: 1rem; width: 45%; }
.sq-court  { width: 30%; }
.sq-moyen  { width: 65%; }
.sq-pastille { height: 1.4rem; width: 4.5rem; border-radius: 999px; }
.sq-ico    { height: 2.5rem; width: 2.5rem; border-radius: .625rem; flex: none; }

/* Une carte de liste : pictogramme, deux lignes, une pastille à droite. */
.sq-carte {
  display: flex; align-items: center; gap: .75rem;
  padding: .85rem .9rem;
  border: 1px solid rgb(var(--line)); border-radius: .75rem;
  background: rgb(var(--surface));
}
.sq-carte > .sq-corps { flex: 1 1 auto; min-width: 0;
                        display: flex; flex-direction: column; gap: .45rem; }

/* Une ligne de tableau. */
.sq-rang { display: flex; align-items: center; gap: 1rem; padding: .7rem .75rem;
           border-bottom: 1px solid rgb(var(--line)); }

@media (prefers-reduced-motion: reduce) {
  .sq::after { animation: none; display: none; }
}

/* ── Largeur des boutons au téléphone ──────────────────────────────────────
   static/css/myoneart.css, chargée avant celle-ci, étend chaque « .btn » à
   toute la largeur de son conteneur sous 768 px. Deux boutons posés côte à
   côte dans une barre d'action prenaient alors chacun la largeur du bloc :
   sur l'écran de recherche par code, 576 px chacun dans une page de 768, soit
   524 px hors cadre.

   Un bouton prend la largeur de son texte ; celui qui doit s'étendre le
   demande, avec « btn-pleine ».
   ------------------------------------------------------------------------ */
@media (max-width: 768px) {
  .btn { width: auto; }
  .btn-pleine { width: 100%; justify-content: center; }
}

/* ── Se déconnecter, dans la coque sombre ──────────────────────────────────
   Un vrai bouton, nommé et pleine largeur, au pied de la barre latérale.
   L'icône seule au bout de la ligne du compte se confondait avec un réglage :
   on cherchait la sortie sans la trouver. Il reste discret au repos et prend
   la teinte d'alerte au survol, parce qu'il met fin à la session.
   ------------------------------------------------------------------------ */
.deconnexion-pave {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; padding: .55rem .75rem;
  border-radius: .625rem; border: 1px solid rgb(255 255 255 / .16);
  background: rgb(255 255 255 / .05);
  color: rgb(255 255 255 / .82);
  font-size: .8125rem; font-weight: 600; text-decoration: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.deconnexion-pave:hover {
  background: rgb(var(--danger) / .9);
  border-color: rgb(var(--danger));
  color: #fff;
}
.deconnexion-pave:focus-visible {
  outline: 2px solid rgb(var(--coque-clair)); outline-offset: 2px;
}

/* ── Menu du compte, dans la barre supérieure ──────────────────────────────
   Le coin haut-droit menait directement aux paramètres : un clic de trop pour
   sortir, et aucune indication qu'on le pouvait. Il ouvre maintenant un menu.
   ------------------------------------------------------------------------ */
.menu-compte { position: relative; }
.menu-compte-liste {
  position: absolute; top: calc(100% + .5rem); right: 0; z-index: 60;
  min-width: 14rem; padding: .35rem;
  background: rgb(var(--surface)); border: 1px solid rgb(var(--line));
  border-radius: .75rem; box-shadow: 0 12px 32px rgb(var(--ombre) / .16);
}
.menu-compte-liste[hidden] { display: none; }
.menu-compte-entete {
  padding: .55rem .6rem .5rem; border-bottom: 1px solid rgb(var(--line));
  margin-bottom: .35rem;
}
.menu-compte-lien {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .5rem .6rem; border-radius: .5rem;
  font-size: .8125rem; font-weight: 500; color: rgb(var(--ink-2));
  text-decoration: none; background: none; border: 0; cursor: pointer;
  text-align: left;
}
.menu-compte-lien:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); }
.menu-compte-lien.est-sortie { color: rgb(var(--danger)); }
.menu-compte-lien.est-sortie:hover {
  background: rgb(var(--danger-fond)); color: rgb(var(--danger));
}
.menu-compte-separe { height: 1px; background: rgb(var(--line)); margin: .35rem 0; }

/* ── Statistiques : des blocs posés sur du blanc ───────────────────────────
   `.page-section` et `.kpi-card` viennent de l'ancienne feuille et appellent
   `var(--surface)` et `var(--surface-2)`. La charte a redéfini ces jetons en
   canaux RVB (« 255 255 255 »), qui ne sont pas des couleurs : la déclaration
   était invalide et les blocs n'avaient **aucun fond**. Les graphiques
   flottaient sur le fond de page, ce qui rendait l'écran illisible.

   Signalé par le Dr Kalonji le 8 octobre 2026. On repose ici un fond blanc,
   un filet et une ombre, avec les jetons de la charte.
   ------------------------------------------------------------------------ */
.page-section {
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  border-radius: .875rem;
  padding: 1.25rem;
  box-shadow: 0 1px 2px rgb(var(--ombre) / .05);
}

.kpi-card {
  background: rgb(var(--surface));
  border: 1px solid rgb(var(--line));
  border-radius: .875rem;
  padding: 1.1rem 1.25rem;
  box-shadow: 0 1px 2px rgb(var(--ombre) / .05);
  display: flex; align-items: center; gap: .9rem;
}
.kpi-card:hover { box-shadow: 0 6px 18px rgb(var(--ombre) / .09); }

.kpi-label {
  font-size: .6875rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: rgb(var(--muted)); margin: 0 0 .15rem;
}
.kpi-value {
  font-size: 1.5rem; font-weight: 800; line-height: 1.1;
  color: rgb(var(--ink)); font-variant-numeric: tabular-nums; margin: 0;
}
.kpi-value.text-base { font-size: 1rem; }

/* Les pastilles d'icône prennent les couleurs de sens de la charte : le bleu
   vif, le cyan et l'ambre d'origine ne figurent dans aucune autre page. */
.kpi-icon {
  width: 44px; height: 44px; border-radius: .625rem;
  display: grid; place-items: center; flex: none;
}
.kpi-blue   { background: rgb(var(--info-fond));    color: rgb(var(--info)); }
.kpi-green  { background: rgb(var(--succes-fond));  color: rgb(var(--succes)); }
.kpi-purple { background: rgb(var(--brand-50));     color: rgb(var(--brand-600)); }
.kpi-amber  { background: rgb(var(--attente-fond)); color: rgb(var(--attente)); }
.kpi-orange { background: rgb(var(--brand-50));     color: rgb(var(--brand-700)); }
.kpi-cyan   { background: rgb(var(--info-fond));    color: rgb(var(--info)); }
.kpi-red    { background: rgb(var(--danger-fond));  color: rgb(var(--danger)); }

.section-header-title { color: rgb(var(--ink)); }
