/* ============================================================================
   Cabinet ORL — feuille de style applicative
   ----------------------------------------------------------------------------
   Bootstrap 5.1 fournit la base ; ce fichier porte l'identité visuelle.

   Auparavant, la couleur #0d6efd (le bleu primaire par défaut de Bootstrap)
   était répétée en dur sur le bandeau, les en-têtes de cartes, les en-têtes de
   tables et les onglets actifs. Deux conséquences : aucune identité propre, et
   une saturation telle que plus rien ne ressortait — quand tout est mis en
   avant, rien ne l'est.

   La palette ci-dessous est centralisée dans des variables CSS : changer une
   teinte se fait à un seul endroit.
   ========================================================================== */

/* ------------------------------------------------------------- Police ---- */
/* « Helvetica » a été la demande de départ, mais c'est une police
   propriétaire (Linotype/Monotype) : ni Google Fonts, ni fichier à
   redistribuer sans licence, alors que le cabinet doit rester fonctionnel
   sans accès Internet (même contrainte que Bootstrap et Bootstrap Icons,
   servis localement eux aussi).

   Inter la remplace : dessinée pour l'écran, dans le même registre neutre
   et sans empattement, avec une licence libre (OFL) qui autorise
   l'hébergement local. Servie en .woff2 — un seul format, largement
   suffisant pour les navigateurs que ce cabinet utilise, et plus léger que
   le .ttf qu'Open Sans occupait ici avant elle.

   Quatre graisses suffisent — 400, 400 italique, 600, 700 ; tout le reste
   est synthétisé par le navigateur et n'apporterait que du poids. */

@font-face {
    font-family: 'Inter';
    src: url('../fonts/Inter-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('../fonts/Inter-Italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('../fonts/Inter-SemiBold.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Inter';
    src: url('../fonts/Inter-Bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* ─── La charte ───────────────────────────────────────────────────────────
   Deuxième version de la charte : l'encre foncée qui remplissait la barre du
   haut et les en-têtes de carte disparaît. Le bleu médical est désormais la
   seule couleur qui signale « ceci est actif, ceci est cliquable » ; l'encre
   ne sert plus qu'au texte. Une carte, une barre de navigation, un en-tête —
   tout est blanc ou gris très clair, et un filet remplace l'aplat.

     #2563EB   le bleu d'action (primaire)   #0F172A   l'encre
     #DBEAFE   le bleu clair (primaire)      #F8FAFC   le fond de page
     #6366F1   l'indigo (identité)

   Les neutres suivent une seule échelle de gris ardoise, du plus soutenu
   (texte) au plus clair (fond de page) : c'est elle qui évite qu'un filet de
   tableau et un fond de carte semblent sortir de deux palettes différentes.

   #2563EB sur blanc donne un contraste de 5,2:1, au-dessus du seuil de 4,5:1
   des textes courants — contrairement à son prédécesseur (3,7:1), il n'a pas
   besoin d'une nuance plus sombre pour servir de couleur de lien. La nuance
   plus sombre, #1D4ED8, reste utile ailleurs : le survol d'un bouton plein,
   où il faut qu'un aplat change visiblement de teinte.

   L'indigo (#6366F1) n'habille pas l'avatar : répété sur des dizaines de
   lignes de liste, il pèserait autant que le bleu d'action et donnerait
   l'impression que tout, sur l'écran, est de la même couleur — l'avatar est
   donc resté neutre, comme le reste d'une ligne de tableau (voir plus bas).
   L'indigo attend un usage isolé, qui n'apparaît qu'une fois par écran.

   Les couleurs sémantiques plus bas — vert, ambre, rouge — ne sont pas de la
   charte et n'ont pas à s'y plier : elles portent un sens, pas une identité.
   Le rouge et le bleu de l'audiogramme non plus : ce sont les couleurs
   conventionnelles de l'oreille droite et de l'oreille gauche.
   ───────────────────────────────────────────────────────────────────────── */
:root {
    /* Encre — le texte, les titres, ce qui n'est pas une action */
    --orl-brand: #0f172a;
    --orl-brand-soft: #eff6ff;

    /* Action — le bleu de la charte, réservé à ce qui est cliquable */
    --orl-accent: #2563eb;
    --orl-accent-dark: #1d4ed8;
    --orl-accent-soft: #dbeafe;

    /* Identité — l'indigo, réservé à l'avatar du patient */
    --orl-accent2: #6366f1;
    --orl-accent2-dark: #4338ca;
    --orl-accent2-soft: #e0e7ff;

    /* Neutres, une seule échelle de gris ardoise */
    --orl-ink: #0f172a;
    --orl-ink-2: #334155;
    --orl-muted: #64748b;
    --orl-line: #e2e8f0;
    --orl-line-soft: #f1f5f9;
    --orl-surface: #ffffff;
    --orl-page: #f8fafc;

    /* Sémantique — la couleur porte du sens, elle ne décore pas */
    --orl-success: #16a34a;
    --orl-success-soft: #dcfce7;
    --orl-warning: #f59e0b;
    --orl-warning-soft: #fef3c7;
    --orl-danger: #dc2626;
    --orl-danger-soft: #fee2e2;
    /* Le filet d'un bouton de danger : la teinte pleine ferait un cadre plus
       lourd que le bouton primaire, pour une action qu'on ne veut pas mettre
       en avant — seulement rendre reconnaissable. */
    --orl-danger-line: #fca5a5;

    /* Le filet du pense-bete accroche au rendez-vous. La teinte pleine servirait
       d'alerte, ce que la note n'est pas : elle se remarque sans reclamer. */
    --orl-warning-line: #fde68a;

    /* Texte et liens sur un aplat de couleur plein (bouton, pastille active) :
       toujours blanc, seule teinte qui tienne le contraste sur les trois
       couleurs d'action de la charte. */
    --orl-on-brand: #ffffff;

    /* 10px passait inaperçu sur les grandes surfaces (une carte de tableau de
       bord, un panneau de liste) : le rayon reste identique en pixels, mais un
       petit bouton de 34px de haut en fait un dixième quand une carte de
       300px n'en fait qu'un centième — l'œil ne lit alors plus aucune courbe.
       --orl-radius-sm ne bouge pas : boutons et champs se lisaient déjà
       arrondis. */
    --orl-radius: 14px;
    --orl-radius-sm: 7px;
    --orl-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 4px 12px rgba(15, 23, 42, .06);

    /* ----------------------------------------------------- Échelle typo ----
       Vingt et une tailles distinctes cohabitaient ici, dont sept entre .8rem
       et .9rem — .78, .8, .8125, .82, .85, .86, .875. Personne ne distingue un
       demi-pixel, mais l'œil voit très bien que deux tableaux voisins ne sont
       pas réglés pareil : c'est ce qui donne à une application l'air d'avoir
       été assemblée par morceaux.

       Neuf échelons, écartés d'assez pour que la différence porte du sens.
       Toute nouvelle règle prend un de ces jetons ; une valeur écrite en dur
       est un écart, pas un réglage fin. */
    --orl-fs-2xs: .6875rem;  /* 11px — mentions légales, exposants */
    --orl-fs-xs: .75rem;     /* 12px — pastilles, légendes */
    --orl-fs-sm: .8125rem;   /* 13px — aide, cellules denses */
    --orl-fs-md: .875rem;    /* 14px — tableaux, texte secondaire */
    --orl-fs-base: 1rem;     /* 16px — corps de page */
    --orl-fs-lg: 1.125rem;   /* 18px — sous-titres */
    --orl-fs-xl: 1.25rem;    /* 20px — titres de bloc */
    --orl-fs-2xl: 1.5rem;    /* 24px — titres de page */
    --orl-fs-3xl: 1.75rem;   /* 28px — titre principal */
}

/* ---------------------------------------------------------------- Base ---- */

/* Colonne pleine hauteur : l'en-tete, le contenu qui s'etire, puis le pied de
   page. Il reste ainsi collé en bas des pages courtes sans etre sorti du flux
   — ce que faisait le montage d'origine, au prix d'un pied de page pose
   par-dessus le contenu, qui interceptait les clics des boutons proches. */
body {
    background-color: var(--orl-page);
    color: var(--orl-ink);
    font-family: 'Inter', 'Segoe UI', Roboto, -apple-system, Arial, sans-serif;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* Pousse le pied de page vers le bas quand la page est courte, et laisse
   toujours de l'air avant lui : le dernier element d'un formulaire — un bouton,
   un lien de retour — venait sinon toucher le filet du pied de page. */
.orl-contenu {
    flex: 1 0 auto;
    padding-bottom: 2.5rem;
}


h1, h2, h3, h4, h5 {
    color: var(--orl-ink);
    text-wrap: balance;
}

a {
    color: var(--orl-accent-dark);
    text-underline-offset: 2px;
}

a:hover { color: var(--orl-brand); }

/* Bootstrap colore <code> en rose par défaut — une couleur sémantique que la
   charte n'a jamais eue, qui ressortait sur les rares pages citant un nom de
   fichier (SAUVEGARDE.md, .env.example…) sans qu'aucune autre page n'en
   affiche l'équivalent. Un fond neutre, comme un extrait de code plutôt
   qu'une alerte. */
code {
    color: var(--orl-ink-2);
    background-color: var(--orl-line-soft);
    padding: .1rem .35rem;
    border-radius: var(--orl-radius-sm);
    font-size: .875em;
}

/* La navbar : même carte que le reste de l'application — coin arrondi
   --orl-radius, ombre --orl-shadow — et non une pilule entièrement ronde,
   qui aurait détonné à côté des cartes et panneaux d'action de chaque
   section. */
.orl-navbar-pilule {
    background-color: var(--orl-surface);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    padding: .35rem .75rem;
    /* Même plafond que .orl-page-large : la barre suit la largeur du
       contenu qu'elle surmonte, elle ne fixe pas la sienne à part. */
    max-width: calc(97.5rem - 7rem);
    margin: 14px auto;
    /* Le 3.5rem de chaque côté est le même que .orl-page-large : en dessous de
       97.5rem, sans lui la pilule touchait le bord de l'écran au lieu de
       s'arrêter où le contenu s'arrête. */
    width: calc(100% - 7rem);
}

/* white-space + flex-shrink: 0 : sans eux, un onglet dont la largeur manque
   ne s'efface pas en entier, il casse entre l'icône et le libellé — l'icône
   seule sur une ligne, le mot en dessous. C'est la recherche patient qui doit
   céder de la place en premier (elle est faite pour se rétrécir), jamais un
   onglet. */
.navbar .nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: .4rem;
    font-weight: 500;
    color: var(--orl-ink-2) !important;
    border-radius: var(--orl-radius-sm);
    padding: .45rem .75rem !important;
    white-space: nowrap;
}

.navbar-nav .nav-item { flex-shrink: 0; }

/* De l'air entre les onglets, la recherche et le compte : serrés contre
   l'arrondi de la pilule, ils donnaient une barre dense plutôt qu'aérée. */
.navbar-nav.me-auto { gap: .15rem; }
.orl-navbar-pilule .navbar-collapse > .navbar-nav:last-child { margin-left: .5rem; }

.navbar .nav-link:hover {
    color: var(--orl-accent-dark) !important;
}

/* Onglet correspondant à la page courante : le fond plein a cédé la place au
   trait sous le libellé — la pilule est déjà blanche, un aplat de couleur à
   l'intérieur aurait fait deux formes arrondies imbriquées. */
.navbar .nav-link.is-current {
    color: var(--orl-accent) !important;
    font-weight: 600;
}

.navbar .nav-link.is-current::after {
    content: "";
    position: absolute;
    left: 1rem;
    right: 1rem;
    bottom: -.3rem;
    height: 2px;
    border-radius: 2px;
    background-color: var(--orl-accent);
}

.navbar .nav-link i { opacity: .8; font-size: 1.05em; }

/* L'icône suit le texte quand l'entrée est active ou survolée : atténuée au
   repos, elle reprend sa pleine couleur en même temps que le libellé. */
.navbar .nav-link:hover i,
.navbar .nav-link.is-current i { opacity: 1; }

/* --------------------------------------------------------------- Cartes ---- */

.card {
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    /* Sans ceci, le fond plein de .card-header et .card-body déborde tout
       droit dans les angles arrondis de .card : les coins semblent carrés
       alors que la bordure, elle, est bien arrondie. */
    overflow: hidden;
}

.card-header {
    background-color: var(--orl-surface);
    color: var(--orl-ink);
    font-weight: 600;
    font-size: var(--orl-fs-base);
    border-bottom: 1px solid var(--orl-line);
    border-top-left-radius: calc(var(--orl-radius) - 1px);
    border-top-right-radius: calc(var(--orl-radius) - 1px);
}

.card-header a { color: var(--orl-accent-dark); }

.card-body {
    background-color: var(--orl-surface);
    padding: 20px;
}

.section-block {
    margin-bottom: 25px;
    padding: 20px;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
}

/* -------------------------------------------------------------- Boutons ---- */
/* Bootstrap 5.1 code les couleurs des boutons en dur : on les redéfinit
   explicitement plutôt que via --bs-primary, qui n'agit pas ici. */

.btn {
    border-radius: var(--orl-radius-sm);
    padding: .4rem .85rem;
    font-weight: 500;
}

.btn-primary {
    background-color: var(--orl-accent);
    border-color: var(--orl-accent);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
    background-color: var(--orl-accent-dark) !important;
    border-color: var(--orl-accent-dark) !important;
}

.btn-outline-primary {
    color: var(--orl-accent-dark);
    border-color: var(--orl-accent);
}

.btn-outline-primary:hover,
.btn-outline-primary:active {
    background-color: var(--orl-accent) !important;
    border-color: var(--orl-accent) !important;
    color: var(--orl-on-brand) !important;
}

/* --orl-line est taillé pour un filet de carte ou de tableau, posé sur toute
   sa longueur ; sur le contour d'un petit bouton, entre deux boutons pleins
   et colorés (primaire, danger), il devenait quasi invisible — au point que
   « Modifier » disparaissait d'une rangée d'actions. --orl-muted est le gris
   le plus clair qui reste un contour net sur fond blanc. */
.btn-outline-secondary {
    color: var(--orl-ink-2);
    border-color: var(--orl-muted);
}

.btn-outline-secondary:hover {
    background-color: var(--orl-brand-soft);
    border-color: var(--orl-muted);
    color: var(--orl-accent-dark);
}

.btn-outline-danger { color: var(--orl-danger); border-color: var(--orl-danger-line); }
.btn-outline-danger:hover { background-color: var(--orl-danger); border-color: var(--orl-danger); }

.btn-link { color: var(--orl-accent-dark); }

.btn:focus-visible,
.form-control:focus-visible,
a:focus-visible {
    outline: 2px solid var(--orl-accent);
    outline-offset: 2px;
    box-shadow: none;
}

/* -------------------------------------------------------------- Tables ---- */

.table {
    border-radius: var(--orl-radius);
    overflow: hidden;
    color: var(--orl-ink);
}

/* En-têtes clairs à texte sombre. L'ancienne règle imposait du blanc sur fond
   bleu vif pour toutes les tables ; combinée à une table à fond clair, elle
   rendait les libellés de colonnes illisibles (blanc sur gris). */
.table thead th {
    background-color: var(--orl-line-soft);
    color: var(--orl-ink-2);
    font-weight: 600;
    font-size: var(--orl-fs-sm);
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom: 1px solid var(--orl-line);
    white-space: nowrap;
}

/* Le corps du tableau était laissé aux réglages de Bootstrap, c'est-à-dire à la
   taille du texte courant — 16 px. Un en-tête de 13 px surmontant des cellules
   de 16 px se lit à l'envers : la colonne pèse plus lourd que sa donnée. Et
   selon que la vue avait pensé à `table-sm` ou non, deux tableaux voisins
   n'avaient ni la même densité ni la même hauteur de ligne.

   Une seule densité pour toute l'application, écrite ici et nulle part
   ailleurs. `table-sm` reste sans effet visible, ce qui est voulu : la vue n'a
   plus à choisir. */
.table > tbody > tr > td,
.table > tbody > tr > th {
    font-size: var(--orl-fs-md);
    padding: .55rem .75rem;
}

.table > thead > tr > th { padding: .55rem .75rem; }

.table tbody tr:hover { background-color: var(--orl-brand-soft); }

/* Le nom d'une ligne de tableau n'est pas une invite à cliquer, c'est la ligne
   entière qui l'est (voir .is-clickable) : un lien bleu répété sur chaque
   ligne d'une liste de plusieurs dizaines de patients pèserait plus que le
   texte lui-même, et rendrait le bleu muet le jour où il sert vraiment à
   signaler une action. Le survol suffit à dire qu'une cellule mène quelque
   part ; les boutons de la colonne « Actions » restent seuls en couleur. */
.table td a:not(.btn) { color: var(--orl-ink); }

.table td a:not(.btn):hover {
    color: var(--orl-accent-dark);
    text-decoration: underline;
}

/* Le curseur « main » était appliqué à toutes les lignes, y compris celles qui
   ne sont pas cliquables : il annonçait une interaction inexistante. */
.table tbody tr.is-clickable { cursor: pointer; }

/* Les tableaux qui portent leur propre classe sont des grilles, pas des listes
   — saisie de l'audiogramme, différentiel de l'historique. Ils gardent leur
   densité propre, qui répond à une contrainte de lecture et non à un oubli. */
.orl-audio-tableau > tbody > tr > td,
.orl-journal-diff > tbody > tr > td {
    font-size: var(--orl-fs-sm);
    padding: .3rem .45rem;
}

/* Le caractère du symbole, devant le bouton qui l'arme et devant la ligne de
   saisie qui le porte. En chasse fixe et un peu plus gros que le texte : c'est
   la forme qu'on cherche sur la courbe, pas le mot qui la nomme. */
.orl-audio-symbole {
    font-family: var(--bs-font-monospace, monospace);
    font-weight: 700;
    margin-right: .3rem;
}

/* Weber : la flèche au-dessus, le mot en dessous. La flèche donne le sens de
   lecture d'un coup d'œil, le mot lève l'ambiguïté — l'oreille droite étant
   dessinée à gauche de l'écran, une flèche seule pouvait se lire à l'envers. */
.orl-weber { line-height: 1.1; padding-top: .2rem; padding-bottom: .2rem; }
.orl-weber-fleche { display: block; letter-spacing: -1px; }
.orl-weber-mot { display: block; font-size: var(--orl-fs-xs, .75rem); font-weight: 400; }

/* Une case vide veut dire « non pratiqué ». Sans hauteur minimale elle
   s'écraserait, et la ligne du Weber sauterait à chaque clic. */
.orl-weber:empty { min-height: 2.4rem; min-width: 4.5rem; }

.table-scroll-xs, .table-scroll-s {
    overflow-y: auto;
    overflow-x: hidden;
    display: block;
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    box-shadow: var(--orl-shadow);
    padding: 0;
}

.table-scroll-xs { max-height: 400px; }
.table-scroll-s { max-height: 600px; }

/* -------------------------------------------------------------- Onglets ---- */

.nav-tabs {
    border-bottom: 1px solid var(--orl-line);
    gap: .25rem;
}

.nav-tabs .nav-link {
    font-weight: 600;
    padding: .55rem 1rem;
    color: var(--orl-muted);
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}

.nav-tabs .nav-link:hover {
    background-color: var(--orl-brand-soft);
    color: var(--orl-accent-dark);
}

/* Onglet actif souligné plutôt que rempli de bleu : moins lourd, et la couleur
   reste disponible pour signaler ce qui compte vraiment. */
.nav-tabs .nav-link.active {
    background-color: transparent;
    color: var(--orl-accent-dark);
    border-bottom-color: var(--orl-accent);
}

/* --------------------------------------------------------- Formulaires ---- */

.form-control, .form-select {
    border-radius: var(--orl-radius-sm);
    border-color: var(--orl-line);
    color: var(--orl-ink);
}

.form-control:focus, .form-select:focus {
    border-color: var(--orl-accent);
    box-shadow: 0 0 0 .2rem rgba(37, 99, 235, .2);
}

label, .form-label {
    font-weight: 600;
    font-size: var(--orl-fs-md);
    color: var(--orl-ink-2);
    margin-bottom: .3rem;
}

/* .form-group a été supprimée en Bootstrap 5 : elle ne produit plus aucun
   espacement. Les vues sont converties en « mb-3 » ; cette règle sert de
   filet pour tout gabarit qui l'utiliserait encore. */
.form-group { margin-bottom: 1rem; }

.text-danger { color: var(--orl-danger) !important; font-size: var(--orl-fs-md); }

/* --------------------------------------------------- Notifications ---- */

.orl-toasts {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1090;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: min(24rem, calc(100vw - 2rem));
}

.orl-toast {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-left: 4px solid var(--orl-accent);
    border-radius: var(--orl-radius-sm);
    box-shadow: 0 .5rem 1.25rem rgba(15, 23, 42, .16);
    padding: .7rem .9rem;
    font-size: var(--orl-fs-md);
    animation: orl-toast-in .18s ease-out;
}

.orl-toast.is-success { border-left-color: var(--orl-success); background: var(--orl-success-soft); }
.orl-toast.is-error   { border-left-color: var(--orl-danger);  background: var(--orl-danger-soft); }
.orl-toast.is-warning { border-left-color: var(--orl-warning); background: var(--orl-warning-soft); }

.orl-toast i { font-size: var(--orl-fs-base); line-height: 1.35; }
.orl-toast.is-success i { color: var(--orl-success); }
.orl-toast.is-error i   { color: var(--orl-danger); }
.orl-toast.is-warning i { color: var(--orl-warning); }

.orl-toast .btn-close { margin-left: auto; font-size: var(--orl-fs-2xs); opacity: .5; }

@keyframes orl-toast-in {
    from { opacity: 0; transform: translateY(-.4rem); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .orl-toast { animation: none; }
    * { transition: none !important; }
}

/* ------------------------------------------------------- États vides ---- */

.orl-empty {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--orl-muted);
    background: var(--orl-surface);
    border: 1px dashed var(--orl-line);
    border-radius: var(--orl-radius);
}

.orl-empty i {
    font-size: var(--orl-fs-3xl);
    display: block;
    margin-bottom: .5rem;
    opacity: .5;
}

/* ------------------------------------------------------------ Badges ---- */

.orl-pill {
    display: inline-block;
    font-size: var(--orl-fs-xs);
    font-weight: 600;
    padding: .15rem .55rem;
    border-radius: 999px;
    border: 1px solid transparent;
}

.orl-pill.is-neutral { background: var(--orl-line-soft); color: var(--orl-ink-2); border-color: var(--orl-line); }
.orl-pill.is-success { background: var(--orl-success-soft); color: var(--orl-success); }
.orl-pill.is-warning { background: var(--orl-warning-soft); color: var(--orl-warning); }
.orl-pill.is-danger  { background: var(--orl-danger-soft); color: var(--orl-danger); }
/* Turquoise : un fait acquis, sans jugement — un rendez-vous confirmé n'est ni
   une réussite (le patient n'est pas encore venu) ni une alerte. Le vert et
   l'ambre restent ainsi disponibles pour ce qui est vraiment terminé ou
   vraiment anormal. */
.orl-pill.is-info    { background: var(--orl-accent-soft); color: var(--orl-accent-dark); }

/* Le statut du jour, modifiable sans quitter l'accueil : un <select> habillé
   en pastille plutôt qu'un <span> — même forme, même couleurs par état, mais
   cliquable. Les couleurs elles-mêmes restent celles de .orl-pill.is-*, fixées
   par AppointmentStatus côté serveur puis retouchées par rdv-liste.js au choix. */
.orl-pill-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    cursor: pointer;
    font: inherit;
    /* Une flèche discrète, pour que la pastille se distingue d'un simple
       texte sans reprendre le chrome natif du navigateur — variable selon
       qu'il est ouvert en clair ou en sombre. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M2.5 4.5 6 8l3.5-3.5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .3rem center;
    background-size: .6rem;
    padding-right: 1.2rem;
}

.orl-pill-select:focus-visible { outline: 2px solid var(--orl-accent); outline-offset: 1px; }

/* La ligne entière fait ce que fait son bouton principal — sauf sur un lien,
   un bouton ou le statut, que rdv-liste.js laisse gérer leur propre clic.
   Absente d'une ligne qui n'a rien à proposer : une consultation déjà reçue a
   ses propres actions, et cliquer la ligne ne doit pas en offrir une autre. */
.orl-rdv-ligne-cliquable { cursor: pointer; }

/* ----------------------------------------------------------- Utilitaires ---- */

.text-brand { color: var(--orl-brand); }
.text-accent { color: var(--orl-accent-dark); }

/* Bootstrap 5.1 code .rounded, .alert, .modal-content et .dropdown-menu en
   dur a .25rem — une troisieme valeur de rayon qui ne correspond a aucun des
   deux tokens de la charte, et qui aurait fini par recreer sur les alertes et
   le menu du compte le meme defaut que sur l'accueil : un rayon trop petit
   pour se voir a cote d'un bouton ou d'une carte. */
.rounded { border-radius: var(--orl-radius-sm) !important; }
.alert { border-radius: var(--orl-radius-sm); }
/* overflow: hidden — sans lui, le survol du premier ou du dernier lien
   dessine un rectangle qui deborde tout droit du coin arrondi du menu. */
.dropdown-menu { border-radius: var(--orl-radius-sm); overflow: hidden; }
.modal-content { border-radius: var(--orl-radius); }

/* En-tête de dossier patient : le praticien doit savoir en permanence de qui
   il est question, sans remonter en haut de page. */
.orl-patient-bar {
    display: flex;
    align-items: center;
    gap: .9rem;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-left: 4px solid var(--orl-accent);
    border-radius: var(--orl-radius);
    padding: .8rem 1rem;
    margin-bottom: 1rem;
    box-shadow: var(--orl-shadow);
}

/* Pastille d'initiales, utilisable seule (listes) ou dans l'en-tête patient. */
.orl-avatar {
    width: 2.25rem;
    height: 2.25rem;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--orl-line-soft);
    color: var(--orl-ink-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: var(--orl-fs-sm);
    letter-spacing: .02em;
}

.orl-patient-bar .orl-avatar {
    width: 2.5rem;
    height: 2.5rem;
    font-size: var(--orl-fs-md);
}

.orl-patient-bar .orl-name {
    font-weight: 700;
    font-size: var(--orl-fs-lg);
    line-height: 1.2;
    color: inherit;
    text-decoration: none;
    display: inline-block;
}

.orl-patient-bar .orl-name:hover {
    text-decoration: underline;
}

.orl-patient-bar .orl-meta {
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
}

/* Allergies connues. Le rouge est justifié ici : c'est la seule information du
   bandeau qui doit interrompre la lecture, et elle n'apparaît que si elle a été
   saisie — un bandeau sans allergie reste calme. */
.orl-allergie {
    display: inline-flex;
    align-items: baseline;
    gap: .4rem;
    margin-top: .35rem;
    padding: .2rem .6rem;
    border-radius: var(--orl-radius-sm);
    background: var(--orl-danger-soft);
    color: var(--orl-danger);
    font-size: var(--orl-fs-md);
}

/* Le bloc « Onglets en cadre » (.orl-frame) a ete supprime avec les iframes.
   Les onglets du dossier patient sont desormais des vues partielles rendues
   dans la page : plus de hauteur a deviner, plus de double barre de defilement,
   et le contenu reprend le flux normal du document. */

/* ------------------------------------------------------------ Footer ---- */
/* Même carte que la navbar (--orl-radius, --orl-shadow) : le pied de page
   ferme la page dans le thème qu'elle a ouvert, plutôt qu'un simple filet
   de séparation. */

.footer {
    background: transparent;
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
    margin-top: 1rem;
}

.orl-footer-carte {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1.5rem;
    background-color: var(--orl-surface);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    padding: .85rem 1.25rem;
    margin-bottom: 14px;
}

.orl-footer-marque {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-weight: 600;
    color: var(--orl-ink-2);
    white-space: nowrap;
}

.orl-footer-marque i { color: var(--orl-accent); }

.orl-footer-liens {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin-right: auto;
}

.orl-footer-liens a {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--orl-muted);
    text-decoration: none;
}

.orl-footer-liens a:hover { color: var(--orl-accent-dark); }

.orl-footer-version {
    font-family: var(--bs-font-monospace, monospace);
    font-size: var(--orl-fs-xs);
    color: var(--orl-muted);
    background-color: var(--orl-line-soft);
    border-radius: var(--orl-radius-sm);
    padding: .2rem .5rem;
    white-space: nowrap;
}

/* ------------------------------------------------------ Espace compte ---- */
/* Les pages de gestion du compte proviennent du gabarit ASP.NET Identity :
   titres surdimensionnés, bouton « Save » pleine largeur en btn-lg, menu en
   nav-pills bleu vif. Rien de tout cela ne correspond au reste de
   l'application, et l'ensemble criait plus fort que le dossier patient — qui
   est pourtant l'écran qui compte.

   Le parti pris ici : la couleur ne sert qu'à désigner la page courante et
   l'unique bouton d'envoi. Tout le reste est en neutres. */

/* Plafonnée à 76rem auparavant : sur un grand écran, la barre de menu — qui
   suit toute la largeur de la page — dépassait ce plafond, et un grand vide
   apparaissait sous elle. Elle suit maintenant la largeur de la page comme
   le reste des écrans, sans plafond qui lui soit propre. */
.orl-account {
    width: 100%;
}

.orl-account-title {
    font-size: var(--orl-fs-xl);
    font-weight: 600;
    margin-bottom: .15rem;
}

.orl-account-intro {
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
    margin-bottom: 1.5rem;
}

/* Menu latéral : filet de sélection à gauche plutôt qu'une pastille pleine.
   Même principe que les onglets du dossier patient, pour que les deux
   navigations se lisent de la même manière. */
.orl-account-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    border-left: 1px solid var(--orl-line);
}

.orl-account-nav a {
    display: block;
    padding: .45rem .85rem;
    margin-left: -1px;
    border-left: 2px solid transparent;
    color: var(--orl-ink-2);
    font-size: var(--orl-fs-md);
    text-decoration: none;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}

.orl-account-nav a:hover {
    color: var(--orl-accent-dark);
    background-color: var(--orl-brand-soft);
}

.orl-account-nav a.is-current {
    color: var(--orl-accent-dark);
    border-left-color: var(--orl-accent);
    font-weight: 600;
}

/* Panneau de contenu : une simple surface, sans ombre ni en-tête coloré —
   il n'y a qu'un panneau par page, le distinguer n'apporte rien. */
.orl-account-panel {
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    padding: 1.5rem;
}

.orl-account-panel h2 {
    font-size: var(--orl-fs-base);
    font-weight: 600;
    margin-bottom: .15rem;
}

/* Texte d'aide sous un champ : explique à quoi il sert, plutôt que de laisser
   deviner. Volontairement discret — on le lit une fois. */
.orl-hint {
    display: block;
    color: var(--orl-muted);
    font-size: var(--orl-fs-sm);
    margin-top: .3rem;
    line-height: 1.45;
}

/* Champ non modifiable : il doit se lire comme une information, pas comme une
   saisie possible. Bootstrap grise le texte, ce qui ne suffit pas à le dire. */
.orl-account .form-control:disabled,
.orl-account .form-control[readonly] {
    background-color: var(--orl-line-soft);
    color: var(--orl-ink-2);
    border-style: dashed;
}

/* ------------------------------------------------------ Facturation ---- */

/* Ce qui est dû, ce qui est entré, ce qui reste. Ces trois chiffres se lisent
   ensemble : un bandeau d'un seul tenant, et non trois cartes qui leur
   donneraient le poids de trois sections indépendantes. */
.orl-solde {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--orl-line);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    overflow: hidden;
    margin-bottom: 1rem;
}

.orl-solde-case {
    background: var(--orl-surface);
    padding: .85rem 1.1rem;
}

.orl-solde-libelle {
    display: block;
    font-size: var(--orl-fs-sm);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--orl-muted);
    margin-bottom: .15rem;
}

/* tabular-nums : sans lui, les chiffres n'ont pas tous la même largeur et
   trois montants empilés ne s'alignent pas sur la virgule. */
.orl-solde-valeur {
    font-size: var(--orl-fs-xl);
    font-weight: 600;
    color: var(--orl-ink);
    font-variant-numeric: tabular-nums;
}

/* Le reste à payer est la seule des trois valeurs qui appelle un geste. */
.orl-solde-case.is-du .orl-solde-valeur { color: var(--orl-warning); }
.orl-solde-case.is-solde .orl-solde-valeur { color: var(--orl-success); }

/* Colonne de montants dans un tableau : alignés à droite, sur la virgule, et
   jamais coupés en deux lignes. */
.orl-montant {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Une facture annulée reste au livre mais ne doit pas se confondre avec une
   facture due : elle s'efface sans disparaître. */
.orl-facture-annulee { color: var(--orl-muted); }
.orl-facture-annulee td { opacity: .75; }

@media (max-width: 720px) {
    .orl-solde { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------ Fil d'Ariane ---- */
/* Affiché uniquement sur les écrans situés sous le dossier patient. Sur le
   dossier lui-même, la barre patient porte déjà le retour à la liste : deux
   chemins de retour concurrents se seraient contredits.

   Volontairement discret — c'est un repère, pas une action. */

.orl-fil {
    font-size: var(--orl-fs-sm);
    margin-bottom: .5rem;
    padding: 0;
    background: transparent;
}

.orl-fil .breadcrumb-item + .breadcrumb-item::before {
    content: "›";
    color: var(--orl-muted);
    padding-right: .4rem;
}

.orl-fil a {
    color: var(--orl-muted);
    text-decoration: none;
}

.orl-fil a:hover {
    color: var(--orl-brand);
    text-decoration: underline;
}

.orl-fil .breadcrumb-item.active {
    color: var(--orl-ink-2);
    font-weight: 600;
}

/* ------------------------------------------------ Recherche patient ---- */
/* Champ permanent dans la barre de navigation. Discret au repos — c'est un
   outil, pas une action mise en avant — et souligné d'accent au focus. */

.orl-recherche {
    position: relative;
    flex: 0 1 22rem;
    margin-right: 1rem;
}

.orl-recherche .form-control {
    padding-left: 2.1rem;
    padding-right: 2.2rem;
    height: 2.2rem;
    font-size: var(--orl-fs-md);
    background-color: var(--orl-page);
}

.orl-recherche .form-control:focus {
    background-color: var(--orl-surface);
}

.orl-recherche-icone {
    position: absolute;
    left: .7rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
    pointer-events: none;
}

.orl-recherche-raccourci {
    position: absolute;
    right: .55rem;
    top: 50%;
    transform: translateY(-50%);
    background: var(--orl-line-soft);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    color: var(--orl-muted);
    font-size: var(--orl-fs-xs);
    padding: 0 .3rem;
    pointer-events: none;
}

/* Le raccourci disparait des que le champ sert : il n'a plus rien a apprendre. */
.orl-recherche .form-control:focus ~ .orl-recherche-raccourci { display: none; }

/* La recherche de la liste des patients réutilise la liste déroulante de la
   barre du haut, mais rien de son habillage : là-bas le champ est étroit, à
   hauteur réduite, et l'icône est posée en absolu par-dessus. Ici l'icône est un
   élément du groupe Bootstrap et le champ garde sa taille normale.

   Seule la position relative est commune — c'est elle qui ancre la liste. */
.orl-recherche-liste {
    position: relative;
}

.orl-recherche-resultats {
    position: absolute;
    top: calc(100% + .3rem);
    left: 0;
    right: 0;
    z-index: 1080;
    margin: 0;
    padding: .25rem;
    list-style: none;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    box-shadow: 0 .5rem 1.25rem rgba(15, 23, 42, .16);
    max-height: 22rem;
    overflow-y: auto;
}

.orl-recherche-item {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    padding: .4rem .6rem;
    border-radius: var(--orl-radius-sm);
    cursor: pointer;
}

.orl-recherche-item:hover,
.orl-recherche-item.is-active {
    background: var(--orl-brand-soft);
}

.orl-recherche-nom {
    font-weight: 600;
    font-size: var(--orl-fs-md);
    color: var(--orl-ink);
}

.orl-recherche-meta {
    font-size: var(--orl-fs-sm);
    color: var(--orl-muted);
}

/* Ligne « créer le dossier » de la recherche patient : séparée des résultats
   par un filet, et hors du parcours clavier — elle ne prend jamais la classe
   is-active. */
.orl-recherche-item.orl-recherche-creer {
    border-top: 1px solid var(--orl-line);
    color: var(--orl-accent-dark);
    font-weight: 600;
}

.orl-recherche-vide {
    padding: .6rem;
    font-size: var(--orl-fs-md);
    color: var(--orl-muted);
    text-align: center;
}

/* Sous la barre repliee, le champ passe en pleine largeur plutot que de
   comprimer les liens de navigation. */
@media (max-width: 991.98px) {
    .orl-recherche {
        flex: 1 1 100%;
        margin: .5rem 0;
    }
}

/* ------------------------------------------------------ Pagination ---- */
/* Bootstrap code le bleu de ses liens de pagination en dur, comme pour les
   boutons : on realigne sur la palette du cabinet. */

.pagination .page-link {
    color: var(--orl-accent-dark);
    border-color: var(--orl-line);
}

.pagination .page-link:hover {
    background-color: var(--orl-brand-soft);
    border-color: var(--orl-line);
    color: var(--orl-accent-dark);
}

.pagination .page-item.active .page-link {
    background-color: var(--orl-accent);
    border-color: var(--orl-accent);
    color: var(--orl-on-brand);
}

.pagination .page-item.disabled .page-link {
    color: var(--orl-muted);
    background-color: transparent;
    border-color: var(--orl-line-soft);
}

/* ------------------------------------------- Journal du dossier ---- */
/* Historique des modifications : une colonne d'evenements datee, lue du
   plus recent au plus ancien. Le filet vertical relie les pastilles pour
   qu'on lise une continuite plutot qu'une liste. */

.orl-journal {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}

.orl-journal-entree {
    display: flex;
    gap: .9rem;
    padding-bottom: 1.5rem;
    position: relative;
}

.orl-journal-entree:last-child { padding-bottom: 0; }

/* Le filet s'arrete a la derniere pastille au lieu de flotter dans le vide. */
.orl-journal-entree:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 1rem;
    top: 2.1rem;
    bottom: .25rem;
    width: 1px;
    background: var(--orl-line);
}

.orl-journal-puce {
    flex: 0 0 2rem;
    height: 2rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--orl-fs-md);
    background: var(--orl-line-soft);
    color: var(--orl-ink-2);
    border: 1px solid var(--orl-line);
    z-index: 1;
}

.orl-journal-puce.is-success { background: var(--orl-success-soft); color: var(--orl-success); border-color: transparent; }
.orl-journal-puce.is-danger  { background: var(--orl-danger-soft);  color: var(--orl-danger);  border-color: transparent; }
.orl-journal-puce.is-warning { background: var(--orl-warning-soft); color: var(--orl-warning); border-color: transparent; }

.orl-journal-corps { flex: 1 1 auto; min-width: 0; padding-top: .15rem; }

.orl-journal-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem;
    margin-bottom: .35rem;
}

.orl-journal-diff th,
.orl-journal-diff td {
    border: 0;
    padding: .2rem .5rem .2rem 0;
    vertical-align: top;
}

.orl-journal-diff th {
    font-weight: 500;
    color: var(--orl-muted);
    white-space: nowrap;
    width: 1%;
}

/* L'ancienne valeur est barree : l'oeil comprend le remplacement sans lire. */
.orl-journal-avant {
    color: var(--orl-muted);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.orl-journal-fleche { color: var(--orl-muted); width: 1%; }

.orl-journal-apres { font-weight: 500; }

/* ------------------------------------------------------- Rendez-vous ---- */
/* Prise de rendez-vous : un seul ecran, patient compris. Les trois decisions
   — qui, quel jour, quelle heure — sont separees en blocs pour qu'aucune ne
   soit prise par defaut. */

.orl-rdv-bloc {
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    padding: 1.1rem 1.25rem 1.25rem;
    margin-bottom: 1rem;
}

/* legend flotte hors du flux par defaut et se superpose a la bordure. */
.orl-rdv-legende {
    float: none;
    width: auto;
    font-size: var(--orl-fs-sm);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--orl-muted);
    margin-bottom: .75rem;
}

.orl-rdv-date { max-width: 15rem; }
.orl-rdv-statut { max-width: 15rem; }

.orl-rdv-aide {
    margin: .75rem 0 0;
    font-size: var(--orl-fs-sm);
    color: var(--orl-muted);
}

.orl-rdv-actions {
    display: flex;
    gap: .6rem;
    align-items: center;
}

/* ------------------------------------------------ Fiche patient en deux ----
   La fiche tient en deux colonnes : a gauche qui est le patient et ou il
   habite, a droite comment on le joint. Un filet les separe.

   Le filet est pose sur la colonne de droite et non entre les deux : une
   bordure sur un element de grille suit sa hauteur, donc la plus haute des
   deux colonnes, sans qu'on ait a la connaitre.

   Il ne parait qu'a partir de « lg ». En dessous, les deux colonnes s'empilent
   et un trait vertical n'aurait plus rien a separer — il barrerait le cote de
   la page. */
@media (min-width: 992px) {
    .orl-fiche-colonne-jointe {
        border-left: 1px solid var(--orl-line);
    }
}

/* -- Le pense-bete du rendez-vous -- */

/* Papier plutot que pastille : une pastille se lit comme un statut, et le
   planning en aligne deja une par ligne. Le fond creme et le bord gauche epais
   disent « quelqu'un a colle un mot ici » sans avoir a l'ecrire. */
.orl-postit {
    display: flex;
    align-items: flex-start;
    gap: .4rem;
    max-width: 26rem;
    margin-top: .35rem;
    padding: .3rem .55rem;
    background: var(--orl-warning-soft);
    border: 1px solid var(--orl-warning-line);
    border-left: 3px solid var(--orl-warning);
    border-radius: var(--orl-radius-sm);
    font-size: var(--orl-fs-sm);
    font-weight: 400;
    color: var(--orl-ink-2);

    /* Ce qui a ete saisi sur plusieurs lignes se lit sur plusieurs lignes : une
       note d'accueil s'ecrit souvent en liste. */
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.orl-postit > .bi {
    flex: none;
    margin-top: .1em;
    color: var(--orl-warning);
}

/* Hors tableau — detail et suppression du rendez-vous — la note n'a plus de nom
   au-dessus d'elle : elle prend un peu de place pour se tenir seule. */
.orl-postit-seul {
    max-width: 34rem;
    margin: .25rem 0 1rem;
    padding: .55rem .75rem;
    font-size: var(--orl-fs-md);
}

/* Le champ de saisie porte le meme papier que la note affichee : ce qu'on tape
   ressemble a ce qu'on verra. */
.orl-postit-champ {
    background-color: var(--orl-warning-soft);
    border-color: var(--orl-warning-line);
    resize: vertical;
}

.orl-postit-champ:focus {
    background-color: var(--orl-warning-soft);
    border-color: var(--orl-warning);
}

/* -- Patient -- */

/* Le champ de recherche est ici un element de formulaire, pas un accessoire de
   barre de navigation : il occupe la largeur du bloc. */
.orl-patient-recherche {
    flex: none;
    margin-right: 0;
    max-width: 26rem;
}

.orl-patient-recherche .form-control {
    height: auto;
    padding-top: .375rem;
    padding-bottom: .375rem;
    padding-right: .75rem;
    font-size: var(--orl-fs-md);
}

.orl-patient-choisi {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .75rem;
    background: var(--orl-accent-soft);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    max-width: 26rem;
}

.orl-patient-choisi .bi { color: var(--orl-accent-dark); }

.orl-patient-nom {
    font-weight: 600;
    color: var(--orl-ink);
}

/* Repousse « Changer » a droite sans le detacher de la carte. */
.orl-patient-choisi .btn-link {
    margin-left: auto;
    padding: 0;
    font-size: var(--orl-fs-sm);
    text-decoration: none;
}

/* ------------------------------------------------------- Largeur page ---- */

/* Remplace « container » de Bootstrap, plafonne a 1140px. Sur un ecran de
   1920, un tiers de la page restait vide et les tableaux se comprimaient
   sans raison.

   1560px et non toute la largeur : au-dela, l'oeil peine a suivre une ligne
   de tableau de gauche a droite, et les formulaires prendraient des champs
   impossibles a relire. */
.orl-page-large {
    width: 100%;
    max-width: 97.5rem;
    margin: 0 auto;
    padding-left: 3.5rem;
    padding-right: 3.5rem;
}

/* Largeurs de formulaire, a poser sur le <form> lui-meme.

   Un formulaire n'occupe pas la largeur de la page : ces classes remplacent
   les « row > col-md-4 » qui enfermaient les formulaires dans un tiers de
   page — soit environ 380px, ou aucun libelle ne tenait sur une ligne. */
/* orl-rdv-form et orl-param-form sont les noms d'origine, gardes pour les
   ecrans qui les portent deja ; les valeurs sont declarees une seule fois
   pour qu'elles ne puissent plus diverger. */
.orl-form,
.orl-rdv-form { max-width: 46rem; }

.orl-form-large,
.orl-param-form { max-width: 76rem; }

/* Dans les Paramètres, le formulaire vit déjà dans la colonne de contenu de
   .orl-account (elle-même large de toute la page) : le plafond de 76rem,
   pensé pour un formulaire posé seul sur la page, laissait un vide entre le
   panneau et le menu du haut. Ne s'applique qu'ici — Facture et Consultation
   posent le même .orl-param-form seul sur la page et gardent leur plafond. */
.orl-account .orl-param-form { max-width: none; }

/* Le fil d'Ariane et la carte patient qui précèdent ces blocs : même largeur
   qu'eux, pour que rien ne déborde plus large que ce qu'il surmonte. */
.orl-entete-dossier { max-width: 76rem; }

/* ------------------------------------------------------ Consultation ---- */

/* En-tete : quand a eu lieu la consultation, et de quel type. Ces deux faits
   se lisent d'un coup d'oeil, avant le contenu medical. */
.orl-consult-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: 1.25rem;
    padding-bottom: .9rem;
    border-bottom: 1px solid var(--orl-line);
}

.orl-consult-quand {
    font-size: var(--orl-fs-lg);
    font-weight: 600;
    color: var(--orl-ink);
}

.orl-consult-heure {
    margin-left: .5rem;
    color: var(--orl-muted);
    font-variant-numeric: tabular-nums;
}

.orl-consult-champ + .orl-consult-champ { margin-top: 1.1rem; }

/* Intitule du champ : discret, en capitales, pour que le texte medical reste
   ce que l'oeil accroche en premier. */
.orl-consult-titre {
    margin: 0 0 .25rem;
    font-size: var(--orl-fs-xs);
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--orl-muted);
}

.orl-consult-texte {
    margin: 0;
    color: var(--orl-ink);
    /* Les champs medicaux n'ont plus de limite de longueur : une mesure de
       lecture confortable evite les lignes interminables sur grand ecran. */
    max-width: 68ch;
}

.orl-consult-vide {
    margin: 0;
    color: var(--orl-muted);
    font-style: italic;
    font-size: var(--orl-fs-md);
}

/* Le diagnostic est la conclusion de la consultation : un filet le distingue
   sans recourir a une couleur, qui porterait un sens qu'il n'a pas. */
.orl-consult-diagnostic {
    padding-left: .75rem;
    border-left: 3px solid var(--orl-accent);
    font-weight: 500;
}

/* pre-line : les retours a la ligne saisis par le praticien etaient avales,
   et une note structuree en paragraphes revenait en pave continu. */
.orl-consult-notes { white-space: pre-line; }

/* -------------------------------------------------------- Mon compte ---- */

/* Liste de faits en lecture. Le terme au-dessus de la valeur, et non a cote :
   dans une colonne etroite, « Double authentification » imposait sa largeur a
   toute la grille, et il ne restait plus assez de place pour une adresse
   e-mail — qui se coupait alors en trois morceaux. */
.orl-compte-faits {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    margin: 0;
}

.orl-compte-faits dt {
    font-weight: 400;
    font-size: var(--orl-fs-sm);
    letter-spacing: .02em;
    color: var(--orl-muted);
    margin-bottom: .1rem;
}

.orl-compte-faits dd {
    margin: 0;
    font-size: var(--orl-fs-md);
    /* anywhere plutot que break-word : une adresse longue se coupe alors
       proprement en fin de ligne au lieu de deborder du bloc. */
    overflow-wrap: anywhere;
}

/* minmax etroit : les quatre chiffres tiennent sur une ligne des que le bloc
   depasse 30rem, au lieu de laisser le quatrieme seul en dessous. */
.orl-compte-chiffres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr));
    gap: .75rem;
}

.orl-compte-chiffre {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    padding: .8rem .9rem;
    background: var(--orl-page);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
}

.orl-compte-valeur {
    font-size: var(--orl-fs-2xl);
    line-height: 1.1;
    font-weight: 600;
    color: var(--orl-brand);
    font-variant-numeric: tabular-nums;
}

.orl-compte-libelle {
    font-size: var(--orl-fs-sm);
    color: var(--orl-muted);
}

/* ---------------------------------------------------------- Parametres ---- */

/* La largeur de ces ecrans est declaree plus haut, avec les autres.

   Elargir ne suffisait pas : un champ « Adresse » etire sur toute la page se
   remplit mal et se relit encore moins bien. On garde donc des champs de
   longueur raisonnable, et ce sont les blocs que l'on met cote a cote.

   Deux colonnes a partir de 1200px seulement : en dessous, les blocs
   s'empilent et occupent toute la largeur disponible. */
@media (min-width: 75rem) {
    .orl-param-colonnes {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 1rem;
        align-items: start;
    }

    /* Un bloc marque « large » reprend les deux colonnes : les horaires
       alignent quatre champs, les couper en deux les rendrait illisibles. */
    .orl-param-colonnes > .orl-param-large { grid-column: 1 / -1; }

    /* Les blocs sont poses par la grille : leur marge propre creerait un
       ecart different entre colonnes voisines et blocs empiles. */
    .orl-param-colonnes > .orl-rdv-bloc { margin-bottom: 0; }

    /* La marge retiree ci-dessus laissait les boutons coller au dernier bloc :
       elle est rendue au conteneur, qui la porte une seule fois. */
    .orl-param-colonnes { margin-bottom: 1rem; }
}

/* Une duree se saisit courte et se lit avec son unite : un champ nombre
   etire sur la colonne entiere suggererait qu'on y attend autre chose. */
.orl-duree {
    display: flex;
    align-items: baseline;
    gap: .6rem;
}

.orl-duree .form-control {
    width: 6.5rem;
    font-variant-numeric: tabular-nums;
}

.orl-duree-unite {
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
}

/* Navigation entre les sections des parametres. Des liens vers des pages
   distinctes, et non des onglets : chaque section a son formulaire et sa
   validation, si bien qu'un message d'erreur ne peut pas se retrouver
   cache derriere un onglet inactif. */
/* Navigation des parametres : laterale et groupee, non plus une rangee
   d'onglets. Ils etaient neuf, ajoutes un par un au fil des livraisons, et une
   rangee de neuf ne se lit plus — elle se parcourt en cherchant, et se replie
   sur deux lignes des que l'ecran retrecit.

   Elle reutilise « orl-account-nav » plutot que d'inventer un second menu
   lateral : les reglages du cabinet et ceux du compte se lisent alors de la
   meme maniere, et il n'y a qu'un jeu de regles a tenir. Seuls les titres de
   groupe et le retrait des sous-entrees sont propres a cet ecran. */
.orl-param-nav {
    margin-bottom: 1.5rem;
}

/* Titre de groupe : discret, en capitales espacees. Il classe sans attirer
   l'oeil — ce qu'on cherche est l'entree, pas le groupe. */
.orl-param-groupe {
    font-size: var(--orl-fs-xs);
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--orl-muted);
    padding: 0 0 .35rem .85rem;
}

/* L'air se pose entre deux groupes, jamais au-dessus du premier : une marge
   portee par le titre lui-meme aurait decale le menu entier vers le bas. */
.orl-param-bloc + .orl-param-bloc .orl-param-groupe {
    margin-top: 1.25rem;
}

/* Sous-entree : les quatre sections de la sauvegarde, developpees seulement
   quand on s'y trouve. Le retrait dit la subordination, la taille dit qu'il
   s'agit d'un detail du sujet au-dessus. */
.orl-account-nav a.orl-param-sous {
    padding-left: 1.7rem;
    font-size: var(--orl-fs-md);
}

@media (max-width: 991.98px) {
    /* En colonne unique, le menu passe au-dessus du contenu. Empile, il
       occuperait tout le premier ecran avant la moindre ligne utile — plus mal
       que la rangee d'onglets qu'il remplace. Les groupes se posent donc cote a
       cote, autant que la largeur en accepte, et la hauteur est divisee par
       trois. Un filet separe l'ensemble du contenu, faute de quoi les deux se
       confondent. */
    .orl-param-nav {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
        gap: 0 1.25rem;
        align-items: start;
        border-bottom: 1px solid var(--orl-line);
        padding-bottom: .75rem;
    }

    .orl-param-nav > .orl-param-bloc > .orl-param-groupe {
        margin-top: 1rem;
    }
}

/* Encart d'information : ce qui va se passer, dit avant l'action plutot
   qu'apres coup dans un message de confirmation. */
.orl-avis {
    display: flex;
    gap: .65rem;
    margin-top: 1rem;
    padding: .75rem .9rem;
    background: var(--orl-brand-soft);
    border: 1px solid var(--orl-line);
    border-left: 3px solid var(--orl-accent);
    border-radius: var(--orl-radius-sm);
    font-size: var(--orl-fs-md);
    color: var(--orl-ink-2);
}

.orl-avis .bi {
    flex: none;
    margin-top: .1rem;
    color: var(--orl-accent);
}

/* -- Logo du cabinet -- */

.orl-logo {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1.25rem;
}

/* Le damier laisse voir la transparence d'un PNG : un logo blanc sur fond
   blanc paraitrait manquant. */
.orl-logo-apercu {
    flex: none;
    width: 8rem;
    height: 5rem;
    display: grid;
    place-items: center;
    padding: .5rem;
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    background-color: var(--orl-surface);
    background-image:
        linear-gradient(45deg, var(--orl-line-soft) 25%, transparent 25%),
        linear-gradient(-45deg, var(--orl-line-soft) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--orl-line-soft) 75%),
        linear-gradient(-45deg, transparent 75%, var(--orl-line-soft) 75%);
    background-size: 12px 12px;
    background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}

.orl-logo-apercu img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.orl-logo-vide {
    font-size: var(--orl-fs-sm);
    color: var(--orl-muted);
}

.orl-logo-actions {
    flex: 1 1 18rem;
    min-width: 0;
}

/* -- Creneaux -- */

/* auto-fill plutot qu'un nombre fixe de colonnes : la grille se resserre sur
   telephone sans media query, et les creneaux gardent une taille cliquable. */
.orl-creneaux {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
    gap: .5rem;
    margin-top: .35rem;
}

.orl-creneaux-message {
    grid-column: 1 / -1;
    margin: 0;
    padding: .75rem 0;
    color: var(--orl-muted);
    font-size: var(--orl-fs-md);
}

.orl-creneau {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
    padding: .5rem .7rem;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    cursor: pointer;
    text-align: left;
    transition: border-color .12s, background-color .12s;
}

.orl-creneau:hover:not(:disabled) {
    border-color: var(--orl-accent);
    background: var(--orl-accent-soft);
}

.orl-creneau-heure {
    font-weight: 600;
    font-size: var(--orl-fs-base);
    color: var(--orl-ink);
    font-variant-numeric: tabular-nums;
}

.orl-creneau-fin {
    font-size: var(--orl-fs-xs);
    color: var(--orl-muted);
}

/* Le creneau retenu ne se distingue pas que par la couleur : le fond plein et
   le texte inverse restent lisibles en cas de daltonisme ou d'impression. */
.orl-creneau.is-choisi {
    background: var(--orl-accent);
    border-color: var(--orl-accent-dark);
}

.orl-creneau.is-choisi .orl-creneau-heure,
.orl-creneau.is-choisi .orl-creneau-fin { color: var(--orl-on-brand); }

.orl-creneau.is-pris {
    background: var(--orl-line-soft);
    border-style: dashed;
    cursor: not-allowed;
}

.orl-creneau.is-pris .orl-creneau-heure {
    color: var(--orl-muted);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

/* Pastille de la barre de navigation : le nombre d'alertes de stock.
   ------------------------------------------------------------------
   Ambre et non rouge : ce n'est pas une panne, c'est quelque chose à décider —
   jeter un lot, en commander un autre. Le rouge de la charte est réservé à ce
   qui est cassé, et l'user pour un réapprovisionnement le rendrait muet le jour
   où il servira vraiment. */
.orl-nav-pastille {
    background: var(--orl-warning);
    border-radius: 999px;
    color: #fff;
    font-size: .6875rem;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    line-height: 1;
    margin-inline-start: .25rem;
    padding: .15rem .4rem;
    vertical-align: text-top;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Agenda à durée libre
   ═══════════════════════════════════════════════════════════════════════════

   Le mode se règle dans Paramètres → Agenda, et se voit à trois endroits : le
   choix lui-même, la saisie de la durée, et le planning où les blocs cessent
   d'être tous égaux.

   Aucune couleur nouvelle : tout reprend l'accent et les gris de la charte. */

/* Les deux modes, en cartes cliquables. Le choix engage la façon de travailler
   du secrétariat et se fait une fois : il mérite de montrer ce qu'il implique,
   pas de tenir sur une ligne repliée dans une liste déroulante. */
.orl-mode-agenda {
    display: grid;
    gap: .75rem;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.orl-mode-carte {
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    cursor: pointer;
    display: grid;
    gap: .35rem;
    padding: 1rem;
    transition: border-color .12s ease, background-color .12s ease;
}

.orl-mode-carte:hover { border-color: var(--orl-accent); }

.orl-mode-carte.is-choisi {
    background: var(--orl-page);
    border-color: var(--orl-accent);
    box-shadow: inset 0 0 0 1px var(--orl-accent);
}

.orl-mode-titre {
    font-size: var(--orl-fs-md);
    font-weight: 600;
}

.orl-mode-texte { color: var(--orl-ink); }

.orl-mode-detail {
    color: var(--orl-muted);
    font-size: var(--orl-fs-sm);
}

/* Ce qui est déjà pris, sous les champs de saisie. Sans grille à griser, c'est
   la seule chose qui dise où se loger. */
.orl-occupation {
    background: var(--orl-page);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius-sm);
    padding: .6rem .8rem;
}

.orl-occupation-titre {
    color: var(--orl-muted);
    display: block;
    font-size: var(--orl-fs-sm);
    letter-spacing: .02em;
    margin-bottom: .35rem;
    text-transform: uppercase;
}

.orl-occupation-liste {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.orl-occupation-plage {
    background: var(--orl-line-soft);
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
    padding: .1rem .45rem;
}

.orl-occupation-vide { color: var(--orl-muted); }

/* Le planning, quand les durées cessent d'être égales.
   ---------------------------------------------------
   Le trait de gauche est proportionnel à la durée : c'est ce qui rend visible,
   en parcourant la colonne, qu'un rendez-vous en vaut trois. Une grille
   régulière n'en avait pas besoin — toutes les lignes s'y valaient.

   La hauteur est bornée : sans plafond, un rendez-vous de quatre heures
   étirerait sa ligne au point de repousser les suivantes hors de l'écran. Le
   trait dit la proportion, pas la mesure exacte ; c'est le libellé « 45 min »
   qui donne le chiffre. */
.orl-agenda-horaire {
    align-items: center;
    display: flex;
    gap: .5rem;
}

/* Couleur par praticien : une bordure sur la première cellule de la ligne.

   Trois causes de décalage écartées, dans l'ordre où elles ont été trouvées :
     1. un <span> interne dont la hauteur dépendait de la durée du
        rendez-vous (l'ancien .orl-agenda-bloc) — elle pouvait dépasser
        celle de la ligne et déborder sur la suivante ;
     2. box-shadow posé sur <tr> plutôt que sur une cellule — masqué par le
        fond opaque des cellules, qui se peint par-dessus le fond de leur
        ligne dans le modèle de rendu des tableaux ;
     3. LA VRAIE CAUSE : .orl-agenda-horaire posait display:flex
        DIRECTEMENT SUR LE <td>. Un <td> ainsi transformé perd son
        comportement de cellule de tableau — sa hauteur ne suit plus celle
        de la ligne, elle retombe sur son seul contenu. Dès qu'une autre
        cellule de la même ligne réclamait plus de hauteur (un nom de
        patient qui repasse à la ligne, par exemple), cette cellule-là
        restait courte : la bordure qu'elle porte semblait alors s'arrêter
        avant la fin de la ligne. Le correctif est dans la vue : le flex vit
        maintenant sur un <div> À L'INTÉRIEUR du <td>, qui reste une vraie
        cellule et suit donc toujours la hauteur réelle de sa ligne — voir
        Views/Appointment/Index.cshtml.

   La classe est posée sur <tr> — voir WebUi.Helpers.PraticienAffichage, qui
   la choisit — et la durée reste lisible via .orl-agenda-duree, en toutes
   lettres, qui ne l'a jamais quittée.

   Palette à part de celle des statuts (is-success, is-warning…) : celle-ci
   n'est pas une gravité, c'est une catégorie, et le vert ou le rouge y
   ferait croire à une alerte qui n'existe pas. */
.table > tbody > tr.orl-praticien-1 > td:first-child { border-left: 4px solid #2563eb; }
.table > tbody > tr.orl-praticien-2 > td:first-child { border-left: 4px solid #7c3aed; }
.table > tbody > tr.orl-praticien-3 > td:first-child { border-left: 4px solid #0891b2; }
.table > tbody > tr.orl-praticien-4 > td:first-child { border-left: 4px solid #db2777; }
.table > tbody > tr.orl-praticien-5 > td:first-child { border-left: 4px solid #ea580c; }
.table > tbody > tr.orl-praticien-6 > td:first-child { border-left: 4px solid #0d9488; }
.table > tbody > tr.orl-praticien-7 > td:first-child { border-left: 4px solid #4338ca; }
/* Fuchsia, et non plus la pierre #78716c qui occupait cette case. Un gris ne
   peut pas désigner un praticien : c'est la teinte que l'œil lit comme « rien »,
   et c'est celle qui marque, deux lignes plus bas, un rendez-vous sans agenda.
   La même couleur disait donc deux choses opposées — et celui qui y tombait
   paraissait ne pas en avoir. */
.table > tbody > tr.orl-praticien-8 > td:first-child { border-left: 4px solid #c026d3; }
/* Rendez-vous d'avant le cloisonnement, sans praticien précis. Un gris neutre,
   et non plus var(--orl-accent) : celle-ci vaut #2563eb, c'est-à-dire
   exactement la teinte du praticien n°1 — « le cabinet » et le premier
   praticien portaient le même filet, sur le seul écran qui sert à les
   distinguer. Le gris dit ici ce qu'il doit dire : personne en particulier. */
.table > tbody > tr.orl-praticien-aucun > td:first-child { border-left: 4px solid #94a3b8; }

.orl-agenda-plage { font-variant-numeric: tabular-nums; }

.orl-agenda-duree {
    color: var(--orl-muted);
    font-size: var(--orl-fs-sm);
    font-weight: 400;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Tableau de bord des statistiques
   ═══════════════════════════════════════════════════════════════════════════

   Rien ici n'introduit de couleur nouvelle : les séries reprennent le
   bleu-vert de la marque et son accent, éclaircis par paliers. Le vert,
   l'ambre et le rouge de la charte sont réservés aux graphiques où « réglé »
   et « impayé » ont vraiment ce sens — une tranche d'âge n'est ni bonne ni
   mauvaise, et la teinter en rouge le laisserait croire.

   Aucune bibliothèque de graphiques n'est chargée. L'application est servie
   sans accès extérieur : un cabinet doit pouvoir ouvrir cet écran avec une
   connexion médiocre, ou sans connexion du tout. */

.orl-stat-intro {
    font-size: var(--orl-fs-md);
    margin-bottom: 1.25rem;
    max-width: 62ch;
}

/* ─── Les chiffres d'en-tête ─────────────────────────────────────────────── */

.orl-stat-chiffres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .75rem;
    margin-bottom: 1.75rem;
}

.orl-stat-chiffre {
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    padding: .9rem 1rem;
    display: flex;
    flex-direction: column;
    gap: .15rem;

    /* Le filet coloré remplace un aplat de fond : il signale la carte sans
       en faire un bloc de couleur, et il survit à une impression en noir. */
    border-top: 3px solid var(--orl-accent);
}

.orl-stat-chiffre.is-attention { border-top-color: var(--orl-warning); }

.orl-stat-valeur {
    font-size: 1.65rem;
    font-weight: 600;
    line-height: 1.1;
    color: var(--orl-ink);

    /* Les chiffres s'alignent en colonne d'une carte à l'autre. */
    font-variant-numeric: tabular-nums;
}

.orl-stat-libelle {
    font-size: var(--orl-fs-md);
    color: var(--orl-ink);
}

.orl-stat-detail {
    font-size: var(--orl-fs-xs);
    color: var(--orl-muted);
}

/* ─── Sections et cartes ─────────────────────────────────────────────────── */

.orl-stat-section {
    font-size: var(--orl-fs-xl);
    font-weight: 600;
    color: var(--orl-brand);
    margin: 2rem 0 .85rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--orl-line);
}

.orl-stat-grille {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1rem;
}

.orl-stat-carte {
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    box-shadow: var(--orl-shadow);
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

.orl-stat-titre {
    font-size: var(--orl-fs-lg);
    font-weight: 600;
    color: var(--orl-ink);
    margin: 0 0 1rem;
}

/* Une phrase sous le graphique, qui dit comment le lire. Un tableau de bord
   sans mode d'emploi se lit de travers ou pas du tout. */
.orl-stat-lecture {
    font-size: var(--orl-fs-sm);
    color: var(--orl-muted);
    margin: 1rem 0 0;
    padding-top: .75rem;
    border-top: 1px dashed var(--orl-line);
}

.orl-stat-absent {
    display: flex;
    align-items: flex-start;
    gap: .9rem;
}

.orl-stat-absent i {
    font-size: 1.5rem;
    color: var(--orl-muted);
    line-height: 1.3;
}

/* ─── Anneau ─────────────────────────────────────────────────────────────── */

.orl-anneau {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;
}

.orl-anneau-figure {
    width: 170px;
    height: 170px;
    flex: 0 0 auto;
}

.orl-anneau-total {
    text-anchor: middle;
    font-size: 26px;
    font-weight: 600;
    fill: var(--orl-ink);
}

.orl-anneau-unite {
    text-anchor: middle;
    font-size: 12px;
    fill: var(--orl-muted);
}

.orl-anneau-legende {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1 1 200px;
    min-width: 0;
}

.orl-anneau-legende li {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: baseline;
    gap: .5rem;
    padding: .35rem 0;
    border-bottom: 1px solid var(--orl-line-soft);
    font-size: var(--orl-fs-md);
}

.orl-anneau-legende li:last-child { border-bottom: 0; }

.orl-anneau-puce {
    width: .7rem;
    height: .7rem;
    border-radius: 2px;
    display: inline-block;
}

.orl-anneau-nom {
    color: var(--orl-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orl-anneau-part {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.orl-anneau-nombre {
    color: var(--orl-muted);
    font-size: var(--orl-fs-sm);
    font-variant-numeric: tabular-nums;
}

/* ─── Barres horizontales ────────────────────────────────────────────────── */

.orl-barres {
    list-style: none;
    margin: 0;
    padding: 0;
}

.orl-barre {
    display: grid;
    grid-template-columns: minmax(6rem, 11rem) 1fr auto;
    align-items: center;
    gap: .75rem;
    padding: .3rem 0;
}

.orl-barre-nom {
    font-size: var(--orl-fs-md);
    color: var(--orl-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orl-barre-piste {
    background: var(--orl-line-soft);
    border-radius: var(--orl-radius-sm);
    height: 1.15rem;
    overflow: hidden;
}

.orl-barre-valeur {
    display: block;
    height: 100%;
    border-radius: var(--orl-radius-sm);
    min-width: 2px;
}

.orl-barre-chiffre {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    font-variant-numeric: tabular-nums;
    font-size: var(--orl-fs-md);
    white-space: nowrap;
}

.orl-barre-part {
    color: var(--orl-muted);
    font-size: var(--orl-fs-sm);
    min-width: 3.2rem;
    text-align: right;
}

/* ─── Colonnes ───────────────────────────────────────────────────────────── */

.orl-colonnes {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 190px;
    overflow-x: auto;
    padding-bottom: .25rem;
}

.orl-colonne {
    flex: 1 1 0;
    min-width: 18px;
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* La piste occupe toute la hauteur pour que les colonnes partent d'une même
   ligne de base ; sans elle, chacune se cale sur sa propre hauteur et le
   graphique n'a plus de sol. */
.orl-colonne-piste {
    flex: 1 1 auto;
    display: flex;
    align-items: flex-end;
    background: linear-gradient(var(--orl-line-soft), var(--orl-line-soft)) no-repeat center / 100% 1px;
}

.orl-colonne-valeur {
    width: 100%;
    border-radius: 3px 3px 0 0;
    transition: opacity .12s ease;
}

.orl-colonne:hover .orl-colonne-valeur { opacity: .78; }

.orl-colonne-etiquette {
    font-size: var(--orl-fs-xs);
    color: var(--orl-muted);
    text-align: center;
    padding-top: .35rem;
    white-space: nowrap;
    overflow: hidden;
}

.orl-colonne-etiquette.is-masquee { visibility: hidden; }

/* ─── Impression ─────────────────────────────────────────────────────────── */

@media print {
    /* Les cartes ne doivent pas être coupées en deux par un saut de page :
       une légende orpheline sur la page suivante ne veut plus rien dire. */
    .orl-stat-carte,
    .orl-stat-chiffre {
        break-inside: avoid;
        box-shadow: none;
    }

    .orl-stat-section { break-after: avoid; }

    /* Sans cela, les navigateurs suppriment les aplats à l'impression et le
       tableau de bord sort en barres blanches. */
    .orl-barre-valeur,
    .orl-colonne-valeur,
    .orl-anneau-puce,
    .orl-anneau-figure,
    /* Un planning du jour imprime et pose sur le comptoir est un usage reel :
       sans cela le pense-bete sort en texte gris sur blanc, indistinct du
       reste. */
    .orl-postit {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    .orl-colonnes { overflow-x: visible; }
}

/* ─── Choix de la période ────────────────────────────────────────────────── */

.orl-stat-periode {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1.25rem;
    background: var(--orl-surface);
    border: 1px solid var(--orl-line);
    border-radius: var(--orl-radius);
    padding: .75rem .9rem;
    margin-bottom: 1.5rem;
}

.orl-stat-periode-champs {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.orl-stat-periode-champs label {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin: 0;
    font-size: var(--orl-fs-md);
    color: var(--orl-muted);
}

.orl-stat-periode-champs input[type="date"] { width: auto; }

.orl-stat-raccourcis {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-left: auto;
}

/* Des liens, et non des boutons : la période vit dans l'adresse, donc chaque
   raccourci se met en favori et s'ouvre dans un nouvel onglet. */
.orl-stat-raccourci {
    font-size: var(--orl-fs-sm);
    color: var(--orl-accent-dark);
    text-decoration: none;
    padding: .2rem .6rem;
    border: 1px solid var(--orl-line);
    border-radius: 999px;
    white-space: nowrap;
}

.orl-stat-raccourci:hover {
    background: var(--orl-accent-soft);
    border-color: var(--orl-accent);
}

.orl-stat-raccourci.is-actif {
    background: var(--orl-accent);
    border-color: var(--orl-accent);
    color: var(--orl-on-brand);
}

@media print {
    /* Les contrôles ne servent à rien sur papier ; la période, si — elle est
       rappelée dans le titre. */
    .orl-stat-periode-champs,
    .orl-stat-raccourcis { display: none; }
    .orl-stat-periode { border: 0; padding: 0; }
}
